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

# Checkout Sessions API

> Create a time-bounded payment session that activates a subscription on successful payment.

A Checkout Session represents a single payment attempt. Call `POST /v1/checkout/sessions`, get back a payment URL, redirect your customer, and Flexprice activates the subscription once payment is confirmed.

## Session lifecycle

| Status      | Meaning                                                      |
| ----------- | ------------------------------------------------------------ |
| `initiated` | Session created; payment provider call in progress           |
| `pending`   | Payment URL returned; awaiting customer payment              |
| `completed` | Payment confirmed; subscription activated, invoice finalized |
| `failed`    | Payment failed or provider cancelled the link                |
| `expired`   | Session timed out without payment                            |

## Create a Checkout Session

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/checkout/sessions \
  -H "Authorization: Bearer <API_KEY>" \
  -H "X-Environment-ID: <ENVIRONMENT_ID>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_external_id": "cust_abc123",
    "action": "create_subscription",
    "payment_provider": "razorpay",
    "configuration": {
      "create_subscription_params": {
        "plan_id": "plan_xyz",
        "currency": "INR",
        "billing_period": "monthly"
      }
    },
    "success_url": "https://app.example.com/checkout/success",
    "failure_url": "https://app.example.com/checkout/failure",
    "cancel_url": "https://app.example.com/checkout/cancel",
    "idempotency_key": "order_unique_ref_001"
  }'
```

**Response (201):**

```json theme={null}
{
  "id": "chk_01HXXX",
  "customer_id": "cust_01HABC",
  "action": "create_subscription",
  "checkout_status": "pending",
  "payment_provider": "razorpay",
  "expires_at": "2024-01-01T12:15:00Z",
  "payment_action": {
    "type": "payment_link",
    "url": "https://rzp.io/l/XXXXXXX"
  }
}
```

Redirect the customer to `payment_action.url`. Each session has its own link. Do not reuse URLs across sessions.

### Request fields

| Field                                                     | Required | Description                                                                                               |
| --------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `customer_external_id`                                    | Yes      | Your identifier for the customer. Must already exist in Flexprice.                                        |
| `action`                                                  | Yes      | Billing action to perform. `create_subscription` is supported.                                            |
| `payment_provider`                                        | Yes      | Payment gateway to use. See [Choose your provider](/docs/checkout/overview#choose-your-payment-provider). |
| `configuration.create_subscription_params.plan_id`        | Yes      | The plan to subscribe the customer to.                                                                    |
| `configuration.create_subscription_params.currency`       | Yes      | Billing currency (e.g., `INR`, `USD`).                                                                    |
| `configuration.create_subscription_params.billing_period` | No       | `monthly`, `quarterly`, `annual`, etc. Defaults to the plan's period.                                     |
| `configuration.create_subscription_params.start_date`     | No       | Subscription start date. Defaults to now.                                                                 |
| `success_url`                                             | No       | Where to redirect after successful payment.                                                               |
| `failure_url`                                             | No       | Where to redirect after a failed payment.                                                                 |
| `cancel_url`                                              | No       | Where to redirect if the customer cancels.                                                                |
| `idempotency_key`                                         | No       | Prevents duplicate sessions on retry. A duplicate key for an active session returns 409.                  |

## Get a Checkout Session

```bash theme={null}
curl https://api.flexprice.io/v1/checkout/sessions/<SESSION_ID> \
  -H "Authorization: Bearer <API_KEY>" \
  -H "X-Environment-ID: <ENVIRONMENT_ID>"
```

Use this to confirm `checkout_status` on your redirect pages before showing the customer a result.

## Delete a Checkout Session

```bash theme={null}
curl -X DELETE https://api.flexprice.io/v1/checkout/sessions/<SESSION_ID> \
  -H "Authorization: Bearer <API_KEY>" \
  -H "X-Environment-ID: <ENVIRONMENT_ID>"
```

Sessions in a terminal state (`completed`, `failed`, `expired`) cannot be deleted.

## Webhook events

Subscribe to these in **Settings > Webhooks** to drive fulfillment from your backend.

| Event                        | Fired when                                                |
| ---------------------------- | --------------------------------------------------------- |
| `checkout.session.initiated` | Session created and payment URL returned                  |
| `checkout.session.completed` | Payment confirmed; subscription active, invoice finalized |
| `checkout.session.failed`    | Payment failed or provider cancelled                      |
| `checkout.session.expired`   | Session timed out without payment                         |

<Note>
  Safe to receive the same event twice. If your payment provider delivers `payment_link.paid` more than once, Flexprice ignores the duplicate. Your webhook handler should also be idempotent for the same reason.
</Note>

## Requirements

**Customer must exist first.** The `customer_external_id` must refer to a customer already in Flexprice. Create them at sign-up if they don't exist yet.

**Plan must have a non-zero charge.** Checkout requires a payable invoice amount to generate a payment link. Plans with only free or zero-amount charges will cause session creation to fail.

**Idempotency on retry.** If your create call times out, retry with the same `idempotency_key`. You'll get back the existing session instead of a duplicate.

<CardGroup cols={2}>
  <Card icon="credit-card" href="/docs/checkout/razorpay-checkout" title="Razorpay Setup">
    Configure the webhook events Razorpay needs to send Flexprice.
  </Card>

  <Card icon="list-check" href="/docs/checkout/implementation-guide" title="Implementation Guide">
    Full end-to-end integration with code examples.
  </Card>
</CardGroup>

**API References**

* [Create a Checkout Session](/api-reference/checkout/create-checkout-session)
* [Get a Checkout Session](/api-reference/checkout/get-checkout-session)
* [Delete a Checkout Session](/api-reference/checkout/delete-checkout-session)
