github.com/stripe/stripe-go/v76@v76.25.0/params.go (about)

     1  package stripe
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"encoding/base64"
     7  	"fmt"
     8  	"net/http"
     9  	"net/url"
    10  	"time"
    11  
    12  	"github.com/stripe/stripe-go/v76/form"
    13  )
    14  
    15  //
    16  // Public constants
    17  //
    18  
    19  // Contains constants for the names of parameters used for pagination in list APIs.
    20  const (
    21  	EndingBefore  = "ending_before"
    22  	StartingAfter = "starting_after"
    23  )
    24  
    25  //
    26  // Public types
    27  //
    28  
    29  // ExtraValues are extra parameters that are attached to an API request.
    30  // They're implemented as a custom type so that they can have their own
    31  // AppendTo implementation.
    32  type ExtraValues struct {
    33  	url.Values `form:"-"` // See custom AppendTo implementation
    34  }
    35  
    36  // AppendTo implements custom form encoding for extra parameter values.
    37  func (v ExtraValues) AppendTo(body *form.Values, keyParts []string) {
    38  	for k, vs := range v.Values {
    39  		for _, v := range vs {
    40  			body.Add(form.FormatKey(append(keyParts, k)), v)
    41  		}
    42  	}
    43  }
    44  
    45  // Filters is a structure that contains a collection of filters for list-related APIs.
    46  type Filters struct {
    47  	f []*filter `form:"-"` // See custom AppendTo implementation
    48  }
    49  
    50  // AddFilter adds a new filter with a given key, op and value.
    51  func (f *Filters) AddFilter(key, op, value string) {
    52  	filter := &filter{Key: key, Op: op, Val: value}
    53  	f.f = append(f.f, filter)
    54  }
    55  
    56  // AppendTo implements custom form encoding for filters.
    57  func (f Filters) AppendTo(body *form.Values, keyParts []string) {
    58  	if len(f.f) > 0 {
    59  		for _, v := range f.f {
    60  			if len(v.Op) > 0 {
    61  				body.Add(form.FormatKey(append(keyParts, v.Key, v.Op)), v.Val)
    62  			} else {
    63  				body.Add(form.FormatKey(append(keyParts, v.Key)), v.Val)
    64  			}
    65  		}
    66  	}
    67  }
    68  
    69  // ListContainer is a general interface for which all list object structs
    70  // should comply. They achieve this by embedding a ListMeta struct and
    71  // inheriting its implementation of this interface.
    72  type ListContainer interface {
    73  	GetListMeta() *ListMeta
    74  }
    75  
    76  // ListMeta is the structure that contains the common properties
    77  // of List iterators. The Count property is only populated if the
    78  // total_count include option is passed in (see tests for example).
    79  type ListMeta struct {
    80  	HasMore bool   `json:"has_more"`
    81  	URL     string `json:"url"`
    82  
    83  	// TotalCount is the total number of objects in the collection (beyond just
    84  	// on the current page). This is not returned in most list calls.
    85  	//
    86  	// Deprecated: TotalCount is only included in some legacy situations and
    87  	// not generally available anymore.
    88  	TotalCount uint32 `json:"total_count"`
    89  }
    90  
    91  // GetListMeta returns a ListMeta struct (itself). It exists because any
    92  // structs that embed ListMeta will inherit it, and thus implement the
    93  // ListContainer interface.
    94  func (l *ListMeta) GetListMeta() *ListMeta {
    95  	return l
    96  }
    97  
    98  // ListParams is the structure that contains the common properties
    99  // of any *ListParams structure.
   100  type ListParams struct {
   101  	// Context used for request. It may carry deadlines, cancelation signals,
   102  	// and other request-scoped values across API boundaries and between
   103  	// processes.
   104  	//
   105  	// Note that a cancelled or timed out context does not provide any
   106  	// guarantee whether the operation was or was not completed on Stripe's API
   107  	// servers. For certainty, you must either retry with the same idempotency
   108  	// key or query the state of the API.
   109  	Context context.Context `form:"-"`
   110  
   111  	EndingBefore *string `form:"ending_before"`
   112  	// Deprecated: Please use Expand in the surrounding struct instead.
   113  	Expand  []*string `form:"expand"`
   114  	Filters Filters   `form:"*"`
   115  	Limit   *int64    `form:"limit"`
   116  
   117  	// Single specifies whether this is a single page iterator. By default,
   118  	// listing through an iterator will automatically grab additional pages as
   119  	// the query progresses. To change this behavior and just load a single
   120  	// page, set this to true.
   121  	Single bool `form:"-"` // Not an API parameter
   122  
   123  	StartingAfter *string `form:"starting_after"`
   124  
   125  	// StripeAccount may contain the ID of a connected account. By including
   126  	// this field, the request is made as if it originated from the connected
   127  	// account instead of under the account of the owner of the configured
   128  	// Stripe key.
   129  	StripeAccount *string `form:"-"` // Passed as header
   130  }
   131  
   132  // AddExpand on the embedded ListParams struct is deprecated.
   133  // Deprecated: please use AddExpand on the surrounding struct instead.
   134  func (p *ListParams) AddExpand(f string) {
   135  	p.Expand = append(p.Expand, &f)
   136  }
   137  
   138  // GetListParams returns a ListParams struct (itself). It exists because any
   139  // structs that embed ListParams will inherit it, and thus implement the
   140  // ListParamsContainer interface.
   141  func (p *ListParams) GetListParams() *ListParams {
   142  	return p
   143  }
   144  
   145  // GetParams returns ListParams as a Params struct. It exists because any
   146  // structs that embed Params will inherit it, and thus implement the
   147  // ParamsContainer interface.
   148  func (p *ListParams) GetParams() *Params {
   149  	return p.ToParams()
   150  }
   151  
   152  // SetStripeAccount sets a value for the Stripe-Account header.
   153  func (p *ListParams) SetStripeAccount(val string) {
   154  	p.StripeAccount = &val
   155  }
   156  
   157  // ToParams converts a ListParams to a Params by moving over any fields that
   158  // have valid targets in the new type. This is useful because fields in
   159  // Params can be injected directly into an http.Request while generally
   160  // ListParams is only used to build a set of parameters.
   161  func (p *ListParams) ToParams() *Params {
   162  	return &Params{
   163  		Context:       p.Context,
   164  		StripeAccount: p.StripeAccount,
   165  	}
   166  }
   167  
   168  // ListParamsContainer is a general interface for which all list parameter
   169  // structs should comply. They achieve this by embedding a ListParams struct
   170  // and inheriting its implementation of this interface.
   171  type ListParamsContainer interface {
   172  	GetListParams() *ListParams
   173  }
   174  
   175  // Params is the structure that contains the common properties
   176  // of any *Params structure.
   177  type Params struct {
   178  	// Context used for request. It may carry deadlines, cancelation signals,
   179  	// and other request-scoped values across API boundaries and between
   180  	// processes.
   181  	//
   182  	// Note that a cancelled or timed out context does not provide any
   183  	// guarantee whether the operation was or was not completed on Stripe's API
   184  	// servers. For certainty, you must either retry with the same idempotency
   185  	// key or query the state of the API.
   186  	Context context.Context `form:"-"`
   187  
   188  	// Deprecated: please use Expand in the surrounding struct instead.
   189  	Expand []*string    `form:"expand"`
   190  	Extra  *ExtraValues `form:"*"`
   191  
   192  	// Headers may be used to provide extra header lines on the HTTP request.
   193  	Headers http.Header `form:"-"`
   194  
   195  	IdempotencyKey *string `form:"-"` // Passed as header
   196  
   197  	// Deprecated: Please use Metadata in the surrounding struct instead.
   198  	Metadata map[string]string `form:"metadata"`
   199  
   200  	// StripeAccount may contain the ID of a connected account. By including
   201  	// this field, the request is made as if it originated from the connected
   202  	// account instead of under the account of the owner of the configured
   203  	// Stripe key.
   204  	StripeAccount *string `form:"-"` // Passed as header
   205  
   206  	usage []string `form:"-"` // Tracked behaviors
   207  }
   208  
   209  // AddExpand on the Params embedded struct is deprecated.
   210  // Deprecated: please use Expand in the surrounding struct instead.
   211  func (p *Params) AddExpand(f string) {
   212  	p.Expand = append(p.Expand, &f)
   213  }
   214  
   215  // InternalSetUsage sets the usage field on the Params struct.
   216  // Unstable: for internal stripe-go usage only.
   217  func (p *Params) InternalSetUsage(usage []string) {
   218  	p.usage = usage
   219  }
   220  
   221  // AddExtra adds a new arbitrary key-value pair to the request data
   222  func (p *Params) AddExtra(key, value string) {
   223  	if p.Extra == nil {
   224  		p.Extra = &ExtraValues{Values: make(url.Values)}
   225  	}
   226  
   227  	p.Extra.Add(key, value)
   228  }
   229  
   230  // AddMetadata on the Params embedded struct is deprecated.
   231  // Deprecated: please use .AddMetadata of the surrounding struct.
   232  func (p *Params) AddMetadata(key, value string) {
   233  	if p.Metadata == nil {
   234  		p.Metadata = make(map[string]string)
   235  	}
   236  
   237  	p.Metadata[key] = value
   238  }
   239  
   240  // GetParams returns a Params struct (itself). It exists because any structs
   241  // that embed Params will inherit it, and thus implement the ParamsContainer
   242  // interface.
   243  func (p *Params) GetParams() *Params {
   244  	return p
   245  }
   246  
   247  // SetIdempotencyKey sets a value for the Idempotency-Key header.
   248  func (p *Params) SetIdempotencyKey(val string) {
   249  	p.IdempotencyKey = &val
   250  }
   251  
   252  // SetStripeAccount sets a value for the Stripe-Account header.
   253  func (p *Params) SetStripeAccount(val string) {
   254  	p.StripeAccount = &val
   255  }
   256  
   257  // ParamsContainer is a general interface for which all parameter structs
   258  // should comply. They achieve this by embedding a Params struct and inheriting
   259  // its implementation of this interface.
   260  type ParamsContainer interface {
   261  	GetParams() *Params
   262  }
   263  
   264  // RangeQueryParams are a set of generic request parameters that are used on
   265  // list endpoints to filter their results by some timestamp.
   266  type RangeQueryParams struct {
   267  	// GreaterThan specifies that values should be a greater than this
   268  	// timestamp.
   269  	GreaterThan int64 `form:"gt"`
   270  
   271  	// GreaterThanOrEqual specifies that values should be greater than or equal
   272  	// to this timestamp.
   273  	GreaterThanOrEqual int64 `form:"gte"`
   274  
   275  	// LesserThan specifies that values should be lesser than this timetamp.
   276  	LesserThan int64 `form:"lt"`
   277  
   278  	// LesserThanOrEqual specifies that values should be lesser than or
   279  	// equalthis timetamp.
   280  	LesserThanOrEqual int64 `form:"lte"`
   281  }
   282  
   283  //
   284  // Public functions
   285  //
   286  
   287  // NewIdempotencyKey generates a new idempotency key that
   288  // can be used on a request.
   289  func NewIdempotencyKey() string {
   290  	now := time.Now().UnixNano()
   291  	buf := make([]byte, 4)
   292  	if _, err := rand.Read(buf); err != nil {
   293  		panic(err)
   294  	}
   295  	return fmt.Sprintf("%v_%v", now, base64.URLEncoding.EncodeToString(buf)[:6])
   296  }
   297  
   298  //
   299  // Private types
   300  //
   301  
   302  // filter is the structure that contains a filter for list-related APIs.
   303  // It ends up passing query string parameters in the format key[op]=value.
   304  type filter struct {
   305  	Key, Op, Val string
   306  }