From ea3749a2065767bac6100f378f3c7f582ae86b59 Mon Sep 17 00:00:00 2001 From: Remi Jannel Date: Wed, 16 Jan 2019 20:03:26 -0800 Subject: [PATCH] Add support for Checkout Session --- checkout/session/client.go | 43 ++++++++++ checkout/session/client_test.go | 51 ++++++++++++ checkout_session.go | 136 ++++++++++++++++++++++++++++++++ client/api.go | 4 + 4 files changed, 234 insertions(+) create mode 100644 checkout/session/client.go create mode 100644 checkout/session/client_test.go create mode 100644 checkout_session.go diff --git a/checkout/session/client.go b/checkout/session/client.go new file mode 100644 index 0000000000..07a8d06b16 --- /dev/null +++ b/checkout/session/client.go @@ -0,0 +1,43 @@ +// Package session provides API functions related to checkout sessions. +package session + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go" +) + +// Client is used to invoke /checkout_sessions APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new session. +func New(params *stripe.CheckoutSessionParams) (*stripe.CheckoutSession, error) { + return getC().New(params) +} + +// New creates a new session. +func (c Client) New(params *stripe.CheckoutSessionParams) (*stripe.CheckoutSession, error) { + session := &stripe.CheckoutSession{} + err := c.B.Call(http.MethodPost, "/v1/checkout/sessions", c.Key, params, session) + return session, err +} + +// Get retrieves a session. +func Get(id string, params *stripe.CheckoutSessionParams) (*stripe.CheckoutSession, error) { + return getC().Get(id, params) +} + +// Get retrieves a session. +func (c Client) Get(id string, params *stripe.CheckoutSessionParams) (*stripe.CheckoutSession, error) { + path := stripe.FormatURLPath("/v1/checkout/sessions/%s", id) + session := &stripe.CheckoutSession{} + err := c.B.Call(http.MethodGet, path, c.Key, params, session) + return session, err +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/checkout/session/client_test.go b/checkout/session/client_test.go new file mode 100644 index 0000000000..cb65303bad --- /dev/null +++ b/checkout/session/client_test.go @@ -0,0 +1,51 @@ +package session + +import ( + "testing" + + assert "github.com/stretchr/testify/require" + stripe "github.com/stripe/stripe-go" + _ "github.com/stripe/stripe-go/testing" +) + +func TestCheckoutSessionGet(t *testing.T) { + session, err := Get("cs_123", nil) + assert.Nil(t, err) + assert.NotNil(t, session) +} + +func TestCheckoutSessionNew(t *testing.T) { + session, err := New(&stripe.CheckoutSessionParams{ + CancelURL: stripe.String("https://stripe.com/cancel"), + ClientReferenceID: stripe.String("1234"), + LineItems: []*stripe.CheckoutSessionLineItemParams{ + { + Amount: stripe.Int64(1234), + Currency: stripe.String(string(stripe.CurrencyUSD)), + Description: stripe.String("description"), + Images: []*string{ + stripe.String("https://stripe.com/image1"), + }, + Name: stripe.String("name"), + Quantity: stripe.Int64(2), + }, + }, + PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ + Description: stripe.String("description"), + Shipping: &stripe.ShippingDetailsParams{ + Address: &stripe.AddressParams{ + Line1: stripe.String("line1"), + City: stripe.String("city"), + }, + Carrier: stripe.String("carrier"), + Name: stripe.String("name"), + }, + }, + PaymentMethodTypes: []*string{ + stripe.String("card"), + }, + SuccessURL: stripe.String("https://stripe.com/success"), + }) + assert.Nil(t, err) + assert.NotNil(t, session) +} diff --git a/checkout_session.go b/checkout_session.go new file mode 100644 index 0000000000..afe77535e8 --- /dev/null +++ b/checkout_session.go @@ -0,0 +1,136 @@ +package stripe + +import ( + "encoding/json" +) + +// CheckoutSessionDisplayItemType is the list of allowed values for the display item type. +type CheckoutSessionDisplayItemType string + +// List of values that CheckoutSessionDisplayItemType can take. +const ( + CheckoutSessionDisplayItemTypeCustom CheckoutSessionDisplayItemType = "custom" + CheckoutSessionDisplayItemTypePlan CheckoutSessionDisplayItemType = "plan" + CheckoutSessionDisplayItemTypeSKU CheckoutSessionDisplayItemType = "sku" +) + +// CheckoutSessionLineItemParams is the set of parameters allowed for a line item +// on a checkout session. +type CheckoutSessionLineItemParams struct { + Amount *int64 `form:"amount"` + Currency *string `form:"currency"` + Description *string `form:"description"` + Images []*string `form:"images"` + Name *string `form:"name"` + Quantity *int64 `form:"quantity"` +} + +// CheckoutSessionPaymentIntentDataTransferDataParams is the set of parameters allowed for the +// transfer_data hash. +type CheckoutSessionPaymentIntentDataTransferDataParams struct { + Destination *string `form:"destination"` +} + +// CheckoutSessionPaymentIntentDataParams is the set of parameters allowed for the +// payment intent creation on a checkout session. +type CheckoutSessionPaymentIntentDataParams struct { + Params `form:"*"` + ApplicationFeeAmount *int64 `form:"application_fee_amount"` + CaptureMethod *string `form:"capture_method"` + Description *string `form:"description"` + OnBehalfOf *string `form:"on_behalf_of"` + ReceiptEmail *string `form:"receipt_email"` + Shipping *ShippingDetailsParams `form:"shipping"` + StatementDescriptor *string `form:"statement_descriptor"` + TransferData *CheckoutSessionPaymentIntentDataTransferDataParams `form:"transfer_data"` +} + +// CheckoutSessionSubscriptionDataItemsParams is the set of parameters allowed for one item on a +// checkout session associated with a subscription. +type CheckoutSessionSubscriptionDataItemsParams struct { + Plan *string `form:"plan"` + Quantity *int64 `form:"quantity"` +} + +// CheckoutSessionSubscriptionDataParams is the set of parameters allowed for the subscription +// creation on a checkout session. +type CheckoutSessionSubscriptionDataParams struct { + Params `form:"*"` + Items *CheckoutSessionSubscriptionDataItemsParams `form:"items"` + TrialEnd *int64 `form:"trial_end"` + TrialPeriodDays *int64 `form:"trial_period_days"` +} + +// CheckoutSessionParams is the set of parameters that can be used when creating +// a checkout session. +// For more details see https://stripe.com/docs/api/checkout/sessions/create +type CheckoutSessionParams struct { + Params `form:"*"` + BillingAddressCollection *string `form:"billing_address_collection"` + CancelURL *string `form:"cancel_url"` + ClientReferenceID *string `form:"client_reference_id"` + Customer *string `form:"customer"` + CustomerEmail *string `form:"customer_email"` + LineItems []*CheckoutSessionLineItemParams `form:"line_items"` + Locale *string `form:"locale"` + PaymentIntentData *CheckoutSessionPaymentIntentDataParams `form:"payment_intent_data"` + PaymentMethodTypes []*string `form:"payment_method_types"` + SubscriptionData *CheckoutSessionSubscriptionDataParams `form:"subscription_data"` + SuccessURL *string `form:"success_url"` +} + +// CheckoutSessionDisplayItemCustom represents an item of type custom in a checkout session +type CheckoutSessionDisplayItemCustom struct { + Description string `json:"description"` + Images []string `json:"images"` + Name string `json:"name"` +} + +// CheckoutSessionDisplayItem represents one of the items in a checkout session. +type CheckoutSessionDisplayItem struct { + Amount int64 `json:"amount"` + Currency Currency `json:"currency"` + Custom *CheckoutSessionDisplayItemCustom `json:"custom"` + Quantity int64 `json:"quantity"` + Plan *Plan `json:"plan"` + SKU *SKU `json:"sku"` + Type CheckoutSessionDisplayItemType `json:"type"` +} + +// CheckoutSession is the resource representing a Stripe checkout session. +// For more details see https://stripe.com/docs/api/checkout/sessions/object +type CheckoutSession struct { + CancelURL string `json:"cancel_url"` + ClientReferenceID string `json:"client_reference_id"` + Customer *Customer `json:"customer"` + CustomerEmail string `json:"customer_email"` + Deleted bool `json:"deleted"` + DisplayItems []*CheckoutSessionDisplayItem `json:"display_items"` + ID string `json:"id"` + Livemode bool `json:"livemode"` + Locale string `json:"locale"` + Object string `json:"object"` + PaymentIntent *PaymentIntent `json:"payment_intent"` + PaymentMethodTypes []string `json:"payment_method_types"` + Subscription *Subscription `json:"subscription"` + SuccessURL string `json:"success_url"` +} + +// UnmarshalJSON handles deserialization of a checkout session. +// This custom unmarshaling is needed because the resulting +// property may be an id or the full struct if it was expanded. +func (p *CheckoutSession) UnmarshalJSON(data []byte) error { + if id, ok := ParseID(data); ok { + p.ID = id + return nil + } + + type session CheckoutSession + var v session + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + *p = CheckoutSession(v) + return nil +} diff --git a/client/api.go b/client/api.go index 49e4d4205a..e1dc3ab837 100644 --- a/client/api.go +++ b/client/api.go @@ -11,6 +11,7 @@ import ( "github.com/stripe/stripe-go/bitcointransaction" "github.com/stripe/stripe-go/card" "github.com/stripe/stripe-go/charge" + checkoutsession "github.com/stripe/stripe-go/checkout/session" "github.com/stripe/stripe-go/countryspec" "github.com/stripe/stripe-go/coupon" "github.com/stripe/stripe-go/customer" @@ -83,6 +84,8 @@ type API struct { Cards *card.Client // Charges is the client used to invoke /charges APIs. Charges *charge.Client + // CheckoutSessions is the client used to invoke /checkout_sessions APIs. + CheckoutSessions *checkoutsession.Client // CountrySpec is the client used to invoke /country_specs APIs. CountrySpec *countryspec.Client // Coupons is the client used to invoke /coupons APIs. @@ -207,6 +210,7 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.BitcoinTransactions = &bitcointransaction.Client{B: backends.API, Key: key} a.Cards = &card.Client{B: backends.API, Key: key} a.Charges = &charge.Client{B: backends.API, Key: key} + a.CheckoutSessions = &checkoutsession.Client{B: backends.API, Key: key} a.CountrySpec = &countryspec.Client{B: backends.API, Key: key} a.Coupons = &coupon.Client{B: backends.API, Key: key} a.Customers = &customer.Client{B: backends.API, Key: key}