Go Stripe
The official Stripe Go client library.
Installation
Make sure your project is using Go Modules (it will have a go.mod
file in its root if it already is):
go mod init
Then, reference stripe-go in a Go program with import
:
import (
"github.com/stripe/stripe-go/v71"
"github.com/stripe/stripe-go/v71/customer"
)
Run any of the normal go
commands (build
/install
/test
). The Go toolchain will resolve and fetch the stripe-go module automatically.
Documentation
For a comprehensive list of examples, check out the API documentation.
For details on all the functionality in this library, see the GoDoc documentation.
Below are a few simple examples:
Customers
params := &stripe.CustomerParams{
Description: stripe.String("Stripe Developer"),
Email: stripe.String("gostripe@stripe.com"),
}
customer, err := customer.New(params)
PaymentIntents
params := &stripe.PaymentIntentListParams{
Customer: stripe.String(customer.ID),
}
// set this so you can easily retry your request in case of a timeout
params.Params.IdempotencyKey = stripe.NewIdempotencyKey()
i := paymentintent.List(params)
for i.Next() {
pi := i.PaymentIntent()
}
if err := i.Err(); err != nil {
// handle
}
Events
i := event.List(nil)
for i.Next() {
e := i.Event()
// 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.PrevPreviousAttributes["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.
Authentication with Connect
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")
// For any other kind of request
params := &stripe.CustomerParams{}
params.SetStripeAccount("acct_123")
To use a key, pass it to API
's Init
function:
import (
"github.com/stripe/stripe-go/v71"
"github.com/stripe/stripe-go/v71/client"
)
stripe := &client.API{}
stripe.Init("access_token", nil)
Google AppEngine
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/v71"
"github.com/stripe/stripe-go/v71/client"
)
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
httpClient := urlfetch.Client(c)
sc := stripeClient.New("sk_test_123", stripe.NewBackends(httpClient))
params := &stripe.CustomerParams{
Description: stripe.String("Stripe Developer"),
Email: stripe.String("[email protected]"),
}
customer, err := sc.Customers.New(params)
if err != nil {
fmt.Fprintf(w, "Could not create customer: %v", err)
}
fmt.Fprintf(w, "Customer created: %v", customer.ID)
}
Usage
While some resources may contain more/less APIs, the following pattern is applied throughout the library for a given $resource$
:
Without a Client
If you're only dealing with a single key, you can simply import the packages required for the resources you're interacting with without the need to create a client.
import (
"github.com/stripe/stripe-go/v71"
"github.com/stripe/stripe-go/v71/$resource$"
)
// Setup
stripe.Key = "sk_key"
stripe.SetBackend("api", backend) // optional, useful for mocking
// Create
$resource$, err := $resource$.New(stripe.$Resource$Params)
// Get
$resource$, err := $resource$.Get(id, stripe.$Resource$Params)
// Update
$resource$, err := $resource$.Update(stripe.$Resource$Params)
// Delete
resourceDeleted, err := $resource$.Del(id, stripe.$Resource$Params)
// List
i := $resource$.List(stripe.$Resource$ListParams)
for i.Next() {
$resource$ := i.$Resource$()
}
if err := i.Err(); err != nil {
// handle
}
With a Client
If you're dealing with multiple keys, it is recommended you use client.API
. This allows you to create as many clients as needed, each with their own individual key.
import (
"github.com/stripe/stripe-go/v71"
"github.com/stripe/stripe-go/v71/client"
)
// Setup
sc := &client.API{}
sc.Init("sk_key", nil) // the second parameter overrides the backends used if needed for mocking
// Create
$resource$, err := sc.$Resource$s.New(stripe.$Resource$Params)
// Get
$resource$, err := sc.$Resource$s.Get(id, stripe.$Resource$Params)
// Update
$resource$, err := sc.$Resource$s.Update(stripe.$Resource$Params)
// Delete
resourceDeleted, err := sc.$Resource$s.Del(id, stripe.$Resource$Params)
// List
i := sc.$Resource$s.List(stripe.$Resource$ListParams)
for i.Next() {
resource := i.$Resource$()
}
if err := i.Err(); err != nil {
// handle
}
Automatic Retries
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/v71"
"github.com/stripe/stripe-go/v71/client"
)
config := &stripe.BackendConfig{
MaxNetworkRetries: stripe.Int64(0), // Zero retries
}
sc := &client.API{}
sc.Init("sk_key", &stripe.Backends{
API: stripe.GetBackendWithConfig(stripe.APIBackend, config),
Uploads: stripe.GetBackendWithConfig(stripe.UploadsBackend, config),
})
coupon, err := sc.Coupons.New(...)
Configuring Logging
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.
Writing a Plugin
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.
Request latency telemetry
By default, the library sends request latency telemetry to Stripe. These numbers help Stripe improve the overall latency of its API for all users.
You can disable this behavior if you prefer:
config := &stripe.BackendConfig{
EnableTelemetry: stripe.Bool(false),
}
Development
Pull requests from the community are welcome. If you submit one, please keep the following guidelines in mind:
- Code must be
go fmt
compliant. - All types, structs and funcs should be documented.
- Ensure that
make test
succeeds.
Test
The test suite needs testify's require
package to run:
github.com/stretchr/testify/require
Before running the tests, make sure to grab all of the package's dependencies:
go get -t -v
It also 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:
make test
Run tests for one package:
go test ./invoice
Run a single test:
go test ./invoice -run TestInvoiceGet
For any requests, bug or comments, please open an issue or submit a pull request.