# Accept a payment Securely accept payments online. ## Start here: Install agent skills Stripe recommends using official skills to integrate with the API using best practices. Follow the instructions below to learn how. **Tip: Use curl instead of Fetch tools.** Skills are detailed 10–20 KB markdown files. Fetch tools summarize them. `curl -sL` guarantees the full content. **Using `npx skills`**: Check if `npx` is installed on the system. If `npx` is available, run `npx skills add https://docs.stripe.com --list` to list available skills, then run `npx skills add https://docs.stripe.com --yes --skill <--skill other-skills>` to install individual skills. **If `npx skills` isn’t available**: You can use curl to fetch the index of available skills, what they do, and their files from `https://docs.stripe.com/.well-known/skills/index.json`. To download a skill and its related files, use curl to download them from `https://docs.stripe.com/.well-known/skills/`. For this article, we recommend using these skills: `stripe-best-practices` Instructions for LLMs: Stripe recommends using the Checkout Sessions API with the Payment Element over Payment Intents for most integrations. Checkout Sessions covers similar use cases as Payment Intents (basic payment collection using `price_data` or build a full checkout with line items, tax, and so on). Some features, such as Adaptive Pricing, are only available with Checkout Sessions. Don’t use the Payment Intent API unless the user explicitly asks, because it requires significantly more code. Learn more about Elements with the Checkout Sessions API: https://docs.stripe.com/payments/quickstart-checkout-sessions. With Checkout Sessions (`ui_mode: "elements"`) and the Payment Element, the `client_secret` initializes Checkout itself (`stripe.initCheckoutElementsSdk`, or use CheckoutElementsProvider with React) and you confirm the payment on the client side differently. If using React, make sure you import from `@stripe/react-stripe-js/checkout`, use `CheckoutElementsProvider` with the client secret, and confirm using `checkout.confirm`. If using HTML, make sure you use `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");` and confirm with `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();`. Coding agents should install the Stripe CLI (`npm i -g @stripe/cli`) and run the command `stripe sandbox create --help` to provision an anonymous Stripe sandbox with working API keys. No account registration required. Build a payment form or use a prebuilt checkout page to start accepting online payments. # Full embedded page Embed a prebuilt payment form on your site using [Stripe Checkout](https://docs.stripe.com/payments/checkout.md). See how this integration [compares to Stripe’s other integration types](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability). #### Integration effort Complexity: 2/5 #### Integration type Embed prebuilt payment form on your site #### UI customization Limited customization - 20 preset fonts - 3 preset border radius - Custom background and border color - Custom logo Use the [branding settings](https://dashboard.stripe.com/settings/branding/checkout) in the Stripe Dashboard to match Checkout to your site design. First, [register](https://dashboard.stripe.com/register) for a Stripe account. Use our official libraries to access the Stripe API from your application: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Create a Checkout Session [Server-side] From your server, create a *Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription) and set the [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) to `embedded_page`. 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?payment-ui=checkout&ui=embedded-page#return-page) and other options for [customizing redirect behavior](https://docs.stripe.com/payments/checkout/custom-success-page.md?payment-ui=embedded-page). After you create the Checkout Session, use the `client_secret` returned in the response to [mount Checkout](https://docs.stripe.com/payments/accept-a-payment.md#mount-checkout). #### Ruby ```ruby # This example sets up an endpoint using the Sinatra framework. require 'json' require 'sinatra' require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-checkout-session' do session = client.v1.checkout.sessions.create({ line_items: [{ price_data: { currency: 'usd', product_data: { name: 'T-shirt', }, unit_amount: 2000, }, quantity: 1, }], mode: 'payment',ui_mode: 'embedded_page', return_url: 'https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}' }) {clientSecret: session.client_secret}.to_json end ``` ## Mount Checkout [Client-side] #### HTML + JS Checkout is available as part of [Stripe.js](https://docs.stripe.com/js.md). 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 const stripe = Stripe('<>'); 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.createEmbeddedCheckoutPage({ fetchClientSecret, }); // Mount Checkout checkout.mount('#checkout'); } ``` #### React 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 = React.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. ### Customize appearance Customize Checkout to match the design of your site by setting the background color, button color, border radius, and fonts in your account’s [branding settings](https://dashboard.stripe.com/settings/branding). By default, Checkout renders with no external padding or margin. We recommend using a container element such as a div to apply your desired margin (for example, 16px on all sides). ## Show a return page After your customer attempts payment, Stripe redirects them to a return page that you host on your site. When you created the Checkout Session, you specified the URL of the return page in the [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) parameter. Read more about other options for [customizing redirect behavior](https://docs.stripe.com/payments/checkout/custom-success-page.md?payment-ui=embedded-page). When rendering your return page, retrieve the Checkout Session status using the Checkout Session ID in the URL. Handle the result according to the session status as follows: - `complete`: The payment succeeded. Use the information from the Checkout Session to render a success page. - `open`: The payment failed or was canceled. Remount Checkout so that your customer can try again. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') get '/session-status' do session = client.v1.checkout.sessions.retrieve(params[:session_id]) {status: session.status, customer_email: session.customer_details.email}.to_json end ``` ```javascript const session = await fetch(`/session_status?session_id=${session_id}`) if (session.status == 'open') { // Remount embedded Checkout } else if (session.status == 'complete') { // Show success page // Optionally use session.payment_status or session.customer_email // to customize the success page } ``` #### Redirect-based payment methods During payment, some payment methods redirect the customer to an intermediate page, such as a bank authorization page. When they complete that page, Stripe redirects them to your return page. Learn more about [redirect-based payment methods and redirect behavior](https://docs.stripe.com/payments/checkout/custom-success-page.md?payment-ui=embedded-page#redirect-based-payment-methods). ## Handle post-payment events Stripe sends a [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) event when a customer completes a Checkout Session payment. Use the [Dashboard webhook tool](https://dashboard.stripe.com/webhooks) or follow the [webhook guide](https://docs.stripe.com/webhooks/quickstart.md) to receive and handle these events, which might trigger you to: - Send an order confirmation email to your customer. - Log the sale in a database. - Start a shipping workflow. Listen for these events rather than waiting for your customer to be redirected back to your website. Triggering fulfillment only from your Checkout landing page is unreliable. Setting up your integration to listen for asynchronous events allows you to accept [different types of payment methods](https://stripe.com/payments/payment-methods-guide) with a single integration. Learn more in our [fulfillment guide for Checkout](https://docs.stripe.com/checkout/fulfillment.md). Handle the following events when collecting payments with the Checkout: | Event | Description | Action | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | Sent when a customer successfully completes a Checkout Session. | Send the customer an order confirmation and *fulfill* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) their order. | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | Sent when a payment made with a delayed payment method, such as ACH direct debt, succeeds. | Send the customer an order confirmation and *fulfill* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) their order. | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | Sent when a payment made with a delayed payment method, such as ACH direct debt, fails. | Notify the customer of the failure and bring them back on-session to attempt payment again. | ## Test your integration To test your embedded payment form integration: 1. Create an embedded Checkout Session and mount the payment form on your page. 2. Fill out the payment details with a method from the table below. - Enter any future date for card expiry. - Enter any 3-digit number for CVC. - Enter any billing postal code. 3. Click **Pay**. You’re redirected to your `return_url`. 4. Go to the Dashboard and look for the payment on the [Transactions page](https://dashboard.stripe.com/test/payments?status%5B0%5D=successful). If your payment succeeded, you’ll see it in that list. 5. Click your payment to see more details, like a Checkout summary with billing information and the list of purchased items. You can use this information to fulfill the order. Learn more about [testing your integration](https://docs.stripe.com/testing.md). #### Cards | Card number | Scenario | How to test | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | 4242424242424242 | The card payment succeeds and doesn’t require authentication. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. | | 4000002500003155 | The card payment requires *authentication* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. | | 4000000000009995 | The card is declined with a decline code like `insufficient_funds`. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. | | 6205500000000000004 | The UnionPay card has a variable length of 13-19 digits. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. | #### Wallets | Payment method | Scenario | How to test | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Alipay | Your customer successfully pays with a redirect-based and [immediate notification](https://docs.stripe.com/payments/payment-methods.md#payment-notification) payment method. | Choose any redirect-based payment method, fill out the required details, and confirm the payment. Then click **Complete test payment** on the redirect page. | #### Bank redirects | Payment method | Scenario | How to test | | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | BECS Direct Debit | Your customer successfully pays with BECS Direct Debit. | Fill out the form using the account number `900123456` and BSB `000000`. The confirmed PaymentIntent initially transitions to `processing`, then transitions to the `succeeded` status 3 minutes later. | | BECS Direct Debit | Your customer’s payment fails with an `account_closed` error code. | Fill out the form using the account number `111111113` and BSB `000000`. | | Bancontact, EPS, iDEAL, and Przelewy24 | Your customer fails to authenticate on the redirect page for a redirect-based and immediate notification payment method. | Choose any redirect-based payment method, fill out the required details, and confirm the payment. Then click **Fail test payment** on the redirect page. | | Pay by Bank | Your customer successfully pays with a redirect-based and [delayed notification](https://docs.stripe.com/payments/payment-methods.md#payment-notification) payment method. | Choose the payment method, fill out the required details, and confirm the payment. Then click **Complete test payment** on the redirect page. | | Pay by Bank | Your customer fails to authenticate on the redirect page for a redirect-based and delayed notification payment method. | Choose the payment method, fill out the required details, and confirm the payment. Then click **Fail test payment** on the redirect page. | | BLIK | BLIK payments fail in a variety of ways—immediate failures (for example, the code is expired or invalid), delayed errors (the bank declines) or timeouts (the customer didn’t respond in time). | Use email patterns to [simulate the different failures.](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Bank debits | Payment method | Scenario | How to test | | ----------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SEPA Direct Debit | Your customer successfully pays with SEPA Direct Debit. | Fill out the form using the account number `AT321904300235473204`. The confirmed PaymentIntent initially transitions to processing, then transitions to the succeeded status three minutes later. | | SEPA Direct Debit | Your customer’s payment intent status transitions from `processing` to `requires_payment_method`. | Fill out the form using the account number `AT861904300235473202`. | #### Vouchers | Payment method | Scenario | How to test | | -------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | Boleto, OXXO | Your customer pays with a Boleto or OXXO voucher. | Select Boleto or OXXO as the payment method and submit the payment. Close the dialog after it appears. | See [Testing](https://docs.stripe.com/testing.md) for additional information to test your integration. ## Optional: Add more payment methods By default, Checkout [supports many payment methods](https://docs.stripe.com/payments/payment-methods/integration-options.md#choose-how-to-add-payment-methods). You have to take additional steps to enable and display some methods, like Apple Pay, Google Pay, and buy now, pay later methods. ### Apple Pay and Google Pay To accept payments from Apple Pay and Google Pay, you must: - Enable them in your [payment methods settings](https://dashboard.stripe.com/settings/payment_methods). Apple Pay is enabled by default. - Serve your application over HTTPS in development and production. - [Register your domain](https://docs.stripe.com/payments/payment-methods/pmd-registration.md). - Serve your application over HTTPS in development and production. You can use a service like [ngrok](https://ngrok.com/) to serve your application for local testing. In addition, a Checkout Session only displays the Apple Pay button to customers when *all* of the following conditions are true: - The customer’s device is running macOS version 17 or later or iOS version 17 or later. - The customer is using the Safari browser. - The customer has a valid card registered with Apple Pay. A Checkout Session only displays the Google Pay button to customers when *all* of the following conditions are true: - The customer’s device is running Chrome 61 or newer. - The customer has a valid card registered with Google Pay. > #### Regional testing > > Stripe Checkout doesn’t support Apple Pay or Google Pay for Stripe accounts or customers in India. If your IP address is in India, you can’t test your Apple Pay or Google Pay integration, even if the Stripe account is outside India. ## Optional: Create products and prices Before you create a Checkout Session, you can create *Products* (Products represent what your business sells—whether that's a good or a service) and *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) upfront. Use products to represent different physical goods or levels of service, and *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) to represent each product’s pricing. You can [set up your Checkout Session](https://docs.stripe.com/payments/checkout/pay-what-you-want.md) to accept tips and donations, or sell pay-what-you-want products and services. For example, you can create a T-shirt as a product with a price of 20 USD. This allows you to update and add prices without needing to change the details of your underlying products. You can either create products and prices with the Stripe Dashboard or API. Learn more about [how products and prices work](https://docs.stripe.com/products-prices/how-products-and-prices-work.md). #### API The API only requires a `name` to create a [Product](https://docs.stripe.com/api/products.md). Checkout displays the product `name`, `description`, and `images` that you supply. ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ -d name=T-shirt ``` Next, create a [Price](https://docs.stripe.com/api/prices.md) to define how much to charge for your product. This includes how much the product costs and what currency to use. ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d "product={{PRODUCT_ID}}" \ -d unit_amount=2000 \ -d currency=usd ``` #### Dashboard > Copy products created in a sandbox to live mode so that you don’t need to re-create them. In the Product detail view in the Dashboard, click **Copy to live mode** in the upper right corner. You can copy the same sandbox product to live mode more than once. Each copy creates a separate live product, and subsequent updates to the sandbox product aren’t reflected in existing live copies. Make sure you’re in a sandbox by clicking **Sandboxes** within the Dashboard account picker. Next, define the items you want to sell. To create a new product and price: - Navigate to the [Products](https://dashboard.stripe.com/test/products) section in the Dashboard. - Click **Add product**. - Select **One time** when setting the price. Checkout displays the product name, description, and images that you supply. Each price you create has an ID. When you create a Checkout Session, reference the price ID and quantity. If you’re selling in multiple currencies, make your Price *multi-currency* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration). Checkout automatically [determines the customer’s local currency](https://docs.stripe.com/payments/checkout/localize-prices/manual-currency-prices.md) and presents that currency if the Price supports it. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d mode=payment \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" ``` ## 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](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email) when creating a Checkout Session. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ --data-urlencode "customer_email=customer@example.com" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" ``` ## 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. ### 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. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d customer_creation=always \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "payment_intent_data[setup_future_usage]=off_session" ``` 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/custom-components.md#customize-text) 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/link/checkout-link.md) 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. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d customer_creation=always \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "saved_payment_method_options[payment_method_save]=enabled" ``` 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. > #### Use the Accounts v2 API to represent customers > > The Accounts v2 API is generally available for Connect users, and in public preview for other Stripe users. If you’re part of the Accounts v2 preview, you need to specify a [specify a preview version](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in your code. > > To request access to the Accounts v2 preview, > > For most use cases, we recommend [modeling your customers as customer-configured Account objects](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md) instead of using [Customer](https://docs.stripe.com/api/customers.md) objects. 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 an object to represent your customer (either a customer-configured `Account` or a `Customer`). To save 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`. 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). ### Let customers remove saved payment methods To let your customers remove a saved payment method so it doesn’t resurface for future payments, use [saved_payment_method_options.payment_method_remove](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_remove) when creating a Checkout Session. #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "saved_payment_method_options[payment_method_remove]=enabled" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d customer={{CUSTOMER_ID}} \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "saved_payment_method_options[payment_method_remove]=enabled" ``` The customer can’t remove a payment method if it’s tied to an active subscription and the customer doesn’t have a default payment method saved for invoice and subscription payments. ## Optional: Customer account management [No code] Let your customers [manage](https://docs.stripe.com/customer-management.md) their own accounts by sharing a link to your *customer portal* (The customer portal is a secure, Stripe-hosted page that lets your customers manage their subscriptions and billing details). The customer portal lets customers log in with their email to manage subscriptions, update payment methods, and so on. ## Optional: Separate authorization and capture [Server-side] Stripe supports two-step card payments so you can first authorize a card, then capture funds later. When Stripe authorizes a payment, the card issuer guarantees the funds and places a hold for the payment amount on the customer’s card. You then have a certain amount of time to capture the funds, [depending on the card](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md#auth-capture-limitations)). If you don’t capture the payment before the authorization expires, the payment is canceled and the issuer releases the held funds. 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 might 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 Stripe authorized the customer’s payment method. 2. Consult your inventory management system to confirm that the item is still available. 3. Update your inventory management system to indicate that a customer has purchased the item. 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](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-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 curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_intent_data[capture_method]=manual" \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" ``` To capture an uncaptured payment, you can use either the [Dashboard](https://dashboard.stripe.com/test/payments?status%5B%5D=uncaptured) or the [capture](https://docs.stripe.com/api/payment_intents/capture.md) endpoint. Programmatically capturing payments requires access to the PaymentIntent created during the Checkout Session, which you can get from the [Session](https://docs.stripe.com/api/payment_intents/capture.md) object. ## Optional: Order fulfillment Learn how to [programmatically get a notification](https://docs.stripe.com/checkout/fulfillment.md) whenever a customer pays. ## See also - [Add discounts](https://docs.stripe.com/payments/checkout/discounts.md) - [Collect taxes](https://docs.stripe.com/payments/checkout/taxes.md) - [Collect tax IDs](https://docs.stripe.com/tax/checkout/tax-ids.md) - [Add shipping](https://docs.stripe.com/payments/collect-addresses.md?payment-ui=checkout) - [Customize your branding](https://docs.stripe.com/payments/checkout/customization.md)