--- title: Save payment details during payment subtitle: Learn how to accept a payment and save your customer's payment details for future purchases. route: /payments/checkout/save-during-payment --- # Save payment details during payment Learn how to accept a payment and save your customer's payment details for future purchases. # Stripe-hosted page > This is a Stripe-hosted page for when payment-ui is stripe-hosted. View the original doc at https://docs.stripe.com/payments/checkout/save-during-payment?payment-ui=stripe-hosted. Use [Stripe Checkout](https://docs.stripe.com/payments/checkout.md) for a fast, low-code integration that allows your customers to save their payment details for future purchases. ## Set up Stripe Use our official libraries to access the Stripe API from your application: ```bash \# Available as a gem sudo gem install stripe ``` ```ruby \# If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ```bash \# Install through pip pip3 install --upgrade stripe ``` ```bash \# Or find the Stripe package on http://pypi.python.org/pypi/stripe/ ``` ```python \# 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>=5.0.0 ``` ```bash \# Install the PHP library with Composer composer require stripe/stripe-php ``` ```bash \# Or download the source directly: https://github.com/stripe/stripe-php/releases ``` ```java /* For Gradle, add the following dependency to your build.gradle and replace 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:29.0.0" ``` ```xml com.stripe stripe-java 29.0.0 ``` ```bash \# 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 ``` ```bash \# Install with npm npm install stripe --save ``` ```bash \# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v82 ``` ```go // Then import the package import ( "github.com/stripe/stripe-go/v82" ) ``` ```bash \# Install with dotnet dotnet add package Stripe.net dotnet restore ``` ```bash \# Or install with NuGet Install-Package Stripe.net ``` ## Create a customer To set a card up for future payments, you must attach it to a *Customer*. Create a Customer object when your customer creates an account with your business. Customer objects allow for reusing payment methods and tracking across multiple payments. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new CustomerCreateOptions { Name = "Jenny Rosen", Email = "jennyrosen@example.com" }; var service = new CustomerService(); Customer customer = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CustomerParams{ Name: stripe.String("Jenny Rosen"), Email: stripe.String("jennyrosen@example.com"), }; result, err := customer.New(params); ``` ```java Stripe.apiKey = "<>"; CustomerCreateParams params = CustomerCreateParams.builder().setName("Jenny Rosen").setEmail("jennyrosen@example.com").build(); Customer customer = Customer.create(params); ``` ```node const stripe = require('stripe')('<>'); const customer = await stripe.customers.create({ name: 'Jenny Rosen', email: 'jennyrosen@example.com', }); ``` ```python import stripe stripe.api_key = "<>" customer = stripe.Customer.create( name="Jenny Rosen", email="jennyrosen@example.com", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $customer = $stripe->customers->create([ 'name' => 'Jenny Rosen', 'email' => 'jennyrosen@example.com', ]); ``` ```ruby Stripe.api_key = '<>' customer = Stripe::Customer.create({ name: 'Jenny Rosen', email: 'jennyrosen@example.com', }) ``` Successful creation returns the [Customer](https://docs.stripe.com/api/customers/object.md) object. You can inspect the object for the customer `id` and store the value in your database for later retrieval. You can find these customers in the [Customers](https://dashboard.stripe.com/customers) page in the Dashboard. ## Create a Checkout Session Add a checkout button to your website that calls a server-side endpoint to create a [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md). You can also create a Checkout Session for an [existing customer](https://docs.stripe.com/payments/existing-customers.md?platform=web&ui=stripe-hosted), allowing you to prefill Checkout fields with known contact information and unify your purchase history for that customer. ```html Buy cool new product
``` 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](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items) to charge * Currencies to use You must populate `success_url` with the URL value of a page on your website that Checkout returns your customer to after they complete the payment. You can optionally also provide a `cancel_url` value of a page on your website that Checkout returns your customer to if they terminate the payment process before completion. Checkout Sessions expire 24 hours after creation by default. After creating a Checkout Session, redirect your customer to the [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) returned in the response. ```ruby \# This example sets up an endpoint using the Sinatra framework. # Watch this video to get started: https://youtu.be/8aA9Enb8NVc. require 'json' require 'sinatra' require 'stripe' <> post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', # These placeholder URLs will be replaced in a following step. success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) redirect session.url, 303 end ``` ```python \# 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, redirect app = Flask(__name__) stripe.api_key = '<>' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode='payment', success_url='http://localhost:4242/success', cancel_url='http://localhost:4242/cancel', ) return redirect(session.url, code=303) if __name__== '__main__': app.run(port=4242) ``` ```php >'); $checkout_session = $stripe->checkout->sessions->create([ 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'http://localhost:4242/success', 'cancel_url' => 'http://localhost:4242/cancel', ]); header("HTTP/1.1 303 See Other"); header("Location: " . $checkout_session->url); ?> ``` ```java 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.stripe.Stripe; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionCreateParams; public class Server { public static void main(String[] args) { port(4242); Stripe.apiKey = "<>"; post("/create-checkout-session", (request, response) -> { SessionCreateParams params = SessionCreateParams.builder() .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("http://localhost:4242/success") .setCancelUrl("http://localhost:4242/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); response.redirect(session.getUrl(), 303); return ""; }); } } ``` ```javascript // 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(); const stripe = require('stripe')('<>') app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }, ], mode: 'payment', success_url: 'http://localhost:4242/success', cancel_url: 'http://localhost:4242/cancel', }); res.redirect(303, session.url); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`)); ``` ```go package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v{{golang.major_version}}" "github.com/stripe/stripe-go/v{{golang.major_version}}/checkout/session" ) // This example sets up an endpoint using the Echo framework. // Watch this video to get started: https://youtu.be/ePmEVBu8w6Y. func main() { stripe.Key = "<>" e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.POST("/create-checkout-session", createCheckoutSession) e.Logger.Fatal(e.Start("localhost:4242")) } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ 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("http://localhost:4242/success"), CancelURL: stripe.String("http://localhost:4242/cancel"), } s, _ := session.New(params) if err != nil { return err } return c.Redirect(http.StatusSeeOther, s.URL) } ``` ```dotnet // 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() { StripeConfiguration.ApiKey = "<>"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { LineItems = new List { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "http://localhost:4242/success", CancelUrl = "http://localhost:4242/cancel", }; var service = new SessionService(); Session session = service.Create(options); Response.Headers.Add("Location", session.Url); return new StatusCodeResult(303); } } } ``` ### Payment methods By default, Stripe enables cards and other common payment methods. You can turn individual payment methods on or off in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). In Checkout, Stripe evaluates the currency and any restrictions, then dynamically presents the supported payment methods to the customer. To see how your payment methods appear to customers, enter a transaction ID or set an order amount and currency in the Dashboard. You can enable Apple Pay and Google Pay in your [payment methods settings](https://dashboard.stripe.com/settings/payment_methods). By default, Apple Pay is enabled and Google Pay is disabled. However, in some cases Stripe filters them out even when they’re enabled. We filter Google Pay if you [enable automatic tax](https://docs.stripe.com/tax/checkout.md) without collecting a shipping address. Checkout’s Stripe-hosted pages don’t need integration changes to enable Apple Pay or Google Pay. Stripe handles these payments the same way as other card payments. ### Confirm your endpoint Confirm your endpoint is accessible by starting your web server (for example, `localhost:4242`) and running the following command: ```bash curl -X POST -is "http://localhost:4242/create-checkout-session" -d "" ``` You should see a response in your terminal that looks like this: ```bash HTTP/1.1 303 See Other Location: https://checkout.stripe.com/c/pay/cs_test_... ... ``` ### Testing You should now have a working checkout button that redirects your customer to Stripe Checkout. 1. Click the checkout button. 1. You’re redirected to the Stripe Checkout payment form. If your integration isn’t working: 1. Open the Network tab in your browser’s developer tools. 1. Click the checkout button and confirm it sent an XHR request to your server-side endpoint (`POST /create-checkout-session`). 1. Verify the request is returning a 200 status. 1. Use `console.log(session)` inside your button click listener to confirm the correct data returned. For more information about configuring and testing your hosted Checkout integration, see [Accept a Payment](https://docs.stripe.com/payments/accept-a-payment.md?platform=web&ui=hosted-form). ## Save payment method After setting up your hosted Checkout integration, choose a configuration for your integration to save the payment methods used by your customers. By default, payment methods used to make a one-time payment with Checkout aren’t available for future use. ### Save payment methods to charge them off-session You can set Checkout to save payment methods used to make a one-time payment by passing the [payment_intent_data.setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-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. If you use Checkout in `subscription` mode, Stripe automatically saves the payment method to charge it for subsequent payments. Card payment methods saved to customers using either `setup_future_usage` or `subscription` mode don’t appear for return purchases in Checkout (more on this below). We recommend using [custom text](https://docs.stripe.com/payments/checkout/customization/policies.md) to link out to any relevant terms regarding the usage of saved payment information. Global privacy laws are complicated and nuanced. We recommend contacting your legal and privacy team prior to implementing [setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_intent_data-setup_future_usage) because it might implicate your existing privacy compliance framework. Refer to [the guidance issued by the European Protection Board](https://edpb.europa.eu/system/files/2021-05/recommendations022021_on_storage_of_credit_card_data_en_1.pdf) to learn more about saving payment details. ### Save payment methods to prefill them in Checkout By default, Checkout uses [Link](https://docs.stripe.com/payments/checkout/customization/behavior.md#link) to provide your customers with the option to securely save and reuse their payment information. If you prefer to manage payment methods yourself, use [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) when creating a Checkout Session to let your customers save their payment methods for future purchases in Checkout. Passing this parameter in either [payment](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) or [subscription](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) mode displays an optional checkbox to let customers explicitly save their payment method for future purchases. When customers check this checkbox, Checkout saves the payment method with [allow_redisplay: always](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay). Checkout uses this parameter to determine whether a payment method can be prefilled on future purchases. When using `saved_payment_method_options.payment_method_save`, you don’t need to pass in `setup_future_usage` to save the payment method. Using [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) requires a `Customer`. To save a new customer, set the Checkout Session’s [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md) to `always`. Otherwise, the session doesn’t save the customer or the payment method. If `payment_method_save` isn’t passed in or if the customer doesn’t agree to save the payment method, Checkout still saves payment methods created in `subscription` mode or using `setup_future_usage`. These payment methods have an `allow_redisplay` value of `limited`, which prevents them from being prefilled for returning purchases and allows you to comply with card network rules and data protection regulations. Learn how to [change the default behavior enabled by these modes](https://support.stripe.com/questions/prefilling-saved-cards-in-checkout) and how to change or override `allow_redisplay` behavior. You can use Checkout to save cards and other payment methods to charge them off-session, but Checkout only prefills saved cards. Learn how to [prefill saved cards](https://support.stripe.com/questions/prefilling-saved-cards-in-checkout). To save a payment method without an initial payment, [use Checkout in setup mode](https://docs.stripe.com/payments/save-and-reuse.md?platform=checkout). # Embedded form > This is a Embedded form for when payment-ui is embedded-form. View the original doc at https://docs.stripe.com/payments/checkout/save-during-payment?payment-ui=embedded-form. Use [Stripe Checkout](https://docs.stripe.com/payments/checkout.md) to embed a prebuilt payment form on your website that allows your customers to save their payment details for future purchases. ## Set up Stripe Use our official libraries to access the Stripe API from your application: ```bash \# Available as a gem sudo gem install stripe ``` ```ruby \# If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ```bash \# Install through pip pip3 install --upgrade stripe ``` ```bash \# Or find the Stripe package on http://pypi.python.org/pypi/stripe/ ``` ```python \# 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>=5.0.0 ``` ```bash \# Install the PHP library with Composer composer require stripe/stripe-php ``` ```bash \# Or download the source directly: https://github.com/stripe/stripe-php/releases ``` ```java /* For Gradle, add the following dependency to your build.gradle and replace 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:29.0.0" ``` ```xml com.stripe stripe-java 29.0.0 ``` ```bash \# 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 ``` ```bash \# Install with npm npm install stripe --save ``` ```bash \# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v82 ``` ```go // Then import the package import ( "github.com/stripe/stripe-go/v82" ) ``` ```bash \# Install with dotnet dotnet add package Stripe.net dotnet restore ``` ```bash \# Or install with NuGet Install-Package Stripe.net ``` ## Create a customer To set a card up for future payments, you must attach it to a *Customer*. Create a Customer object when your customer creates an account with your business. Customer objects allow for reusing payment methods and tracking across multiple payments. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new CustomerCreateOptions { Name = "Jenny Rosen", Email = "jennyrosen@example.com" }; var service = new CustomerService(); Customer customer = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CustomerParams{ Name: stripe.String("Jenny Rosen"), Email: stripe.String("jennyrosen@example.com"), }; result, err := customer.New(params); ``` ```java Stripe.apiKey = "<>"; CustomerCreateParams params = CustomerCreateParams.builder().setName("Jenny Rosen").setEmail("jennyrosen@example.com").build(); Customer customer = Customer.create(params); ``` ```node const stripe = require('stripe')('<>'); const customer = await stripe.customers.create({ name: 'Jenny Rosen', email: 'jennyrosen@example.com', }); ``` ```python import stripe stripe.api_key = "<>" customer = stripe.Customer.create( name="Jenny Rosen", email="jennyrosen@example.com", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $customer = $stripe->customers->create([ 'name' => 'Jenny Rosen', 'email' => 'jennyrosen@example.com', ]); ``` ```ruby Stripe.api_key = '<>' customer = Stripe::Customer.create({ name: 'Jenny Rosen', email: 'jennyrosen@example.com', }) ``` Successful creation returns the [Customer](https://docs.stripe.com/api/customers/object.md) object. You can inspect the object for the customer `id` and store the value in your database for later retrieval. You can find these customers in the [Customers](https://dashboard.stripe.com/customers) page in the Dashboard. ## Create a Checkout Session From your server, create a *Checkout Session* and set the [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) to `embedded`. You can configure the [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) with [line items](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items) to include and options such as [currency](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-currency). You can also create a Checkout Session for an [existing customer](https://docs.stripe.com/payments/existing-customers.md?platform=web&ui=stripe-hosted), allowing you to prefill Checkout fields with known contact information and unify your purchase history for that customer. To return customers to a custom page that you host on your website, specify that page’s URL in the [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) parameter. Include the `{CHECKOUT_SESSION_ID}` template variable in the URL to retrieve the session’s status on the return page. Checkout automatically substitutes the variable with the Checkout Session ID before redirecting. Read more about [configuring the return page](https://docs.stripe.com/payments/accept-a-payment.md?platform=web&ui=embedded-form#return-page) and other options for [customizing redirect behavior](https://docs.stripe.com/payments/checkout/custom-success-page.md?payment-ui=embedded-form). After you create the Checkout Session, use the `client_secret` returned in the response to [mount Checkout](#mount-checkout). ```ruby \# This example sets up an endpoint using the Sinatra framework. # To learn more about Sinatra, watch this video: https://youtu.be/8aA9Enb8NVc. require 'json' require 'sinatra' require 'stripe' <> post '/create-checkout-session' do session = Stripe::Checkout::Session.create({ line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}' }) {clientSecret: session.client_secret}.to_json end ``` ```python \# This example sets up an endpoint using the Flask framework. # To learn more about Flask, watch this video: https://youtu.be/7Ul1vfsmsDck. import os import stripe from flask import Flask, redirect app = Flask(__name__) stripe.api_key = '<>' @app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): session = stripe.checkout.Session.create( line_items = [{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': 'T-shirt', }, 'unit_amount': 2000, }, 'quantity': 1, }], mode = 'payment', ui_mode = 'embedded', return_url = 'https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}', ) return jsonify(clientSecret=session.client_secret) if __name__ == '__main__': app.run(port=4242) ``` ```php '<>' ]); $checkout_session = $stripe->checkout->sessions->create([ 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'T-shirt', ], 'unit_amount' => 2000, ], 'quantity' => 1, ]], 'mode' => 'payment', 'ui_mode' => 'embedded', 'return_url' => 'https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}', ]); echo json_encode(array('clientSecret' => $checkout_session->client_secret)); ?> ``` ```java 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 { public static void main(String[] args) { port(4242); Stripe.apiKey = "<>"; Gson gson = new Gson(); post("/create-checkout-session", (request, response) -> { SessionCreateParams params = SessionCreateParams.builder() .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.EMBEDDED) .setReturnUrl("https://example.com/return?session_id={CHECKOUT_SESSION_ID}") .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 map = new HashMap(); map.put("clientSecret", session.getRawJsonObject().getAsJsonPrimitive("client_secret").getAsString()); return map; }, gson::toJson); } } ``` ```javascript // This example sets up an endpoint using the Express framework. // To learn more about Express, watch this video: https://youtu.be/rPR2aJ6XnAc. const express = require('express'); const app = express(); const stripe = require('stripe')('<>'); app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}' }); res.send({clientSecret: session.client_secret}); }); app.listen(4242, () => console.log(`Listening on port ${4242}!`)); ``` ```go package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/stripe/stripe-go/v{{golang.major_version}}" "github.com/stripe/stripe-go/v{{golang.major_version}}/checkout/session" ) // This example sets up an endpoint using the Echo framework. // To learn more about Echo, watch this video: https://youtu.be/ePmEVBu8w6Y. func main() { stripe.Key = "<>" 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 CheckoutData struct { ClientSecret string `json:"clientSecret"` } func createCheckoutSession(c echo.Context) (err error) { params := &stripe.CheckoutSessionParams{ Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String("embedded"), ReturnURL: stripe.String("https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}"), 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), }, }, } s, _ := session.New(params) if err != nil { return err } data := CheckoutData{ ClientSecret: s.ClientSecret, } return c.JSON(http.StatusOK, data) } ``` ```dotnet // This example sets up an endpoint using the ASP.NET MVC framework. // To learn more about ASP.NET MVC, watch this video: 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() { StripeConfiguration.ApiKey = "<>"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { LineItems = new List { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", UiMode = "embedded", ReturnUrl = "https://example.com/return?session_id={CHECKOUT_SESSION_ID}", }; var service = new SessionService(); Session session = service.Create(options); return Json(new {clientSecret = session.ClientSecret}); } } } ``` ## Mount Checkout Checkout is available as part of [Stripe.js](https://docs.stripe.com/js). Include the Stripe.js script on your page by adding it to the head of your HTML file. Next, create an empty DOM node (container) to use for mounting. ```html
``` Initialize Stripe.js with your publishable API key. Create an asynchronous `fetchClientSecret` function that makes a request to your server to create the Checkout Session and retrieve the client secret. Pass this function into `options` when you create the Checkout instance: ```javascript // Initialize Stripe.js initialize(); // Fetch Checkout Session and retrieve the client secret async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Initialize Checkout const checkout = await stripe.initEmbeddedCheckout({ fetchClientSecret, }); // Mount Checkout checkout.mount('#checkout'); } ``` Install [react-stripe-js](https://docs.stripe.com/sdks/stripejs-react.md) and the Stripe.js loader from npm: ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` To use the Embedded Checkout component, create an `EmbeddedCheckoutProvider`. Call `loadStripe` with your publishable API key and pass the returned `Promise` to the provider. Create an asynchronous `fetchClientSecret` function that makes a request to your server to create the Checkout Session and retrieve the client secret. Pass this function into the `options` prop accepted by the provider. ```jsx import * as React from 'react'; import {loadStripe} from '@stripe/stripe-js'; import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-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_123'); const App = () => { const fetchClientSecret = useCallback(() => { // Create a Checkout Session return fetch("/create-checkout-session", { method: "POST", }) .then((res) => res.json()) .then((data) => data.clientSecret); }, []); const options = {fetchClientSecret}; return (
) } ``` Checkout renders in an iframe that securely sends payment information to Stripe over an HTTPS connection. Avoid placing Checkout within another iframe because some payment methods require redirecting to another page for payment confirmation. ## Save payment method After setting up your embedded Checkout integration, choose a configuration for your integration to save the payment methods used by your customers. By default, payment methods used to make a one-time payment with Checkout aren’t available for future use. ### Save payment methods to charge them off-session You can set Checkout to save payment methods used to make a one-time payment by passing the [payment_intent_data.setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-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. If you use Checkout in `subscription` mode, Stripe automatically saves the payment method to charge it for subsequent payments. Card payment methods saved to customers using either `setup_future_usage` or `subscription` mode don’t appear for return purchases in Checkout (more on this below). We recommend using [custom text](https://docs.stripe.com/payments/checkout/customization/policies.md) to link out to any relevant terms regarding the usage of saved payment information. Global privacy laws are complicated and nuanced. We recommend contacting your legal and privacy team prior to implementing [setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_intent_data-setup_future_usage) because it might implicate your existing privacy compliance framework. Refer to [the guidance issued by the European Protection Board](https://edpb.europa.eu/system/files/2021-05/recommendations022021_on_storage_of_credit_card_data_en_1.pdf) to learn more about saving payment details. ### Save payment methods to prefill them in Checkout By default, Checkout uses [Link](https://docs.stripe.com/payments/checkout/customization/behavior.md#link) to provide your customers with the option to securely save and reuse their payment information. If you prefer to manage payment methods yourself, use [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) when creating a Checkout Session to let your customers save their payment methods for future purchases in Checkout. Passing this parameter in either [payment](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) or [subscription](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) mode displays an optional checkbox to let customers explicitly save their payment method for future purchases. When customers check this checkbox, Checkout saves the payment method with [allow_redisplay: always](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay). Checkout uses this parameter to determine whether a payment method can be prefilled on future purchases. When using `saved_payment_method_options.payment_method_save`, you don’t need to pass in `setup_future_usage` to save the payment method. Using [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) requires a `Customer`. To save a new customer, set the Checkout Session’s [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md) to `always`. Otherwise, the session doesn’t save the customer or the payment method. If `payment_method_save` isn’t passed in or if the customer doesn’t agree to save the payment method, Checkout still saves payment methods created in `subscription` mode or using `setup_future_usage`. These payment methods have an `allow_redisplay` value of `limited`, which prevents them from being prefilled for returning purchases and allows you to comply with card network rules and data protection regulations. Learn how to [change the default behavior enabled by these modes](https://support.stripe.com/questions/prefilling-saved-cards-in-checkout) and how to change or override `allow_redisplay` behavior. You can use Checkout to save cards and other payment methods to charge them off-session, but Checkout only prefills saved cards. Learn how to [prefill saved cards](https://support.stripe.com/questions/prefilling-saved-cards-in-checkout). To save a payment method without an initial payment, [use Checkout in setup mode](https://docs.stripe.com/payments/save-and-reuse.md?platform=checkout). # Embedded components > This is a Embedded components for when payment-ui is embedded-components. View the original doc at https://docs.stripe.com/payments/checkout/save-during-payment?payment-ui=embedded-components. Support for saved payment methods using Elements and the Checkout Sessions API only includes cards. It doesn’t support other saved payment methods, such as bank accounts. ## Enable saved payment methods To allow a customer to save their payment method for future use, specify the [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) parameter when creating the Checkout Session. Saving a payment method requires a [Customer](https://docs.stripe.com/api/customers/object.md). Pass an existing [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer), or, to create a new customer, set the Checkout Session’s [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation) to `always`. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 2 }, }, Mode = "payment", UiMode = "custom", CustomerCreation = "always", SavedPaymentMethodOptions = new Stripe.Checkout.SessionSavedPaymentMethodOptionsOptions { PaymentMethodSave = "enabled", }, }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(2), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), CustomerCreation: stripe.String(string(stripe.CheckoutSessionCustomerCreationAlways)), SavedPaymentMethodOptions: &stripe.CheckoutSessionSavedPaymentMethodOptionsParams{ PaymentMethodSave: stripe.String(string(stripe.CheckoutSessionSavedPaymentMethodOptionsPaymentMethodSaveEnabled)), }, }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(2L).build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.CUSTOM) .setCustomerCreation(SessionCreateParams.CustomerCreation.ALWAYS) .setSavedPaymentMethodOptions( SessionCreateParams.SavedPaymentMethodOptions.builder() .setPaymentMethodSave( SessionCreateParams.SavedPaymentMethodOptions.PaymentMethodSave.ENABLED ) .build() ) .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ line_items: [ { price: '<>', quantity: 2, }, ], mode: 'payment', ui_mode: 'custom', customer_creation: 'always', saved_payment_method_options: { payment_method_save: 'enabled', }, }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( line_items=[{"price": "<>", "quantity": 2}], mode="payment", ui_mode="custom", customer_creation="always", saved_payment_method_options={"payment_method_save": "enabled"}, ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'line_items' => [ [ 'price' => '<>', 'quantity' => 2, ], ], 'mode' => 'payment', 'ui_mode' => 'custom', 'customer_creation' => 'always', 'saved_payment_method_options' => ['payment_method_save' => 'enabled'], ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ line_items: [ { price: '<>', quantity: 2, }, ], mode: 'payment', ui_mode: 'custom', customer_creation: 'always', saved_payment_method_options: {payment_method_save: 'enabled'}, }) ``` After you create the Checkout Session, use the [client secret](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) returned in the response to [build your checkout page](https://docs.stripe.com/checkout/custom/quickstart.md). ## Collect consent Global privacy laws are complicated and nuanced. Before implementing the ability to store customer payment method details, work with your legal team to make sure that it complies with your privacy and compliance framework. In most cases, you must collect a customer’s consent before you save their payment methods. The following example shows how to obtain consent using a checkbox. ```html
``` ```jsx import React from 'react'; type Props = { savePaymentMethod: boolean; onSavePaymentMethodChange: (save: boolean) => void; } const ConsentCollection = (props: Props) => { const handleChange = (e: React.ChangeEvent) => { props.onSavePaymentMethodChange(e.target.checked); }; return ( ); }; export default ConsentCollection; ``` Indicate to Stripe whether your customer has provided consent when you call [confirm](https://docs.stripe.com/js/custom_checkout/confirm) by passing the `savePaymentMethod` parameter. When you save a customer’s payment details, you’re responsible for complying with all applicable laws, regulations, and network rules. ```js stripe.initCheckout({fetchClientSecret}).then((checkout) => { const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); const checkbox = document.getElementById('save-payment-method-checkbox'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; const savePaymentMethod = checkbox.checked; checkout.confirm({savePaymentMethod}).then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); }); ``` ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js'; type Props = { savePaymentMethod: boolean; } const PayButton = (props: Props) => { const {confirm} = useCheckout(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); const handleClick = () => { setLoading(true); confirm({savePaymentMethod: props.savePaymentMethod}).then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## Reuse a previously saved payment method You can redisplay previously saved payment methods for your customer to use during checkout. ### Identify your customer Each saved payment method is linked to a [Customer](https://docs.stripe.com/api/customers/object.md) object. Before creating the Checkout Session, authenticate your customer, and pass the corresponding [Customer ID](https://docs.stripe.com/api/customers/object.md#customer_object-id) to the Checkout Session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 2 }, }, Mode = "payment", UiMode = "custom", Customer = "<>", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(2), }, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), Customer: stripe.String("<>"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(2L).build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.CUSTOM) .setCustomer("<>") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ line_items: [ { price: '<>', quantity: 2, }, ], mode: 'payment', ui_mode: 'custom', customer: '<>', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( line_items=[{"price": "<>", "quantity": 2}], mode="payment", ui_mode="custom", customer="<>", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'line_items' => [ [ 'price' => '<>', 'quantity' => 2, ], ], 'mode' => 'payment', 'ui_mode' => 'custom', 'customer' => '<>', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ line_items: [ { price: '<>', quantity: 2, }, ], mode: 'payment', ui_mode: 'custom', customer: '<>', }) ``` ### Render saved payment methods Use the [savedPaymentMethods](https://docs.stripe.com/js/custom_checkout/session_object#custom_checkout_session_object-savedPaymentMethods) array on the front end to render the customer’s available payment methods. The `savedPaymentMethods` array includes only the payment methods that have [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) set to `always`. Follow the steps to [collecting consent](#collect-consent) from your customer, which ensures that `allow_redisplay` is properly set. ```html
``` ```js stripe.initCheckout({fetchClientSecret}).then((checkout) => { const container = document.getElementById('saved-payment-methods'); checkout.session().savedPaymentMethods.forEach((pm) => { const label = document.createElement('label'); const radio = document.createElement('input'); radio.type = 'radio'; radio.value = pm.id; label.appendChild(radio); label.appendChild(document.createTextNode(`Card ending in ${pm.card.last4}`)); container.appendChild(label); }); }); ``` ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js'; type Props = { selectedPaymentMethod: string | null; onSelectPaymentMethod: (paymentMethod: string) => void; }; const PaymentMethods = (props: Props) => { const {savedPaymentMethods} = useCheckout(); const handleOptionChange = (e: React.ChangeEvent) => { props.onSelectPaymentMethod(e.target.value); }; return (
{savedPaymentMethods.map((pm) => ( ))}
); }; export default PaymentMethods; ``` ### Confirm with a saved payment method When your customer has selected a saved payment method and is ready to complete checkout, call [confirm](https://docs.stripe.com/js/custom_checkout/confirm), passing in the [paymentMethod](https://docs.stripe.com/js/custom_checkout/confirm#custom_checkout_session_confirm-options-paymentMethod) ID. ```html ``` ```js stripe.initCheckout({fetchClientSecret}).then((checkout) => { const button = document.getElementById('pay-button'); button.addEventListener('click', () => { checkout.confirm({paymentMethod: selectedPaymentMethod}).then((result) => { if (result.error) { // Confirmation failed. Display the error message. } }); }); }); ``` ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js'; type Props = { selectedPaymentMethod: string | null; } const PayButton = (props: Props) => { const {confirm} = useCheckout(); const [loading, setLoading] = React.useState(false); const handleClick = () => { setLoading(true); confirm({paymentMethod: props.selectedPaymentMethod}).then((result) => { if (result.error) { // Confirmation failed. Display the error message. } setLoading(false); }) }; return ( ) }; export default PayButton; ```