> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration when using Stripe-hosted checkout

## Overview

Stigg can redirect customers to a **Stripe-hosted checkout page** to collect payment details, while Stigg continues to manage the subscription lifecycle. This is the lowest-effort way to collect payment, since Stripe builds and hosts the entire payment page - there's no need to build a custom checkout form with [Stripe Elements](/documentation/native-integrations/billing/stripe/integration-when-using-stripe-elements-for-checkout) or embed the [Stigg checkout widget](/documentation/snap-in-widgets/checkout).

To use it, pass a `checkoutOptions` object when calling [Provision Subscription](/api-and-sdks/api-reference/rest/subscriptions-create). If the customer doesn't have a payment method on file and the plan requires payment, Stigg creates a Stripe Checkout Session and returns its URL so your application can redirect the customer to it.

<Note>
  Before implementing this flow, review the [checkout experience comparison](/guides/i-want-to/add-a-checkout-experience-to-my-application) - a Stripe-hosted checkout page can only be used to provision a new subscription, not to update an existing one (upgrades/downgrades of an existing paid subscription require a different checkout experience).
</Note>

## Before we begin

In order to complete this guide in your application code, please make sure that you have:

* [Modeled your pricing in Stigg](/documentation/modeling-your-pricing-in-stigg/overview)
* A Stigg environment that's [integrated with Stripe](/documentation/native-integrations/billing/stripe/overview)
* [Installed the Stigg Node.js server SDK](/api-and-sdks/integration/backend/nodejs#installing-the-sdk)
* [A Stigg **full access** key](/api-and-sdks/integration/backend/nodejs#retrieving-the-full-access-key)
* [Provisioned a customer](/guides/quick-start-guides/provisioning-customers)

## How it works

When [provisioning a subscription](/guides/quick-start-guides/creating-subscriptions), Stigg checks whether the environment has a billing integration and whether the customer already has a payment method on file. Only when payment is required and no payment method exists does Stigg return a checkout URL instead of an active subscription:

<img src="https://mintcdn.com/stigg/imNqv5Llzt3VPpq8/images/6998840-image.png?fit=max&auto=format&n=imNqv5Llzt3VPpq8&q=85&s=a6de269cbdf29b2bcd0a07199baa80f0" alt="" width="965" height="1039" data-path="images/6998840-image.png" />

## Provisioning a subscription with checkoutOptions

Pass `checkoutOptions` on the same call you'd otherwise use to [provision a subscription](/guides/quick-start-guides/creating-subscriptions). At minimum, `successUrl` and `cancelUrl` are required:

<CodeGroup>
  ```typescript TypeScript theme={null}
  const result = await stiggClient.provisionSubscription({
      customerId: 'customer-demo-01',
      planId: 'plan-basic',
      billingPeriod: 'MONTHLY', // mandatory when using checkoutOptions
      checkoutOptions: {
          successUrl: "https://your-app.com/checkout/success", // mandatory, redirect URL after a successful checkout
          cancelUrl: "https://your-app.com/checkout/cancel",   // mandatory, redirect URL if the customer cancels checkout
          allowPromoCodes: true,        // optional, allow the customer to enter a promo code on checkout
          allowTaxIdCollection: true,   // optional, allow the customer to enter a tax ID to be shown on the invoice
          collectBillingAddress: true,  // optional, collect a billing address for the invoice
          collectPhoneNumber: true,     // optional, collect a phone number on checkout
          referenceId: 'your-internal-id', // optional, reconcile the checkout session with internal systems, such as referral programs
      },
  });
  ```
</CodeGroup>

<Note>
  `billingPeriod` is mandatory when `checkoutOptions` is provided - Stigg needs it to price the checkout session. The full list of `provisionSubscription` parameters is available in the [Node.js SDK reference](/api-and-sdks/integration/backend/nodejs#provisioning-subscriptions) and the [REST API reference](/api-and-sdks/api-reference/rest/subscriptions-create).
</Note>

## Redirecting the customer to checkout

When payment is required, the result of `provisionSubscription` includes a `checkoutUrl` instead of an active subscription. Redirect the customer's browser to that URL to complete payment on Stripe's hosted page:

<CodeGroup>
  ```typescript TypeScript theme={null}
  if (result.status === 'PAYMENT_REQUIRED' && result.checkoutUrl) {
    // e.g. res.redirect(result.checkoutUrl) on the server,
    // or window.location.href = result.checkoutUrl on the client
  }
  ```
</CodeGroup>

The customer enters their payment details entirely on Stripe's page - your application never handles card data.

## What happens after checkout

### Successful payment

Once the customer completes payment, Stripe redirects them to `successUrl` and Stigg automatically creates the subscription and grants the associated entitlements. Stigg also fires the [`subscription.created`](/documentation/native-integrations/webhooks/events) webhook.

On the `successUrl` page, call `refresh()` to re-fetch the current customer data and entitlements on the client:

<CodeGroup>
  ```typescript TypeScript theme={null}
  await stiggClient.refresh();
  ```
</CodeGroup>

### Customer cancels or abandons checkout

No subscription is created in Stigg unless the customer completes payment - `provisionSubscription` only returns a `checkoutUrl`, without a subscription. If the customer clicks Stripe's back/cancel link, they're redirected to `cancelUrl` with no subscription ever having been created in Stigg. The same applies if the customer simply closes the tab without completing checkout, or if the Stripe Checkout Session expires (24 hours after creation, by default).

<Note>
  Because no subscription exists until checkout completes, avoid granting entitlements based on the `provisionSubscription` call itself - wait for the [`subscription.created`](/documentation/native-integrations/webhooks/events) webhook before granting access.
</Note>

### Payment is declined during checkout

Card declines and other in-session payment errors (for example, insufficient funds or a failed 3D Secure challenge) are handled entirely by Stripe's hosted checkout page - Stripe surfaces the error to the customer and lets them retry with a different payment method without leaving the page. Stigg isn't notified of these in-page retries; it only receives a result once the session succeeds or expires.

### Failed recurring payments

The behavior above applies only to the initial checkout. Once the subscription is active, a failed *renewal* charge instead fires the [`customer.payment_failed`](/documentation/native-integrations/webhooks/events) webhook so you can start dunning or notify the customer.

## Related articles

<Card title="Add a checkout experience to my application" href="/guides/i-want-to/add-a-checkout-experience-to-my-application" icon="cart-shopping" horizontal />

<Card title="Provisioning subscriptions" href="/guides/quick-start-guides/creating-subscriptions" icon="rocket" horizontal />

<Card title="Integration when using Stripe Elements for checkout" href="/documentation/native-integrations/billing/stripe/integration-when-using-stripe-elements-for-checkout" icon="stripe" horizontal />
