forked from stripe/stripe-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bankaccount.go
197 lines (166 loc) · 7.48 KB
/
bankaccount.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package stripe
import (
"encoding/json"
"strconv"
"github.com/stripe/stripe-go/v72/form"
)
// BankAccountAvailablePayoutMethod is a set of available payout methods for the card.
type BankAccountAvailablePayoutMethod string
// List of values that CardAvailablePayoutMethod can take.
const (
BankAccountAvailablePayoutMethodInstant BankAccountAvailablePayoutMethod = "instant"
BankAccountAvailablePayoutMethodStandard BankAccountAvailablePayoutMethod = "standard"
)
// BankAccountStatus is the list of allowed values for the bank account's status.
type BankAccountStatus string
// List of values that BankAccountStatus can take.
const (
BankAccountStatusErrored BankAccountStatus = "errored"
BankAccountStatusNew BankAccountStatus = "new"
BankAccountStatusValidated BankAccountStatus = "validated"
BankAccountStatusVerificationFailed BankAccountStatus = "verification_failed"
BankAccountStatusVerified BankAccountStatus = "verified"
)
// BankAccountAccountHolderType is the list of allowed values for the bank account holder type.
type BankAccountAccountHolderType string
// List of values that BankAccountAccountHolderType can take.
const (
BankAccountAccountHolderTypeCompany BankAccountAccountHolderType = "company"
BankAccountAccountHolderTypeIndividual BankAccountAccountHolderType = "individual"
)
// BankAccountParams is the set of parameters that can be used when updating a
// bank account.
//
// Note that while form annotations are used for updates, bank accounts have
// some unusual logic on creates that necessitates manual handling of all
// parameters. See AppendToAsSourceOrExternalAccount.
type BankAccountParams struct {
Params `form:"*"`
// Account is the identifier of the parent account under which bank
// accounts are nested.
Account *string `form:"-"`
AccountHolderName *string `form:"account_holder_name"`
AccountHolderType *string `form:"account_holder_type"`
AccountNumber *string `form:"account_number"`
Country *string `form:"country"`
Currency *string `form:"currency"`
Customer *string `form:"-"`
DefaultForCurrency *bool `form:"default_for_currency"`
RoutingNumber *string `form:"routing_number"`
// Token is a token referencing an external account like one returned from
// Stripe.js.
Token *string `form:"-"`
// ID is used when tokenizing a bank account for shared customers
ID *string `form:"*"`
}
// AppendToAsSourceOrExternalAccount appends the given BankAccountParams as
// either a source or external account.
//
// It may look like an AppendTo from the form package, but it's not, and is
// only used in the special case where we use `bankaccount.New`. It's needed
// because we have some weird encoding logic here that can't be handled by the
// form package (and it's special enough that it wouldn't be desirable to have
// it do so).
//
// This is not a pattern that we want to push forward, and this largely exists
// because the bank accounts endpoint is a little unusual. There is one other
// resource like it, which is cards.
func (a *BankAccountParams) AppendToAsSourceOrExternalAccount(body *form.Values) {
// Rather than being called in addition to `AppendTo`, this function
// *replaces* `AppendTo`, so we must also make sure to handle the encoding
// of `Params` so metadata and the like is included in the encoded payload.
form.AppendTo(body, a.Params)
isCustomer := a.Customer != nil
var sourceType string
if isCustomer {
sourceType = "source"
} else {
sourceType = "external_account"
}
// Use token (if exists) or a dictionary containing a user’s bank account details.
if a.Token != nil {
body.Add(sourceType, StringValue(a.Token))
if a.DefaultForCurrency != nil {
body.Add("default_for_currency", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
}
} else {
body.Add(sourceType+"[object]", "bank_account")
body.Add(sourceType+"[country]", StringValue(a.Country))
body.Add(sourceType+"[account_number]", StringValue(a.AccountNumber))
body.Add(sourceType+"[currency]", StringValue(a.Currency))
// These are optional and the API will fail if we try to send empty
// values in for them, so make sure to check that they're actually set
// before encoding them.
if a.AccountHolderName != nil {
body.Add(sourceType+"[account_holder_name]", StringValue(a.AccountHolderName))
}
if a.AccountHolderType != nil {
body.Add(sourceType+"[account_holder_type]", StringValue(a.AccountHolderType))
}
if a.RoutingNumber != nil {
body.Add(sourceType+"[routing_number]", StringValue(a.RoutingNumber))
}
if a.DefaultForCurrency != nil {
body.Add(sourceType+"[default_for_currency]", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
}
}
}
// BankAccountListParams is the set of parameters that can be used when listing bank accounts.
type BankAccountListParams struct {
ListParams `form:"*"`
// The identifier of the parent account under which the bank accounts are
// nested. Either Account or Customer should be populated.
Account *string `form:"-"`
// The identifier of the parent customer under which the bank accounts are
// nested. Either Account or Customer should be populated.
Customer *string `form:"-"`
}
// AppendTo implements custom encoding logic for BankAccountListParams
// so that we can send the special required `object` field up along with the
// other specified parameters.
func (p *BankAccountListParams) AppendTo(body *form.Values, keyParts []string) {
body.Add(form.FormatKey(append(keyParts, "object")), "bank_account")
}
// BankAccount represents a Stripe bank account.
type BankAccount struct {
APIResource
Account *Account `json:"account"`
AccountHolderName string `json:"account_holder_name"`
AccountHolderType BankAccountAccountHolderType `json:"account_holder_type"`
AvailablePayoutMethods []BankAccountAvailablePayoutMethod `json:"available_payout_methods"`
BankName string `json:"bank_name"`
Country string `json:"country"`
Currency Currency `json:"currency"`
Customer *Customer `json:"customer"`
DefaultForCurrency bool `json:"default_for_currency"`
Deleted bool `json:"deleted"`
Fingerprint string `json:"fingerprint"`
ID string `json:"id"`
Last4 string `json:"last4"`
Metadata map[string]string `json:"metadata"`
Object string `json:"object"`
RoutingNumber string `json:"routing_number"`
Status BankAccountStatus `json:"status"`
}
// BankAccountList is a list object for bank accounts.
type BankAccountList struct {
APIResource
ListMeta
Data []*BankAccount `json:"data"`
}
// UnmarshalJSON handles deserialization of a BankAccount.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (b *BankAccount) UnmarshalJSON(data []byte) error {
if id, ok := ParseID(data); ok {
b.ID = id
return nil
}
type bankAccount BankAccount
var v bankAccount
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*b = BankAccount(v)
return nil
}