The official Stripe Go client library.
Make sure your project is using Go Modules (it will have a go.mod
file in its root if it already is):
Then, reference stripe-go in a Go program with import
:
import ( "github.com/stripe/stripe-go/v82" "github.com/stripe/stripe-go/v82/customer" )
Run any of the normal go
commands (build
/install
/test
). The Go toolchain will resolve and fetch the stripe-go module automatically.
Alternatively, you can also explicitly go get
the package into a project:
go get -u github.com/stripe/stripe-go/v82
For a comprehensive list of examples, check out the API documentation.
For details on all the functionality in this library, see the Go documentation.
Below are a few simple examples:
sc := stripe.NewClient(apiKey) params := &stripe.CustomerCreateParams{ Description: stripe.String("Stripe Developer"), Email: stripe.String("gostripe@stripe.com"), PreferredLocales: stripe.StringSlice([]string{"en", "es"}), } c, err := sc.V1Customers.Create(context.TODO(), params)
sc := stripe.NewClient(apiKey) params := &stripe.PaymentIntentListParams{ Customer: stripe.String(customer.ID), } for pi, err := range sc.V1PaymentIntents.List(context.TODO(), params) { // handle err // do something }
sc := stripe.NewClient(apiKey) for e, err := range sc.V1Events.List(context.TODO(), nil) { // access event data via e.GetObjectValue("resource_name_based_on_type", "resource_property_name") // alternatively you can access values via e.Data.Object["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"] // access previous attributes via e.GetPreviousValue("resource_name_based_on_type", "resource_property_name") // alternatively you can access values via e.Data.PreviousAttributes["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"] }
Alternatively, you can use the event.Data.Raw
property to unmarshal to the appropriate struct.
There are two ways of authenticating requests when performing actions on behalf of a connected account, one that uses the Stripe-Account
header containing an account's ID, and one that uses the account's keys. Usually the former is the recommended approach. See the documentation for more information.
To use the Stripe-Account
approach, use SetStripeAccount()
on a ListParams
or Params
class. For example:
// For a list request listParams := &stripe.CustomerListParams{} listParams.SetStripeAccount("acct_123")
To use a key, pass it into stripe.NewClient
:
import ( "github.com/stripe/stripe-go/v82" ) sc := stripe.NewClient("access_token")
If you're running the client in a Google AppEngine environment, you'll need to create a per-request Stripe client since the http.DefaultClient
is not available. Here's a sample handler:
import ( "fmt" "net/http" "google.golang.org/appengine" "google.golang.org/appengine/urlfetch" "github.com/stripe/stripe-go/v82" ) func handler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) httpClient := urlfetch.Client(ctx) backends := stripe.NewBackends(httpClient) sc := stripe.NewClient("sk_test_123", stripe.WithBackends(backends)) params := &stripe.CustomerCreateParams{ Description: stripe.String("Stripe Developer"), Email: stripe.String("gostripe@stripe.com"), } customer, err := sc.V1Customers.Create(ctx, params) if err != nil { fmt.Fprintf(w, "Could not create customer: %v", err) return } fmt.Fprintf(w, "Customer created: %v", customer.ID) }
While some resources may contain more/less APIs, the following pattern is applied throughout the library for a given resource (like Customer
).
The recommended pattern to access all Stripe resources is using stripe.Client
. Below are some examples of how to use it to access the Customer
resource.
import "github.com/stripe/stripe-go/v82" // Setup sc := stripe.NewClient("sk_key") // To set backends, e.g. for testing, or to customize use this instead: // sc := stripe.NewClient("sk_key", stripe.WithBackends(backends)) // Create c, err := sc.V1Customers.Create(context.TODO(), &stripe.CustomerCreateParams{}) // Retrieve c, err := sc.V1Customers.Retrieve(context.TODO(), id, &stripe.CustomerRetrieveParams{}) // Update c, err := sc.V1Customers.Update(context.TODO(), id, &stripe.CustomerUpdateParams{}) // Delete c, err := sc.V1Customers.Delete(context.TODO(), id, &stripe.CustomerDeleteParams{}) // List for c, err := range sc.Customers.List(context.TODO(), &stripe.CustomerListParams{}) { // handle err // do something }
stripe.Client
vs legacy client.API
pattern
We introduced stripe.Client
in v82.1 of the Go SDK. The legacy client pattern used prior to that version (using client.API
) is still available to use but is marked as deprecated. Review the migration guide to use stripe.Client to help you move from the legacy pattern to stripe.Client
.
The legacy pattern to access Stripe APIs is the "resource pattern" shown below. We plan to deprecate this pattern in a future release. Note also that Stripe's V2 APIs are not supported by this pattern.
import ( "github.com/stripe/stripe-go/v82" "github.com/stripe/stripe-go/v82/customer" ) // Setup stripe.Key = "sk_key" // Set backend (optional, useful for mocking) // stripe.SetBackend("api", backend) // Create c, err := customer.New(&stripe.CustomerParams{}) // Get c, err := customer.Get(id, &stripe.CustomerParams{}) // Update c, err := customer.Update(id, &stripe.CustomerParams{}) // Delete c, err := customer.Del(id, &stripe.CustomerParams{}) // List i := customer.List(&stripe.CustomerListParams{}) for i.Next() { c := i.Customer() // do something } if err := i.Err(); err != nil { // handle }Accessing the Last Response
Use LastResponse
on any APIResource
to look at the API response that generated the current object:
coupon, err := sc.V1Coupons.Create(...) requestID := coupon.LastResponse.RequestID
See the definition of APIResponse
for available fields.
Note that where API resources are nested in other API resources, only LastResponse
on the top-level resource is set.
The library automatically retries requests on intermittent failures like on a connection error, timeout, or on certain API responses like a status 409 Conflict
. Idempotency keys are always added to requests to make any such subsequent retries safe.
By default, it will perform up to two retries. That number can be configured with MaxNetworkRetries
:
import ( "github.com/stripe/stripe-go/v82" ) config := &stripe.BackendConfig{ MaxNetworkRetries: stripe.Int64(0), // Zero retries } backends := &stripe.NewBackendWithConfig(config) sc := stripe.NewClient("sk_key", stripe.WithBackends(backends)) coupon, err := sc.V1Coupons.Create(...)
By default, the library logs error messages only (which are sent to stderr
). Configure default logging using the global DefaultLeveledLogger
variable:
stripe.DefaultLeveledLogger = &stripe.LeveledLogger{ Level: stripe.LevelInfo, }
Or on a per-backend basis:
config := &stripe.BackendConfig{ LeveledLogger: &stripe.LeveledLogger{ Level: stripe.LevelInfo, }, }
It's possible to use non-Stripe leveled loggers as well. Stripe expects loggers to comply to the following interface:
type LeveledLoggerInterface interface { Debugf(format string, v ...interface{}) Errorf(format string, v ...interface{}) Infof(format string, v ...interface{}) Warnf(format string, v ...interface{}) }
Some loggers like Logrus and Zap's SugaredLogger support this interface out-of-the-box so it's possible to set DefaultLeveledLogger
to a *logrus.Logger
or *zap.SugaredLogger
directly. For others it may be necessary to write a thin shim layer to support them.
All expandable objects in stripe-go take the form of a full resource struct, but unless expansion is requested, only the ID
field of that struct is populated. Expansion is requested by calling AddExpand
on parameter structs. For example:
// // *Without* expansion // c, _ := sc.V1Charges.Retrieve(context.TODO(), "ch_123", nil) c.Customer.ID // Only ID is populated c.Customer.Name // All other fields are always empty // // With expansion // p := &stripe.ChargeCreateParams{} p.AddExpand("customer") c, _ = sc.V1Charges.Retrieve(context.TODO(), "ch_123", p) c.Customer.ID // ID is still available c.Customer.Name // Name is now also available (if it had a value)How to use undocumented parameters and properties
stripe-go is a typed library and it supports all public properties or parameters.
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.
To pass undocumented parameters to Stripe using stripe-go you need to use the AddExtra()
method, as shown below:
params := &stripe.CustomerCreateParams{ Email: stripe.String("jenny.rosen@example.com") } params.AddExtra("secret_feature_enabled", "true") params.AddExtra("secret_parameter[primary]","primary value") params.AddExtra("secret_parameter[secondary]","secondary value") customer, err := sc.V1Customer.Create(context.TODO(), params)
You can access undocumented properties returned by Stripe by querying the raw response JSON object. An example of this is shown below:
customer, _ = sc.V1Charges.Retrieve(context.TODO(), "cus_1234", nil); var rawData map[string]interface{} _ = json.Unmarshal(customer.LastResponse.RawJSON, &rawData) secretFeatureEnabled, _ := string(rawData["secret_feature_enabled"].(bool)) secretParameter, ok := rawData["secret_parameter"].(map[string]interface{}) if ok { primary := secretParameter["primary"].(string) secondary := secretParameter["secondary"].(string) }
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.
You can use stripe.GenerateTestSignedPayload
to mock webhook events that come from Stripe:
payload := map[string]interface{}{ "id": "evt_test_webhook", "object": "event", "api_version": stripe.APIVersion, } testSecret := "whsec_test_secret" payloadBytes, err := json.Marshal(payload) signedPayload := stripe.GenerateTestSignedPayload(&webhook.UnsignedPayload{Payload: payloadBytes, Secret: testSecret}) event, err := stripe.ConstructEvent(signedPayload.Payload, signedPayload.Header, signedPayload.Secret) if event.ID == payload["id"] { // Do something with the mocked signed event } else { // Handle invalid event payload }
If you're writing a plugin that uses the library, we'd appreciate it if you identified using stripe.SetAppInfo
:
stripe.SetAppInfo(&stripe.AppInfo{ Name: "MyAwesomePlugin", URL: "https://myawesomeplugin.info", Version: "1.2.34", })
This information is passed along when the library makes calls to the Stripe API. Note that while Name
is always required, URL
and Version
are optional.
By default, the library sends telemetry to Stripe regarding request latency and feature usage. These numbers help Stripe improve the overall latency of its API for all users, and improve popular features.
You can disable this behavior if you prefer:
config := &stripe.BackendConfig{ EnableTelemetry: stripe.Bool(false), }Mocking clients for unit tests
To mock a Stripe client for a unit tests using GoMock:
Backend
type mock.mockgen -destination=mocks/backend.go -package=mocks github.com/stripe/stripe-go/v82 Backend
Backend
mock to initialize and call methods on the client.import ( "example/hello/mocks" "testing" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stripe/stripe-go/v82" ) func UseMockedStripeClient(t *testing.T) { // Create a mock controller mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() // Create a mock stripe backend mockBackend := mocks.NewMockBackend(mockCtrl) backends := &stripe.Backends{API: mockBackend} client := stripe.NewClient("sk_test", stripe.WithBackends(backends)) // Set up a mock call mockBackend.EXPECT().Call("GET", "/v1/accounts/acc_123", gomock.Any(), gomock.Any(), gomock.Any()). // Return nil error Return(nil). Do(func(method string, path string, key string, params stripe.ParamsContainer, v *stripe.Account) { // Set the return value for the method *v = stripe.Account{ ID: "acc_123", } }).Times(1) // Call the client method acc, _ := client.V1Accounts.GetByID(context.TODO(), "acc_123", nil) // Asset the result assert.Equal(t, "acc_123", acc.ID) }
Stripe has features in the public preview phase that can be accessed via versions of this package that have the -beta.X
suffix like 82.2.0-beta.2
. We would love for you to try these as we incrementally release new features and improve them based on your feedback.
To install, choose the version that includes support for the preview feature you are interested in by reviewing the releases page and use it in your go.mod
file:
require (
...
github.com/stripe/stripe-go/v82 <replace-with-the-version-of-your-choice>
...
)
Note There can be breaking changes between two versions of the public preview SDKs without a bump in the major version.
Some preview features require a name and version to be set in the Stripe-Version
header like feature_beta=v3
. If your preview feature has this requirement, use the stripe.AddBetaVersion
function (available only in the public preview SDKs):
stripe.AddBetaVersion("feature_beta", "v3")
If you would like to send a request to an API that is:
You can use the rawrequest
package:
import ( "encoding/json" "fmt" "github.com/stripe/stripe-go/v82" "github.com/stripe/stripe-go/v82/form" "github.com/stripe/stripe-go/v82/rawrequest" ) func make_raw_request() error { stripe.Key = "sk_test_123" b, err := stripe.GetRawRequestBackend(stripe.APIBackend) if err != nil { return err } client := rawrequest.Client{B: b, Key: apiKey} payload := map[string]interface{}{ "event_name": "hotdogs_eaten", "payload": map[string]string{ "value": "123", "stripe_customer_id": "cus_Quq8itmW58RMet", }, } // for a v2 request, json encode the payload body, err := json.Marshal(payload) if err != nil { return err } v2_resp, err := client.RawRequest(http.MethodPost, "/v2/billing/meter_events", string(body), nil) if err != nil { return err } var v2_response map[string]interface{} err = json.Unmarshal(v2_resp.RawJSON, &v2_response) if err != nil { return err } fmt.Printf("%#v\n", v2_response) // for a v1 request, form encode the payload formValues := &form.Values{} form.AppendTo(formValues, payload) content := formValues.Encode() v1_resp, err := client.RawRequest(http.MethodPost, "/v1/billing/meter_events", content, nil) if err != nil { return err } var v1_response map[string]interface{} err = json.Unmarshal(v1_resp.RawJSON, &v1_response) if err != nil { return err } fmt.Printf("%#v\n", v1_response) return nil }
See more examples in the /example/v2 folder.
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.
Pull requests from the community are welcome. If you submit one, please keep the following guidelines in mind:
go fmt
compliant.just test
succeeds.Other contribution guidelines for this project
We use just for conveniently running development tasks. You can use them directly, or copy the commands out of the justfile
. To our help docs, run just
.
This package depends on stripe-mock, so make sure to fetch and run it from a background terminal (stripe-mock's README also contains instructions for installing via Homebrew and other methods):
go get -u github.com/stripe/stripe-mock
stripe-mock
Run all tests:
just test # or: go test ./...
Run tests for one package:
just test ./invoice # or: go test ./invoice
Run a single test:
just test ./invoice -run TestInvoiceGet # or: go test ./invoice -run TestInvoiceGet
For any requests, bug or comments, please open an issue or submit a pull request.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4