mirror of
https://github.com/rjNemo/go-wiki
synced 2026-06-06 02:36:40 +00:00
202 lines
5.6 KiB
Go
202 lines
5.6 KiB
Go
package stripe
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/stripe/stripe-go/form"
|
|
)
|
|
|
|
// PaymentSourceType consts represent valid payment sources.
|
|
type PaymentSourceType string
|
|
|
|
// List of values that PaymentSourceType can take.
|
|
const (
|
|
PaymentSourceTypeAccount PaymentSourceType = "account"
|
|
PaymentSourceTypeBankAccount PaymentSourceType = "bank_account"
|
|
PaymentSourceTypeBitcoinReceiver PaymentSourceType = "bitcoin_receiver"
|
|
PaymentSourceTypeCard PaymentSourceType = "card"
|
|
PaymentSourceTypeObject PaymentSourceType = "source"
|
|
)
|
|
|
|
// SourceParams is a union struct used to describe an
|
|
// arbitrary payment source.
|
|
type SourceParams struct {
|
|
Card *CardParams `form:"-"`
|
|
Token *string `form:"source"`
|
|
}
|
|
|
|
// AppendTo implements custom encoding logic for SourceParams.
|
|
func (p *SourceParams) AppendTo(body *form.Values, keyParts []string) {
|
|
if p.Card != nil {
|
|
p.Card.AppendToAsCardSourceOrExternalAccount(body, keyParts)
|
|
}
|
|
}
|
|
|
|
// CustomerSourceParams are used to manipulate a given Stripe
|
|
// Customer object's payment sources.
|
|
// For more details see https://stripe.com/docs/api#sources
|
|
type CustomerSourceParams struct {
|
|
Params `form:"*"`
|
|
Customer *string `form:"-"` // Goes in the URL
|
|
Source *SourceParams `form:"*"` // SourceParams has custom encoding so brought to top level with "*"
|
|
}
|
|
|
|
// SourceVerifyParams are used to verify a customer source
|
|
// For more details see https://stripe.com/docs/guides/ach-beta
|
|
type SourceVerifyParams struct {
|
|
Params `form:"*"`
|
|
Amounts [2]int64 `form:"amounts"` // Amounts is used when verifying bank accounts
|
|
Customer *string `form:"-"` // Goes in the URL
|
|
Values []*string `form:"values"` // Values is used when verifying sources
|
|
}
|
|
|
|
// SetSource adds valid sources to a CustomerSourceParams object,
|
|
// returning an error for unsupported sources.
|
|
func (cp *CustomerSourceParams) SetSource(sp interface{}) error {
|
|
source, err := SourceParamsFor(sp)
|
|
cp.Source = source
|
|
return err
|
|
}
|
|
|
|
// SourceParamsFor creates SourceParams objects around supported
|
|
// payment sources, returning errors if not.
|
|
//
|
|
// Currently supported source types are Card (CardParams) and
|
|
// Tokens/IDs (string), where Tokens could be single use card
|
|
// tokens or bitcoin receiver ids
|
|
func SourceParamsFor(obj interface{}) (*SourceParams, error) {
|
|
var sp *SourceParams
|
|
var err error
|
|
switch p := obj.(type) {
|
|
case *CardParams:
|
|
sp = &SourceParams{
|
|
Card: p,
|
|
}
|
|
case string:
|
|
sp = &SourceParams{
|
|
Token: &p,
|
|
}
|
|
default:
|
|
err = fmt.Errorf("Unsupported source type %s", p)
|
|
}
|
|
return sp, err
|
|
}
|
|
|
|
// PaymentSource describes the payment source used to make a Charge.
|
|
// The Type should indicate which object is fleshed out (eg. BitcoinReceiver or Card)
|
|
// For more details see https://stripe.com/docs/api#retrieve_charge
|
|
type PaymentSource struct {
|
|
BankAccount *BankAccount `json:"-"`
|
|
BitcoinReceiver *BitcoinReceiver `json:"-"`
|
|
Card *Card `json:"-"`
|
|
Deleted bool `json:"deleted"`
|
|
ID string `json:"id"`
|
|
SourceObject *Source `json:"-"`
|
|
Type PaymentSourceType `json:"object"`
|
|
}
|
|
|
|
// SourceList is a list object for cards.
|
|
type SourceList struct {
|
|
ListMeta
|
|
Data []*PaymentSource `json:"data"`
|
|
}
|
|
|
|
// SourceListParams are used to enumerate the payment sources that are attached
|
|
// to a Customer.
|
|
type SourceListParams struct {
|
|
ListParams `form:"*"`
|
|
Customer *string `form:"-"` // Handled in URL
|
|
}
|
|
|
|
// UnmarshalJSON handles deserialization of a PaymentSource.
|
|
// This custom unmarshaling is needed because the specific
|
|
// type of payment instrument it refers to is specified in the JSON
|
|
func (s *PaymentSource) UnmarshalJSON(data []byte) error {
|
|
if id, ok := ParseID(data); ok {
|
|
s.ID = id
|
|
return nil
|
|
}
|
|
|
|
type paymentSource PaymentSource
|
|
var v paymentSource
|
|
if err := json.Unmarshal(data, &v); err != nil {
|
|
return err
|
|
}
|
|
|
|
var err error
|
|
*s = PaymentSource(v)
|
|
|
|
switch s.Type {
|
|
case PaymentSourceTypeBankAccount:
|
|
err = json.Unmarshal(data, &s.BankAccount)
|
|
case PaymentSourceTypeBitcoinReceiver:
|
|
err = json.Unmarshal(data, &s.BitcoinReceiver)
|
|
case PaymentSourceTypeCard:
|
|
err = json.Unmarshal(data, &s.Card)
|
|
case PaymentSourceTypeObject:
|
|
err = json.Unmarshal(data, &s.SourceObject)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
// MarshalJSON handles serialization of a PaymentSource.
|
|
// This custom marshaling is needed because the specific type
|
|
// of payment instrument it represents is specified by the Type
|
|
func (s *PaymentSource) MarshalJSON() ([]byte, error) {
|
|
var target interface{}
|
|
|
|
switch s.Type {
|
|
case PaymentSourceTypeBitcoinReceiver:
|
|
target = struct {
|
|
*BitcoinReceiver
|
|
Type PaymentSourceType `json:"object"`
|
|
}{
|
|
BitcoinReceiver: s.BitcoinReceiver,
|
|
Type: s.Type,
|
|
}
|
|
case PaymentSourceTypeCard:
|
|
var customerID *string
|
|
if s.Card.Customer != nil {
|
|
customerID = &s.Card.Customer.ID
|
|
}
|
|
|
|
target = struct {
|
|
*Card
|
|
Customer *string `json:"customer"`
|
|
Type PaymentSourceType `json:"object"`
|
|
}{
|
|
Card: s.Card,
|
|
Customer: customerID,
|
|
Type: s.Type,
|
|
}
|
|
case PaymentSourceTypeAccount:
|
|
target = struct {
|
|
ID string `json:"id"`
|
|
Type PaymentSourceType `json:"object"`
|
|
}{
|
|
ID: s.ID,
|
|
Type: s.Type,
|
|
}
|
|
case PaymentSourceTypeBankAccount:
|
|
var customerID *string
|
|
if s.BankAccount.Customer != nil {
|
|
customerID = &s.BankAccount.Customer.ID
|
|
}
|
|
|
|
target = struct {
|
|
*BankAccount
|
|
Customer *string `json:"customer"`
|
|
Type PaymentSourceType `json:"object"`
|
|
}{
|
|
BankAccount: s.BankAccount,
|
|
Customer: customerID,
|
|
Type: s.Type,
|
|
}
|
|
case "":
|
|
target = s.ID
|
|
}
|
|
|
|
return json.Marshal(target)
|
|
}
|