Starting a Subscription with Checkout

    Use Stripe Checkout to sell your products or services that require recurring payments.

    Checkout creates a secure, Stripe-hosted payment page that lets you collect payments with just a few lines of code. Checkout is also flexible for when you need additional options such as defining product amounts dynamically, two-step card payments (separate authorization and capture), or adding line items to subscriptions.

    Choosing your integration

    Client-only Integration

    For simple subscriptions
    A depiction of product creation in the Stripe Dashboard
    • Define subscription plans through the Dashboard or API
    • Collect billing address details
    • Cannot associate payments with existing Customers
    • Cannot use separate authorization and capture for card payments
    • Cannot add extra line items to the order
    • No Connect support

    Client and Server Integration

    For subscriptions and more
    A sample of Stripe Checkout Session creation code
    • Define subscription plans through the Dashboard or API
    • Collect billing address details
    • Can associate payments with existing Customers
    • Can use separate authorization and capture for card payments
    • Add extra line items to the order
    • Works with Connect

    Client-only integration

    With the client-only integration, you create reucrring products and pricing plans directly in the Stripe Dashboard and embed a Checkout button for those items on your website. Follow these steps to create a Checkout page for recurring payments:

    1. Enable Checkout in the Dashboard
    2. Create recurring products in the Dashboard
    3. Generate the Checkout button

    Step 1: Enable Checkout in the Dashboard

    To begin using Checkout, log into the Stripe Dashboard and navigate to the Checkout settings. From here you can enable the client integration and customize the look and feel of your checkout page.

    Step 2: Create recurring products in the Dashboard

    Before you start configuring products, make sure you are in test mode by toggling the View test data button at the bottom of the Stripe Dashboard. Next, define the goods and services you plan to sell. To create a new product:

    • Navigate to the Products section in the Dashboard
    • Click New
    • Click Recurring products
    • Add a pricing plan

    You can define multiple pricing plans with different parameters for each recurring product. Each plan has a generated ID that you can use as a reference during the checkout process. You can also define trial periods for each pricing plan.

    Step 3: Generate the Checkout button

    To use Checkout on your website, you must add a snippet of code that includes the desired plan ID. You can use the Dashboard to generate the necessary code, or you can write it yourself.

    In the Products section of the Dashboard, select the product that you want to sell. In the product detail view, click the Use with Checkout button next to a plan to generate a code snippet that you can add to your website.

    When your customer successfully completes their payment, they are redirected to the success URL that you specified when configuring the code snippet. Typically, this is a page on your website that informs the customer that their payment was successful. When your customer clicks on your logo in a Checkout Session without completing a payment, Checkout redirects them back to your website by navigating to the cancel URL you specified when configuring the code snippet. Typically, this is the page on your website that the customer viewed prior to redirecting to Checkout.

    Copy and paste the snippet into the body of a web page to add a payment button that, when clicked, redirects the customer to Checkout. You can include multiple checkout buttons on the same page by modifying the dashboard-generated snippets to use unique button IDs.

    Checkout relies on Stripe.js. To get started, include the following script tag on your website—it should always be loaded directly from https://js.stripe.com:

    <script src="https://js.stripe.com/v3/"></script>
    

    Next, create an instance of the Stripe object by providing your publishable API key as the first parameter:

    var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    
    const stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    

    When your customer is ready to pay, call redirectToCheckout to begin the checkout process. Pass it an array of objects containing the plan ID, quantity, a success URL, and a cancel URL.

    When your customer successfully completes their payment, they are redirected to the success URL that you specified when calling redirectToCheckout. Typically, this is a page on your website that informs the customer that their payment was successful. When your customer clicks on your logo in a Checkout Session without completing a payment, Checkout redirects them back to your website by navigating to the cancel URL that you specified when calling redirectToCheckout. Typically, this is the page on your website which the customer viewed prior to redirecting to Checkout.

    stripe.redirectToCheckout({
      items: [{
        // Replace with the ID of your plan
        plan: 'plan_123'
        quantity: 1,
      }],
      successUrl: 'https://example.com/success',
      cancelUrl: 'https://example.com/cancel',
    }).then(function (result) {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });
    
    stripe.redirectToCheckout({
      items: [{
        // Replace with the ID of your plan
        plan: 'plan_123'
        quantity: 1,
      }],
      successUrl: 'https://example.com/success',
      cancelUrl: 'https://example.com/cancel',
    }).then((result) => {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });
    

    The snippet calls a function that, when invoked, redirects the customer to Checkout.

    Fulfill the customer’s purchase when you have a successful payment. You can use webhooks to fulfill the purchase when the checkout.session.completed event triggers. Next, see how to handle actions after the payment.

    Client and server integration

    The client and server integration uses a Session to represent each time your customer is in the checkout flow. Unlike the client-only integration, the client and server integration does not require using the Dashboard to pre-define payment options or domains. You can also use advanced configuration options such as supplying payment or subscription metadata.

    Follow these steps to create a Checkout page for recurring payments:

    1. Create a subscription
    2. Create a Checkout Session on your server
    3. Redirect to Checkout

    Step 1: Create a subscription

    You first need to create a Product (an item that your customers can subscribe to) and a Plan that determines the pricing. You can either create a product and a plan through the API or through the Dashboard. If you have an existing Plan you’d like to use, skip this step.

    Step 2: Create a Checkout Session on your server

    Create a Session with subscription_data and the plan ID from the previous step or the ID of an existing Plan.

    When your customer successfully completes their payment, they are redirected to the success_url, a page on your website that informs the customer that their payment was successful. When your customer clicks on your logo in a Checkout Session without completing a payment, Checkout redirects them back to your website by navigating to the cancel_url. Typically, this is the page on your website that the customer viewed prior to redirecting to Checkout.

    curl https://api.stripe.com/v1/checkout/sessions \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d "payment_method_types[]=card" \
      -d "subscription_data[items][][plan]=plan_123" \
      -d success_url="https://example.com/success" \
      -d cancel_url="https://example.com/cancel"
    
    # Set your secret key: remember to change this 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'],
      subscription_data: {
        items: [{
          plan: 'plan_123',
        }],
      },
      success_url: 'https://example.com/success',
      cancel_url: 'https://example.com/cancel',
    )
    
    # Set your secret key: remember to change this 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'],
      subscription_data={
        'items': [{
          'plan': 'plan_123',
        }],
      },
      success_url='https://example.com/success',
      cancel_url='https://example.com/cancel',
    )
    
    // Set your secret key: remember to change this 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'],
      'subscription_data' => [
        'items' => [[
          'plan' => 'plan_123',
        ]],
      ],
      'success_url' => 'https://example.com/success',
      'cancel_url' => 'https://example.com/cancel',
    ]);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Map<String, Object> params = new HashMap<String, Object>();
    
    ArrayList<String> paymentMethodTypes = new ArrayList<>();
    paymentMethodTypes.add("card");
    params.put("payment_method_types", paymentMethodTypes);
    
    HashMap<String, Object> subscriptionData = new HashMap<String, Object>();
    HashMap<String, Object> items = new HashMap<String, Object>();
    HashMap<String, Object> item = new HashMap<String, Object>();
    item.put("plan", "plan_123");
    items.put("0", item);
    subscriptionData.put("items", items);
    params.put("subscription_data", subscriptionData);
    
    params.put("success_url", "https://example.com/success");
    params.put("cancel_url", "https://example.com/cancel");
    
    Session session = Session.create(params);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    (async () => {
      const session = await stripe.checkout.sessions.create({
        payment_method_types: ['card'],
        subscription_data: {
          items: [{
            plan: 'plan_123',
          }],
        },
        success_url: 'https://example.com/success',
        cancel_url: 'https://example.com/cancel',
      });
    })();
    
    // Set your secret key: remember to change this 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",
        }),
        SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{
            Items: []*stripe.CheckoutSessionSubscriptionDataItemsParams{
                &stripe.CheckoutSessionSubscriptionDataItemsParams{
                    Plan: stripe.String("plan_123"),
                },
            },
        },
        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 change this 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",
        },
        SubscriptionData = new SessionSubscriptionDataOptions {
            Items = new List<SessionSubscriptionDataItemOptions> {
                new SessionSubscriptionDataItemOptions {
                    PlanId = "plan_123",
                },
            },
        },
        SuccessUrl = "https://example.com/success",
        CancelUrl = "https://example.com/cancel",
    };
    
    var service = new SessionService();
    Session session = service.Create(options);
    

    Note that unlike the client-only integration, sessions created via the client and server integration do not support creating subscriptions with trial_period_days set at the plan level. Instead, pass the desired trial length as the value of the subscription_data.trial_period_days argument.

    Creating a Checkout Session returns a Session id which is important for the following steps. Note that Checkout Sessions expire 24 hours after creation.

    Step 3: Redirect to Checkout

    Checkout relies on Stripe.js, Stripe’s foundational JavaScript library for building payment flows. Include the following script tag on your website—always load it directly from https://js.stripe.com:

    <script src="https://js.stripe.com/v3/"></script>
    

    Next, create an instance of the Stripe object by providing your publishable API key as the first parameter:

    var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    
    const stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    

    To use Checkout on your website, you must add a snippet of code that includes the Session id from step two. When your customer is ready to pay, call redirectToCheckout and provide the Session id as a parameter to begin the payment process.

    stripe.redirectToCheckout({
      // Make the id field from the Checkout Session creation API response
      // available to this file, so you can provide it as parameter here
      // instead of the {{CHECKOUT_SESSION_ID}} placeholder.
      sessionId: '{{CHECKOUT_SESSION_ID}}'
    }).then(function (result) {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });
    stripe.redirectToCheckout({
      // Make the id field from the Checkout Session creation API response
      // available to this file, so you can provide it as parameter here
      // instead of the {{CHECKOUT_SESSION_ID}} placeholder.
      sessionId: '{{CHECKOUT_SESSION_ID}}'
    }).then((result) => {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });

    This code is typically invoked from an event handler that triggers in response to an action taken by your customer, such as clicking on a payment button.

    Once payment is successful, you should fulfill the customer’s purchase. You can use webhooks to fulfill the purchase when the checkout.session.completed event triggers. For more details about handling purchase fulfillment with Checkout, see after the payment.

    Next steps

    Now that you have a working integration, learn how to handle actions after the payment and the options available for customizing Checkout.

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page