From b74a522d98f94d6c1e77689dc463a5902e61b63c Mon Sep 17 00:00:00 2001 From: Remi Jannel Date: Sun, 3 May 2020 20:40:32 -0700 Subject: [PATCH] Add support for the `LineItem` resource and APIs --- .travis.yml | 2 +- checkout/session/client.go | 22 ++++++++++++++++ checkout_session.go | 44 ++++++++++++++++++++++++++------ lineitem.go | 51 ++++++++++++++++++++++++++++++++++++++ lineitem/client.go | 16 ++++++++++++ testing/testing.go | 2 +- 6 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 lineitem.go create mode 100644 lineitem/client.go diff --git a/.travis.yml b/.travis.yml index aedf4db1e0..c6250b51f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ cache: env: global: # If changing this number, please also change it in `testing/testing.go`. - - STRIPE_MOCK_VERSION=0.89.0 + - STRIPE_MOCK_VERSION=0.90.0 go: - "1.10.x" diff --git a/checkout/session/client.go b/checkout/session/client.go index 27da0f563b..ae73040769 100644 --- a/checkout/session/client.go +++ b/checkout/session/client.go @@ -6,6 +6,7 @@ import ( stripe "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/form" + "github.com/stripe/stripe-go/v71/lineitem" ) // Client is used to invoke /checkout_sessions APIs. @@ -59,6 +60,27 @@ func (c Client) List(listParams *stripe.CheckoutSessionListParams) *Iter { })} } +// ListLineItems returns a list of line items on a session. +func ListLineItems(params *stripe.CheckoutSessionListLineItemParams) *lineitem.Iter { + return getC().ListLineItems(params) +} + +// ListLineItems returns a list of line items on a session. +func (c Client) ListLineItems(listParams *stripe.CheckoutSessionListLineItemParams) *lineitem.Iter { + path := stripe.FormatURLPath("/v1/checkout/sessions/%s/line_items", stripe.StringValue(listParams.Session)) + return &lineitem.Iter{stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListMeta, error) { + list := &stripe.LineItemList{} + err := c.B.CallRaw(http.MethodGet, path, c.Key, b, p, list) + + ret := make([]interface{}, len(list.Data)) + for i, v := range list.Data { + ret[i] = v + } + + return ret, list.ListMeta, err + })} +} + // Iter is an iterator for sessions. type Iter struct { *stripe.Iter diff --git a/checkout_session.go b/checkout_session.go index 6eee1c19a6..e6d98d8caa 100644 --- a/checkout_session.go +++ b/checkout_session.go @@ -36,16 +36,38 @@ const ( CheckoutSessionModeSubscription CheckoutSessionMode = "subscription" ) +// CheckoutSessionLineItemPriceDataRecurringParams is the set of parameters for the recurring +// components of a price created inline for a line item +type CheckoutSessionLineItemPriceDataRecurringParams struct { + AggregateUsage *string `form:"aggregate_usage"` + Interval *string `form:"interval"` + IntervalCount *int64 `form:"interval_count"` + TrialPeriodDays *int64 `form:"trial_period_days"` + UsageType *string `form:"usage_type"` +} + +// CheckoutSessionLineItemPriceDataParams is a structure representing the parameters to create +// an inline price for a line item. +type CheckoutSessionLineItemPriceDataParams struct { + Currency *string `form:"currency"` + Product *string `form:"product"` + Recurring *CheckoutSessionLineItemPriceDataRecurringParams `form:"recurring"` + UnitAmount *int64 `form:"unit_amount"` + UnitAmountDecimal *float64 `form:"unit_amount_decimal,high_precision"` +} + // 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"` - TaxRates []*string `form:"tax_rates"` + Amount *int64 `form:"amount"` + Currency *string `form:"currency"` + Description *string `form:"description"` + Images []*string `form:"images"` + Name *string `form:"name"` + Price *string `form:"price"` + PriceData *CheckoutSessionLineItemPriceDataParams `form:"price_data"` + Quantity *int64 `form:"quantity"` + TaxRates []*string `form:"tax_rates"` } // CheckoutSessionPaymentIntentDataTransferDataParams is the set of parameters allowed for the @@ -130,6 +152,13 @@ type CheckoutSessionParams struct { SuccessURL *string `form:"success_url"` } +// CheckoutSessionListLineItemParams is the set of parameters that can be +// used when listing line items on a session. +type CheckoutSessionListLineItemParams struct { + ListParams `form:"*"` + Session *string `form:"-"` // Included in URL +} + // CheckoutSessionListParams is the set of parameters that can be // used when listing sessions. // For more details see: https://stripe.com/docs/api/checkout/sessions/list @@ -174,6 +203,7 @@ type CheckoutSession struct { Deleted bool `json:"deleted"` DisplayItems []*CheckoutSessionDisplayItem `json:"display_items"` ID string `json:"id"` + LineItems []*LineItem `json:"line_items"` Livemode bool `json:"livemode"` Locale string `json:"locale"` Metadata map[string]string `json:"metadata"` diff --git a/lineitem.go b/lineitem.go new file mode 100644 index 0000000000..f09c46df6a --- /dev/null +++ b/lineitem.go @@ -0,0 +1,51 @@ +package stripe + +import ( + "encoding/json" +) + +// LineItemTax represent the details of one tax rate applied to a line item. +type LineItemTax struct { + Amount int64 `json:"amount"` + TaxRate *TaxRate `json:"tax_rate"` +} + +// LineItem is the resource representing a line item. +type LineItem struct { + APIResource + AmountSubtotal int64 `json:"amount_subtotal"` + AmountTotal int64 `json:"amount_total"` + Currency Currency `json:"currency"` + Description string `json:"description"` + ID string `json:"id"` + Object string `json:"object"` + Price *Price `json:"price"` + Quantity int64 `json:"quantity"` + Taxes []*LineItemTax `json:"taxes"` +} + +// LineItemList is a list of prices as returned from a list endpoint. +type LineItemList struct { + APIResource + ListMeta + Data []*LineItem `json:"data"` +} + +// UnmarshalJSON handles deserialization of a LineItem. +// This custom unmarshaling is needed because the resulting +// property may be an id or the full struct if it was expanded. +func (s *LineItem) UnmarshalJSON(data []byte) error { + if id, ok := ParseID(data); ok { + s.ID = id + return nil + } + + type price LineItem + var v price + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + *s = LineItem(v) + return nil +} diff --git a/lineitem/client.go b/lineitem/client.go new file mode 100644 index 0000000000..2cf22ab0ea --- /dev/null +++ b/lineitem/client.go @@ -0,0 +1,16 @@ +// Package lineitem provides the tools needs to interact with the LineItem resource. +package lineitem + +import ( + stripe "github.com/stripe/stripe-go/v71" +) + +// Iter is an iterator for line items across various resources. +type Iter struct { + *stripe.Iter +} + +// LineItem returns the line item which the iterator is currently pointing to. +func (i *Iter) LineItem() *stripe.LineItem { + return i.Current().(*stripe.LineItem) +} diff --git a/testing/testing.go b/testing/testing.go index 9b104cac2f..13b7e85c7a 100644 --- a/testing/testing.go +++ b/testing/testing.go @@ -25,7 +25,7 @@ const ( // added in a more recent version of stripe-mock, we can show people a // better error message instead of the test suite crashing with a bunch of // confusing 404 errors or the like. - MockMinimumVersion = "0.89.0" + MockMinimumVersion = "0.90.0" // TestMerchantID is a token that can be used to represent a merchant ID in // simple tests.