Go Stripe
The official Stripe Go client library.
Installation
Install stripe-go with:
go get -u github.com/stripe/stripe-go
Then, import it using:
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/customer"
)
Go Module Support
The library currently does not ship with first-class support for Stripe
modules. We put in support for it before, but ran into compatibility problems
for existing installations using Dep (see discussion in closer to the bottom
of this thread, and reverted support. Our current
plan is to wait for better module compatibility in Dep (see a preliminary
patch here), give the release a little grace time to become
more widely distributed, then bring support back.
For now, require stripe-go in go.mod
with a version but without a version
suffix in the path like so:
module github.com/my/package
require (
github.com/stripe/stripe-go v59.1.0
)
And use the same style of import paths as above:
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/customer"
)
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{
AccountBalance: stripe.Int64(-123),
Description: stripe.String("Stripe Developer"),
Email: stripe.String("gostripe@stripe.com"),
}
params.SetSource("tok_1234")
customer, err := customer.New(params)
Charges
params := &stripe.ChargeListParams{Customer: stripe.String(customer.ID)}
params.Filters.AddFilter("include[]", "", "total_count")
params.Params.IdempotencyKey = stripe.NewIdempotencyKey()
i := charge.List(params)
for i.Next() {
charge := i.Charge()
}
if err := i.Err(); err != nil {
}
Events
i := event.List(nil)
for i.Next() {
e := i.Event()
}
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:
listParams := &stripe.ChargeListParams{}
listParams.SetStripeAccount("acct_123")
params := &stripe.CustomerParams{}
params.SetStripeAccount("acct_123")
To use a key, pass it to API
's Init
function:
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/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"
"github.com/stripe/stripe-go/client"
)
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
httpClient := urlfetch.Client(c)
sc := stripeClient.New("sk_live_key", stripe.NewBackends(httpClient))
chargeParams := &stripe.ChargeParams{
Amount: stripe.Int64(2000),
Currency: stripe.String(string(stripe.CurrencyUSD)),
Description: stripe.String("Charge from Google App Engine"),
}
chargeParams.SetSource("tok_amex")
charge, err := sc.Charges.New(chargeParams)
if err != nil {
fmt.Fprintf(w, "Could not process payment: %v", err)
}
fmt.Fprintf(w, "Completed payment: %v", charge.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"
"github.com/stripe/stripe-go/$resource$"
)
stripe.Key = "sk_key"
stripe.SetBackend("api", backend)
$resource$, err := $resource$.New(stripe.$Resource$Params)
$resource$, err := $resource$.Get(id, stripe.$Resource$Params)
$resource$, err := $resource$.Update(stripe.$Resource$Params)
resourceDeleted, err := $resource$.Del(id, stripe.$Resource$Params)
i := $resource$.List(stripe.$Resource$ListParams)
for i.Next() {
$resource$ := i.$Resource$()
}
if err := i.Err(); err != nil {
}
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"
"github.com/stripe/stripe-go/client"
)
sc := &client.API{}
sc.Init("sk_key", nil)
$resource$, err := sc.$Resource$s.New(stripe.$Resource$Params)
$resource$, err := sc.$Resource$s.Get(id, stripe.$Resource$Params)
$resource$, err := sc.$Resource$s.Update(stripe.$Resource$Params)
resourceDeleted, err := sc.$Resource$s.Del(id, stripe.$Resource$Params)
i := sc.$Resource$s.List(stripe.$Resource$ListParams)
for i.Next() {
resource := i.$Resource$()
}
if err := i.Err(); err != nil {
}
Configuring Automatic Retries
The library can be configured to automatically retry requests that fail due to
an intermittent network problem or other knowingly non-deterministic errors:
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/client"
)
config := &stripe.BackendConfig{
MaxNetworkRetries: 2,
}
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(...)
Idempotency keys are added to requests to guarantee that
retries are safe.
Configuring Logging
Configure 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 support this interface out-of-the-box so
it's possible to set DefaultLeveledLogger
to a *logrus.Logger
directly. For
others (Zap for example) it'll 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.
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.