Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
Security
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
How cards work
Sample integration
Accept a payment
More payment scenarios
U.S. and Canadian cards
Testing
payments
·
HomePaymentsOnline payments

Accept a payment

Securely accept payments online.

Prebuilt Checkout page Custom payment flow
Complexity
Low
Customizability
Prebuilt with customizable branding

For a more immersive guide, check out our sample integration.

What you're building

Install the Stripe CLI, then run the following in your terminal:

$
stripe samples create checkout-one-time-payments

Contains examples in PHP, Node.js, Ruby, Java, Python. The sample will be configured with your Stripe test key if you have set up the CLI with your Stripe account

We have a set of samples on GitHub to help you get started.

$
git clone https://github.com/stripe-samples/checkout-one-time-payments

Contains examples in PHP, Node.js, Ruby, Java, Python.

This guide shows you how to:

  1. Add a checkout button to your webpage that sends your customer to a Stripe-hosted checkout page.
  2. Create an order success page to show your customer after the payment.

1 Set up Stripe Server-side

First, make sure that you have set up an account name on the Stripe Dashboard.

Then install the libraries for access to the Stripe API from your application:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

2 Add a checkout button on your webpage Client-side

Create a checkout button on your website that takes your customer to Stripe Checkout, a Stripe-hosted payment form where they can complete their payment.

HTML + JS React

Add a button

Start by adding a checkout button to your page:

checkout.html
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>

Add the Stripe.js library to your page

Adding Stripe.js to your page automatically includes advanced fraud detection whenever your customers use Checkout.

Add the library to your page:

checkout.html
<html> <head> <title>Buy cool new product</title> <script src="https://js.stripe.com/v3/"></script> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>
<html> <head> <title>Buy cool new product</title> <script src="https://js.stripe.com/v3/"></script> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>

Always load Stripe.js directly from https://js.stripe.com. You can't include it in a bundle or self-host it.

Add a button

Start by adding a checkout button to your page:

index.js
import React from 'react'; import ReactDOM from 'react-dom'; function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

Install Stripe.js

When you add Stripe.js to your page, you automatically get advanced fraud detection included whenever your customers use Checkout.

First, install the Stripe.js ES Module:

Terminal
npm install @stripe/stripe-js
npm install @stripe/stripe-js

If you are using Node.js on the server, you need to install both the stripe and @stripe/stripe-js packages. stripe is used on the server-side to make requests to the Stripe API, whereas @stripe/stripe-js provides methods for including Stripe.js in your client-side code.

Initialize Stripe.js

Call loadStripe with your publishable API key. It returns a Promise that resolves with the Stripe object as soon as Stripe.js loads.

index.js
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

3 Redirect your customer to Stripe Checkout

Set up the new button to redirect your customer to a Stripe Checkout-hosted payment form. After being redirected, your customer can enter their payment details in the form.

The redirect to Stripe Checkout cuts down on development time and maintenance and gives you added security. It also reduces the amount of private customer information you handle on your site, gives you immediate access to digital wallets in addition to card payments, and allows you to customize the styling of the Checkout form to match your branding.

Create a Checkout Session

A Checkout Session is the programmatic representation of what your customer sees when they’re redirected to the payment form. You can configure it with options such as:

  • line items to charge
  • currencies to use
  • payment methods you accept

You also need to specify:

  • A success_url, a page on your website to redirect your customer after they complete the payment.
  • A cancel_url, a page on your website to redirect your customer if they click on your logo in Checkout.

For a full list of configuration options, see Checkout Session.

Checkout Sessions expire 24 hours after creation.

After successfully creating a Checkout Session, redirect your customer to Stripe Checkout.

You need a server-side endpoint to create the Checkout Session. Creating the Checkout Session server-side prevents malicious customers from being able to choose their own prices.

Ruby Python PHP Java Node Go .NET
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', # For now leave these URLs as placeholder values. # # Later on in the guide, you'll create a real success page, but no need to # do it yet. success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', # For now leave these URLs as placeholder values. # # Later on in the guide, you'll create a real success page, but no need to # do it yet. success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }

Apple Pay and Google Pay are enabled by default and automatically appear in Checkout when a customer uses a supported device and has saved at least one card in their digital wallet. You can also accept other payment method types by passing them in to your create Checkout Session API call. For details, see Payment Methods.

Test your endpoint by starting your web server (e.g., localhost:4242) and running the following command:

Terminal
curl -X POST -is "http://localhost:4242/create-checkout-session" -d ""
curl -X POST -is "http://localhost:4242/create-checkout-session" -d ""

You should see a response in your terminal that looks like this:

cURL response
HTTP/1.1 200 OK Content-Type: application/json { id: "cs_test_.........." }
HTTP/1.1 200 OK Content-Type: application/json { id: "cs_test_.........." }

Add an event handler to the checkout button

Now that you have a <button> and an endpoint to create a Checkout Session, modify the <button> to redirect to Stripe Checkout when clicked, using redirectToCheckout and providing the Checkout Session ID:

HTML + JS React
checkout.html
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> <script type="text/javascript"> // Create an instance of the Stripe object with your publishable API key var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { // Create a new Checkout Session using the server-side endpoint you // created in step 3. fetch('/create-checkout-session', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { // If `redirectToCheckout` fails due to a browser or network // error, you should display the localized error message to your // customer using `error.message`. if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); </script> </body> </html>
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> <script type="text/javascript"> // Create an instance of the Stripe object with your publishable API key var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { // Create a new Checkout Session using the server-side endpoint you // created in step 3. fetch('/create-checkout-session', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { // If `redirectToCheckout` fails due to a browser or network // error, you should display the localized error message to your // customer using `error.message`. if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); </script> </body> </html>
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { const handleClick = async (event) => { // Get Stripe.js instance const stripe = await stripePromise; // Call your backend to create the Checkout Session const response = await fetch('/create-checkout-session', { method: 'POST' }); const session = await response.json(); // When the customer clicks on the button, redirect them to Checkout. const result = await stripe.redirectToCheckout({ sessionId: session.id, }); if (result.error) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. } }; return ( <button type="button" role="link" onClick={handleClick}> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { const handleClick = async (event) => { // Get Stripe.js instance const stripe = await stripePromise; // Call your backend to create the Checkout Session const response = await fetch('/create-checkout-session', { method: 'POST' }); const session = await response.json(); // When the customer clicks on the button, redirect them to Checkout. const result = await stripe.redirectToCheckout({ sessionId: session.id, }); if (result.error) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. } }; return ( <button type="button" role="link" onClick={handleClick}> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

Testing

You should now have a working checkout button that redirects your customer to Stripe Checkout.

  • Click the checkout button.
  • You’re redirected to a Stripe Checkout payment form.

If your integration isn’t working:

  • Open the Network tab in your browser’s developer tools.
  • Click the checkout button and see if an XHR request is made to your server-side endpoint (POST /create-checkout-session).
  • Verify the request is returning a 200 status.
  • Use console.log(session) inside your button click listener to confirm the correct data is returned.

4 Show a success page Client and server

It’s important for your customer to see a success page after they successfully submit the payment form. This success page is hosted on your site.

Create a minimal success page:

success.html
<html> <head><title>Thanks for your order!</title></head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>
<html> <head><title>Thanks for your order!</title></head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>

Next, update the Checkout Session creation endpoint to use this new page:

Ruby Python PHP Java Node Go .NET
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', success_url: "https://yoursite.com/success.html", cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', success_url: "https://yoursite.com/success.html", cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url= "https://yoursite.com/success.html", cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url= "https://yoursite.com/success.html", cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://yoursite.com/success.html', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://yoursite.com/success.html', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://yoursite.com/success.html") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://yoursite.com/success.html") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://yoursite.com/success.html', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://yoursite.com/success.html', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://yoursite.com/success.html"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://yoursite.com/success.html"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://yoursite.com/success.html", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://yoursite.com/success.html", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }

If you want to customize your success page, read the custom success page guide.

Testing

  • Click your checkout button
  • Fill out the payment details with the test card information:
    • Enter 4242 4242 4242 4242 as the card number.
    • Enter any future date for card expiry.
    • Enter any 3-digit number for CVC.
    • Enter any billing ZIP code.
  • Click Pay.
  • You’re redirected to your new success page.

Next, find the new payment in the Stripe Dashboard. Successful payments appear in the Dashboard’s list of payments. When you click a payment, it takes you to the payment detail page. The Checkout summary section contains billing information and the list of items purchased, which you can use to manually fulfill the order.

Additional testing resources

There are several test cards you can use to make sure your integration is ready for production. Use them with any CVC, postal code, and future expiration date.

Number Description
4242424242424242 Succeeds and immediately processes the payment.
4000000000003220 3D Secure 2 authentication must be completed for a successful payment.
4000000000009995 Always fails with a decline code of insufficient_funds.

For the full list of test cards see our guide on testing.

Apple Pay and Google Pay

No configuration or integration changes are required to enable Apple Pay or Google Pay in Stripe Checkout. These payments are handled the same way as other card payments.

Apple Pay Google Pay

The Apple Pay button is displayed in a given Checkout Session if all of the following apply:

  • Apple Pay is enabled for Checkout in your Stripe Dashboard.
  • The customer’s device is running macOS 10.14.1+ or iOS 12.1+.
  • The customer is using the Safari browser.
  • The customer has a valid card registered with Apple Pay.

This ensures that Checkout only displays the Apple Pay button to customers who are able to use it.

The Google Pay button is displayed in a given Checkout Session if all of the following apply:

  • Google Pay is enabled for Checkout in your Stripe Dashboard.
  • The customer is using Google Chrome or Safari.
  • The customer has a valid card registered with Google Pay.

This ensures that Checkout only displays the Google Pay button to customers who are able to use it.

Optional Create products and prices upfront

The Prices API unifies how one-time purchases and subscriptions are modeled on Stripe. Existing integrations that don’t use the Prices API are still supported. However, some Checkout features only support Prices. See the migration guide to upgrade to the Prices API.

You can also create products and prices upfront before creating a Checkout Session. Present different physical goods or levels of service with a Product. Use Prices to represent each product’s pricing.

For example, you can create a T-shirt product that has two prices for different currencies, 20 USD and 15 EUR. This allows you to change and add prices without needing to change the details of your underlying products. You can either create products and prices with the API or through the Stripe Dashboard.

API Dashboard

To create a Product with the API, only a name is required. The product name, description, and images that you supply are displayed to customers on Checkout.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/products \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d name=T-shirt
curl https://api.stripe.com/v1/products \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d name=T-shirt
product = Stripe::Product.create( { name: 'T-shirt', } )
product = Stripe::Product.create( { name: 'T-shirt', } )
product = stripe.Product.create( name='T-shirt', )
product = stripe.Product.create( name='T-shirt', )
$product = \Stripe\Product::create([ 'name' => 'T-shirt', ]);
$product = \Stripe\Product::create([ 'name' => 'T-shirt', ]);
ProductCreateParams params = ProductCreateParams.builder() .setName("T-shirt") .build(); Product product = Product.create(params);
ProductCreateParams params = ProductCreateParams.builder() .setName("T-shirt") .build(); Product product = Product.create(params);
const product = await stripe.products.create({ name: 'T-shirt', });
const product = await stripe.products.create({ name: 'T-shirt', });
params := &stripe.ProductParams{ Name: stripe.String("T-shirt"), } p, _ := product.New(params)
params := &stripe.ProductParams{ Name: stripe.String("T-shirt"), } p, _ := product.New(params)
var productService = new ProductService(); var options = new ProductCreateOptions { Name = "T-shirt", }; var product = productService.Create(options);
var productService = new ProductService(); var options = new ProductCreateOptions { Name = "T-shirt", }; var product = productService.Create(options);

Next, create a Price to define how much to charge for your product. This includes how much the product costs and what currency to use.

curl Ruby Python PHP Java Node Go .NET
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/prices \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d product="{{PRODUCT_ID}}" \ -d unit_amount=2000 \ -d currency=usd
price = Stripe::Price.create( { product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', } )
price = Stripe::Price.create( { product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', } )
price = stripe.Price.create( product='{{PRODUCT_ID}}', unit_amount=2000, currency='usd', )
price = stripe.Price.create( product='{{PRODUCT_ID}}', unit_amount=2000, currency='usd', )
$price = \Stripe\Price::create([ 'product' => '{{PRODUCT_ID}}', 'unit_amount' => 2000, 'currency' => 'usd', ]);
$price = \Stripe\Price::create([ 'product' => '{{PRODUCT_ID}}', 'unit_amount' => 2000, 'currency' => 'usd', ]);
PriceCreateParams params = PriceCreateParams.builder() .setProduct("{{PRODUCT_ID}}") .setUnitAmount(2000) .setCurrency("usd") .build(); Price price = Price.create(params);
PriceCreateParams params = PriceCreateParams.builder() .setProduct("{{PRODUCT_ID}}") .setUnitAmount(2000) .setCurrency("usd") .build(); Price price = Price.create(params);
const price = await stripe.prices.create({ product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', });
const price = await stripe.prices.create({ product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', });
params := &stripe.PriceParams{ Product: stripe.String("{{PRODUCT_ID}}"), UnitAmount: stripe.Int64(2000), Currency: stripe.String("usd"), } p, _ := price.New(params)
params := &stripe.PriceParams{ Product: stripe.String("{{PRODUCT_ID}}"), UnitAmount: stripe.Int64(2000), Currency: stripe.String("usd"), } p, _ := price.New(params)
var priceService = new PriceService(); var options = new PriceCreateOptions { Product = "{{PRODUCT_ID}}", UnitAmount = 2000, Currency = "usd", }; var price = priceService.Create(options);
var priceService = new PriceService(); var options = new PriceCreateOptions { Product = "{{PRODUCT_ID}}", UnitAmount = 2000, Currency = "usd", }; var price = priceService.Create(options);

Products created in test mode can be copied to live mode so that you don’t need to recreate them. In the Product detail view in the Dashboard, click Copy to live mode in the upper right corner. You can only do this once for each product created in test mode. Subsequent updates to the test product are not reflected for the live product.

Make sure you are in test mode by toggling the View test data button at the bottom of the Stripe Dashboard. Next, define the items you want to sell. To create a new product and price:

  • Navigate to the Products section in the Dashboard
  • Click Add product
  • Select One time when setting the price

The product name, description, and image that you supply are displayed to customers in Checkout.

Each price you create has an ID. When you create a Checkout Session, reference the price ID and quantity.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success?session_id={CHECKOUT_SESSION_ID}") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success?session_id={CHECKOUT_SESSION_ID}") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { 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);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { 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);

Optional Existing customers Server-side

If you have previously created a Customer object to represent a customer, use the customer argument to pass their Customer ID when creating a Checkout Session. This ensures that all objects created during the Session are associated with the correct Customer object.

When you pass a Customer ID, Stripe also uses the email stored on the Customer object to prefill the email field on the Checkout page. If the customer changes their email on the Checkout page, it will be updated on the Customer object after a successful payment.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("subscription"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("subscription"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Optional Prefill customer data Server-side

If you've already collected your customer's email and want to prefill it in the Checkout Session for them, pass customer_email when creating a Checkout Session.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer_email="customer@example.com" \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer_email="customer@example.com" \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer_email='customer@example.com', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer_email='customer@example.com', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer_email' => 'customer@example.com', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer_email' => 'customer@example.com', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomerEmail("customer@example.com") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomerEmail("customer@example.com") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ CustomerEmail: stripe.String("customer@example.com"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ CustomerEmail: stripe.String("customer@example.com"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { CustomerEmail = "customer@example.com", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { CustomerEmail = "customer@example.com", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Optional Save payment method details Server-side

By default, payment methods used to make a one-time payment with Checkout aren’t available for future use outside of Checkout. You can instruct Checkout to save payment methods used to make a one-time payment by passing the payment_intent_data.setup_future_usage argument. This is useful if you need to capture a payment method on-file to use for future fees, such as cancellation or no-show fees.

Stripe uses setup_future_usage to dynamically optimize your payment flow and comply with regional legislation and network rules. For example, if your customer is impacted by Strong Customer Authentication, passing setup_future_usage=off_session ensures that they’re authenticated while processing this payment. You can then collect future off-session payments for this customer using the Payment Intents API. Reusing these payment methods in future Checkout Sessions isn’t currently supported.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_intent_data[setup_future_usage]"=off_session \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_intent_data[setup_future_usage]"=off_session \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_intent_data={ 'setup_future_usage': 'off_session', }, customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_intent_data={ 'setup_future_usage': 'off_session', }, customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_intent_data' => [ 'setup_future_usage' => 'off_session', ], 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_intent_data' => [ 'setup_future_usage' => 'off_session', ], 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setSetupFutureUsage(SessionCreateParams.PaymentIntentData.SetupFutureUsage.OFF_SESSION) .build()) .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setSetupFutureUsage(SessionCreateParams.PaymentIntentData.SetupFutureUsage.OFF_SESSION) .build()) .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ SetupFutureUsage: stripe.String("off_session"), }, Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ SetupFutureUsage: stripe.String("off_session"), }, Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentIntentData = new SessionPaymentIntentDataOptions { SetupFutureUsage = "off_session", }, Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentIntentData = new SessionPaymentIntentDataOptions { SetupFutureUsage = "off_session", }, Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Use Checkout setup mode to collect payment method details without immediately collecting a payment.

Optional Separate authorization and capture Server-side

Stripe supports two-step card payments so you can first authorize a card, then wait to capture funds later. When a payment is authorized, the funds are guaranteed by the card issuer and the amount is held on the customer’s card for up to 7 days. If the payment isn’t captured within this time, the payment is canceled and the funds are released.

Separating authorization and capture is useful if you need to take additional actions between confirming that a customer is able to pay and collecting their payment. For example, if you’re selling stock-limited items, you may need to confirm that an item purchased by your customer using Checkout is still available before capturing their payment and fulfilling the purchase. Accomplish this using the following workflow:

  1. Confirm that the customer’s payment method is authorized.
  2. Consult your inventory management system to confirm that the item is still available.
  3. Update your inventory management system to indicate that the item has been purchased.
  4. Capture the customer’s payment.
  5. Inform your customer whether their purchase was successful on your confirmation page.

To indicate that you want to separate authorization and capture, you must set the value of payment_intent_data.capture_method to manual when creating the Checkout Session. This instructs Stripe to only authorize the amount on the customer’s card.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d "payment_intent_data[capture_method]"=manual \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d "payment_intent_data[capture_method]"=manual \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', payment_intent_data={ 'capture_method': 'manual', }, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', payment_intent_data={ 'capture_method': 'manual', }, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'payment_intent_data' => [ 'capture_method' => 'manual', ], 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'payment_intent_data' => [ 'capture_method' => 'manual', ], 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setCaptureMethod(SessionCreateParams.PaymentIntentData.CaptureMethod.MANUAL) .build()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setCaptureMethod(SessionCreateParams.PaymentIntentData.CaptureMethod.MANUAL) .build()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ CaptureMethod: stripe.String("manual"), }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ CaptureMethod: stripe.String("manual"), }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", PaymentIntentData = new SessionPaymentIntentDataOptions { CaptureMethod = "manual", }, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", PaymentIntentData = new SessionPaymentIntentDataOptions { CaptureMethod = "manual", }, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

To capture an uncaptured payment, you can use either the Dashboard or the capture endpoint. Programmatically capturing payments requires access to the PaymentIntent created during the Checkout Session, which you can get from the Session object.

Now that you have your basic integration working, learn how to programmatically get a notification whenever a customer pays.

See also

  • Add discounts
  • Collect taxes
  • Customize your branding and address collection
  • Customize your success page
Complexity
Medium
Customizability
Fully customizable drop-in components

For a more immersive guide, check out our sample integration.

Checkout Web iOS Android Web platform or CMS
Complexity
Low
Customizability
Prebuilt with customizable branding

For a more immersive guide, check out our sample integration.

What you're building

Install the Stripe CLI, then run the following in your terminal:

$
stripe samples create checkout-one-time-payments

Contains examples in PHP, Node.js, Ruby, Java, Python. The sample will be configured with your Stripe test key if you have set up the CLI with your Stripe account

We have a set of samples on GitHub to help you get started.

$
git clone https://github.com/stripe-samples/checkout-one-time-payments

Contains examples in PHP, Node.js, Ruby, Java, Python.

This guide shows you how to:

  1. Add a checkout button to your webpage that sends your customer to a Stripe-hosted checkout page.
  2. Create an order success page to show your customer after the payment.

1 Set up Stripe Server-side

First, make sure that you have set up an account name on the Stripe Dashboard.

Then install the libraries for access to the Stripe API from your application:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

2 Add a checkout button on your webpage Client-side

Create a checkout button on your website that takes your customer to Stripe Checkout, a Stripe-hosted payment form where they can complete their payment.

HTML + JS React

Add a button

Start by adding a checkout button to your page:

checkout.html
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>

Add the Stripe.js library to your page

Adding Stripe.js to your page automatically includes advanced fraud detection whenever your customers use Checkout.

Add the library to your page:

checkout.html
<html> <head> <title>Buy cool new product</title> <script src="https://js.stripe.com/v3/"></script> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>
<html> <head> <title>Buy cool new product</title> <script src="https://js.stripe.com/v3/"></script> </head> <body> <button type="button" id="checkout-button">Checkout</button> </body> </html>

Always load Stripe.js directly from https://js.stripe.com. You can't include it in a bundle or self-host it.

Add a button

Start by adding a checkout button to your page:

index.js
import React from 'react'; import ReactDOM from 'react-dom'; function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

Install Stripe.js

When you add Stripe.js to your page, you automatically get advanced fraud detection included whenever your customers use Checkout.

First, install the Stripe.js ES Module:

Terminal
npm install @stripe/stripe-js
npm install @stripe/stripe-js

If you are using Node.js on the server, you need to install both the stripe and @stripe/stripe-js packages. stripe is used on the server-side to make requests to the Stripe API, whereas @stripe/stripe-js provides methods for including Stripe.js in your client-side code.

Initialize Stripe.js

Call loadStripe with your publishable API key. It returns a Promise that resolves with the Stripe object as soon as Stripe.js loads.

index.js
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { return ( <button type="button" role="link"> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

3 Redirect your customer to Stripe Checkout

Set up the new button to redirect your customer to a Stripe Checkout-hosted payment form. After being redirected, your customer can enter their payment details in the form.

The redirect to Stripe Checkout cuts down on development time and maintenance and gives you added security. It also reduces the amount of private customer information you handle on your site, gives you immediate access to digital wallets in addition to card payments, and allows you to customize the styling of the Checkout form to match your branding.

Create a Checkout Session

A Checkout Session is the programmatic representation of what your customer sees when they’re redirected to the payment form. You can configure it with options such as:

  • line items to charge
  • currencies to use
  • payment methods you accept

You also need to specify:

  • A success_url, a page on your website to redirect your customer after they complete the payment.
  • A cancel_url, a page on your website to redirect your customer if they click on your logo in Checkout.

For a full list of configuration options, see Checkout Session.

Checkout Sessions expire 24 hours after creation.

After successfully creating a Checkout Session, redirect your customer to Stripe Checkout.

You need a server-side endpoint to create the Checkout Session. Creating the Checkout Session server-side prevents malicious customers from being able to choose their own prices.

Ruby Python PHP Java Node Go .NET
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', # For now leave these URLs as placeholder values. # # Later on in the guide, you'll create a real success page, but no need to # do it yet. success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', # For now leave these URLs as placeholder values. # # Later on in the guide, you'll create a real success page, but no need to # do it yet. success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }

Apple Pay and Google Pay are enabled by default and automatically appear in Checkout when a customer uses a supported device and has saved at least one card in their digital wallet. You can also accept other payment method types by passing them in to your create Checkout Session API call. For details, see Payment Methods.

Test your endpoint by starting your web server (e.g., localhost:4242) and running the following command:

Terminal
curl -X POST -is "http://localhost:4242/create-checkout-session" -d ""
curl -X POST -is "http://localhost:4242/create-checkout-session" -d ""

You should see a response in your terminal that looks like this:

cURL response
HTTP/1.1 200 OK Content-Type: application/json { id: "cs_test_.........." }
HTTP/1.1 200 OK Content-Type: application/json { id: "cs_test_.........." }

Add an event handler to the checkout button

Now that you have a <button> and an endpoint to create a Checkout Session, modify the <button> to redirect to Stripe Checkout when clicked, using redirectToCheckout and providing the Checkout Session ID:

HTML + JS React
checkout.html
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> <script type="text/javascript"> // Create an instance of the Stripe object with your publishable API key var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { // Create a new Checkout Session using the server-side endpoint you // created in step 3. fetch('/create-checkout-session', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { // If `redirectToCheckout` fails due to a browser or network // error, you should display the localized error message to your // customer using `error.message`. if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); </script> </body> </html>
<html> <head> <title>Buy cool new product</title> </head> <body> <button type="button" id="checkout-button">Checkout</button> <script type="text/javascript"> // Create an instance of the Stripe object with your publishable API key var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { // Create a new Checkout Session using the server-side endpoint you // created in step 3. fetch('/create-checkout-session', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { // If `redirectToCheckout` fails due to a browser or network // error, you should display the localized error message to your // customer using `error.message`. if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); </script> </body> </html>
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { const handleClick = async (event) => { // Get Stripe.js instance const stripe = await stripePromise; // Call your backend to create the Checkout Session const response = await fetch('/create-checkout-session', { method: 'POST' }); const session = await response.json(); // When the customer clicks on the button, redirect them to Checkout. const result = await stripe.redirectToCheckout({ sessionId: session.id, }); if (result.error) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. } }; return ( <button type="button" role="link" onClick={handleClick}> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import { loadStripe } from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); function App() { const handleClick = async (event) => { // Get Stripe.js instance const stripe = await stripePromise; // Call your backend to create the Checkout Session const response = await fetch('/create-checkout-session', { method: 'POST' }); const session = await response.json(); // When the customer clicks on the button, redirect them to Checkout. const result = await stripe.redirectToCheckout({ sessionId: session.id, }); if (result.error) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. } }; return ( <button type="button" role="link" onClick={handleClick}> Checkout </button> ); } ReactDOM.render(<App />, document.getElementById('root'));

Testing

You should now have a working checkout button that redirects your customer to Stripe Checkout.

  • Click the checkout button.
  • You’re redirected to a Stripe Checkout payment form.

If your integration isn’t working:

  • Open the Network tab in your browser’s developer tools.
  • Click the checkout button and see if an XHR request is made to your server-side endpoint (POST /create-checkout-session).
  • Verify the request is returning a 200 status.
  • Use console.log(session) inside your button click listener to confirm the correct data is returned.

4 Show a success page Client and server

It’s important for your customer to see a success page after they successfully submit the payment form. This success page is hosted on your site.

Create a minimal success page:

success.html
<html> <head><title>Thanks for your order!</title></head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>
<html> <head><title>Thanks for your order!</title></head> <body> <h1>Thanks for your order!</h1> <p> We appreciate your business! If you have any questions, please email <a href="mailto:orders@example.com">orders@example.com</a>. </p> </body> </html>

Next, update the Checkout Session creation endpoint to use this new page:

Ruby Python PHP Java Node Go .NET
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', success_url: "https://yoursite.com/success.html", cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' require 'json' require 'sinatra' post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', success_url: "https://yoursite.com/success.html", cancel_url: 'https://example.com/cancel', }) { id: session.id }.to_json end #
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url= "https://yoursite.com/success.html", cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
# This example sets up an endpoint using the Flask framework. # Watch this video to get started: https://youtu.be/7Ul1vfmsDck. import os import stripe from flask import Flask, jsonify app = Flask(__name__) # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url= "https://yoursite.com/success.html", cancel_url='https://example.com/cancel', ) return jsonify(id=session.id) if __name__== '__main__': app.run(port=4242)
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://yoursite.com/success.html', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
<?php // This example sets up an endpoint using the Slim framework. // Watch this video to get started: https://youtu.be/sGcNPFX1Ph4. use Slim\Http\Request; use Slim\Http\Response; use Stripe\Stripe; require 'vendor/autoload.php'; $app = new \Slim\App; $app->add(function ($request, $response, $next) { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); return $next($request, $response); }); $app->post('/create-checkout-session', function (Request $request, Response $response) { $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://yoursite.com/success.html', 'cancel_url' => 'https://example.com/cancel', ]); return $response->withJson([ 'id' => $session->id ])->withStatus(200); }); $app->run();
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://yoursite.com/success.html") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
import java.util.HashMap; import java.util.Map; import static spark.Spark.get; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.google.gson.Gson; import com.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { private static Gson gson = new Gson(); public static void main(String[] args) { port(4242); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; post("/create-checkout-session", (request, response) -> { response.type("application/json"); SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://yoursite.com/success.html") .setCancelUrl("https://example.com/cancel") .addLineItem( SessionCreateParams.LineItem.builder() .setQuantity(1L) .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setCurrency("usd") .setUnitAmount(2000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build()) .build()) .build()) .build(); Session session = Session.create(params); Map<String, String> responseData = new HashMap(); responseData.put("id", session.getId()); return gson.toJson(responseData); }); } }
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://yoursite.com/success.html', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
// This example sets up an endpoint using the Express framework. // Watch this video to get started: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'https://yoursite.com/success.html', cancel_url: 'https://example.com/cancel', }); res.json({ id: session.id }); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`));
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://yoursite.com/success.html"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } type CreateCheckoutSessionResponse struct { SessionID string `json:"id"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ Currency: stripe.String("usd"), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, UnitAmount: stripe.Int64(2000), }, Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://yoursite.com/success.html"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params) if err != nil { return err } data := CreateCheckoutSessionResponse{ SessionID: session.ID, } return c.JSON(http.StatusOK, data) }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://yoursite.com/success.html", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }
// This example sets up an endpoint using the ASP.NET MVC framework. // Watch this video to get started: https://youtu.be/2-mMOB8MhmE. using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://yoursite.com/success.html", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options); return Json(new { id = session.Id }); } } }

If you want to customize your success page, read the custom success page guide.

Testing

  • Click your checkout button
  • Fill out the payment details with the test card information:
    • Enter 4242 4242 4242 4242 as the card number.
    • Enter any future date for card expiry.
    • Enter any 3-digit number for CVC.
    • Enter any billing ZIP code.
  • Click Pay.
  • You’re redirected to your new success page.

Next, find the new payment in the Stripe Dashboard. Successful payments appear in the Dashboard’s list of payments. When you click a payment, it takes you to the payment detail page. The Checkout summary section contains billing information and the list of items purchased, which you can use to manually fulfill the order.

Additional testing resources

There are several test cards you can use to make sure your integration is ready for production. Use them with any CVC, postal code, and future expiration date.

Number Description
4242424242424242 Succeeds and immediately processes the payment.
4000000000003220 3D Secure 2 authentication must be completed for a successful payment.
4000000000009995 Always fails with a decline code of insufficient_funds.

For the full list of test cards see our guide on testing.

Apple Pay and Google Pay

No configuration or integration changes are required to enable Apple Pay or Google Pay in Stripe Checkout. These payments are handled the same way as other card payments.

Apple Pay Google Pay

The Apple Pay button is displayed in a given Checkout Session if all of the following apply:

  • Apple Pay is enabled for Checkout in your Stripe Dashboard.
  • The customer’s device is running macOS 10.14.1+ or iOS 12.1+.
  • The customer is using the Safari browser.
  • The customer has a valid card registered with Apple Pay.

This ensures that Checkout only displays the Apple Pay button to customers who are able to use it.

The Google Pay button is displayed in a given Checkout Session if all of the following apply:

  • Google Pay is enabled for Checkout in your Stripe Dashboard.
  • The customer is using Google Chrome or Safari.
  • The customer has a valid card registered with Google Pay.

This ensures that Checkout only displays the Google Pay button to customers who are able to use it.

Optional Create products and prices upfront

The Prices API unifies how one-time purchases and subscriptions are modeled on Stripe. Existing integrations that don’t use the Prices API are still supported. However, some Checkout features only support Prices. See the migration guide to upgrade to the Prices API.

You can also create products and prices upfront before creating a Checkout Session. Present different physical goods or levels of service with a Product. Use Prices to represent each product’s pricing.

For example, you can create a T-shirt product that has two prices for different currencies, 20 USD and 15 EUR. This allows you to change and add prices without needing to change the details of your underlying products. You can either create products and prices with the API or through the Stripe Dashboard.

API Dashboard

To create a Product with the API, only a name is required. The product name, description, and images that you supply are displayed to customers on Checkout.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/products \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d name=T-shirt
curl https://api.stripe.com/v1/products \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d name=T-shirt
product = Stripe::Product.create( { name: 'T-shirt', } )
product = Stripe::Product.create( { name: 'T-shirt', } )
product = stripe.Product.create( name='T-shirt', )
product = stripe.Product.create( name='T-shirt', )
$product = \Stripe\Product::create([ 'name' => 'T-shirt', ]);
$product = \Stripe\Product::create([ 'name' => 'T-shirt', ]);
ProductCreateParams params = ProductCreateParams.builder() .setName("T-shirt") .build(); Product product = Product.create(params);
ProductCreateParams params = ProductCreateParams.builder() .setName("T-shirt") .build(); Product product = Product.create(params);
const product = await stripe.products.create({ name: 'T-shirt', });
const product = await stripe.products.create({ name: 'T-shirt', });
params := &stripe.ProductParams{ Name: stripe.String("T-shirt"), } p, _ := product.New(params)
params := &stripe.ProductParams{ Name: stripe.String("T-shirt"), } p, _ := product.New(params)
var productService = new ProductService(); var options = new ProductCreateOptions { Name = "T-shirt", }; var product = productService.Create(options);
var productService = new ProductService(); var options = new ProductCreateOptions { Name = "T-shirt", }; var product = productService.Create(options);

Next, create a Price to define how much to charge for your product. This includes how much the product costs and what currency to use.

curl Ruby Python PHP Java Node Go .NET
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/prices \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d product="{{PRODUCT_ID}}" \ -d unit_amount=2000 \ -d currency=usd
price = Stripe::Price.create( { product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', } )
price = Stripe::Price.create( { product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', } )
price = stripe.Price.create( product='{{PRODUCT_ID}}', unit_amount=2000, currency='usd', )
price = stripe.Price.create( product='{{PRODUCT_ID}}', unit_amount=2000, currency='usd', )
$price = \Stripe\Price::create([ 'product' => '{{PRODUCT_ID}}', 'unit_amount' => 2000, 'currency' => 'usd', ]);
$price = \Stripe\Price::create([ 'product' => '{{PRODUCT_ID}}', 'unit_amount' => 2000, 'currency' => 'usd', ]);
PriceCreateParams params = PriceCreateParams.builder() .setProduct("{{PRODUCT_ID}}") .setUnitAmount(2000) .setCurrency("usd") .build(); Price price = Price.create(params);
PriceCreateParams params = PriceCreateParams.builder() .setProduct("{{PRODUCT_ID}}") .setUnitAmount(2000) .setCurrency("usd") .build(); Price price = Price.create(params);
const price = await stripe.prices.create({ product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', });
const price = await stripe.prices.create({ product: '{{PRODUCT_ID}}', unit_amount: 2000, currency: 'usd', });
params := &stripe.PriceParams{ Product: stripe.String("{{PRODUCT_ID}}"), UnitAmount: stripe.Int64(2000), Currency: stripe.String("usd"), } p, _ := price.New(params)
params := &stripe.PriceParams{ Product: stripe.String("{{PRODUCT_ID}}"), UnitAmount: stripe.Int64(2000), Currency: stripe.String("usd"), } p, _ := price.New(params)
var priceService = new PriceService(); var options = new PriceCreateOptions { Product = "{{PRODUCT_ID}}", UnitAmount = 2000, Currency = "usd", }; var price = priceService.Create(options);
var priceService = new PriceService(); var options = new PriceCreateOptions { Product = "{{PRODUCT_ID}}", UnitAmount = 2000, Currency = "usd", }; var price = priceService.Create(options);

Products created in test mode can be copied to live mode so that you don’t need to recreate them. In the Product detail view in the Dashboard, click Copy to live mode in the upper right corner. You can only do this once for each product created in test mode. Subsequent updates to the test product are not reflected for the live product.

Make sure you are in test mode by toggling the View test data button at the bottom of the Stripe Dashboard. Next, define the items you want to sell. To create a new product and price:

  • Navigate to the Products section in the Dashboard
  • Click Add product
  • Select One time when setting the price

The product name, description, and image that you supply are displayed to customers in Checkout.

Each price you create has an ID. When you create a Checkout Session, reference the price ID and quantity.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success?session_id={CHECKOUT_SESSION_ID}") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success?session_id={CHECKOUT_SESSION_ID}") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { 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);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { 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);

Optional Existing customers Server-side

If you have previously created a Customer object to represent a customer, use the customer argument to pass their Customer ID when creating a Checkout Session. This ensures that all objects created during the Session are associated with the correct Customer object.

When you pass a Customer ID, Stripe also uses the email stored on the Customer object to prefill the email field on the Checkout page. If the customer changes their email on the Checkout page, it will be updated on the Customer object after a successful payment.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("subscription"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("subscription"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "subscription", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Optional Prefill customer data Server-side

If you've already collected your customer's email and want to prefill it in the Checkout Session for them, pass customer_email when creating a Checkout Session.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer_email="customer@example.com" \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer_email="customer@example.com" \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer_email='customer@example.com', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( customer_email='customer@example.com', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer_email' => 'customer@example.com', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'customer_email' => 'customer@example.com', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomerEmail("customer@example.com") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setCustomerEmail("customer@example.com") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ customer_email: 'customer@example.com', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ CustomerEmail: stripe.String("customer@example.com"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ CustomerEmail: stripe.String("customer@example.com"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { CustomerEmail = "customer@example.com", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { CustomerEmail = "customer@example.com", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Optional Save payment method details Server-side

By default, payment methods used to make a one-time payment with Checkout aren’t available for future use outside of Checkout. You can instruct Checkout to save payment methods used to make a one-time payment by passing the payment_intent_data.setup_future_usage argument. This is useful if you need to capture a payment method on-file to use for future fees, such as cancellation or no-show fees.

Stripe uses setup_future_usage to dynamically optimize your payment flow and comply with regional legislation and network rules. For example, if your customer is impacted by Strong Customer Authentication, passing setup_future_usage=off_session ensures that they’re authenticated while processing this payment. You can then collect future off-session payments for this customer using the Payment Intents API. Reusing these payment methods in future Checkout Sessions isn’t currently supported.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_intent_data[setup_future_usage]"=off_session \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_intent_data[setup_future_usage]"=off_session \ -d customer=cus_123 \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_intent_data={ 'setup_future_usage': 'off_session', }, customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_intent_data={ 'setup_future_usage': 'off_session', }, customer='cus_123', payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_intent_data' => [ 'setup_future_usage' => 'off_session', ], 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_intent_data' => [ 'setup_future_usage' => 'off_session', ], 'customer' => 'cus_123', 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setSetupFutureUsage(SessionCreateParams.PaymentIntentData.SetupFutureUsage.OFF_SESSION) .build()) .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setSetupFutureUsage(SessionCreateParams.PaymentIntentData.SetupFutureUsage.OFF_SESSION) .build()) .setCustomer("cus_123") .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_intent_data: { setup_future_usage: 'off_session', }, customer: 'cus_123', payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ SetupFutureUsage: stripe.String("off_session"), }, Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ SetupFutureUsage: stripe.String("off_session"), }, Customer: stripe.String("cus_123"), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentIntentData = new SessionPaymentIntentDataOptions { SetupFutureUsage = "off_session", }, Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentIntentData = new SessionPaymentIntentDataOptions { SetupFutureUsage = "off_session", }, Customer = "cus_123", PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

Use Checkout setup mode to collect payment method details without immediately collecting a payment.

Optional Separate authorization and capture Server-side

Stripe supports two-step card payments so you can first authorize a card, then wait to capture funds later. When a payment is authorized, the funds are guaranteed by the card issuer and the amount is held on the customer’s card for up to 7 days. If the payment isn’t captured within this time, the payment is canceled and the funds are released.

Separating authorization and capture is useful if you need to take additional actions between confirming that a customer is able to pay and collecting their payment. For example, if you’re selling stock-limited items, you may need to confirm that an item purchased by your customer using Checkout is still available before capturing their payment and fulfilling the purchase. Accomplish this using the following workflow:

  1. Confirm that the customer’s payment method is authorized.
  2. Consult your inventory management system to confirm that the item is still available.
  3. Update your inventory management system to indicate that the item has been purchased.
  4. Capture the customer’s payment.
  5. Inform your customer whether their purchase was successful on your confirmation page.

To indicate that you want to separate authorization and capture, you must set the value of payment_intent_data.capture_method to manual when creating the Checkout Session. This instructs Stripe to only authorize the amount on the customer’s card.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d "payment_intent_data[capture_method]"=manual \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=payment \ -d "payment_intent_data[capture_method]"=manual \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', payment_intent_data={ 'capture_method': 'manual', }, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='payment', payment_intent_data={ 'capture_method': 'manual', }, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'payment_intent_data' => [ 'capture_method' => 'manual', ], 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'payment', 'payment_intent_data' => [ 'capture_method' => 'manual', ], 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setCaptureMethod(SessionCreateParams.PaymentIntentData.CaptureMethod.MANUAL) .build()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setPaymentIntentData( SessionCreateParams.PaymentIntentData.builder() .setCaptureMethod(SessionCreateParams.PaymentIntentData.CaptureMethod.MANUAL) .build()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', payment_intent_data: { capture_method: 'manual', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ CaptureMethod: stripe.String("manual"), }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("payment"), PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{ CaptureMethod: stripe.String("manual"), }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", PaymentIntentData = new SessionPaymentIntentDataOptions { CaptureMethod = "manual", }, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "payment", PaymentIntentData = new SessionPaymentIntentDataOptions { CaptureMethod = "manual", }, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); Session session = service.Create(options);

To capture an uncaptured payment, you can use either the Dashboard or the capture endpoint. Programmatically capturing payments requires access to the PaymentIntent created during the Checkout Session, which you can get from the Session object.

Now that you have your basic integration working, learn how to programmatically get a notification whenever a customer pays.

See also

  • Add discounts
  • Collect taxes
  • Customize your branding and address collection
  • Customize your success page

Payment completed

What you're building

Success! Here's the PaymentIntent that was returned by the Stripe API. The status of succeeded indicates that the payment was completed successfully.

Install the Stripe CLI, then run the following in your terminal:

$
stripe samples create accept-a-card-payment

Contains examples in PHP, Node.js, Ruby, Java, Python. The sample will be configured with your Stripe test key if you have set up the CLI with your Stripe account

Select the using-webhooks integration type when prompted by the CLI.

We have a set of samples on GitHub to help you get started.

$
git clone https://github.com/stripe-samples/accept-a-card-payment

Contains examples in PHP, Node.js, Ruby, Java, Python.

Open the using-webhooks directory after cloning to see this integration.

1 Set up Stripe Server-side

First, you need a Stripe account. Register now.

Use our official libraries for access to the Stripe API from your application:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

2 Create a PaymentIntent Server-side

Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking charge attempts and payment state changes throughout the process.

Create a PaymentIntent on your server with an amount and currency. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
server.rb
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', })
server.py
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', )
index.php
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]);
Server.java
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setCurrency("usd") .setAmount(1099L) .build(); PaymentIntent intent = PaymentIntent.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setCurrency("usd") .setAmount(1099L) .build(); PaymentIntent intent = PaymentIntent.create(params);
server.js
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', });
Server.go
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params)
server.cs
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options);

Included in the returned PaymentIntent is a client secret, which is used on the client side to securely complete the payment process instead of passing the entire PaymentIntent object. There are different approaches that you can use to pass the client secret to the client side.

Single-page application Server-side rendering

You can retrieve the client secret from an endpoint on your server using the browser’s fetch function on the client side. This approach is generally most suitable when your client side is a single-page application, particularly one built with a modern frontend framework such as React. This example shows how to create the server endpoint that serves the client secret:

Ruby Python PHP Java Node Go .NET
main.rb
get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end
get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end
app.py
from flask import Flask, jsonify app = Flask(__name__) @app.route('/secret') def secret(): intent = # ... Create or retrieve the PaymentIntent return jsonify(client_secret=intent.client_secret)
from flask import Flask, jsonify app = Flask(__name__) @app.route('/secret') def secret(): intent = # ... Create or retrieve the PaymentIntent return jsonify(client_secret=intent.client_secret)
secret.php
<?php $intent = # ... Create or retrieve the PaymentIntent echo json_encode(array('client_secret' => $intent->client_secret)); ?>
<?php $intent = # ... Create or retrieve the PaymentIntent echo json_encode(array('client_secret' => $intent->client_secret)); ?>
app.java
import java.util.HashMap; import java.util.Map; import com.stripe.model.PaymentIntent; import com.google.gson.Gson; import static spark.Spark.get; public class StripeJavaQuickStart { public static void main(String[] args) { Gson gson = new Gson(); get("/secret", (request, response) -> { PaymentIntent intent = // ... Fetch or create the PaymentIntent Map<String, String> map = new HashMap(); map.put("client_secret", intent.getClientSecret()); return map; }, gson::toJson); } }
import java.util.HashMap; import java.util.Map; import com.stripe.model.PaymentIntent; import com.google.gson.Gson; import static spark.Spark.get; public class StripeJavaQuickStart { public static void main(String[] args) { Gson gson = new Gson(); get("/secret", (request, response) -> { PaymentIntent intent = // ... Fetch or create the PaymentIntent Map<String, String> map = new HashMap(); map.put("client_secret", intent.getClientSecret()); return map; }, gson::toJson); } }
app.js
const express = require('express'); const app = express(); app.get('/secret', async (req, res) => { const intent = // ... Fetch or create the PaymentIntent res.json({client_secret: intent.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); });
const express = require('express'); const app = express(); app.get('/secret', async (req, res) => { const intent = // ... Fetch or create the PaymentIntent res.json({client_secret: intent.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); });
app.go
package main import ( "encoding/json" "net/http" stripe "github.com/stripe/stripe-go/v71" ) type CheckoutData struct { ClientSecret string `json:"client_secret"` } func main() { http.HandleFunc("/secret", func(w http.ResponseWriter, r *http.Request) { intent := // ... Fetch or create the PaymentIntent data := CheckoutData{ ClientSecret: intent.ClientSecret, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(data) }) http.ListenAndServe(":3000", nil) }
package main import ( "encoding/json" "net/http" stripe "github.com/stripe/stripe-go/v71" ) type CheckoutData struct { ClientSecret string `json:"client_secret"` } func main() { http.HandleFunc("/secret", func(w http.ResponseWriter, r *http.Request) { intent := // ... Fetch or create the PaymentIntent data := CheckoutData{ ClientSecret: intent.ClientSecret, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(data) }) http.ListenAndServe(":3000", nil) }
Controllers/CheckoutApiController.cs
using System; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("secret")] [ApiController] public class CheckoutApiController : Controller { [HttpGet] public ActionResult Get() { var intent = // ... Fetch or create the PaymentIntent return Json(new {client_secret = intent.ClientSecret}); } } }
using System; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("secret")] [ApiController] public class CheckoutApiController : Controller { [HttpGet] public ActionResult Get() { var intent = // ... Fetch or create the PaymentIntent return Json(new {client_secret = intent.ClientSecret}); } } }

This example demonstrates how to fetch the client secret with JavaScript on the client side:

JavaScript JavaScript (ESNext)
var response = fetch('/secret').then(function(response) { return response.json(); }).then(function(responseJson) { var clientSecret = responseJson.client_secret; // Call stripe.confirmCardPayment() with the client secret. });
var response = fetch('/secret').then(function(response) { return response.json(); }).then(function(responseJson) { var clientSecret = responseJson.client_secret; // Call stripe.confirmCardPayment() with the client secret. });
(async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Call stripe.confirmCardPayment() with the client secret. })();
(async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Call stripe.confirmCardPayment() with the client secret. })();

If your application uses server-side rendering, you may wish to use your template framework to embed the client secret in the HTML output of your checkout page during rendering. You can embed it in a data attribute or hidden HTML element and then extract it with JavaScript in order to use it to complete payment.

Ruby Python PHP Java Node Go .NET
views/checkout.erb
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="<%= @intent.client_secret %>">Submit Payment</button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="<%= @intent.client_secret %>">Submit Payment</button>
main.rb
get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end
get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end
checkout.html
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
app.py
@app.route('/checkout') def checkout(): intent = # ... Fetch or create the PaymentIntent return render_template('checkout.html', client_secret=intent.client_secret)
@app.route('/checkout') def checkout(): intent = # ... Fetch or create the PaymentIntent return render_template('checkout.html', client_secret=intent.client_secret)
checkout.php
<?php $intent = # ... Fetch or create the PaymentIntent; ?> ... <input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="<?= $intent->client_secret ?>"> Submit Payment </button> ...
<?php $intent = # ... Fetch or create the PaymentIntent; ?> ... <input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="<?= $intent->client_secret ?>"> Submit Payment </button> ...
resources/templates/checkout.hbs
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
main.java
import java.util.HashMap; import java.util.Map; import com.stripe.model.PaymentIntent; import spark.ModelAndView; import static spark.Spark.get; public class StripeJavaQuickStart { public static void main(String[] args) { get("/checkout", (request, response) -> { PaymentIntent intent = // ... Fetch or create the PaymentIntent Map map = new HashMap(); map.put("client_secret", intent.getClientSecret()); return new ModelAndView(map, "checkout.hbs"); }, new HandlebarsTemplateEngine()); } }
import java.util.HashMap; import java.util.Map; import com.stripe.model.PaymentIntent; import spark.ModelAndView; import static spark.Spark.get; public class StripeJavaQuickStart { public static void main(String[] args) { get("/checkout", (request, response) -> { PaymentIntent intent = // ... Fetch or create the PaymentIntent Map map = new HashMap(); map.put("client_secret", intent.getClientSecret()); return new ModelAndView(map, "checkout.hbs"); }, new HandlebarsTemplateEngine()); } }
views/checkout.hbs
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ client_secret }}"> Submit Payment </button>
app.js
const express = require('express'); const expressHandlebars = require('express-handlebars'); const app = express(); app.engine('.hbs', expressHandlebars({ extname: '.hbs' })); app.set('view engine', '.hbs'); app.set('views', './views'); app.get('/checkout', async (req, res) => { const intent = // ... Fetch or create the PaymentIntent res.render('checkout', { client_secret: intent.client_secret }); }); app.listen(3000, () => { console.log('Running on port 3000'); });
const express = require('express'); const expressHandlebars = require('express-handlebars'); const app = express(); app.engine('.hbs', expressHandlebars({ extname: '.hbs' })); app.set('view engine', '.hbs'); app.set('views', './views'); app.get('/checkout', async (req, res) => { const intent = // ... Fetch or create the PaymentIntent res.render('checkout', { client_secret: intent.client_secret }); }); app.listen(3000, () => { console.log('Running on port 3000'); });
views/checkout.html
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ .ClientSecret }}"> Submit Payment </button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="{{ .ClientSecret }}"> Submit Payment </button>
app.go
package main import ( "html/template" "net/http" stripe "github.com/stripe/stripe-go/v71" ) type CheckoutData struct { ClientSecret string } func main() { checkoutTmpl := template.Must(template.ParseFiles("views/checkout.html")) http.HandleFunc("/checkout", func(w http.ResponseWriter, r *http.Request) { intent := // ... Fetch or create the PaymentIntent data := CheckoutData{ ClientSecret: intent.ClientSecret, } checkoutTmpl.Execute(w, data) }) http.ListenAndServe(":3000", nil) }
package main import ( "html/template" "net/http" stripe "github.com/stripe/stripe-go/v71" ) type CheckoutData struct { ClientSecret string } func main() { checkoutTmpl := template.Must(template.ParseFiles("views/checkout.html")) http.HandleFunc("/checkout", func(w http.ResponseWriter, r *http.Request) { intent := // ... Fetch or create the PaymentIntent data := CheckoutData{ ClientSecret: intent.ClientSecret, } checkoutTmpl.Execute(w, data) }) http.ListenAndServe(":3000", nil) }
Views/Checkout/Index.cshtml
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="@ViewData["ClientSecret"]"> Submit Payment </button>
<input id="card-name" type="text"> <!-- placeholder for Elements --> <div id="card-element"></div> <button id="card-button" data-secret="@ViewData["ClientSecret"]"> Submit Payment </button>
Controllers/CheckoutApiController.cs
using System; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("/[controller]")] public class CheckoutController : Controller { public IActionResult Index() { var intent = // ... Fetch or create the PaymentIntent ViewData["ClientSecret"] = intent.ClientSecret; return View(); } } }
using System; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("/[controller]")] public class CheckoutController : Controller { public IActionResult Index() { var intent = // ... Fetch or create the PaymentIntent ViewData["ClientSecret"] = intent.ClientSecret; return View(); } } }

3 Collect card details Client-side

You’re ready to collect card information on the client with Stripe Elements. Elements is a set of prebuilt UI components for collecting and validating card number, ZIP code, and expiration date.

A Stripe Element contains an iframe that securely sends the payment information to Stripe over an HTTPS connection. The checkout page address must also start with https:// rather than http:// for your integration to work.

You can test your integration without using HTTPS. Enable it when you’re ready to accept live payments.

Set up Stripe Elements

HTML + JS React

Stripe Elements is automatically available as a feature of Stripe.js. Include the Stripe.js script on your checkout page by adding it to the head of your HTML file. Always load Stripe.js directly from js.stripe.com to remain PCI compliant. Do not include the script in a bundle or host a copy of it yourself.

checkout.html
<head> <title>Checkout</title> <script src="https://js.stripe.com/v3/"></script> </head>
<head> <title>Checkout</title> <script src="https://js.stripe.com/v3/"></script> </head>

Create an instance of Elements with the following JavaScript on your checkout page:

script.js
// Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/account/apikeys var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var elements = stripe.elements();
// Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/account/apikeys var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var elements = stripe.elements();

Add Elements to your payment page

Elements needs a place to live in your payment form. Create empty DOM nodes (containers) with unique IDs in your payment form and then pass those IDs to Elements.

checkout.html
View full sample
<form id="payment-form"> <div id="card-element"> <!-- Elements will create input elements here --> </div> <!-- We'll put the error messages in this element --> <div id="card-errors" role="alert"></div> <button id="submit">Pay</button> </form>
<form id="payment-form"> <div id="card-element"> <!-- Elements will create input elements here --> </div> <!-- We'll put the error messages in this element --> <div id="card-errors" role="alert"></div> <button id="submit">Pay</button> </form>

When the form above has loaded, create an instance of an Element and mount it to the Element container:

client.js
View full sample
// Set up Stripe.js and Elements to use in checkout form var elements = stripe.elements(); var style = { base: { color: "#32325d", } }; var card = elements.create("card", { style: style }); card.mount("#card-element");
// Set up Stripe.js and Elements to use in checkout form var elements = stripe.elements(); var style = { base: { color: "#32325d", } }; var card = elements.create("card", { style: style }); card.mount("#card-element");

More examples

See additional payment forms created with Elements on GitHub.

The card Element simplifies the form and minimizes the number of required fields by inserting a single, flexible input field that securely collects all necessary card and billing details. Otherwise, combine cardNumber, cardExpiry, and cardCvc Elements for a flexible, multi-input card form.

Always collect a postal code to increase card acceptance rates and reduce fraud.

The single input card Element automatically collects and sends the customer’s postal code to Stripe. If you build your payment form with multi-input card Elements (cardNumber, cardExpiry, cardCvc), add a separate input field for the customer’s postal code.

For a full list of supported Element types, refer to our Stripe.js reference documentation.

Elements validates user input as it is typed. To help your customers catch mistakes, listen to change events on the card Element and display any errors:

JavaScript (ESNext) JavaScript
card.on('change', ({error}) => { let displayError = document.getElementById('card-errors'); if (error) { displayError.textContent = error.message; } else { displayError.textContent = ''; } });
card.on('change', ({error}) => { let displayError = document.getElementById('card-errors'); if (error) { displayError.textContent = error.message; } else { displayError.textContent = ''; } });
card.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });
card.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });

Postal code validation depends on your customer’s billing country. Use our international test cards to experiment with other postal code formats.

npm umd

Install React Stripe.js and the Stripe.js loader from the npm public registry.

Terminal
npm install --save @stripe/react-stripe-js @stripe/stripe-js
npm install --save @stripe/react-stripe-js @stripe/stripe-js

We also provide a UMD build for sites that do not use npm or modules.

Include the Stripe.js script, which exports a global Stripe function, and the UMD build of React Stripe.js, which exports a global ReactStripe object. Always load the Stripe.js script directly from js.stripe.com to remain PCI compliant. Do not include the script in a bundle or host a copy of it yourself.

<!-- Stripe.js --> <script src="https://js.stripe.com/v3/"></script> <!-- React Stripe.js development build --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.js"></script> <!-- When you are ready to deploy your site to production, remove the above development script, and include the following production build. --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.min.js"></script>
<!-- Stripe.js --> <script src="https://js.stripe.com/v3/"></script> <!-- React Stripe.js development build --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.js"></script> <!-- When you are ready to deploy your site to production, remove the above development script, and include the following production build. --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.min.js"></script>

The demo in CodeSandbox lets you try out React Stripe.js without having to create a new project.

Add Stripe.js and Elements to your page

To use Element components, wrap the root of your React app in an Elements provider. Call loadStripe with your publishable key and pass the returned Promise to the Elements provider.

index.js
import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe("pk_test_TYooMQauvdEDq54NiTphI7jx"); function App() { return ( <Elements stripe={stripePromise}> <CheckoutForm /> </Elements> ); }; ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe("pk_test_TYooMQauvdEDq54NiTphI7jx"); function App() { return ( <Elements stripe={stripePromise}> <CheckoutForm /> </Elements> ); }; ReactDOM.render(<App />, document.getElementById('root'));

Add and configure a CardElement component

Use individual Element components, such as CardElement, to build your form.

JSX CSS
CardSection.js
/** * Use the CSS tab above to style your Element's container. */ import React from 'react'; import {CardElement} from '@stripe/react-stripe-js'; import './CardSectionStyles.css' const CARD_ELEMENT_OPTIONS = { style: { base: { color: "#32325d", fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: "antialiased", fontSize: "16px", "::placeholder": { color: "#aab7c4", }, }, invalid: { color: "#fa755a", iconColor: "#fa755a", }, }, }; function CardSection() { return ( <label> Card details <CardElement options={CARD_ELEMENT_OPTIONS} /> </label> ); }; export default CardSection;
/** * Use the CSS tab above to style your Element's container. */ import React from 'react'; import {CardElement} from '@stripe/react-stripe-js'; import './CardSectionStyles.css' const CARD_ELEMENT_OPTIONS = { style: { base: { color: "#32325d", fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: "antialiased", fontSize: "16px", "::placeholder": { color: "#aab7c4", }, }, invalid: { color: "#fa755a", iconColor: "#fa755a", }, }, }; function CardSection() { return ( <label> Card details <CardElement options={CARD_ELEMENT_OPTIONS} /> </label> ); }; export default CardSection;
CardSectionStyles.css
/** * Shows how you can use CSS to style your Element's container. * These classes are added to your Stripe Element by default. * You can override these classNames by using the options passed * to the CardElement component. * https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options-classes */ .StripeElement { height: 40px; padding: 10px 12px; width: 100%; color: #32325d; background-color: white; border: 1px solid transparent; border-radius: 4px; box-shadow: 0 1px 3px 0 #e6ebf1; -webkit-transition: box-shadow 150ms ease; transition: box-shadow 150ms ease; } .StripeElement--focus { box-shadow: 0 1px 3px 0 #cfd7df; } .StripeElement--invalid { border-color: #fa755a; } .StripeElement--webkit-autofill { background-color: #fefde5 !important; }
/** * Shows how you can use CSS to style your Element's container. * These classes are added to your Stripe Element by default. * You can override these classNames by using the options passed * to the CardElement component. * https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options-classes */ .StripeElement { height: 40px; padding: 10px 12px; width: 100%; color: #32325d; background-color: white; border: 1px solid transparent; border-radius: 4px; box-shadow: 0 1px 3px 0 #e6ebf1; -webkit-transition: box-shadow 150ms ease; transition: box-shadow 150ms ease; } .StripeElement--focus { box-shadow: 0 1px 3px 0 #cfd7df; } .StripeElement--invalid { border-color: #fa755a; } .StripeElement--webkit-autofill { background-color: #fefde5 !important; }

Elements are completely customizable. You can style Elements to match the look and feel of your site, providing a seamless checkout experience for your customers. It’s also possible to style various input states, for example when the Element has focus.

The CardElement simplifies the form and minimizes the number of required fields by inserting a single, flexible input field that securely collects all necessary card and billing details. Otherwise, combine CardNumberElement, CardExpiryElement, and CardCvcElement elements for a flexible, multi-input card form.

Always collect a postal code to increase card acceptance rates and reduce fraud.

The single input CardElement automatically collects and sends the customer’s postal code to Stripe. If you build your payment form with multi-input card Elements, add a separate <input> field for the customer’s postal code.

4 Submit the payment to Stripe Client-side

Rather than sending the entire PaymentIntent object to the client, use its client secret from step 2. This is different from your API keys that authenticate Stripe API requests.

The client secret should still be handled carefully because it can complete the charge. Do not log it, embed it in URLs, or expose it to anyone but the customer.

HTML + JS React

To complete the payment when the user clicks, retrieve the client secret from the PaymentIntent you created in step two and call stripe.confirmCardPayment with the client secret.

Pass additional billing details, such as the cardholder name and address, to the billing_details hash. The card Element automatically sends the customer’s postal code information. However, combining cardNumber, cardCvc, and cardExpiry Elements requires you to pass the postal code to billing_details[address][postal_code].

client.js
View full sample
var form = document.getElementById('payment-form'); form.addEventListener('submit', function(ev) { ev.preventDefault(); stripe.confirmCardPayment(clientSecret, { payment_method: { card: card, billing_details: { name: 'Jenny Rosen' } } }).then(function(result) { if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }); });
var form = document.getElementById('payment-form'); form.addEventListener('submit', function(ev) { ev.preventDefault(); stripe.confirmCardPayment(clientSecret, { payment_method: { card: card, billing_details: { name: 'Jenny Rosen' } } }).then(function(result) { if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }); });

stripe.confirmCardPayment may take several seconds to complete. During that time, disable your form from being resubmitted and show a waiting indicator like a spinner. If you receive an error, show it to the customer, re-enable the form, and hide the waiting indicator.

If the customer must authenticate the card, Stripe.js walks them through that process by showing them a modal. You can see an example of this modal experience by using the test card number 4000 0025 0000 3155 with any CVC, future expiration date, and postal code in the demo at the top of the page.

When the payment completes successfully, the value of the returned PaymentIntent’s status property is succeeded. Check the status of a PaymentIntent in the Dashboard or by inspecting the status property on the object. If the payment is not successful, inspect the returned error to determine the cause.

To complete the payment when the user clicks, retrieve the client secret from the PaymentIntent you created in step two and call stripe.confirmCardPayment with the client secret and the Element. Pass additional billing details, such as the cardholder name and address, to the billing_details hash.

To call stripe.confirmCardPayment from your payment form component, use the useStripe and useElements hooks.

If you prefer traditional class components over hooks, you can instead use an ElementsConsumer.

Hooks Class Components
CheckoutForm.js
import React from 'react'; import {useStripe, useElements, CardElement} from '@stripe/react-stripe-js'; import CardSection from './CardSection'; export default function CheckoutForm() { const stripe = useStripe(); const elements = useElements(); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const result = await stripe.confirmCardPayment('{CLIENT_SECRET}', { payment_method: { card: elements.getElement(CardElement), billing_details: { name: 'Jenny Rosen', }, } }); if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }; return ( <form onSubmit={handleSubmit}> <CardSection /> <button disabled={!stripe}>Confirm order</button> </form> ); }
import React from 'react'; import {useStripe, useElements, CardElement} from '@stripe/react-stripe-js'; import CardSection from './CardSection'; export default function CheckoutForm() { const stripe = useStripe(); const elements = useElements(); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const result = await stripe.confirmCardPayment('{CLIENT_SECRET}', { payment_method: { card: elements.getElement(CardElement), billing_details: { name: 'Jenny Rosen', }, } }); if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }; return ( <form onSubmit={handleSubmit}> <CardSection /> <button disabled={!stripe}>Confirm order</button> </form> ); }
CheckoutForm.js
import React from 'react'; import {ElementsConsumer, CardElement} from '@stripe/react-stripe-js'; import CardSection from './CardSection'; class CheckoutForm extends React.Component { handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const {stripe, elements} = this.props if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const result = await stripe.confirmCardPayment('{CLIENT_SECRET}', { payment_method: { card: elements.getElement(CardElement), billing_details: { name: 'Jenny Rosen', }, } }); if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }; render() { return ( <form onSubmit={this.handleSubmit}> <CardSection /> <button disabled={!this.props.stripe}>Confirm order</button> </form> ); } } export default function InjectedCheckoutForm() { return ( <ElementsConsumer> {({stripe, elements}) => ( <CheckoutForm stripe={stripe} elements={elements} /> )} </ElementsConsumer> ); }
import React from 'react'; import {ElementsConsumer, CardElement} from '@stripe/react-stripe-js'; import CardSection from './CardSection'; class CheckoutForm extends React.Component { handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const {stripe, elements} = this.props if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const result = await stripe.confirmCardPayment('{CLIENT_SECRET}', { payment_method: { card: elements.getElement(CardElement), billing_details: { name: 'Jenny Rosen', }, } }); if (result.error) { // Show error to your customer (e.g., insufficient funds) console.log(result.error.message); } else { // The payment has been processed! if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } }; render() { return ( <form onSubmit={this.handleSubmit}> <CardSection /> <button disabled={!this.props.stripe}>Confirm order</button> </form> ); } } export default function InjectedCheckoutForm() { return ( <ElementsConsumer> {({stripe, elements}) => ( <CheckoutForm stripe={stripe} elements={elements} /> )} </ElementsConsumer> ); }

stripe.confirmCardPayment may take several seconds to complete. During that time, disable your form from being resubmitted and show a waiting indicator like a spinner. If you receive an error, show it to the customer, re-enable the form, and hide the waiting indicator.

If the customer must authenticate the card, Stripe.js walks them through that process by showing them a modal. You can see an example of this modal experience by using the test card number 4000 0025 0000 3155 with any CVC, future expiration date, and postal code in the demo at the top of the page.

When the payment completes successfully, the value of the returned PaymentIntent’s status property is succeeded. Check the status of a PaymentIntent in the Dashboard or by inspecting the status property on the object. If the payment is not successful, inspect the returned error to determine the cause.

5 Test the integration

There are several test cards you can use in test mode to make sure this integration is ready. Use them with any CVC, postal code, and future expiration date.

For the full list of test cards see our guide on testing.

Optional Handle post-payment events

Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Setting up your integration to listen for asynchronous events also makes it easier to accept more payment methods in the future. Check out our guide to payment methods to see the differences between all supported payment methods.

To closely control when funds move, you can manually authorize the payment and finalize it on your server. This integration is significantly different and has limitations.

Receive events and run business actions

Manually

Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.

View your test payments in the Dashboard

Custom code

Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.

Build a custom webhook

Prebuilt apps

Handle common business events, like shipping and inventory management, by integrating a partner application.

Browse shipping apps and extensions

Browse inventory management apps and extensions

See all partner solutions

See also

Congratulations, you’re done with your integration! Next, you can learn more about the Payment Intents API and Elements.

  • Learn about Payment Intents
  • Learn about Stripe Elements

Collecting payments in your iOS app consists of creating an object to track a payment on your server, collecting card information in your app, and submitting the payment to Stripe for processing.

Stripe uses this payment object, called a PaymentIntent, to track and handle all the states of the payment until it’s completed—even when the bank requires customer intervention, like two-factor authentication.

The steps in this guide are fully implemented on GitHub in the using-webhooks directory. Clone the repo and follow the instructions to run the demo app.

1 Set up Stripe Server-side Client-side

First, you need a Stripe account. Register now.

Server-side

This integration requires endpoints on your server that talk to the Stripe API. Use our official libraries for access to the Stripe API from your server:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

Client-side

The iOS SDK is open source, fully documented, and compatible with apps supporting iOS 11 or above.

CocoaPods Carthage Dynamic Framework
  1. If you haven't already, install the latest version of CocoaPods.
  2. If you don't have an existing Podfile, run the following command to create one:
    Terminal
    pod init
    pod init
  3. Add this line to your Podfile:
    Podfile
    pod 'Stripe'
    pod 'Stripe'
  4. Run the following command:
    Terminal
    pod install
    pod install
  5. Don't forget to use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file, from here on out.
  6. In the future, to update to the latest version of the SDK, just run:
    Terminal
    pod update Stripe
    pod update Stripe
  1. If you haven't already, install the latest version of Carthage.
  2. Add this line to your Cartfile:
    Cartfile
    github "stripe/stripe-ios"
    github "stripe/stripe-ios"
  3. Follow the Carthage installation instructions.
  4. In the future, to update to the latest version of the SDK, run the following command:
    Terminal
    carthage update stripe-ios --platform ios
    carthage update stripe-ios --platform ios
  1. Head to our GitHub releases page and download and unzip Stripe.framework.zip.
  2. Drag Stripe.framework to the "Embedded Binaries" section of your Xcode project's "General" settings. Make sure to select "Copy items if needed".
  3. Head to the "Build Phases" section of your Xcode project settings, and create a new "Run Script Build Phase". Paste the following snippet into the text field:
    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Stripe.framework/integrate-dynamic-framework.sh"
    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Stripe.framework/integrate-dynamic-framework.sh"
  4. In the future, to update to the latest version of our SDK, just repeat steps 1 and 2.

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.

When your app starts, configure the SDK with your Stripe publishable key so that it can make requests to the Stripe API.

Swift Objective-C
AppDelegate.swift
import UIKit import Stripe @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { StripeAPI.defaultPublishableKey = "pk_test_TYooMQauvdEDq54NiTphI7jx" // do any other necessary launch configuration return true } }
import UIKit import Stripe @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { StripeAPI.defaultPublishableKey = "pk_test_TYooMQauvdEDq54NiTphI7jx" // do any other necessary launch configuration return true } }
AppDelegate.m
#import "AppDelegate.h" @import Stripe; @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [StripeAPI setDefaultPublishableKey:@"pk_test_TYooMQauvdEDq54NiTphI7jx"]; // do any other necessary launch configuration return YES; } @end
#import "AppDelegate.h" @import Stripe; @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [StripeAPI setDefaultPublishableKey:@"pk_test_TYooMQauvdEDq54NiTphI7jx"]; // do any other necessary launch configuration return YES; } @end

Use your test mode keys while you test and develop, and your live mode keys before you publish your app.

2 Create your checkout page Client-side

Want a prebuilt UI instead?

The iOS Basic Integration features prebuilt, full size screens to collect payment information.

Securely collect card information on the client with STPPaymentCardTextField, a drop-in UI component provided by the SDK.

STPPaymentCardTextField performs on-the-fly validation and formatting.

Create an instance of the card component and a Pay button with the following code:

Swift Objective-C
CheckoutViewController.swift
View full sample
import UIKit import Stripe class CheckoutViewController: UIViewController { lazy var cardTextField: STPPaymentCardTextField = { let cardTextField = STPPaymentCardTextField() return cardTextField }() lazy var payButton: UIButton = { let button = UIButton(type: .custom) button.layer.cornerRadius = 5 button.backgroundColor = .systemBlue button.titleLabel?.font = UIFont.systemFont(ofSize: 22) button.setTitle("Pay", for: .normal) button.addTarget(self, action: #selector(pay), for: .touchUpInside) return button }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let stackView = UIStackView(arrangedSubviews: [cardTextField, payButton]) stackView.axis = .vertical stackView.spacing = 20 stackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2), view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2), stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.topAnchor, multiplier: 2), ]) } @objc func pay() { // ... } }
import UIKit import Stripe class CheckoutViewController: UIViewController { lazy var cardTextField: STPPaymentCardTextField = { let cardTextField = STPPaymentCardTextField() return cardTextField }() lazy var payButton: UIButton = { let button = UIButton(type: .custom) button.layer.cornerRadius = 5 button.backgroundColor = .systemBlue button.titleLabel?.font = UIFont.systemFont(ofSize: 22) button.setTitle("Pay", for: .normal) button.addTarget(self, action: #selector(pay), for: .touchUpInside) return button }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let stackView = UIStackView(arrangedSubviews: [cardTextField, payButton]) stackView.axis = .vertical stackView.spacing = 20 stackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2), view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2), stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.topAnchor, multiplier: 2), ]) } @objc func pay() { // ... } }
CheckoutViewController.m
View full sample
#import "CheckoutViewController.h" @import Stripe; @interface CheckoutViewController () @property (weak) STPPaymentCardTextField *cardTextField; @property (weak) UIButton *payButton; @end @implementation CheckoutViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; STPPaymentCardTextField *cardTextField = [[STPPaymentCardTextField alloc] init]; self.cardTextField = cardTextField; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.layer.cornerRadius = 5; button.backgroundColor = [UIColor systemBlueColor]; button.titleLabel.font = [UIFont systemFontOfSize:22]; [button setTitle:@"Pay" forState:UIControlStateNormal]; [button addTarget:self action:@selector(pay) forControlEvents:UIControlEventTouchUpInside]; self.payButton = button; UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[cardTextField, button]]; stackView.axis = UILayoutConstraintAxisVertical; stackView.translatesAutoresizingMaskIntoConstraints = NO; stackView.spacing = 20; [self.view addSubview:stackView]; [NSLayoutConstraint activateConstraints:@[ [stackView.leftAnchor constraintEqualToSystemSpacingAfterAnchor:self.view.leftAnchor multiplier:2], [self.view.rightAnchor constraintEqualToSystemSpacingAfterAnchor:stackView.rightAnchor multiplier:2], [stackView.topAnchor constraintEqualToSystemSpacingBelowAnchor:self.view.topAnchor multiplier:2], ]]; } - (void)pay { // ... } @end
#import "CheckoutViewController.h" @import Stripe; @interface CheckoutViewController () @property (weak) STPPaymentCardTextField *cardTextField; @property (weak) UIButton *payButton; @end @implementation CheckoutViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; STPPaymentCardTextField *cardTextField = [[STPPaymentCardTextField alloc] init]; self.cardTextField = cardTextField; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.layer.cornerRadius = 5; button.backgroundColor = [UIColor systemBlueColor]; button.titleLabel.font = [UIFont systemFontOfSize:22]; [button setTitle:@"Pay" forState:UIControlStateNormal]; [button addTarget:self action:@selector(pay) forControlEvents:UIControlEventTouchUpInside]; self.payButton = button; UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[cardTextField, button]]; stackView.axis = UILayoutConstraintAxisVertical; stackView.translatesAutoresizingMaskIntoConstraints = NO; stackView.spacing = 20; [self.view addSubview:stackView]; [NSLayoutConstraint activateConstraints:@[ [stackView.leftAnchor constraintEqualToSystemSpacingAfterAnchor:self.view.leftAnchor multiplier:2], [self.view.rightAnchor constraintEqualToSystemSpacingAfterAnchor:stackView.rightAnchor multiplier:2], [stackView.topAnchor constraintEqualToSystemSpacingBelowAnchor:self.view.topAnchor multiplier:2], ]]; } - (void)pay { // ... } @end

Run your app, and make sure your checkout page shows the card component and pay button.

3 Create a PaymentIntent Server-side Client-side

Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.

Server-side

On your server, make an endpoint that creates a PaymentIntent with an amount and currency. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
server.rb
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', }) client_secret = payment_intent['client_secret'] # Pass the client secret to the client
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', }) client_secret = payment_intent['client_secret'] # Pass the client secret to the client
server.py
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', ) client_secret = intent.client_secret # Pass the client secret to the client
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', ) client_secret = intent.client_secret # Pass the client secret to the client
index.php
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]); $client_secret = $intent->client_secret; // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]); $client_secret = $intent->client_secret; // Pass the client secret to the client
Server.java
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setAmount(1099L) .setCurrency("usd") .build(); PaymentIntent intent = PaymentIntent.create(params); String clientSecret = intent.getClientSecret(); // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setAmount(1099L) .setCurrency("usd") .build(); PaymentIntent intent = PaymentIntent.create(params); String clientSecret = intent.getClientSecret(); // Pass the client secret to the client
server.js
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', }); const clientSecret = paymentIntent.client_secret // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', }); const clientSecret = paymentIntent.client_secret // Pass the client secret to the client
Server.go
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params) // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params) // Pass the client secret to the client
server.cs
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options); // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options); // Pass the client secret to the client

Instead of passing the entire PaymentIntent object to your app, just return its client secret. The PaymentIntent’s client secret is a unique key that lets you confirm the payment and update card details on the client, without allowing manipulation of sensitive information, like payment amount.

Client-side

On the client, request a PaymentIntent from your server and store its client secret.

Swift Objective-C
CheckoutViewController.swift
View full sample
class CheckoutViewController: UIViewController { var paymentIntentClientSecret: String? // ...continued from previous step override func viewDidLoad() { // ...continued from previous step startCheckout() } func startCheckout() { // Request a PaymentIntent from your server and store its client secret // Click Open on GitHub to see a full implementation } }
class CheckoutViewController: UIViewController { var paymentIntentClientSecret: String? // ...continued from previous step override func viewDidLoad() { // ...continued from previous step startCheckout() } func startCheckout() { // Request a PaymentIntent from your server and store its client secret // Click Open on GitHub to see a full implementation } }
CheckoutViewController.m
View full sample
@interface CheckoutViewController () // ...continued from previous step @property (strong) NSString *paymentIntentClientSecret; @end @implementation CheckoutViewController - (void)viewDidLoad { [super viewDidLoad]; // ...continued from previous step [self startCheckout]; } - (void)startCheckout { // Request a PaymentIntent from your server and store its client secret // Click Open on GitHub to see a full implementation } @end
@interface CheckoutViewController () // ...continued from previous step @property (strong) NSString *paymentIntentClientSecret; @end @implementation CheckoutViewController - (void)viewDidLoad { [super viewDidLoad]; // ...continued from previous step [self startCheckout]; } - (void)startCheckout { // Request a PaymentIntent from your server and store its client secret // Click Open on GitHub to see a full implementation } @end

4 Submit the payment to Stripe Client-side

When the customer taps the Pay button, confirm the PaymentIntent to complete the payment.

First, assemble a STPPaymentIntentParams object with:

  1. The card text field’s payment method details
  2. The PaymentIntent client secret from your server

Rather than sending the entire PaymentIntent object to the client, use its client secret. This is different from your API keys that authenticate Stripe API requests. The client secret is a string that lets your app access important fields from the PaymentIntent (e.g., status) while hiding sensitive ones (e.g., customer).

The client secret should still be handled carefully because it can complete the charge. Do not log it, embed it in URLs, or expose it to anyone but the customer.

Next, complete the payment by calling the STPPaymentHandler confirmPayment method.

Swift Objective-C
CheckoutViewController.swift
View full sample
class CheckoutViewController: UIViewController { // ... @objc func pay() { guard let paymentIntentClientSecret = paymentIntentClientSecret else { return; } // Collect card details let cardParams = cardTextField.cardParams let paymentMethodParams = STPPaymentMethodParams(card: cardParams, billingDetails: nil, metadata: nil) let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClientSecret) paymentIntentParams.paymentMethodParams = paymentMethodParams // Submit the payment let paymentHandler = STPPaymentHandler.shared() paymentHandler.confirmPayment(withParams: paymentIntentParams, authenticationContext: self) { (status, paymentIntent, error) in switch (status) { case .failed: self.displayAlert(title: "Payment failed", message: error?.localizedDescription ?? "") break case .canceled: self.displayAlert(title: "Payment canceled", message: error?.localizedDescription ?? "") break case .succeeded: self.displayAlert(title: "Payment succeeded", message: paymentIntent?.description ?? "", restartDemo: true) break @unknown default: fatalError() break } } } } extension CheckoutViewController: STPAuthenticationContext { func authenticationPresentingViewController() -> UIViewController { return self } }
class CheckoutViewController: UIViewController { // ... @objc func pay() { guard let paymentIntentClientSecret = paymentIntentClientSecret else { return; } // Collect card details let cardParams = cardTextField.cardParams let paymentMethodParams = STPPaymentMethodParams(card: cardParams, billingDetails: nil, metadata: nil) let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClientSecret) paymentIntentParams.paymentMethodParams = paymentMethodParams // Submit the payment let paymentHandler = STPPaymentHandler.shared() paymentHandler.confirmPayment(withParams: paymentIntentParams, authenticationContext: self) { (status, paymentIntent, error) in switch (status) { case .failed: self.displayAlert(title: "Payment failed", message: error?.localizedDescription ?? "") break case .canceled: self.displayAlert(title: "Payment canceled", message: error?.localizedDescription ?? "") break case .succeeded: self.displayAlert(title: "Payment succeeded", message: paymentIntent?.description ?? "", restartDemo: true) break @unknown default: fatalError() break } } } } extension CheckoutViewController: STPAuthenticationContext { func authenticationPresentingViewController() -> UIViewController { return self } }
CheckoutViewController.m
View full sample
@interface CheckoutViewController () <STPAuthenticationContext> // ... @end @implementation CheckoutViewController // ... - (void)pay { if (!self.paymentIntentClientSecret) { NSLog(@"PaymentIntent hasn't been created"); return; } // Collect card details STPPaymentMethodCardParams *cardParams = self.cardTextField.cardParams; STPPaymentMethodParams *paymentMethodParams = [STPPaymentMethodParams paramsWithCard:cardParams billingDetails:nil metadata:nil]; STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:self.paymentIntentClientSecret]; paymentIntentParams.paymentMethodParams = paymentMethodParams; // Submit the payment STPPaymentHandler *paymentHandler = [STPPaymentHandler sharedHandler]; [paymentHandler confirmPayment:paymentIntentParams withAuthenticationContext:self completion:^(STPPaymentHandlerActionStatus status, STPPaymentIntent *paymentIntent, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ switch (status) { case STPPaymentHandlerActionStatusFailed: { [self displayAlertWithTitle:@"Payment failed" message:error.localizedDescription ?: @"" restartDemo:NO]; break; } case STPPaymentHandlerActionStatusCanceled: { [self displayAlertWithTitle:@"Payment canceled" message:error.localizedDescription ?: @"" restartDemo:NO]; break; } case STPPaymentHandlerActionStatusSucceeded: { [self displayAlertWithTitle:@"Payment succeeded" message:paymentIntent.description ?: @"" restartDemo:YES]; break; } default: break; } }); }]; } # pragma mark STPAuthenticationContext - (UIViewController *)authenticationPresentingViewController { return self; } @end
@interface CheckoutViewController () <STPAuthenticationContext> // ... @end @implementation CheckoutViewController // ... - (void)pay { if (!self.paymentIntentClientSecret) { NSLog(@"PaymentIntent hasn't been created"); return; } // Collect card details STPPaymentMethodCardParams *cardParams = self.cardTextField.cardParams; STPPaymentMethodParams *paymentMethodParams = [STPPaymentMethodParams paramsWithCard:cardParams billingDetails:nil metadata:nil]; STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:self.paymentIntentClientSecret]; paymentIntentParams.paymentMethodParams = paymentMethodParams; // Submit the payment STPPaymentHandler *paymentHandler = [STPPaymentHandler sharedHandler]; [paymentHandler confirmPayment:paymentIntentParams withAuthenticationContext:self completion:^(STPPaymentHandlerActionStatus status, STPPaymentIntent *paymentIntent, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ switch (status) { case STPPaymentHandlerActionStatusFailed: { [self displayAlertWithTitle:@"Payment failed" message:error.localizedDescription ?: @"" restartDemo:NO]; break; } case STPPaymentHandlerActionStatusCanceled: { [self displayAlertWithTitle:@"Payment canceled" message:error.localizedDescription ?: @"" restartDemo:NO]; break; } case STPPaymentHandlerActionStatusSucceeded: { [self displayAlertWithTitle:@"Payment succeeded" message:paymentIntent.description ?: @"" restartDemo:YES]; break; } default: break; } }); }]; } # pragma mark STPAuthenticationContext - (UIViewController *)authenticationPresentingViewController { return self; } @end

If authentication is required by regulation such as Strong Customer Authentication, STPPaymentHandler presents view controllers using the STPAuthenticationContext passed in and walks the customer through that process. See Supporting 3D Secure Authentication on iOS to learn more.

If the payment succeeds, the completion handler is called with a status of .succeeded. If it fails, the status is .failed and you can display the error.localizedDescription to the user.

You can also check the status of a PaymentIntent in the Dashboard or by inspecting the status property on the object.

5 Test the integration

By this point you should have a basic card integration that collects card details and makes a payment.

There are several test cards you can use in test mode to make sure this integration is ready. Use them with any CVC, postal code, and future expiration date.

Number Description
4242424242424242 Succeeds and immediately processes the payment.
4000002500003155 Requires authentication. Stripe will trigger a modal asking for the customer to authenticate.
4000000000009995 Always fails with a decline code of insufficient_funds.

For the full list of test cards see our guide on testing.

Optional Handle post-payment events

Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Setting up your integration to listen for asynchronous events also makes it easier to accept more payment methods in the future. Check out our guide to payment methods to see the differences between all supported payment methods.

To closely control when funds move, you can manually authorize the payment and finalize it on your server. This integration is significantly different and has limitations.

Receive events and run business actions

Manually

Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.

View your test payments in the Dashboard

Custom code

Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.

Build a custom webhook

Prebuilt apps

Handle common business events, like shipping and inventory management, by integrating a partner application.

Browse shipping apps and extensions

Browse inventory management apps and extensions

See all partner solutions

See also

  • Accept Apple Pay
  • Save card details during payment
  • Learn more about the Payment Intents API

Collecting payments in your Android app consists of creating an object to track a payment on your server, collecting card information in your app, and submitting the payment to Stripe for processing.

Stripe uses this payment object, called a PaymentIntent, to track and handle all the states of the payment until it’s completed—even when the bank requires customer intervention, like two-factor authentication.

The steps in this guide are fully implemented on GitHub in the using-webhooks directory. Clone the repo and follow the instructions to run the demo app.

1 Set up Stripe Server-side Client-side

First, you need a Stripe account. Register now.

Server-side

This integration requires endpoints on your server that talk to the Stripe API. Use our official libraries for access to the Stripe API from your server:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

Client-side

The Android SDK is open source and fully documented.

To install the SDK, add stripe-android to the dependencies block of your app/build.gradle file:

build.gradle
apply plugin: 'com.android.application' android { ... } dependencies { // ... // Stripe Android SDK implementation 'com.stripe:stripe-android:16.1.1' }
apply plugin: 'com.android.application' android { ... } dependencies { // ... // Stripe Android SDK implementation 'com.stripe:stripe-android:16.1.1' }

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.

Configure the SDK with your Stripe publishable key so that it can make requests to the Stripe API, such as in your Application subclass:

Kotlin Java
import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext, "pk_test_TYooMQauvdEDq54NiTphI7jx" ) } }
import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext, "pk_test_TYooMQauvdEDq54NiTphI7jx" ) } }
import com.stripe.android.PaymentConfiguration; public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); PaymentConfiguration.init( getApplicationContext(), "pk_test_TYooMQauvdEDq54NiTphI7jx" ); } }
import com.stripe.android.PaymentConfiguration; public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); PaymentConfiguration.init( getApplicationContext(), "pk_test_TYooMQauvdEDq54NiTphI7jx" ); } }

Use your test mode keys while you test and develop, and your live mode keys before you publish your app.

Our code samples also use OkHttp and GSON to make HTTP requests to a server.

2 Create your checkout page Client-side

Want a prebuilt UI instead?

The Android Basic Integration features prebuilt, full size screens to collect payment information.

Securely collect card information on the client with CardInputWidget, a drop-in UI component provided by the SDK.

CardInputWidget performs on-the-fly validation and formatting.

Create an instance of the card component and a Pay button by adding the following to your checkout page’s layout:

activity_checkout.xml
View full sample
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="20dp" tools:context=".CheckoutActivityKotlin" tools:showIn="@layout/activity_checkout"> <!-- ... --> <com.stripe.android.view.CardInputWidget android:id="@+id/cardInputWidget" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="@string/pay" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/payButton" android:layout_marginTop="20dp" android:backgroundTint="@android:color/holo_green_light"/> <!-- ... --> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="20dp" tools:context=".CheckoutActivityKotlin" tools:showIn="@layout/activity_checkout"> <!-- ... --> <com.stripe.android.view.CardInputWidget android:id="@+id/cardInputWidget" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="@string/pay" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/payButton" android:layout_marginTop="20dp" android:backgroundTint="@android:color/holo_green_light"/> <!-- ... --> </LinearLayout>

Run your app, and make sure your checkout page shows the card component and pay button.

3 Create a PaymentIntent Server-side Client-side

Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.

Server-side

On your server, make an endpoint that creates a PaymentIntent with an amount and currency. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1099 \ -d currency=usd
server.rb
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', }) client_secret = payment_intent['client_secret'] # Pass the client secret to the client
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', }) client_secret = payment_intent['client_secret'] # Pass the client secret to the client
server.py
View full sample
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', ) client_secret = intent.client_secret # Pass the client secret to the client
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( amount=1099, currency='usd', ) client_secret = intent.client_secret # Pass the client secret to the client
index.php
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]); $client_secret = $intent->client_secret; // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'amount' => 1099, 'currency' => 'usd', ]); $client_secret = $intent->client_secret; // Pass the client secret to the client
Server.java
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setAmount(1099L) .setCurrency("usd") .build(); PaymentIntent intent = PaymentIntent.create(params); String clientSecret = intent.getClientSecret(); // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setAmount(1099L) .setCurrency("usd") .build(); PaymentIntent intent = PaymentIntent.create(params); String clientSecret = intent.getClientSecret(); // Pass the client secret to the client
server.js
View full sample
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', }); const clientSecret = paymentIntent.client_secret // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', }); const clientSecret = paymentIntent.client_secret // Pass the client secret to the client
Server.go
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params) // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(1099), Currency: stripe.String(string(stripe.CurrencyUSD)), } pi, _ := paymentintent.New(params) // Pass the client secret to the client
server.cs
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options); // Pass the client secret to the client
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { Amount = 1099, Currency = "usd", }; var service = new PaymentIntentService(); var paymentIntent = service.Create(options); // Pass the client secret to the client

Instead of passing the entire PaymentIntent object to your app, just return its client secret. The PaymentIntent’s client secret is a unique key that lets you confirm the payment and update card details on the client, without allowing manipulation of sensitive information, like payment amount.

Client-side

On the client, request a PaymentIntent from your server and store its client secret.

Kotlin Java
CheckoutActivity.kt
View full sample
class CheckoutActivity : AppCompatActivity() { private lateinit var paymentIntentClientSecret: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... startCheckout() } private fun startCheckout() { // Request a PaymentIntent from your server and store its client secret in paymentIntentClientSecret // Click Open on GitHub to see a full implementation } }
class CheckoutActivity : AppCompatActivity() { private lateinit var paymentIntentClientSecret: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... startCheckout() } private fun startCheckout() { // Request a PaymentIntent from your server and store its client secret in paymentIntentClientSecret // Click Open on GitHub to see a full implementation } }
CheckoutActivity.java
View full sample
public class CheckoutActivity extends AppCompatActivity { private String paymentIntentClientSecret; @Override public void onCreate(Bundle savedInstanceState) { // ... startCheckout(); } private void startCheckout() { // Request a PaymentIntent from your server and store its client secret in paymentIntentClientSecret // Click Open on GitHub to see a full implementation } }
public class CheckoutActivity extends AppCompatActivity { private String paymentIntentClientSecret; @Override public void onCreate(Bundle savedInstanceState) { // ... startCheckout(); } private void startCheckout() { // Request a PaymentIntent from your server and store its client secret in paymentIntentClientSecret // Click Open on GitHub to see a full implementation } }

4 Submit the payment to Stripe Client-side

When the customer taps the Pay button, confirm the PaymentIntent to complete the payment.

First, assemble a ConfirmPaymentIntentParams object with:

  1. The card component’s payment method details
  2. The PaymentIntent client secret from your server

Rather than sending the entire PaymentIntent object to the client, use its client secret. This is different from your API keys that authenticate Stripe API requests. The client secret is a string that lets your app access important fields from the PaymentIntent (e.g., status) while hiding sensitive ones (e.g., customer).

The client secret should still be handled carefully because it can complete the charge. Do not log it, embed it in URLs, or expose it to anyone but the customer.

Next, complete the payment by calling the stripe confirmPayment method.

Kotlin Java
CheckoutActivity.kt
View full sample
class CheckoutActivity : AppCompatActivity() { // ... private lateinit var paymentIntentClientSecret: String private lateinit var stripe: Stripe private fun startCheckout() { // ... // Hook up the pay button to the card widget and stripe instance val payButton: Button = findViewById(R.id.payButton) payButton.setOnClickListener { val params = cardInputWidget.paymentMethodCreateParams if (params != null) { val confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams(params, paymentIntentClientSecret) stripe = Stripe(applicationContext, PaymentConfiguration.getInstance(applicationContext).publishableKey) stripe.confirmPayment(this, confirmParams) } } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) val weakActivity = WeakReference<Activity>(this) // Handle the result of stripe.confirmPayment stripe.onPaymentResult(requestCode, data, object : ApiResultCallback<PaymentIntentResult> { override fun onSuccess(result: PaymentIntentResult) { val paymentIntent = result.intent val status = paymentIntent.status if (status == StripeIntent.Status.Succeeded) { val gson = GsonBuilder().setPrettyPrinting().create() displayAlert(weakActivity.get(), "Payment succeeded", gson.toJson(paymentIntent), restartDemo = true) } else { displayAlert(weakActivity.get(), "Payment failed", paymentIntent.lastPaymentError?.message ?: "") } } override fun onError(e: Exception) { displayAlert(weakActivity.get(), "Payment failed", e.toString()) } }) } }
class CheckoutActivity : AppCompatActivity() { // ... private lateinit var paymentIntentClientSecret: String private lateinit var stripe: Stripe private fun startCheckout() { // ... // Hook up the pay button to the card widget and stripe instance val payButton: Button = findViewById(R.id.payButton) payButton.setOnClickListener { val params = cardInputWidget.paymentMethodCreateParams if (params != null) { val confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams(params, paymentIntentClientSecret) stripe = Stripe(applicationContext, PaymentConfiguration.getInstance(applicationContext).publishableKey) stripe.confirmPayment(this, confirmParams) } } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) val weakActivity = WeakReference<Activity>(this) // Handle the result of stripe.confirmPayment stripe.onPaymentResult(requestCode, data, object : ApiResultCallback<PaymentIntentResult> { override fun onSuccess(result: PaymentIntentResult) { val paymentIntent = result.intent val status = paymentIntent.status if (status == StripeIntent.Status.Succeeded) { val gson = GsonBuilder().setPrettyPrinting().create() displayAlert(weakActivity.get(), "Payment succeeded", gson.toJson(paymentIntent), restartDemo = true) } else { displayAlert(weakActivity.get(), "Payment failed", paymentIntent.lastPaymentError?.message ?: "") } } override fun onError(e: Exception) { displayAlert(weakActivity.get(), "Payment failed", e.toString()) } }) } }
CheckoutActivity.java
View full sample
public class CheckoutActivity extends AppCompatActivity { // ... private String paymentIntentClientSecret; private Stripe stripe; private void startCheckout() { // ... // Hook up the pay button to the card widget and stripe instance Button payButton = findViewById(R.id.payButton); payButton.setOnClickListener((View view) -> { PaymentMethodCreateParams params = cardInputWidget.getPaymentMethodCreateParams(); if (params != null) { ConfirmPaymentIntentParams confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams(params, paymentIntentClientSecret); final Context context = getApplicationContext(); stripe = new Stripe( context, PaymentConfiguration.getInstance(context).getPublishableKey() ); stripe.confirmPayment(this, confirmParams); } }); } // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // Handle the result of stripe.confirmPayment stripe.onPaymentResult(requestCode, data, new PaymentResultCallback(this)); } // ... private static final class PaymentResultCallback implements ApiResultCallback<PaymentIntentResult> { @NonNull private final WeakReference<CheckoutActivity> activityRef; PaymentResultCallback(@NonNull CheckoutActivity activity) { activityRef = new WeakReference<>(activity); } @Override public void onSuccess(@NonNull PaymentIntentResult result) { final CheckoutActivity activity = activityRef.get(); if (activity == null) { return; } PaymentIntent paymentIntent = result.getIntent(); PaymentIntent.Status status = paymentIntent.getStatus(); if (status == PaymentIntent.Status.Succeeded) { // Payment completed successfully Gson gson = new GsonBuilder().setPrettyPrinting().create(); activity.displayAlert( "Payment completed", gson.toJson(paymentIntent), true ); } else if (status == PaymentIntent.Status.RequiresPaymentMethod) { // Payment failed activity.displayAlert( "Payment failed", Objects.requireNonNull(paymentIntent.getLastPaymentError()).getMessage(), false ); } } @Override public void onError(@NonNull Exception e) { final CheckoutActivity activity = activityRef.get(); if (activity == null) { return; } // Payment request failed – allow retrying using the same payment method activity.displayAlert("Error", e.toString(), false); } } }
public class CheckoutActivity extends AppCompatActivity { // ... private String paymentIntentClientSecret; private Stripe stripe; private void startCheckout() { // ... // Hook up the pay button to the card widget and stripe instance Button payButton = findViewById(R.id.payButton); payButton.setOnClickListener((View view) -> { PaymentMethodCreateParams params = cardInputWidget.getPaymentMethodCreateParams(); if (params != null) { ConfirmPaymentIntentParams confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams(params, paymentIntentClientSecret); final Context context = getApplicationContext(); stripe = new Stripe( context, PaymentConfiguration.getInstance(context).getPublishableKey() ); stripe.confirmPayment(this, confirmParams); } }); } // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // Handle the result of stripe.confirmPayment stripe.onPaymentResult(requestCode, data, new PaymentResultCallback(this)); } // ... private static final class PaymentResultCallback implements ApiResultCallback<PaymentIntentResult> { @NonNull private final WeakReference<CheckoutActivity> activityRef; PaymentResultCallback(@NonNull CheckoutActivity activity) { activityRef = new WeakReference<>(activity); } @Override public void onSuccess(@NonNull PaymentIntentResult result) { final CheckoutActivity activity = activityRef.get(); if (activity == null) { return; } PaymentIntent paymentIntent = result.getIntent(); PaymentIntent.Status status = paymentIntent.getStatus(); if (status == PaymentIntent.Status.Succeeded) { // Payment completed successfully Gson gson = new GsonBuilder().setPrettyPrinting().create(); activity.displayAlert( "Payment completed", gson.toJson(paymentIntent), true ); } else if (status == PaymentIntent.Status.RequiresPaymentMethod) { // Payment failed activity.displayAlert( "Payment failed", Objects.requireNonNull(paymentIntent.getLastPaymentError()).getMessage(), false ); } } @Override public void onError(@NonNull Exception e) { final CheckoutActivity activity = activityRef.get(); if (activity == null) { return; } // Payment request failed – allow retrying using the same payment method activity.displayAlert("Error", e.toString(), false); } } }

If authentication is required by regulation such as Strong Customer Authentication, the SDK presents additional activities and walks the customer through that process. See Supporting 3D Secure Authentication on Android to learn more.

When the payment completes, onSuccess is called and the value of the returned PaymentIntent’s status is Succeeded. Any other value indicates the payment was not successful. Inspect lastPaymentError to determine the cause.

You can also check the status of a PaymentIntent in the Dashboard or by inspecting the status property on the object.

5 Test the integration

By this point you should have a basic card integration that collects card details and makes a payment.

There are several test cards you can use in test mode to make sure this integration is ready. Use them with any CVC, postal code, and future expiration date.

Number Description
4242424242424242 Succeeds and immediately processes the payment.
4000002500003155 Requires authentication. Stripe will trigger a modal asking for the customer to authenticate.
4000000000009995 Always fails with a decline code of insufficient_funds.

For the full list of test cards see our guide on testing.

Optional Handle post-payment events

Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Setting up your integration to listen for asynchronous events also makes it easier to accept more payment methods in the future. Check out our guide to payment methods to see the differences between all supported payment methods.

To closely control when funds move, you can manually authorize the payment and finalize it on your server. This integration is significantly different and has limitations.

Receive events and run business actions

Manually

Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.

View your test payments in the Dashboard

Custom code

Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.

Build a custom webhook

Prebuilt apps

Handle common business events, like shipping and inventory management, by integrating a partner application.

Browse shipping apps and extensions

Browse inventory management apps and extensions

See all partner solutions

See also

  • Accept Google Pay
  • Save card details during payment
  • Learn more about the Payment Intents API

Collect Stripe payments in whichever publishing or e-commerce platform you use, with a Stripe plugin created by our partners. The Stripe developer community uses Stripe’s APIs to create plugins and extensions.

If you use a third-party platform to build and maintain a website, you can add Stripe payments with a plugin.

All plugins on this page are ready for Strong Customer Authentication (SCA).

Get started

Try one of our recommended solutions for your platform:

  • Magento: E-commerce platform creating distinct digital retail experiences
  • WordPress: Website creation tool and content management system
  • Drupal: Open-source content management system
  • Joomla: Open-source content management system

Don’t see your platform? Check out our full list of partners for a solution to your use case.

Questions? Contact us.
Developer tutorials on YouTube.
You can unsubscribe at any time. Read our privacy policy.