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

     1  # Go Stripe
     2  [![Go Reference](https://pkg.go.dev/badge/github.com/stripe/stripe-go)](https://pkg.go.dev/github.com/stripe/stripe-go/v76)
     3  [![Build Status](https://github.com/stripe/stripe-go/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/stripe/stripe-go/actions/workflows/ci.yml?query=branch%3Amaster)
     4  [![Coverage Status](https://coveralls.io/repos/github/stripe/stripe-go/badge.svg?branch=master)](https://coveralls.io/github/stripe/stripe-go?branch=master)
     5  
     6  The official [Stripe][stripe] Go client library.
     7  
     8  ## Requirements
     9  
    10  - Go 1.15 or later
    11  
    12  ## Installation
    13  
    14  Make sure your project is using Go Modules (it will have a `go.mod` file in its
    15  root if it already is):
    16  
    17  ``` sh
    18  go mod init
    19  ```
    20  
    21  Then, reference stripe-go in a Go program with `import`:
    22  
    23  ``` go
    24  import (
    25  	"github.com/stripe/stripe-go/v76"
    26  	"github.com/stripe/stripe-go/v76/customer"
    27  )
    28  ```
    29  
    30  Run any of the normal `go` commands (`build`/`install`/`test`). The Go
    31  toolchain will resolve and fetch the stripe-go module automatically.
    32  
    33  Alternatively, you can also explicitly `go get` the package into a project:
    34  
    35  ```bash
    36  go get -u github.com/stripe/stripe-go/v76
    37  ```
    38  
    39  ## Documentation
    40  
    41  For a comprehensive list of examples, check out the [API
    42  documentation][api-docs].
    43  
    44  See [video demonstrations][youtube-playlist] covering how to use the library.
    45  
    46  For details on all the functionality in this library, see the [Go
    47  documentation][goref].
    48  
    49  Below are a few simple examples:
    50  
    51  ### Customers
    52  
    53  ```go
    54  params := &stripe.CustomerParams{
    55  	Description:      stripe.String("Stripe Developer"),
    56  	Email:            stripe.String("gostripe@stripe.com"),
    57  	PreferredLocales: stripe.StringSlice([]string{"en", "es"}),
    58  }
    59  
    60  c, err := customer.New(params)
    61  ```
    62  
    63  ### PaymentIntents
    64  
    65  ```go
    66  params := &stripe.PaymentIntentListParams{
    67  	Customer: stripe.String(customer.ID),
    68  }
    69  
    70  i := paymentintent.List(params)
    71  for i.Next() {
    72  	pi := i.PaymentIntent()
    73  }
    74  
    75  if err := i.Err(); err != nil {
    76  	// handle
    77  }
    78  ```
    79  
    80  ### Events
    81  
    82  ```go
    83  i := event.List(nil)
    84  for i.Next() {
    85  	e := i.Event()
    86  
    87  	// access event data via e.GetObjectValue("resource_name_based_on_type", "resource_property_name")
    88  	// alternatively you can access values via e.Data.Object["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"]
    89  
    90  	// access previous attributes via e.GetPreviousValue("resource_name_based_on_type", "resource_property_name")
    91  	// alternatively you can access values via e.Data.PrevPreviousAttributes["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"]
    92  }
    93  ```
    94  
    95  Alternatively, you can use the `event.Data.Raw` property to unmarshal to the
    96  appropriate struct.
    97  
    98  ### Authentication with Connect
    99  
   100  There are two ways of authenticating requests when performing actions on behalf
   101  of a connected account, one that uses the `Stripe-Account` header containing an
   102  account's ID, and one that uses the account's keys. Usually the former is the
   103  recommended approach. [See the documentation for more information][connect].
   104  
   105  To use the `Stripe-Account` approach, use `SetStripeAccount()` on a `ListParams`
   106  or `Params` class. For example:
   107  
   108  ```go
   109  // For a list request
   110  listParams := &stripe.CustomerListParams{}
   111  listParams.SetStripeAccount("acct_123")
   112  ```
   113  
   114  ```go
   115  // For any other kind of request
   116  params := &stripe.CustomerParams{}
   117  params.SetStripeAccount("acct_123")
   118  ```
   119  
   120  To use a key, pass it to `API`'s `Init` function:
   121  
   122  ```go
   123  
   124  import (
   125  	"github.com/stripe/stripe-go/v76"
   126  	"github.com/stripe/stripe-go/v76/client"
   127  )
   128  
   129  stripe := &client.API{}
   130  stripe.Init("access_token", nil)
   131  ```
   132  
   133  ### Google AppEngine
   134  
   135  If you're running the client in a Google AppEngine environment, you'll need to
   136  create a per-request Stripe client since the `http.DefaultClient` is not
   137  available. Here's a sample handler:
   138  
   139  ```go
   140  import (
   141  	"fmt"
   142  	"net/http"
   143  
   144  	"google.golang.org/appengine"
   145  	"google.golang.org/appengine/urlfetch"
   146  
   147  	"github.com/stripe/stripe-go/v76"
   148  	"github.com/stripe/stripe-go/v76/client"
   149  )
   150  
   151  func handler(w http.ResponseWriter, r *http.Request) {
   152  	c := appengine.NewContext(r)
   153  	httpClient := urlfetch.Client(c)
   154  
   155  	sc := client.New("sk_test_123", stripe.NewBackends(httpClient))
   156  
   157  	params := &stripe.CustomerParams{
   158  		Description: stripe.String("Stripe Developer"),
   159  		Email:       stripe.String("gostripe@stripe.com"),
   160  	}
   161  	customer, err := sc.Customers.New(params)
   162  	if err != nil {
   163  		fmt.Fprintf(w, "Could not create customer: %v", err)
   164  	}
   165  	fmt.Fprintf(w, "Customer created: %v", customer.ID)
   166  }
   167  ```
   168  
   169  ## Usage
   170  
   171  While some resources may contain more/less APIs, the following pattern is
   172  applied throughout the library for a given `$resource$`:
   173  
   174  ### Without a Client
   175  
   176  If you're only dealing with a single key, you can simply import the packages
   177  required for the resources you're interacting with without the need to create a
   178  client.
   179  
   180  ```go
   181  import (
   182  	"github.com/stripe/stripe-go/v76"
   183  	"github.com/stripe/stripe-go/v76/$resource$"
   184  )
   185  
   186  // Setup
   187  stripe.Key = "sk_key"
   188  
   189  // Set backend (optional, useful for mocking)
   190  // stripe.SetBackend("api", backend)
   191  
   192  // Create
   193  resource, err := $resource$.New(&stripe.$Resource$Params{})
   194  
   195  // Get
   196  resource, err = $resource$.Get(id, &stripe.$Resource$Params{})
   197  
   198  // Update
   199  resource, err = $resource$.Update(id, &stripe.$Resource$Params{})
   200  
   201  // Delete
   202  resourceDeleted, err := $resource$.Del(id, &stripe.$Resource$Params{})
   203  
   204  // List
   205  i := $resource$.List(&stripe.$Resource$ListParams{})
   206  for i.Next() {
   207  	resource := i.$Resource$()
   208  }
   209  
   210  if err := i.Err(); err != nil {
   211  	// handle
   212  }
   213  ```
   214  
   215  ### With a Client
   216  
   217  If you're dealing with multiple keys, it is recommended you use `client.API`.
   218  This allows you to create as many clients as needed, each with their own
   219  individual key.
   220  
   221  ```go
   222  import (
   223  	"github.com/stripe/stripe-go/v76"
   224  	"github.com/stripe/stripe-go/v76/client"
   225  )
   226  
   227  // Setup
   228  sc := &client.API{}
   229  sc.Init("sk_key", nil) // the second parameter overrides the backends used if needed for mocking
   230  
   231  // Create
   232  $resource$, err := sc.$Resource$s.New(&stripe.$Resource$Params{})
   233  
   234  // Get
   235  $resource$, err = sc.$Resource$s.Get(id, &stripe.$Resource$Params{})
   236  
   237  // Update
   238  $resource$, err = sc.$Resource$s.Update(id, &stripe.$Resource$Params{})
   239  
   240  // Delete
   241  $resource$Deleted, err := sc.$Resource$s.Del(id, &stripe.$Resource$Params{})
   242  
   243  // List
   244  i := sc.$Resource$s.List(&stripe.$Resource$ListParams{})
   245  for i.Next() {
   246  	$resource$ := i.$Resource$()
   247  }
   248  
   249  if err := i.Err(); err != nil {
   250  	// handle
   251  }
   252  ```
   253  
   254  ### Accessing the Last Response
   255  
   256  Use `LastResponse` on any `APIResource` to look at the API response that
   257  generated the current object:
   258  
   259  ``` go
   260  c, err := coupon.New(...)
   261  requestID := coupon.LastResponse.RequestID
   262  ```
   263  
   264  Similarly, for `List` operations, the last response is available on the list
   265  object attached to the iterator:
   266  
   267  ``` go
   268  it := coupon.List(...)
   269  for it.Next() {
   270      // Last response *NOT* on the individual iterator object
   271      // it.Coupon().LastResponse // wrong
   272  
   273      // But rather on the list object, also accessible through the iterator
   274      requestID := it.CouponList().LastResponse.RequestID
   275  }
   276  ```
   277  
   278  See the definition of [`APIResponse`][apiresponse] for available fields.
   279  
   280  Note that where API resources are nested in other API resources, only
   281  `LastResponse` on the top-level resource is set.
   282  
   283  ### Automatic Retries
   284  
   285  The library automatically retries requests on intermittent failures like on a
   286  connection error, timeout, or on certain API responses like a status `409
   287  Conflict`. [Idempotency keys][idempotency-keys] are always added to requests to
   288  make any such subsequent retries safe.
   289  
   290  By default, it will perform up to two retries. That number can be configured
   291  with `MaxNetworkRetries`:
   292  
   293  ```go
   294  import (
   295  	"github.com/stripe/stripe-go/v76"
   296  	"github.com/stripe/stripe-go/v76/client"
   297  )
   298  
   299  config := &stripe.BackendConfig{
   300      MaxNetworkRetries: stripe.Int64(0), // Zero retries
   301  }
   302  
   303  sc := &client.API{}
   304  sc.Init("sk_key", &stripe.Backends{
   305      API:     stripe.GetBackendWithConfig(stripe.APIBackend, config),
   306      Uploads: stripe.GetBackendWithConfig(stripe.UploadsBackend, config),
   307  })
   308  
   309  coupon, err := sc.Coupons.New(...)
   310  ```
   311  
   312  ### Configuring Logging
   313  
   314  By default, the library logs error messages only (which are sent to `stderr`).
   315  Configure default logging using the global `DefaultLeveledLogger` variable:
   316  
   317  ```go
   318  stripe.DefaultLeveledLogger = &stripe.LeveledLogger{
   319      Level: stripe.LevelInfo,
   320  }
   321  ```
   322  
   323  Or on a per-backend basis:
   324  
   325  ```go
   326  config := &stripe.BackendConfig{
   327      LeveledLogger: &stripe.LeveledLogger{
   328          Level: stripe.LevelInfo,
   329      },
   330  }
   331  ```
   332  
   333  It's possible to use non-Stripe leveled loggers as well. Stripe expects loggers
   334  to comply to the following interface:
   335  
   336  ```go
   337  type LeveledLoggerInterface interface {
   338  	Debugf(format string, v ...interface{})
   339  	Errorf(format string, v ...interface{})
   340  	Infof(format string, v ...interface{})
   341  	Warnf(format string, v ...interface{})
   342  }
   343  ```
   344  
   345  Some loggers like [Logrus][logrus] and Zap's [SugaredLogger][zapsugaredlogger]
   346  support this interface out-of-the-box so it's possible to set
   347  `DefaultLeveledLogger` to a `*logrus.Logger` or `*zap.SugaredLogger` directly.
   348  For others it may be necessary to write a thin shim layer to support them.
   349  
   350  ### Expanding Objects
   351  
   352  All [expandable objects][expandableobjects] in stripe-go take the form of a
   353  full resource struct, but unless expansion is requested, only the `ID` field of
   354  that struct is populated. Expansion is requested by calling `AddExpand` on
   355  parameter structs. For example:
   356  
   357  ``` go
   358  //
   359  // *Without* expansion
   360  //
   361  c, _ := charge.Get("ch_123", nil)
   362  
   363  c.Customer.ID    // Only ID is populated
   364  c.Customer.Name  // All other fields are always empty
   365  
   366  //
   367  // With expansion
   368  //
   369  p := &stripe.ChargeParams{}
   370  p.AddExpand("customer")
   371  c, _ = charge.Get("ch_123", p)
   372  
   373  c.Customer.ID    // ID is still available
   374  c.Customer.Name  // Name is now also available (if it had a value)
   375  ```
   376  ### How to use undocumented parameters and properties
   377  
   378  stripe-go is a typed library and it supports all public properties or parameters.
   379  
   380  Stripe sometimes launches private beta features which introduce new properties or parameters that are not immediately public. These will not have typed accessors in the stripe-go library but can still be used. 
   381  
   382  #### Parameters
   383  
   384  To pass undocumented parameters to Stripe using stripe-go you need to use the `AddExtra()` method, as shown below:
   385  
   386  ```go
   387  
   388  	params := &stripe.CustomerParams{
   389  		Email: stripe.String("jenny.rosen@example.com")
   390  	}
   391  
   392  	params.AddExtra("secret_feature_enabled", "true")
   393  	params.AddExtra("secret_parameter[primary]","primary value")
   394  	params.AddExtra("secret_parameter[secondary]","secondary value")
   395  
   396  	customer, err := customer.Create(params)
   397  ```
   398  
   399  #### Properties
   400  
   401  You can access undocumented properties returned by Stripe by querying the raw response JSON object. An example of this is shown below:
   402  
   403  ```go
   404  customer, _ = customer.Get("cus_1234", nil);
   405  
   406  var rawData map[string]interface{}
   407  _ = json.Unmarshal(customer.LastResponse.RawJSON, &rawData)
   408  
   409  secret_feature_enabled, _ := string(rawData["secret_feature_enabled"].(bool))
   410  
   411  secret_parameter, ok := rawData["secret_parameter"].(map[string]interface{})
   412  if ok {
   413  	primary := secret_parameter["primary"].(string)
   414  	secondary := secret_parameter["secondary"].(string)
   415  } 
   416  ```
   417  
   418  ### Webhook signing
   419  Stripe can optionally sign the webhook events it sends to your endpoint, allowing you to validate that they were not sent by a third-party. You can read more about it [here](https://stripe.com/docs/webhooks/signatures).
   420  
   421  #### Testing Webhook signing
   422  You can use `stripe.webhook.GenerateTestSignedPayload` to mock webhook events that come from Stripe:
   423  
   424  ```go
   425  payload := map[string]interface{}{
   426  	"id":          "evt_test_webhook",
   427  	"object":      "event",
   428  	"api_version": stripe.APIVersion,
   429  }
   430  testSecret := "whsec_test_secret"
   431  
   432  payloadBytes, err := json.Marshal(payload)
   433  
   434  signedPayload := webhook.GenerateTestSignedPayload(&webhook.UnsignedPayload{Payload: payloadBytes, Secret: testSecret})
   435  event, err := webhook.ConstructEvent(signedPayload.Payload, signedPayload.Header, signedPayload.Secret)
   436  
   437  if event.ID == payload["id"] {
   438  	// Do something with the mocked signed event
   439  } else {
   440  	// Handle invalid event payload
   441  }
   442  ```
   443  
   444  ### Writing a Plugin
   445  
   446  If you're writing a plugin that uses the library, we'd appreciate it if you
   447  identified using `stripe.SetAppInfo`:
   448  
   449  ```go
   450  stripe.SetAppInfo(&stripe.AppInfo{
   451  	Name:    "MyAwesomePlugin",
   452  	URL:     "https://myawesomeplugin.info",
   453  	Version: "1.2.34",
   454  })
   455  ```
   456  
   457  This information is passed along when the library makes calls to the Stripe
   458  API. Note that while `Name` is always required, `URL` and `Version` are
   459  optional.
   460  
   461  ### Telemetry
   462  
   463  By default, the library sends telemetry to Stripe regarding request latency and feature usage. These
   464  numbers help Stripe improve the overall latency of its API for all users, and
   465  improve popular features.
   466  
   467  You can disable this behavior if you prefer:
   468  
   469  ```go
   470  config := &stripe.BackendConfig{
   471  	EnableTelemetry: stripe.Bool(false),
   472  }
   473  ```
   474  
   475  ### Mocking clients for unit tests
   476  
   477  To mock a Stripe client for a unit tests using [GoMock](https://github.com/golang/mock):
   478  
   479  1. Generate a `Backend` type mock.
   480  ```
   481  mockgen -destination=mocks/backend.go -package=mocks github.com/stripe/stripe-go/v76 Backend
   482  ```
   483  2. Use the `Backend` mock to initialize and call methods on the client.
   484  ```go
   485  
   486  import (
   487  	"example/hello/mocks"
   488  	"testing"
   489  
   490  	"github.com/golang/mock/gomock"
   491  	"github.com/stretchr/testify/assert"
   492  	"github.com/stripe/stripe-go/v76"
   493  	"github.com/stripe/stripe-go/v76/account"
   494  )
   495  
   496  func UseMockedStripeClient(t *testing.T) {
   497  	// Create a mock controller
   498  	mockCtrl := gomock.NewController(t)
   499  	defer mockCtrl.Finish()
   500  	// Create a mock stripe backend
   501  	mockBackend := mocks.NewMockBackend(mockCtrl)
   502  	client := account.Client{B: mockBackend, Key: "key_123"}
   503  
   504  	// Set up a mock call
   505  	mockBackend.EXPECT().Call("GET", "/v1/accounts/acc_123", gomock.Any(), gomock.Any(), gomock.Any()).
   506  		// Return nil error
   507  		Return(nil).
   508  		Do(func(method string, path string, key string, params stripe.ParamsContainer, v *stripe.Account) {
   509  			// Set the return value for the method
   510  			*v = stripe.Account{
   511  				ID: "acc_123",
   512  			}
   513  		}).Times(1)
   514  
   515  	// Call the client method
   516  	acc, _ := client.GetByID("acc_123", nil)
   517  
   518  	// Asset the result
   519  	assert.Equal(t, acc.ID, "acc_123")
   520  }
   521  ```
   522  
   523  ### Beta SDKs
   524  
   525  Stripe has features in the beta phase that can be accessed via the beta version of this package.
   526  We would love for you to try these and share feedback with us before these features reach the stable phase.
   527  To install a beta version of stripe-go use the commit notation of the `go get` command to point to a beta tag:
   528  
   529  ```
   530  go get -u github.com/stripe/stripe-go/v76@v73.3.0-beta.1
   531  ```
   532  
   533  > **Note**
   534  > There can be breaking changes between beta versions. 
   535  
   536  We highly recommend keeping an eye on when the beta feature you are interested in goes from beta to stable so that you can move from using a beta version of the SDK to the stable version.
   537  
   538  If your beta feature requires a `Stripe-Version` header to be sent, set the `stripe.APIVersion` field using the `stripe.AddBetaVersion` function to set it:
   539  
   540  > **Note**
   541  > The `APIVersion` can only be set in beta versions of the library. 
   542  
   543  ```go
   544  stripe.AddBetaVersion("feature_beta", "v3")
   545  ```
   546  
   547  ## Support
   548  
   549  New features and bug fixes are released on the latest major version of the Stripe Go client library. If you are on an older major version, we recommend that you upgrade to the latest in order to use the new features and bug fixes including those for security vulnerabilities. Older major versions of the package will continue to be available for use, but will not be receiving any updates.
   550  
   551  ## Development
   552  
   553  Pull requests from the community are welcome. If you submit one, please keep
   554  the following guidelines in mind:
   555  
   556  1. Code must be `go fmt` compliant.
   557  2. All types, structs and funcs should be documented.
   558  3. Ensure that `make test` succeeds.
   559  
   560  ## Test
   561  
   562  The test suite needs testify's `require` package to run:
   563  
   564      github.com/stretchr/testify/require
   565  
   566  Before running the tests, make sure to grab all of the package's dependencies:
   567  
   568      go get -t -v
   569  
   570  It also depends on [stripe-mock][stripe-mock], so make sure to fetch and run it from a
   571  background terminal ([stripe-mock's README][stripe-mock-usage] also contains
   572  instructions for installing via Homebrew and other methods):
   573  
   574      go get -u github.com/stripe/stripe-mock
   575      stripe-mock
   576  
   577  Run all tests:
   578  
   579      make test
   580  
   581  Run tests for one package:
   582  
   583      go test ./invoice
   584  
   585  Run a single test:
   586  
   587      go test ./invoice -run TestInvoiceGet
   588  
   589  For any requests, bug or comments, please [open an issue][issues] or [submit a
   590  pull request][pulls].
   591  
   592  [api-docs]: https://stripe.com/docs/api/?lang=go
   593  [api-changelog]: https://stripe.com/docs/upgrades
   594  [apiresponse]: https://godoc.org/github.com/stripe/stripe-go#APIResponse
   595  [connect]: https://stripe.com/docs/connect/authentication
   596  [depgomodsupport]: https://github.com/golang/dep/pull/1963
   597  [expandableobjects]: https://stripe.com/docs/api/expanding_objects
   598  [goref]: https://pkg.go.dev/github.com/stripe/stripe-go
   599  [gomodrevert]: https://github.com/stripe/stripe-go/pull/774
   600  [gomodvsdep]: https://github.com/stripe/stripe-go/pull/712
   601  [idempotency-keys]: https://stripe.com/docs/api/idempotent_requests?lang=go
   602  [issues]: https://github.com/stripe/stripe-go/issues/new
   603  [logrus]: https://github.com/sirupsen/logrus/
   604  [modules]: https://github.com/golang/go/wiki/Modules
   605  [package-management]: https://code.google.com/p/go-wiki/wiki/PackageManagementTools
   606  [pulls]: https://github.com/stripe/stripe-go/pulls
   607  [stripe]: https://stripe.com
   608  [stripe-mock]: https://github.com/stripe/stripe-mock
   609  [stripe-mock-usage]: https://github.com/stripe/stripe-mock#usage
   610  [youtube-playlist]: https://www.youtube.com/playlist?list=PLy1nL-pvL2M5eqpSBR9KL7K0lcnWo0V0a
   611  [zapsugaredlogger]: https://godoc.org/go.uber.org/zap#SugaredLogger
   612  
   613  <!--
   614  # vim: set tw=79:
   615  -->