# stripe-go: the official Go client for Stripe's API, and the v86 client split

> stripe-go is Stripe's official Go SDK, generated from Stripe's OpenAPI spec and shipped as versioned modules under github.com/stripe/stripe-go/v86. The interesting part is not the API coverage but the v82.1 introduction of stripe.Client, which sits alongside the older resource pattern.

**stripe/stripe-go** — Go library for the Stripe API.    

- Repository: https://github.com/stripe/stripe-go
- Website: https://stripe.com
- Stars: 2,640 · Forks: 532
- Language: Go
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/stripe-stripe-go

## What stripe-go is for, and who ends up using it

stripe-go is the official Go client library for the Stripe API. It exists so that Go services do not have to construct HTTP requests, sign them, and decode JSON responses by hand for every Stripe object. The README describes it as "the official Stripe Go client library" and points to the Go reference on pkg.go.dev for the full surface.

The audience is backend engineers writing payment, billing, or subscription code in Go. That usually means a service that creates customers, charges payment intents, reconciles events from Stripe's webhooks, or lists historical objects for reporting. If your Stripe integration lives entirely in a browser or in a language other than Go, this library is not the thing you want.

The scope is broad because the library is generated rather than handwritten. The top-level repository layout shows a file per resource (account.go, balance.go, bankaccount.go, and so on) alongside a matching directory and a _service.go file. That structure is the giveaway: the SDK tracks Stripe's API surface closely, and the OPENAPI_VERSION and CODEGEN_VERSION files at the repository root confirm the generation pipeline.

## How the client is generated and what stripe.Client changed

The README is explicit that stripe.Client arrived in v82.1 of the Go SDK. Before that, the documented way to reach Stripe resources was the resource pattern: set the package-level stripe.Key, then call package functions such as customer.New, customer.Get, customer.Update, customer.Del, and iterate a list with a Next() loop.

That older pattern still exists but the README says it is "marked as deprecated" and that Stripe plans to deprecate it further in a future release. A wiki page titled Migration guide for Stripe Client is linked from the README for teams moving across.

The replacement is a client object created with stripe.NewClient, which exposes resource accessors like sc.V1Customers and sc.V1PaymentIntents. The V1 prefix is not decoration: the README states plainly that the legacy pattern does not support Stripe's V2 APIs. If you need V2 endpoints, the legacy route is a dead end, and that is the strongest practical reason to migrate.

One detail worth noticing is that list calls changed shape. With stripe.Client the README shows a range loop over the result of sc.V1PaymentIntents.List, which is a Go 1.23 range-over-func iterator, while the module's go.mod declares go 1.22. The README's Requirements section says the project supports the four most recent Go versions at release time and names Go 1.22+ as the current floor. That mismatch between a declared 1.22 floor and iterator-style examples is the kind of thing worth checking against the Go reference before you commit to a pattern in a shared codebase.

## Installation and a first customer creation

The README assumes Go Modules. If your project does not already have a go.mod file, the first step is to create one, then pull the module in. The module path carries the major version, so the import path is github.com/stripe/stripe-go/v86, not the bare repository name.

```bash
go mod init
go get -u github.com/stripe/stripe-go/v86
```

The README notes that running any normal go command (build, install, test) will also cause the toolchain to resolve and fetch the module, so the explicit go get is optional. After the module is present, import the root package and, if you are using the legacy pattern, the per-resource package as well.

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

The README's first real example creates a client and a customer with the stripe.Client pattern. Note that the API key is passed to NewClient, and that the params struct uses helper functions such as stripe.String and stripe.StringSlice to build pointers to the fields you want to send.

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

The README gives no expected output for this call, so there is nothing to compare against beyond the returned customer and error. In a test environment you would see a customer object with a generated ID; the README does not document the response fields.

For Connect platforms, the README describes two authentication routes. The recommended one sets the Stripe-Account header through SetStripeAccount on the params object, and the other passes a connected account's key into stripe.NewClient directly.

```go
listParams := &stripe.CustomerListParams{}
listParams.SetStripeAccount("acct_123")
```

There is also a documented Google App Engine path. Because http.DefaultClient is not available there, the README builds a per-request client using stripe.NewBackends with an App Engine urlfetch client and passes it via stripe.WithBackends.

## Versioning, the go.mod floor, and what upgrades actually cost

The module path includes the major version, and the repository's VERSION file drives a Makefile target that rewrites imports across the tree. In practice this means each major SDK release is a new import path, so upgrading is a mechanical find-and-replace plus a compile. The justfile contains a private update-version recipe that writes the version into VERSION and into the clientversion constant in stripe.go, then normalizes imports.

The go.mod declares go 1.22 and a single direct dependency, github.com/stretchr/testify v1.7.0, with go-spew, go-difflib, and yaml.v3 as indirect. That is a thin dependency tree for an SDK of this size, which keeps the blast radius of an upgrade small on the dependency side. The cost sits in the API surface instead: because files are generated per resource, a major bump can touch many call sites at once.

The release list shows alpha tags such as v86.5.0-alpha.5, v86.5.0-alpha.4, and v86.5.0-alpha.3, published weekly. Alpha tags are not what you pin in production; the README does not document a release cadence or a stability promise for these tags, so treat them as preview builds and pin a stable version instead.

The Makefile carries a note that it is deprecated and slated for deletion in favor of equivalent just commands. That matters for anyone scripting CI around make test or make lint: the justfile defines test, lint, format, bench, and build recipes, and the Makefile's own comment points there. If your pipeline calls make, plan for the switch.

## Where stripe-go is the wrong tool

The clearest limitation is stated by the project itself: the legacy resource pattern does not support Stripe's V2 APIs. A codebase built on package-level stripe.Key and customer.New cannot reach V2 endpoints without moving to stripe.Client, and the README offers no compatibility shim beyond the linked wiki migration guide.

The second constraint is the Go version floor. The README ties support to the four most recent Go releases and names Go 1.22+ as current. A service pinned to an older toolchain is outside that policy, and the README does not describe what happens if you try.

Third, this is a server-side library. It holds a secret API key, which means it does not belong in a browser bundle, a mobile client, or any context where the key would be exposed. If your architecture needs client-side Stripe calls, the Go SDK is not the component that solves that, and the README does not present it as one.

Finally, consider the generation model. Because resources are generated from Stripe's OpenAPI spec, the SDK moves when Stripe's API moves. Teams that want a small, hand-curated surface they fully control will find the breadth here to be more surface area than they want to keep compiling against.

## A real alternative: plain net/http against the Stripe REST API

The honest alternative for a Go service is not another SDK, it is calling Stripe's REST API directly with net/http and encoding/json. Stripe's API is HTTP with form-encoded or JSON bodies and bearer authentication, so a small internal client is entirely feasible.

The difference in approach is where the maintenance burden lands. With stripe-go, Stripe owns the type definitions and the request construction; your code compiles against generated structs, and a breaking API change arrives as a new major module path. With a hand-rolled client, you own the structs, so you only model the fields you actually use, but you also own every change Stripe makes to those endpoints and every retry, pagination, and error-decoding detail.

For a service that touches two or three endpoints, a small internal client can be less code than the SDK plus its generated surface. For anything that spans Connect, events, subscriptions, and payment intents, the generated coverage is the reason to take the dependency. The README's own examples lean toward the second case: the events example shows helpers like GetObjectValue and GetPreviousValue for digging into polymorphic event payloads, with e.Data.Raw offered as the escape hatch when you would rather unmarshal into your own struct. That helper exists precisely because Stripe's event objects vary by type, and reimplementing it is work you would be signing up for.

## Licence and what to verify before you commit

The repository is MIT licensed, with the LICENSE file at the root. MIT is permissive, which means you can use the library in closed-source services without publishing your own code. The practical implication to check is attribution: MIT requires that the copyright notice and permission notice be included in copies or substantial portions of the software, so if you vendor the source rather than importing the module, keep the LICENSE file with it. This is a description of the licence text, not legal advice; route anything unusual through your own counsel.

Before writing production code, verify three things. First, your Go toolchain version against the four-versions support policy the README links to. Second, whether your existing code uses the deprecated client.API pattern or stripe.Client, since the README says the former will be deprecated further and does not support V2 APIs. Third, whether your CI calls the Makefile or the justfile, because the Makefile's own header says it is deprecated and slated for deletion in favor of the just recipes.

## Conclusion

Adopt stripe-go if you already run Stripe on the server side and want typed Go structs instead of hand-rolled HTTP calls. Do not adopt it if you need Stripe's V2 APIs through the legacy resource pattern, since the README states that pattern does not support them, or if you are on a Go version older than 1.22. Before writing code, confirm your project's Go version against the four-versions support policy, and check which client pattern your existing code uses, because mixing stripe.Client and the deprecated client.API in one service makes the eventual migration harder to reason about.

## FAQ

### What is stripe-go?

It is the official Stripe client library for Go, published under the module path github.com/stripe/stripe-go/v86. The README describes it as the official Stripe Go client library and points to the Go reference for the full API surface.

### How do I install stripe-go in a Go project?

Make sure the project uses Go Modules, then run go get -u github.com/stripe/stripe-go/v86, or simply import the package and let the Go toolchain fetch it when you build. The import path includes the major version, so it is github.com/stripe/stripe-go/v86 rather than the bare repository name.

### What Go version does stripe-go require?

The README says the project supports the four most recent Go versions at release time and names Go 1.22+ as the current floor. The full schedule is in Stripe's language version support policy document linked from the README.

### Does stripe-go support Stripe's V2 APIs?

The stripe.Client pattern does, through accessors such as sc.V1Customers and sc.V1PaymentIntents. The README states that the legacy resource pattern does not support the V2 APIs.

## Sources

- [License: MIT](https://github.com/stripe/stripe-go/blob/master/LICENSE)
- [Project website](https://stripe.com)
- [README](https://github.com/stripe/stripe-go/blob/master/README.md)
- [Releases](https://github.com/stripe/stripe-go/releases)
- [stripe/stripe-go on GitHub](https://github.com/stripe/stripe-go)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stripe-stripe-go
