Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bidirectional marshalling/unmarshalling #1198

Open
nghtstr opened this issue Oct 6, 2020 · 2 comments
Open

Support bidirectional marshalling/unmarshalling #1198

nghtstr opened this issue Oct 6, 2020 · 2 comments
Labels

Comments

@nghtstr
Copy link

nghtstr commented Oct 6, 2020

When I get a customer, and expand the sources; if the source is of type Source, it does not json.Marshal correctly. Here is some basic code demonstrating that the code should work as expected:

func (h *Handle) getStripeCustomer(user *netauth.User) *stripe.Customer {
	stripe.Key = h.Options.Stripe.Key
	custID := user.Detail.Stripe // Customer ID as stored in the DB

	params := &stripe.CustomerParams{}
	params.AddExpand("sources")
	params.AddExpand("sources.data")
	params.AddExpand("sources.data.source")
	c, _ := customer.Get(custID, params)
	out, _ := json.MarshalIndent(c, "", "  ")
	fmt.Printf("List: ", string(out))

	testSource := "src_1HXWUoDEks681qEQ2rMI3gWJ" // This is a Stripe test card
	s, _ := source.Get(
		testSource,
		nil,
	)
	fmt.Printf("%+v\n", c.Sources)
	for _, src := range c.Sources.Data {
		fmt.Printf("%+v\n", src.SourceObject)
	}
	out, _ = json.MarshalIndent(s, "", "  ")
	fmt.Printf("Source: ", string(out))

	return c
}

The array of customer.Sources.Data does give the appropriate SourceObject but it does not json.Marshal correctly.

@brandur-stripe
Copy link
Contributor

Hey @nghtstr, we don't currently guarantee that the data structures in stripe-go marshal and unmarshal bidirectionally like you might expect. Most of them do, but there's a few places where structures need some pretty edgy custom UnmarshalJSON implementations to work correctly, and sources are an example of that:

stripe-go/source.go

Lines 333 to 353 in 6bbf083

func (s *Source) UnmarshalJSON(data []byte) error {
type source Source
var v source
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*s = Source(v)
var raw map[string]interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
if d, ok := raw[s.Type]; ok {
if m, ok := d.(map[string]interface{}); ok {
s.TypeData = m
}
}
return nil
}

If you want to store Stripe data somewhere, we'd recommend mapping the stripe-go structures to your own internal variant of such — that way you have full control over how marshaling and unmarshaling works, and won't be broken by any future changes that we might make.

@richardm-stripe richardm-stripe changed the title customer.Sources does not json.Marshal correctly when the source is a source. Support bidirectional marshalling/unmarshalling Oct 13, 2020
@richardm-stripe
Copy link
Contributor

Per some internal discussion, bidirectional marshalling/unmarshalling would be a nice-to-have, so I'm rebranding this as a feature request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants