Awesome Go

stripe

CategoryThird-party APIs
SubcategoryThird-party APIs
Stars2,641

Go client for the Stripe API

About stripe

This large README is shown as a plain-text preview. Read the full README at the source

# Go Stripe

[![Go Reference](https://pkg.go.dev/badge/github.com/stripe/stripe-go)](https://pkg.go.dev/github.com/stripe/stripe-go/v87)
[![Build Status](https://github.com/stripe/stripe-go/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/stripe/stripe-go/actions/workflows/ci.yml?query=branch%3Amaster)

> [!TIP]
> Want to chat live with Stripe engineers? Join us on our [Discord server](https://stripe.com/go/discord/go).

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

## Requirements

Per our [Language Version Support Policy](https://docs.stripe.com/sdks/versioning?lang=go#stripe-sdk-language-version-support-policy), we support Go versions that are currently receiving support, plus those within the extended support window. Currently, that's **Go 1.24+**.

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

```sh
go mod init
```

Then, reference stripe-go in a Go program with `import`:

```go
import (
	"github.com/stripe/stripe-go/v87"
	"github.com/stripe/stripe-go/v87/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:

```bash
go get -u github.com/stripe/stripe-go/v87
```

## 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

```go
sc := stripe.NewClient(apiKey)
params := &stripe.CustomerCreateParams{
	Description:      stripe.String("Stripe Developer"),
	Email:            stripe.String("[email protected]"),
	PreferredLocales: stripe.StringSlice([]string{"en", "es"}),
}

c, err := sc.V1Customers.Create(context.TODO(), params)
```

### PaymentIntents

```go
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

```go
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:

```go
// For a list request
listParams := &stripe.CustomerListParams{}
listParams.SetStripeAccount("acct_123")
```

To use a key, pass it into `stripe.NewClient`:

```go
import (
	"github.com/stripe/stripe-go/v87"
)

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:

```go
import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/urlfetch"

	"github.com/stripe/stripe-go/v87"
)

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("[email protected]"),
	}
	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.

```go
import "github.com/stripe/stripe-go/v87"

// 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](https://github.com/stripe/stripe-go/wiki/Migration-guide-for-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.

```go
import (
	"github.com/stripe/stripe-go/v87"
	"github.com/stripe/stripe-go/v87/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:

```go
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`:

```go
import (
	"github.com/stripe/stripe-go/v87"
)

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:

```go
stripe.DefaultLeveledLogger = &stripe.LeveledLogger{
    Level: stripe.LevelInfo,
}
```

Or on a per-backend basis:

```go
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:

```go
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.

### Suppressing Stripe notices

The SDK may print notices from Stripe that it receives in the `Stripe-Notice` header. These notices are always printed when the SDK runs in an agent environment. For API calls to test accounts or sandboxes, notices are also printed when the SDK runs outside an agent environment. To suppress notices when the SDK runs outside an agent environment, set the `STRIPE_SUPPRESS_NOTICES` environment variable to `true` before running your integration.

### 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:

```go
//
// *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:

```go
params := &stripe.CustomerCreateParams{
	Email: stripe.String("[email protected]")
}
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:

```go
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

```go
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](#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:

```go
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](https://stripe.com/docs/webhooks/signatures).

#### Testing Webhook signing

You can use `stripe.GenerateTestSignedPayload` to mock webhook events that come from Stripe:

```go
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`:

```go
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 popular features.

You can disable this behavior if you prefer:

```go
config := &stripe.BackendConfig{
	EnableTelemetry: stripe.Bool(false),
}
```

### Mocking clients for unit tests

To mock a Stripe client for a unit tests using [GoMock](https://github.com/golang/mock):

1. Generate a `Backend` type mock.

```
mockgen -destination=mocks/backend.go -package=mocks github.com/stripe/stripe-go/v87 Backend
```

2. Use the `Backend` mock to initialize and call methods on the client.

```go

import (
	"example/hello/mocks"
	"testing"

	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/assert"
	"github.com/stripe/stripe-go/v87"
)

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

### Public Preview SDKs

Stripe has features in the [public preview phase](https://docs.stripe.com/release-phases) 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, pick the latest version with the `beta` suffix by reviewing the [releases page](https://github.com/stripe/stripe-go/releases/) and use it in your `go.mod` file:

```
require (
	...
	github.com/stripe/stripe-go/v87 <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):

```go
stripe.AddBetaVersion("feature_beta", "v3")
```

### Private Preview SDKs

Stripe has features in the [private preview phase](https://docs.stripe.com/release-phases) that can be accessed via versions of this package that have the `-alpha.X` suffix like `82.2.0-alpha.2`. You can install the private preview SDKs by following the same instructions as for the [public preview SDKs](https://github.com/stripe/stripe-go?tab=readme-ov-file#public-preview-sdks) above and replacing the term `beta` with `alpha`. Note that access to specific private preview API features may require separate approval.

### Custom Request

> This feature is only available from version 80 of this SDK.

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 the `rawrequest` package:

```go
import (
	"encoding/json"
	"fmt"

	"github.com/stripe/stripe-go/v87"
	"github.com/stripe/stripe-go/v87/form"
	"github.com/stripe/stripe-go/v87/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](example/v2).

## Support

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.

## Development

> [!WARNING]

Frequently Asked Questions

What is stripe?

stripe is a Third-party APIs library for the Go programming language. Go client for the Stripe API

How many GitHub stars does stripe have?

stripe has 2,641 GitHub stars in the directory's latest synchronization.

How do I install stripe?

Install stripe with the Go module system using `go get stripe/stripe-go`. Check the repository for the current installation instructions.

What category does stripe belong to?

stripe is listed under Third-party APIs, specifically Third-party APIs.

← Back to Third-party APIs