diff --git a/.travis.yml b/.travis.yml index 9f50bdb011..33f9cb5d21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ cache: env: global: # If changing this number, please also change it in `testing/testing.go`. - - STRIPE_MOCK_VERSION=0.54.0 + - STRIPE_MOCK_VERSION=0.56.0 go: - "1.9.x" diff --git a/capability.go b/capability.go new file mode 100644 index 0000000000..c09b28ecce --- /dev/null +++ b/capability.go @@ -0,0 +1,88 @@ +package stripe + +import "encoding/json" + +// CapabilityDisabledReason describes why a capability is disabled. +type CapabilityDisabledReason string + +// List of values that CapabilityDisabledReason can take. +const ( + CapabilityDisabledReasonPendingOnboarding CapabilityDisabledReason = "pending.onboarding" + CapabilityDisabledReasonPendingReview CapabilityDisabledReason = "pending.review" + CapabilityDisabledReasonRejectedFraud CapabilityDisabledReason = "rejected_fraud" + CapabilityDisabledReasonRejectedListed CapabilityDisabledReason = "rejected.listed" + CapabilityDisabledReasonRejectedOther CapabilityDisabledReason = "rejected.other" + CapabilityDisabledReasonRequirementsFieldsNeeded CapabilityDisabledReason = "requirement.fields_needed" +) + +// CapabilityStatus describes the different statuses for a capability's status. +type CapabilityStatus string + +// List of values that CapabilityStatus can take. +const ( + CapabilityStatusActive CapabilityStatus = "active" + CapabilityStatusInactive CapabilityStatus = "inactive" + CapabilityStatusPending CapabilityStatus = "pending" + CapabilityStatusUnrequested CapabilityStatus = "unrequested" +) + +// CapabilityParams is the set of parameters that can be used when updating a capability. +// For more details see https://stripe.com/docs/api/capabilities/update +type CapabilityParams struct { + Params `form:"*"` + Account *string `form:"-"` // Included in URL + Requested *bool `form:"requested"` +} + +// CapabilityListParams is the set of parameters that can be used when listing capabilities. +// For more detail see https://stripe.com/docs/api/capabilities/list +type CapabilityListParams struct { + ListParams `form:"*"` + Account *string `form:"-"` // Included in URL +} + +// CapabilityRequirements represents information that needs to be collected for a capability. +type CapabilityRequirements struct { + CurrentDeadline int64 `json:"current_deadline"` + CurrentlyDue []string `json:"currently_due"` + DisabledReason CapabilityDisabledReason `json:"disabled_reason"` + EventuallyDue []string `json:"eventually_due"` + PastDue []string `json:"past_due"` +} + +// Capability is the resource representing a Stripe capability. +// For more details see https://stripe.com/docs/api/capabilities +type Capability struct { + Account *Account `json:"account"` + ID string `json:"id"` + Object string `json:"object"` + Requested bool `json:"requested"` + RequestedAt int64 `json:"requested_at"` + Requirements *CapabilityRequirements `json:"requirements"` + Status CapabilityStatus `json:"status"` +} + +// CapabilityList is a list of capabilities as retrieved from a list endpoint. +type CapabilityList struct { + ListMeta + Data []*Capability `json:"data"` +} + +// UnmarshalJSON handles deserialization of a Capability. +// This custom unmarshaling is needed because the resulting +// property may be an id or the full struct if it was expanded. +func (c *Capability) UnmarshalJSON(data []byte) error { + if id, ok := ParseID(data); ok { + c.ID = id + return nil + } + + type capability Capability + var v capability + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + *c = Capability(v) + return nil +} diff --git a/capability/client.go b/capability/client.go new file mode 100644 index 0000000000..3e2a7faa67 --- /dev/null +++ b/capability/client.go @@ -0,0 +1,84 @@ +// Package capability provides the /accounts/capabilities APIs +package capability + +import ( + "fmt" + "net/http" + + stripe "github.com/stripe/stripe-go" + "github.com/stripe/stripe-go/form" +) + +// Client is used to invoke /accounts/capabilities APIs. +type Client struct { + B stripe.Backend + Key string +} + +// Get returns the details of a account capability. +func Get(id string, params *stripe.CapabilityParams) (*stripe.Capability, error) { + return getC().Get(id, params) +} + +// Get returns the details of a account capability. +func (c Client) Get(id string, params *stripe.CapabilityParams) (*stripe.Capability, error) { + if params == nil { + return nil, fmt.Errorf("params cannot be nil, and params.Account must be set") + } + + path := stripe.FormatURLPath("/v1/accounts/%s/capabilities/%s", + stripe.StringValue(params.Account), id) + capability := &stripe.Capability{} + err := c.B.Call(http.MethodGet, path, c.Key, params, capability) + return capability, err +} + +// Update updates a account capability's properties. +func Update(id string, params *stripe.CapabilityParams) (*stripe.Capability, error) { + return getC().Update(id, params) +} + +// Update updates a account capability's properties. +func (c Client) Update(id string, params *stripe.CapabilityParams) (*stripe.Capability, error) { + path := stripe.FormatURLPath("/v1/accounts/%s/capabilities/%s", + stripe.StringValue(params.Account), id) + capability := &stripe.Capability{} + err := c.B.Call(http.MethodPost, path, c.Key, params, capability) + return capability, err +} + +// List returns a list of account capabilities. +func List(params *stripe.CapabilityListParams) *Iter { + return getC().List(params) +} + +// List returns a list of account capabilities. +func (c Client) List(listParams *stripe.CapabilityListParams) *Iter { + path := stripe.FormatURLPath("/v1/accounts/%s/capabilities", stripe.StringValue(listParams.Account)) + + return &Iter{stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListMeta, error) { + list := &stripe.CapabilityList{} + 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 account capabilities. +type Iter struct { + *stripe.Iter +} + +// Capability returns the account capability which the iterator is currently pointing to. +func (i *Iter) Capability() *stripe.Capability { + return i.Current().(*stripe.Capability) +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/capability/client_test.go b/capability/client_test.go new file mode 100644 index 0000000000..e3819df8fc --- /dev/null +++ b/capability/client_test.go @@ -0,0 +1,37 @@ +package capability + +import ( + "testing" + + assert "github.com/stretchr/testify/require" + stripe "github.com/stripe/stripe-go" + _ "github.com/stripe/stripe-go/testing" +) + +func TestCapabilityGet(t *testing.T) { + capability, err := Get("acap_123", &stripe.CapabilityParams{ + Account: stripe.String("acct_123"), + }) + assert.Nil(t, err) + assert.NotNil(t, capability) +} + +func TestCapabilityList(t *testing.T) { + i := List(&stripe.CapabilityListParams{ + Account: stripe.String("acct_123"), + }) + + // Verify that we can get at least one capability + assert.True(t, i.Next()) + assert.Nil(t, i.Err()) + assert.NotNil(t, i.Capability()) +} + +func TestCapabilityUpdate(t *testing.T) { + capability, err := Update("acap_123", &stripe.CapabilityParams{ + Account: stripe.String("acct_123"), + Requested: stripe.Bool(true), + }) + assert.Nil(t, err) + assert.NotNil(t, capability) +} diff --git a/client/api.go b/client/api.go index b9f0d075c3..3d38367430 100644 --- a/client/api.go +++ b/client/api.go @@ -10,6 +10,7 @@ import ( "github.com/stripe/stripe-go/bankaccount" "github.com/stripe/stripe-go/bitcoinreceiver" "github.com/stripe/stripe-go/bitcointransaction" + "github.com/stripe/stripe-go/capability" "github.com/stripe/stripe-go/card" "github.com/stripe/stripe-go/charge" checkoutsession "github.com/stripe/stripe-go/checkout/session" @@ -90,6 +91,8 @@ type API struct { BitcoinReceivers *bitcoinreceiver.Client // BitcoinTransactions is the client used to invoke /bitcoin/transactions APIs. BitcoinTransactions *bitcointransaction.Client + // Capabilities is the client used to invoke capability related APIs. + Capabilities *capability.Client // Cards is the client used to invoke card related APIs. Cards *card.Client // Charges is the client used to invoke /charges APIs. @@ -233,6 +236,7 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.BankAccounts = &bankaccount.Client{B: backends.API, Key: key} a.BitcoinReceivers = &bitcoinreceiver.Client{B: backends.API, Key: key} a.BitcoinTransactions = &bitcointransaction.Client{B: backends.API, Key: key} + a.Capabilities = &capability.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} diff --git a/testing/testing.go b/testing/testing.go index 075d5e438b..b9ab2cfc03 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.54.0" + MockMinimumVersion = "0.56.0" // TestMerchantID is a token that can be used to represent a merchant ID in // simple tests.