MCPcopy
hub / github.com/stripe/stripe-go

github.com/stripe/stripe-go @v86.1.0 sqlite

repository ↗ · DeepWiki ↗ · release v86.1.0 ↗
16,599 symbols 29,762 edges 657 files 12,881 documented · 78%
README

Go Stripe

Go Reference Build Status

[!TIP] Want to chat live with Stripe engineers? Join us on our Discord server.

The official [Stripe][stripe] Go client library.

Requirements

Per our Language Version Support Policy, we support the 4 most recent Go versions at the time of release. Currently, that's Go 1.22+.

Read more and see the full schedule in the docs: https://docs.stripe.com/sdks/versioning?lang=go#stripe-sdk-language-version-support-policy

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/v86"
    "github.com/stripe/stripe-go/v86/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/v86

Documentation

For a comprehensive list of examples, check out the [API documentation][api-docs].

For details on all the functionality in this library, see the [Go documentation][goref].

Below are a few simple examples:

Customers

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)

PaymentIntents

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
}

Events

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.

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][connect].

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/v86"
)

sc := stripe.NewClient("access_token")

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/v86"
)

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)
}

Usage

While some resources may contain more/less APIs, the following pattern is applied throughout the library for a given resource (like Customer).

With Stripe Client

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/v86"

// 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.

Without a Client (Legacy)

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/v86"
    "github.com/stripe/stripe-go/v86/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
}

Other usage patterns

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][apiresponse] for available fields.

Note that where API resources are nested in other API resources, only LastResponse on the top-level resource is set.

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][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/v86"
)

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(...)

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][logrus] and Zap's [SugaredLogger][zapsugaredlogger] 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.

Expanding Objects

All [expandable objects][expandableobjects] 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 preview 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.

Parameters

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)

Properties

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)
}

For List and Search operations, you can access each resource's RawJSON as you iterate

for cust, err := range sc.V1Customers.List(context.TODO(), &stripe.CustomerListParams{}) {
    if err != nil {
        return err
    }
    customerJSON := cust.LastResponse.RawJSON
    log.Printf("Customer JSON: %s", customerJSON) // {"id":"cus_123",...}
}

Beta headers

To access a private preview feature, you will likely need to use a special beta header. If you are using a public preview or private preview SDK version (those with a version v83.1.0-beta.1 or v83.1.0-alpha.1), you can use the stripe.AddBetaVersion function as described in Public Preview SDKs. With a release version like v83.1.0, you can still set a beta header on a per-request basis in your request params as follows:

params := &stripe.CustomerCreateParams{
    ...
    Params: stripe.Params{
        Headers: http.Header{
            "Stripe-Version": []string{"2025-10-29.preview; beta_feature_1=v3; beta_feature_2=v1"},
        },
    },
}

Webhook signing

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.

Testing Webhook signing

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
}

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.

Telemetry

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

Extension points exported contracts — how you extend this code

LastResponseSetter (Interface)
LastResponseSetter defines a type that contains an HTTP response from a Stripe API endpoint. [9 implementers]
stripe.go
Appender (Interface)
Appender is the interface implemented by types that can append themselves to a collection of form values. This is usual [37 …
form/form.go
ParamsContainer (Interface)
ParamsContainer is a general interface for which all parameter structs should comply. They achieve this by embedding a P [3 …
params.go
LeveledLoggerInterface (Interface)
LeveledLoggerInterface provides a basic leveled logging interface for printing debug, informational, warning, and error [2 …
log.go
V2CoreEvent (Interface)
V2CoreEvent is the interface implemented by V2 Events. To get the underlying Event, use a type switch or type assertion [1 …
v2_events.go
EventNotificationContainer (Interface)
interface to return from ParseEventNotification this is how go's unions basically work? [1 implementers]
event_notification.go
SearchContainer (Interface)
Public types SearchContainer is a general interface for which all search result object structs should comply. They ach [1 …
search_params.go
ClientOption (FuncType)
ClientOption allows for functional options to be passed to the NewClient constructor.
stripe_client.go

Core symbols most depended-on inside this repo

Call
called by 949
stripe.go
New
called by 476
client/api.go
FormatURLPath
called by 374
stripe.go
Err
called by 373
iter_test.go
Encode
called by 262
form/form.go
CallRaw
called by 247
stripe.go
List
called by 213
event/client.go
Errorf
called by 202
log.go

Shape

Struct 8,237
Method 3,285
Function 2,800
TypeAlias 2,248
Interface 17
FuncType 12

Languages

Go100%

Modules by API surface

example/generated_examples_test.go1,327 symbols
paymentintent.go967 symbols
tax_registration.go627 symbols
paymentmethodconfiguration.go604 symbols
checkout_session.go599 symbols
setupintent.go497 symbols
account.go465 symbols
v2core_account_params.go412 symbols
v2core_account.go408 symbols
invoice.go370 symbols
subscription.go301 symbols
paymentlink.go278 symbols

Dependencies from manifests, versioned

github.com/pmezard/go-difflibv1.0.0 · 1×
gopkg.in/yaml.v3v3.0.1 · 1×

For agents

$ claude mcp add stripe-go \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact