mirror of
https://github.com/rjNemo/go-wiki
synced 2026-06-06 02:36:40 +00:00
269 lines
8.2 KiB
Go
269 lines
8.2 KiB
Go
package stripe
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/stripe/stripe-go/form"
|
|
)
|
|
|
|
//
|
|
// Public constants
|
|
//
|
|
|
|
// Contains constants for the names of parameters used for pagination in list APIs.
|
|
const (
|
|
EndingBefore = "ending_before"
|
|
StartingAfter = "starting_after"
|
|
)
|
|
|
|
//
|
|
// Public types
|
|
//
|
|
|
|
// ExtraValues are extra parameters that are attached to an API request.
|
|
// They're implemented as a custom type so that they can have their own
|
|
// AppendTo implementation.
|
|
type ExtraValues struct {
|
|
url.Values `form:"-"` // See custom AppendTo implementation
|
|
}
|
|
|
|
// AppendTo implements custom form encoding for extra parameter values.
|
|
func (v ExtraValues) AppendTo(body *form.Values, keyParts []string) {
|
|
for k, vs := range v.Values {
|
|
for _, v := range vs {
|
|
body.Add(form.FormatKey(append(keyParts, k)), v)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Filters is a structure that contains a collection of filters for list-related APIs.
|
|
type Filters struct {
|
|
f []*filter `form:"-"` // See custom AppendTo implementation
|
|
}
|
|
|
|
// AddFilter adds a new filter with a given key, op and value.
|
|
func (f *Filters) AddFilter(key, op, value string) {
|
|
filter := &filter{Key: key, Op: op, Val: value}
|
|
f.f = append(f.f, filter)
|
|
}
|
|
|
|
// AppendTo implements custom form encoding for filters.
|
|
func (f Filters) AppendTo(body *form.Values, keyParts []string) {
|
|
if len(f.f) > 0 {
|
|
for _, v := range f.f {
|
|
if len(v.Op) > 0 {
|
|
body.Add(form.FormatKey(append(keyParts, v.Key, v.Op)), v.Val)
|
|
} else {
|
|
body.Add(form.FormatKey(append(keyParts, v.Key)), v.Val)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ListMeta is the structure that contains the common properties
|
|
// of List iterators. The Count property is only populated if the
|
|
// total_count include option is passed in (see tests for example).
|
|
type ListMeta struct {
|
|
HasMore bool `json:"has_more"`
|
|
TotalCount uint32 `json:"total_count"`
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
// ListParams is the structure that contains the common properties
|
|
// of any *ListParams structure.
|
|
type ListParams struct {
|
|
// Context used for request. It may carry deadlines, cancelation signals,
|
|
// and other request-scoped values across API boundaries and between
|
|
// processes.
|
|
//
|
|
// Note that a cancelled or timed out context does not provide any
|
|
// guarantee whether the operation was or was not completed on Stripe's API
|
|
// servers. For certainty, you must either retry with the same idempotency
|
|
// key or query the state of the API.
|
|
Context context.Context `form:"-"`
|
|
|
|
EndingBefore *string `form:"ending_before"`
|
|
Expand []*string `form:"expand"`
|
|
Filters Filters `form:"*"`
|
|
Limit *int64 `form:"limit"`
|
|
|
|
// Single specifies whether this is a single page iterator. By default,
|
|
// listing through an iterator will automatically grab additional pages as
|
|
// the query progresses. To change this behavior and just load a single
|
|
// page, set this to true.
|
|
Single bool `form:"-"` // Not an API parameter
|
|
|
|
StartingAfter *string `form:"starting_after"`
|
|
|
|
// StripeAccount may contain the ID of a connected account. By including
|
|
// this field, the request is made as if it originated from the connected
|
|
// account instead of under the account of the owner of the configured
|
|
// Stripe key.
|
|
StripeAccount *string `form:"-"` // Passed as header
|
|
}
|
|
|
|
// AddExpand appends a new field to expand.
|
|
func (p *ListParams) AddExpand(f string) {
|
|
p.Expand = append(p.Expand, &f)
|
|
}
|
|
|
|
// GetListParams returns a ListParams struct (itself). It exists because any
|
|
// structs that embed ListParams will inherit it, and thus implement the
|
|
// ListParamsContainer interface.
|
|
func (p *ListParams) GetListParams() *ListParams {
|
|
return p
|
|
}
|
|
|
|
// GetParams returns ListParams as a Params struct. It exists because any
|
|
// structs that embed Params will inherit it, and thus implement the
|
|
// ParamsContainer interface.
|
|
func (p *ListParams) GetParams() *Params {
|
|
return p.ToParams()
|
|
}
|
|
|
|
// SetStripeAccount sets a value for the Stripe-Account header.
|
|
func (p *ListParams) SetStripeAccount(val string) {
|
|
p.StripeAccount = &val
|
|
}
|
|
|
|
// ToParams converts a ListParams to a Params by moving over any fields that
|
|
// have valid targets in the new type. This is useful because fields in
|
|
// Params can be injected directly into an http.Request while generally
|
|
// ListParams is only used to build a set of parameters.
|
|
func (p *ListParams) ToParams() *Params {
|
|
return &Params{
|
|
Context: p.Context,
|
|
StripeAccount: p.StripeAccount,
|
|
}
|
|
}
|
|
|
|
// ListParamsContainer is a general interface for which all list parameter
|
|
// structs should comply. They achieve this by embedding a ListParams struct
|
|
// and inheriting its implementation of this interface.
|
|
type ListParamsContainer interface {
|
|
GetListParams() *ListParams
|
|
}
|
|
|
|
// Params is the structure that contains the common properties
|
|
// of any *Params structure.
|
|
type Params struct {
|
|
// Context used for request. It may carry deadlines, cancelation signals,
|
|
// and other request-scoped values across API boundaries and between
|
|
// processes.
|
|
//
|
|
// Note that a cancelled or timed out context does not provide any
|
|
// guarantee whether the operation was or was not completed on Stripe's API
|
|
// servers. For certainty, you must either retry with the same idempotency
|
|
// key or query the state of the API.
|
|
Context context.Context `form:"-"`
|
|
|
|
Expand []*string `form:"expand"`
|
|
Extra *ExtraValues `form:"*"`
|
|
|
|
// Headers may be used to provide extra header lines on the HTTP request.
|
|
Headers http.Header `form:"-"`
|
|
|
|
IdempotencyKey *string `form:"-"` // Passed as header
|
|
Metadata map[string]string `form:"metadata"`
|
|
|
|
// StripeAccount may contain the ID of a connected account. By including
|
|
// this field, the request is made as if it originated from the connected
|
|
// account instead of under the account of the owner of the configured
|
|
// Stripe key.
|
|
StripeAccount *string `form:"-"` // Passed as header
|
|
}
|
|
|
|
// AddExpand appends a new field to expand.
|
|
func (p *Params) AddExpand(f string) {
|
|
p.Expand = append(p.Expand, &f)
|
|
}
|
|
|
|
// AddExtra adds a new arbitrary key-value pair to the request data
|
|
func (p *Params) AddExtra(key, value string) {
|
|
if p.Extra == nil {
|
|
p.Extra = &ExtraValues{Values: make(url.Values)}
|
|
}
|
|
|
|
p.Extra.Add(key, value)
|
|
}
|
|
|
|
// AddMetadata adds a new key-value pair to the Metadata.
|
|
func (p *Params) AddMetadata(key, value string) {
|
|
if p.Metadata == nil {
|
|
p.Metadata = make(map[string]string)
|
|
}
|
|
|
|
p.Metadata[key] = value
|
|
}
|
|
|
|
// GetParams returns a Params struct (itself). It exists because any structs
|
|
// that embed Params will inherit it, and thus implement the ParamsContainer
|
|
// interface.
|
|
func (p *Params) GetParams() *Params {
|
|
return p
|
|
}
|
|
|
|
// SetIdempotencyKey sets a value for the Idempotency-Key header.
|
|
func (p *Params) SetIdempotencyKey(val string) {
|
|
p.IdempotencyKey = &val
|
|
}
|
|
|
|
// SetStripeAccount sets a value for the Stripe-Account header.
|
|
func (p *Params) SetStripeAccount(val string) {
|
|
p.StripeAccount = &val
|
|
}
|
|
|
|
// ParamsContainer is a general interface for which all parameter structs
|
|
// should comply. They achieve this by embedding a Params struct and inheriting
|
|
// its implementation of this interface.
|
|
type ParamsContainer interface {
|
|
GetParams() *Params
|
|
}
|
|
|
|
// RangeQueryParams are a set of generic request parameters that are used on
|
|
// list endpoints to filter their results by some timestamp.
|
|
type RangeQueryParams struct {
|
|
// GreaterThan specifies that values should be a greater than this
|
|
// timestamp.
|
|
GreaterThan int64 `form:"gt"`
|
|
|
|
// GreaterThanOrEqual specifies that values should be greater than or equal
|
|
// to this timestamp.
|
|
GreaterThanOrEqual int64 `form:"gte"`
|
|
|
|
// LesserThan specifies that values should be lesser than this timetamp.
|
|
LesserThan int64 `form:"lt"`
|
|
|
|
// LesserThanOrEqual specifies that values should be lesser than or
|
|
// equalthis timetamp.
|
|
LesserThanOrEqual int64 `form:"lte"`
|
|
}
|
|
|
|
//
|
|
// Public functions
|
|
//
|
|
|
|
// NewIdempotencyKey generates a new idempotency key that
|
|
// can be used on a request.
|
|
func NewIdempotencyKey() string {
|
|
now := time.Now().UnixNano()
|
|
buf := make([]byte, 4)
|
|
rand.Read(buf)
|
|
return fmt.Sprintf("%v_%v", now, base64.URLEncoding.EncodeToString(buf)[:6])
|
|
}
|
|
|
|
//
|
|
// Private types
|
|
//
|
|
|
|
// filter is the structure that contains a filter for list-related APIs.
|
|
// It ends up passing query string parameters in the format key[op]=value.
|
|
type filter struct {
|
|
Key, Op, Val string
|
|
}
|