Skip to content

Migration guide for Stripe Client

Michael Broshi edited this page May 6, 2025 · 6 revisions

High-level description of changes

Starting with v82.1, the new stripe.Client type is replacing client.API to provide a more ergonomic, consistent, and less error-prone experience. You create the former using stripe.NewClient(stripeKey). It’s almost a drop-in replacement, except for the differences listed below.

  1. Service method names now align with Stripe API docs. The stripe.Client uses Create, Retrieve, Update, and Delete (instead of New, Get, Update, and Del).
  2. The first argument of each service method is a context.Context.
  3. Parameter objects are now method-specific. For example, CustomerCreateParams and CustomerDeleteParams instead of simply CustomerParams. This allows us to put the right fields in the right methods at compile time.
  4. Services are all version-namespaced for symmetry. E.g. stripeClient.V1Accounts and stripeClient.V2Accounts.
  5. List methods return an iter.Seq2, so they can be ranged over without explicit calls to Next, Current, and Err.

Details of migration

Creating a client

The new stripe.Client is almost, but not quite, a drop-in replacement for client.API. You create a new client using stripe.NewClient(apiKey). You can replace client.API construction with stripe.Client using this regex:

/client.New\((.*), nil\)/stripe.NewClient($1)/

Before

sc := client.New(env().StripeKey, nil)

After

sc := stripe.Client(env().StripeKey)

If you are passing in your own stripe.Backends into client.New, you pass them into the stripe.Client as follows

sc := stripe.NewClient(stripeKey, stripe.WithBackends(backends))

CRUD methods

CRUD methods are now called Create, Retrieve, Update, and Delete

Old New
params := &stripe.CustomerParams{...}
params.Context = context.TODO() 
sc.Customers.New(params)
params := &stripe.CustomerCreateParams{...} 
sc.V1Customers.Create(context.TODO(), params)
params := &stripe.CustomerParams{...}
params.Context = context.TODO() 
sc.Customers.Get(params)
params := &stripe.CustomerRetrieveParams{...} 
sc.V1Customers.Retrieve(context.TODO(), params)
params := &stripe.CustomerParams{...}
params.Context = context.TODO() 
sc.Customers.Update(params)
params := &stripe.CustomerUpdateParams{...} 
sc.V1Customers.Update(context.TODO(), params)
params := &stripe.CustomerParams{...}
params.Context = context.TODO() 
sc.Customers.Del(params)
params := &stripe.CustomerDeleteParams{...} 
sc.V1Customers.Delete(context.TODO(), params)

List methods

OLD

i := sc.Customers.List(&stripe.CustomerListParams{})
for i.Next() {
	cust := i.Customer()
	// handle cust
}
if err := i.Err(); err != nil {
	// handle err
}

NEW

params := &stripe.CustomerListParams{}
for cust, err := range sc.V1Customers.List(context.TODO(), params) {
	// handle err
	// handle cust
}

Method-specific Params

All params are now method-specific. This prevents runtime errors where you pass the wrong params to the Stripe API.
Old

params := &stripe.CustomerParams{Name: stripe.String("Jenny Rosen")}
params.Context = context.TODO()
sc.Customers.Del("cus_123", params) // ❌ -- runtime error from Stripe: Name param not allowed

The general pattern is:

  • Old: {resource_name}{subresource_names?}Params
  • New: {resource_name}{method_name}{subresource_names?}Params

Old

params := &stripe.AppsSecretParams{
	Name:    stripe.String("sec_123"),
	Payload: stripe.String("very secret string"),
	Scope: &stripe.AppsSecretScopeParams{
		Type: stripe.String(stripe.AppsSecretScopeTypeAccount),
	},
}

New

params := &stripe.AppsSecretCreateParams{
	Name:    stripe.String("sec_123"),
	Payload: stripe.String("very secret string"),
	Scope: &stripe.AppsSecretCreateScopeParams{
		Type: stripe.String(stripe.AppsSecretScopeTypeAccount),
	},
}
Clone this wiki locally