- Notifications
You must be signed in to change notification settings - Fork0
Go library for the Stripe API.
License
webcashbookupi-commits/stripe-go
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
The officialStripe Go client library.
- Go 1.18 or later
Make sure your project is using Go Modules (it will have ago.mod file in itsroot if it already is):
go mod init
Then, reference stripe-go in a Go program withimport:
import ("github.com/stripe/stripe-go/v82""github.com/stripe/stripe-go/v82/customer")
Run any of the normalgo commands (build/install/test). The Gotoolchain will resolve and fetch the stripe-go module automatically.
Alternatively, you can also explicitlygo get the package into a project:
go get -u github.com/stripe/stripe-go/v82
For a comprehensive list of examples, check out theAPIdocumentation.
For details on all the functionality in this library, see theGodocumentation.
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),}forpi,err:=rangesc.V1PaymentIntents.List(context.TODO(),params) {// handle err// do something}
sc:=stripe.NewClient(apiKey)fore,err:=rangesc.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 theevent.Data.Raw property to unmarshal to theappropriate struct.
There are two ways of authenticating requests when performing actions on behalfof a connected account, one that uses theStripe-Account header containing anaccount's ID, and one that uses the account's keys. Usually the former is therecommended approach.See the documentation for more information.
To use theStripe-Account approach, useSetStripeAccount() on aListParamsorParams class. For example:
// For a list requestlistParams:=&stripe.CustomerListParams{}listParams.SetStripeAccount("acct_123")
To use a key, pass it intostripe.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 tocreate a per-request Stripe client since thehttp.DefaultClient is notavailable. Here's a sample handler:
import ("fmt""net/http""google.golang.org/appengine""google.golang.org/appengine/urlfetch""github.com/stripe/stripe-go/v82")funchandler(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)iferr!=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 isapplied throughout the library for a given resource (likeCustomer).
The recommended pattern to access all Stripe resources is usingstripe.Client. Below are some examples of how to use it to access theCustomer resource.
import"github.com/stripe/stripe-go/v82"// Setupsc:=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))// Createc,err:=sc.V1Customers.Create(context.TODO(),&stripe.CustomerCreateParams{})// Retrievec,err:=sc.V1Customers.Retrieve(context.TODO(),id,&stripe.CustomerRetrieveParams{})// Updatec,err:=sc.V1Customers.Update(context.TODO(),id,&stripe.CustomerUpdateParams{})// Deletec,err:=sc.V1Customers.Delete(context.TODO(),id,&stripe.CustomerDeleteParams{})// Listforc,err:=rangesc.Customers.List(context.TODO(),&stripe.CustomerListParams{}) {// handle err// do something}
We introducedstripe.Client in v82.1 of the Go SDK. The legacy client pattern used prior to that version (usingclient.API) is still available to use but is marked as deprecated. Review themigration guide to use stripe.Client to help you move from the legacy pattern tostripe.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")// Setupstripe.Key="sk_key"// Set backend (optional, useful for mocking)// stripe.SetBackend("api", backend)// Createc,err:=customer.New(&stripe.CustomerParams{})// Getc,err:=customer.Get(id,&stripe.CustomerParams{})// Updatec,err:=customer.Update(id,&stripe.CustomerParams{})// Deletec,err:=customer.Del(id,&stripe.CustomerParams{})// Listi:=customer.List(&stripe.CustomerListParams{})fori.Next() {c:=i.Customer()// do something}iferr:=i.Err();err!=nil {// handle}
UseLastResponse on anyAPIResource to look at the API response thatgenerated the current object:
coupon,err:=sc.V1Coupons.Create(...)requestID:=coupon.LastResponse.RequestID
See the definition ofAPIResponse for available fields.
Note that where API resources are nested in other API resources, onlyLastResponse on the top-level resource is set.
The library automatically retries requests on intermittent failures like on aconnection error, timeout, or on certain API responses like a status409 Conflict.Idempotency keys are always added to requests tomake any such subsequent retries safe.
By default, it will perform up to two retries. That number can be configuredwithMaxNetworkRetries:
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 tostderr).Configure default logging using the globalDefaultLeveledLogger 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 loggersto comply to the following interface:
typeLeveledLoggerInterfaceinterface {Debugf(formatstring,v...interface{})Errorf(formatstring,v...interface{})Infof(formatstring,v...interface{})Warnf(formatstring,v...interface{})}
Some loggers likeLogrus and Zap'sSugaredLoggersupport this interface out-of-the-box so it's possible to setDefaultLeveledLogger to a*logrus.Logger or*zap.SugaredLogger directly.For others it may be necessary to write a thin shim layer to support them.
Allexpandable objects in stripe-go take the form of afull resource struct, but unless expansion is requested, only theID field ofthat struct is populated. Expansion is requested by callingAddExpand onparameter structs. For example:
//// *Without* expansion//c,_:=sc.V1Charges.Retrieve(context.TODO(),"ch_123",nil)c.Customer.ID// Only ID is populatedc.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 availablec.Customer.Name// Name is now also available (if it had a value)
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 theAddExtra() 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);varrawDatamap[string]interface{}_=json.Unmarshal(customer.LastResponse.RawJSON,&rawData)secretFeatureEnabled,_:=string(rawData["secret_feature_enabled"].(bool))secretParameter,ok:=rawData["secret_parameter"].(map[string]interface{})ifok {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 ithere.
You can usestripe.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)ifevent.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 youidentified usingstripe.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 StripeAPI. Note that whileName is always required,URL andVersion areoptional.
By default, the library sends telemetry to Stripe regarding request latency and feature usage. Thesenumbers help Stripe improve the overall latency of its API for all users, andimprove popular features.
You can disable this behavior if you prefer:
config:=&stripe.BackendConfig{EnableTelemetry:stripe.Bool(false),}
To mock a Stripe client for a unit tests usingGoMock:
- Generate a
Backendtype mock.
mockgen -destination=mocks/backend.go -package=mocks github.com/stripe/stripe-go/v82 Backend- Use the
Backendmock 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")funcUseMockedStripeClient(t*testing.T) {// Create a mock controllermockCtrl:=gomock.NewController(t)defermockCtrl.Finish()// Create a mock stripe backendmockBackend:=mocks.NewMockBackend(mockCtrl)backends:=&stripe.Backends{API:mockBackend}client:=stripe.NewClient("sk_test",stripe.WithBackends(backends))// Set up a mock callmockBackend.EXPECT().Call("GET","/v1/accounts/acc_123",gomock.Any(),gomock.Any(),gomock.Any()).// Return nil errorReturn(nil).Do(func(methodstring,pathstring,keystring,params stripe.ParamsContainer,v*stripe.Account) {// Set the return value for the method*v= stripe.Account{ID:"acc_123",}}).Times(1)// Call the client methodacc,_:=client.V1Accounts.GetByID(context.TODO(),"acc_123",nil)// Asset the resultassert.Equal(t,"acc_123",acc.ID)}
Stripe has features in thepublic preview phase that can be accessed via versions of this package that have the-beta.X suffix like82.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, pick the latest version with thebeta suffix by reviewing thereleases page and use it in yourgo.mod file:
require (...github.com/stripe/stripe-go/v82 <replace-with-the-version-of-your-choice>...)NoteThere 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 theStripe-Version header likefeature_beta=v3. If your preview feature has this requirement, use thestripe.AddBetaVersion function (available only in the public preview SDKs):
stripe.AddBetaVersion("feature_beta","v3")
Stripe has features in theprivate preview phase that can be accessed via versions of this package that have the-alpha.X suffix like82.2.0-alpha.2. These are invite-only features. Once invited, you can install the private preview SDKs by following the same instructions as for thepublic preview SDKs above and replacing the termbeta withalpha.
If you would like to send a request to an API that is:
- undocumented (like a preview feature), or
- you prefer to bypass the method definitions in the library and specify your request details directly
You can use therawrequest 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")funcmake_raw_request()error {stripe.Key="sk_test_123"b,err:=stripe.GetRawRequestBackend(stripe.APIBackend)iferr!=nil {returnerr}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 payloadbody,err:=json.Marshal(payload)iferr!=nil {returnerr}v2_resp,err:=client.RawRequest(http.MethodPost,"/v2/billing/meter_events",string(body),nil)iferr!=nil {returnerr}varv2_responsemap[string]interface{}err=json.Unmarshal(v2_resp.RawJSON,&v2_response)iferr!=nil {returnerr}fmt.Printf("%#v\n",v2_response)// for a v1 request, form encode the payloadformValues:=&form.Values{}form.AppendTo(formValues,payload)content:=formValues.Encode()v1_resp,err:=client.RawRequest(http.MethodPost,"/v1/billing/meter_events",content,nil)iferr!=nil {returnerr}varv1_responsemap[string]interface{}err=json.Unmarshal(v1_resp.RawJSON,&v1_response)iferr!=nil {returnerr}fmt.Printf("%#v\n",v1_response)returnnil}
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 keepthe following guidelines in mind:
- Code must be
go fmtcompliant. - All types, structs and funcs should be documented.
- Ensure that
just testsucceeds.
Other contribution guidelines for this project
We usejust for conveniently running development tasks. You can use them directly, or copy the commands out of thejustfile. To our help docs, runjust.
This package depends onstripe-mock, so make sure to fetch and run it from abackground terminal (stripe-mock's README also containsinstructions for installing via Homebrew and other methods):
go get -u github.com/stripe/stripe-mockstripe-mockRun all tests:
justtest# or: go test ./...
Run tests for one package:
justtest ./invoice# or: go test ./invoice
Run a single test:
justtest ./invoice -run TestInvoiceGet# or: go test ./invoice -run TestInvoiceGet
For any requests, bug or comments, pleaseopen an issue orsubmit apull request.
About
Go library for the Stripe API.
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Languages
- Go100.0%