Payments
Migrate Checkout to use Prices

Checkout prices migration guide

Learn how to update your integration to use prices with Checkout.

The Prices API adds new features and flexibility to how you charge customers. This new integration offers:

  • More unified modeling for Checkout items—instead of plans, SKUs, and inline line items, every item is now a price.
  • The ability to render product images for recurring items.

For the client and server integration, the Prices API unlocks the ability to:

  • Create a reusable product and price catalog instead of one-time line items
  • Create inline pricing for subscriptions
  • Apply dynamic tax rates to subscriptions and one-time payments

Don’t want to migrate? You can continue to use your current integration, but new features are not supported. Any new plans or recurring prices you create can be used in the plan parameter of your existing API calls.

Products and prices overview

Prices are a new, core entity within Stripe that works with subscriptions, invoices, and Checkout. Each price is tied to a single Product, and each product can have multiple prices. Different physical goods or levels of service should be represented by products. Pricing of that product should be represented by prices.

Prices define the base price, currency, and—for recurring products—the billing cycle. This allows you to change and add prices without needing to change the details of what you offer. For example, you might have a single “gold” product that has prices for $10/month, $100/year, €9/month, and €90/year. Or you might have a blue t-shirt with $20 USD and €15 EUR prices.

Plans and SKUs (client-only) may be used with the new integration wherever Prices are accepted. You can either create a product and price through the API or through the Stripe Dashboard.

One-time payments

The client and server integration has the following changes for one-time payments:

  • Instead of ad-hoc line items (i.e. setting the name, amount, and currency), creating a Checkout session requires first creating a product and, usually, a price.
  • mode is now required.

The client-side code remains the same.

Mapping table

Instead of defining each field on line_items, Checkout uses the underlying product and price objects to determine name, description, amount, currency, and images. You can create products and prices with the API or Dashboard.

Without prices With prices
line_items.name product.name

If you want to set a description per Checkout session that is different from the product name, you can use line_items.description.
line_items.description product.description
line_items.amount price.unit_amount

price_data.unit_amount if defined at Checkout session creation.
line_items.currency price.currency

price_data.currency if defined at Checkout session creation.
line_items.images product.images. Like with line_items.images, Checkout will display the first image supplied.

Server-side code for inline items

Previously, the server API offered only inline creation of one-time items. With prices, you can continue to configure your items inline. To define your prices dynamically, you can use the price_data parameter at Checkout session creation.

When you create the Checkout session with price_data, reference an existing product ID with price_data.product, or define your product details dynamically as well using price_data.product_data. This example shows the flow for creating a one-time item.


curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[0][quantity]"=1 \ -d "line_items[0][amount]"=2000 \ -d "line_items[0][name]"=T-shirt \ -d "line_items[0][description]"="Comfortable cotton t-shirt" \ -d "line_items[0][images][]"="https://example.com/t-shirt.png" \ -d "line_items[0][currency]"=usd \ -d "line_items[0][price_data][unit_amount]"=2000 \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][product_data][description]"="Comfortable cotton t-shirt" \ -d "line_items[0][price_data][product_data][images][]"="https://example.com/t-shirt.png" \ -d "line_items[0][price_data][currency]"=usd \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', price_data: { currency: 'usd', unit_amount: 2000, product_data: { name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], }, }, quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
session = stripe.checkout.Session.create( payment_method_types=['#{payment_method_type}'], line_items=[{ 'name': 'T-shirt', 'description': 'Comfortable cotton t-shirt', 'images': ['https://example.com/t-shirt.png'], 'amount': 2000, 'currency': 'usd', 'price_data': { 'currency': 'usd', 'unit_amount': 2000, 'product_data': { 'name': 'T-shirt', 'description': 'Comfortable cotton t-shirt', 'images': ['https://example.com/t-shirt.png'], }, }, 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
$session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], 'amount' => 2000, 'currency' => 'usd', 'price_data' => [ 'currency' => 'usd', 'unit_amount' => 2000, 'product_data' => [ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], ], ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
const session = await stripe.checkout.sessions.create({ payment_method_types: ['#{payment_method_type}'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', price_data: { currency: 'usd', unit_amount: 2000, product_data: { name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], }, }, quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setName("T-shirt") .setDescription("Comfortable cotton t-shirt") .setAmount(2000L) .setCurrency("usd") .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .setDescription("Comfortable cotton t-shirt") .build()) .build()) .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), Amount: stripe.Int64(2000), Currency: stripe.String("usd"), PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), UnitAmount: stripe.Int64(2000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), }, }, Quantity: stripe.Int64(1), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", Amount = 2000, Currency = "usd", PriceData = new SessionLineItemPriceDataOptions { Currency = "usd", UnitAmount = 1, ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Server-side code for one-time prices

With the new integration, you can first create a product and price catalog instead of needing to define the amount, currency, and name each time you create a Checkout session.

You can either create a product and price through the Prices API or through the Stripe Dashboard. You will need the price ID to create the Checkout session. This example shows how to create a product and price via API:


curl https://api.stripe.com/v1/products \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d name=T-shirt \ -d description="Comfortable cotton t-shirt" \ -d "images[]"="https://example.com/t-shirt.png" curl https://api.stripe.com/v1/prices \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d product="{{PRODUCT_ID}}" \ -d unit_amount=2000 \ -d currency=usd curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[0][quantity]"=1 \ -d "line_items[0][amount]"=2000 \ -d "line_items[0][name]"=T-shirt \ -d "line_items[0][description]"="Comfortable cotton t-shirt" \ -d "line_items[0][images][]"="https://example.com/t-shirt.png" \ -d "line_items[0][currency]"=usd \ -d "line_items[0][price]"="{{PRICE_ID}}" \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
product = Stripe::Product.create({ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], }) price = Stripe::Price.create({ product: product.id, unit_amount: 2000, currency: 'usd', }) session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', price: price.id, quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
product = stripe.Product.create( name='T-shirt', description='Comfortable cotton t-shirt', images=['https://example.com/t-shirt.png'], ) price = stripe.Price.create( product=product.id, unit_amount=2000, currency='usd', ) session = stripe.checkout.Session.create( payment_method_types=['#{payment_method_type}'], line_items=[{ 'name': 'T-shirt', 'description': 'Comfortable cotton t-shirt', 'images': ['https://example.com/t-shirt.png'], 'amount': 2000, 'currency': 'usd', 'price': price.id, 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
$product = \Stripe\Product::create([ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], ]); $price = \Stripe\Price::create([ 'product' => $product->id, 'unit_amount' => 2000, 'currency' => 'usd', ]); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], 'amount' => 2000, 'currency' => 'usd', 'price' => $price->id, 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
const product = await stripe.products.create({ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], }); const price = await stripe.prices.create({ product: product.id, unit_amount: 2000, currency: 'usd', }); const session = await stripe.checkout.sessions.create({ payment_method_types: ['#{payment_method_type}'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', price: price.id, quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
ProductCreateParams productCreateParams = ProductCreateParams.builder() .setName("T-shirt") .setDescription("Comfortable cotton t-shirt") .build(); Product product = Product.create(productCreateParams); PriceCreateParams priceCreateParams = PriceCreateParams.builder() .setProduct(product.getId()) .setUnitAmount(2000L) .setCurrency("usd") .build(); Price price = Price.create(priceCreateParams); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setName("T-shirt") .setDescription("Comfortable cotton t-shirt") .setAmount(2000L) .setCurrency("usd") .setPrice(price.getId()) .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
newProductParams := &stripe.ProductParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), } product, _ := product.New(newProductParams) newPriceParams := &stripe.PriceParams{ Product: stripe.String(product.ID), UnitAmount: stripe.Int64(2000), Currency: stripe.String("usd"), } price, _ := price.New(newPriceParams) params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), Amount: stripe.Int64(2000), Currency: stripe.String("usd"), Price: stripe.String(price.ID), Quantity: stripe.Int64(1), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
var productCreateOptions = new ProductCreateOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", }; var productService = new ProductService(); var product = productService.Create(productCreateOptions); var priceCreateOptions = new PriceCreateOptions { Product = product.Id, UnitAmount = 2000, Currency = "usd", }; var priceService = new PriceService(); var price = priceService.Create(priceCreateOptions); var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", Amount = 2000, Currency = "usd", Price = price.Id, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

The client-only integration has the following changes:

  • items is now lineItems. Existing SKUs can be passed into the new field, using lineItems.price.
  • mode is now required.
  • The product description will be product.description instead of the SKU’s attributes.name.

Redirect to Checkout

To redirect to Checkout, pass in a price or SKU ID into lineItems.price. The items parameter in the old API does not accept prices, but the new lineItems API parameter accepts both SKU and price IDs. If you prefer not to change your integration, you may still create SKUs through the Dashboard and API and use your existing integration.


stripe.redirectToCheckout({ items: [{ sku: '{{SKU_ID}}', lineItems: [{ price: '{{PRICE_OR_SKU_ID}}', quantity: 1 }], mode: 'payment', successUrl: 'https://example.com/success', cancelUrl: 'https://example.com/cancel', }) .then((result) => {});

Subscriptions

The client and server integration has the following changes for recurring payments:

  • All items are passed into a single line_items field, instead of subscription_data.items.
  • mode is now required. Set mode=subscription if the session includes any recurring items.

The client-side code remains the same. Existing plans can be used wherever recurring prices are accepted.

Server-side code with plans

Here is a before and after example of creating a Checkout session with a trial and using an existing plan, which can be used interchangeably with a price. The plan is no longer passed into subscription_data.items, but line_items:


curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "subscription_data[items][][plan]"="{{PLAN_OR_PRICE_ID}}" \ -d "line_items[0][price]"="{{PRICE_OR_PLAN_ID}}" \ -d "line_items[0][quantity]"=1 \ -d mode=subscription \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
session = Stripe::Checkout::Session.create( payment_method_types: ['card'], subscription_data: { items: [{ plan: '{{PLAN_OR_PRICE_ID}}', }], }, line_items: [{ price: '{{PRICE_OR_PLAN_ID}}', quantity: 1, }], mode: 'subscription', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
session = stripe.checkout.Session.create( payment_method_types=['#{payment_method_type}'], subscription_data={ 'items': [{ 'plan': '{{PLAN_OR_PRICE_ID}}', }], }, line_items=[{ 'price': '{{PRICE_OR_PLAN_ID}}', 'quantity': 1, }], mode='subscription', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
$session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'subscription_data' => [ 'items' => [[ 'plan' => '{{PLAN_OR_PRICE_ID}}', ]], ], 'line_items' => [[ 'price' => '{{PRICE_OR_PLAN_ID}}', 'quantity' => 1, ]], 'mode' => 'subscription', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
const session = await stripe.checkout.sessions.create({ payment_method_types: ['#{payment_method_type}'], subscription_data: { items: [{ plan: '{{PLAN_OR_PRICE_ID}}', }], }, line_items: [{ price: '{{PRICE_OR_PLAN_ID}}', quantity: 1, }], mode: 'subscription', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) SessionCreateParams.SubscriptionData.Item.builder() .setPlan("{{PRICE_OR_PLAN_ID}}") .build() .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_OR_PLAN_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.SUBSCRIPTION) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{ Items: []*stripe.CheckoutSessionSubscriptionDataItemsParams{ &stripe.CheckoutSessionSubscriptionDataItemsParams{ Plan: stripe.String("{{PLAN_OR_PRICE_ID}}"), }, }, }, LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_OR_PLAN_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModeSubscription)), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, SubscriptionData = new SessionSubscriptionDataOptions { Items = new List<SessionSubscriptionDataItemOptions> { new SessionSubscriptionDataItemOptions { Plan = "{{PLAN_OR_PRICE_ID}}", }, }, }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_OR_PLAN_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Server-side code for recurring price with setup fee

If you have recurring plans with a one-time setup fee, create the product and price representing the one-time fee before creating the Checkout session. See the mapping table for how the old line_items fields map to the new integration. You can either create a product and price through the Prices API or through the Stripe Dashboard. You may also create the one-time item inline. This example uses an existing price ID:


curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[0][quantity]"=1 \ -d "line_items[0][amount]"=2000 \ -d "line_items[0][name]"=T-shirt \ -d "line_items[0][description]"="Comfortable cotton t-shirt" \ -d "line_items[0][images][]"="https://example.com/t-shirt.png" \ -d "line_items[0][currency]"=usd \ -d "subscription_data[items][][plan]"="{{PLAN_ID}}" \ -d "line_items[0][price]"="{{PRICE_OR_PLAN_ID}}" \ -d "line_items[0][quantity]"=1 \ -d "line_items[1][price]"="{{ONE_TIME_PRICE_ID}}" \ -d "line_items[1][quantity]"=1 \ -d mode=subscription \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', }], subscription_data: { items: [{ plan: '{{RECURRING_PRICE_ID}}', }], }, line_items: [{ price: '{{ONE_TIME_PRICE_ID}}', quantity: 1, }, { price: '{{RECURRING_PRICE_OR_PLAN_ID}}', quantity: 1, }], mode: 'subscription', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
session = stripe.checkout.Session.create( payment_method_types=['#{payment_method_type}'], line_items=[{ 'name': 'T-shirt', 'description': 'Comfortable cotton t-shirt', 'images': ['https://example.com/t-shirt.png'], 'amount': 2000, 'currency': 'usd', 'quantity': 1, }], subscription_data={ 'items': [{ 'plan': '{{RECURRING_PRICE_OR_PLAN_ID}}', }], }, line_items=[{ 'price': '{{ONE_TIME_PRICE_ID}}', 'quantity': 1, }, { 'price': '{{RECURRING_PRICE_OR_PLAN_ID}}', 'quantity': 1, }], mode='subscription', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
$session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], 'amount' => 2000, 'currency' => 'usd', 'quantity' => 1, ]], 'subscription_data' => [ 'items' => [[ 'plan' => '{{RECURRING_PRICE_OR_PLAN_ID}}', ]], ], 'line_items' => [[ 'price' => '{{ONE_TIME_PRICE_ID}}', 'quantity' => 1, ], [ 'price' => '{{RECURRING_PRICE_OR_PLAN_ID}}', 'quantity' => 1, ]], 'mode' => 'subscription', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
const session = await stripe.checkout.sessions.create({ payment_method_types: ['#{payment_method_type}'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'usd', quantity: 1, }], subscription_data: { items: [{ plan: '{{RECURRING_PRICE_OR_PLAN_ID}}', }], }, line_items: [{ price: '{{ONE_TIME_PRICE_ID}}', quantity: 1, }, { price: '{{RECURRING_PRICE_OR_PLAN_ID}}', quantity: 1, }], mode: 'subscription', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setName("T-shirt") .setDescription("Comfortable cotton t-shirt") .setAmount(2000L) .setCurrency("usd") .setPrice("{{ONE_TIME_PRICE_ID}}") .setQuantity(1L) .build()) SessionCreateParams.SubscriptionData.Item.builder() .setPlan("{{RECURRING_PRICE_OR_PLAN_ID}}") .build() .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{RECURRING_PRICE_OR_PLAN_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.SUBSCRIPTION) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), Amount: stripe.Int64(2000), Currency: stripe.String("usd"), Quantity: stripe.Int64(1), }, }, SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{ Items: []*stripe.CheckoutSessionSubscriptionDataItemsParams{ &stripe.CheckoutSessionSubscriptionDataItemsParams{ Plan: stripe.String("{{RECURRING_PRICE_OR_PLAN_ID}}"), }, }, }, LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{ONE_TIME_PRICE_ID}}"), Quantity: stripe.Int64(1), }, &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{RECURRING_PRICE_OR_PLAN_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModeSubscription)), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", Amount = 2000, Currency = "usd", Quantity = 1, }, }, SubscriptionData = new SessionSubscriptionDataOptions { Items = new List<SessionSubscriptionDataItemOptions> { new SessionSubscriptionDataItemOptions { Plan = "{{RECURRING_PRICE_OR_PLAN_ID}}", }, }, }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{ONE_TIME_PRICE_ID}}", Quantity = 1, }, new SessionLineItemOptions { Price = "{{RECURRING_PRICE_OR_PLAN_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

The client-only integration has the following changes:

  • items is now lineItems. Existing plans can be passed into the new field, using lineItems.price.
  • mode is now required.

Redirect to Checkout

To redirect to Checkout, pass in a price or plan ID into lineItems.price:


stripe.redirectToCheckout({ items: [{ plan: '{{PLAN_OR_PRICE_ID}}', lineItems: [{ price: '{{PRICE_OR_PLAN_ID}}', quantity: 1 }], mode: 'subscription', successUrl: 'https://example.com/success', cancelUrl: 'https://example.com/cancel', }) .then((result) => {});

Response object changes

Instead of listing items with display_items, the Checkout session object uses line_items. The line_items field does not render by default as display_items did, but you can include it using expand when creating a Checkout session:

curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d mode=payment \ -d "line_items[0][price]"="{{PRICE_ID}}" \ -d "line_items[0][quantity]"=1 \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel" \ -d "expand[]"=line_items
stripe checkout sessions create --expand line_items \ -d payment_method_types[]=card \ -d mode=payment \ -d line_items[0][price]={{PRICE_ID}} \ -d line_items[0][quantity]=1 \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel" \

Webhook changes

Since line_items is includable, the checkout.session.completed webhook response no longer list items by default. The smaller response object enables you to receive your Checkout webhooks faster. You can retrieve items with the new line_items endpoint:

curl https://api.stripe.com/v1/checkout/sessions/cs_123/line_items \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
stripe get /v1/checkout/sessions/cs_123/line_items

For more details, see handling purchase fulfillment with Checkout.