stripe / stripe-go

Go library for the Stripe API.
https://stripe.com
MIT License
2.13k stars 459 forks source link

Support bidirectional marshalling/unmarshalling #1198

Open nghtstr opened 3 years ago

nghtstr commented 3 years ago

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 commented 3 years ago

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:

https://github.com/stripe/stripe-go/blob/6bbf08329864a94a53a1583e52b859bea05e57b2/source.go#L333-L353

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 commented 3 years ago

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