---
title: "Create checkout session"
method: POST
path: "/checkout/sessions"
tags: ["Checkout"]
---

# Create checkout session

`POST /checkout/sessions`

## Request body

- CreateCheckoutSessionRequest
  - `action` 'create_subscription' | 'modify_subscription' | 'wallet_topup', required
  - `cancel_url` string
  - `configuration` TypesCheckoutConfiguration
    - `create_subscription_params` TypesCreateSubscriptionParams
      - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
      - `currency` string
      - `end_date` string, date-time
      - `lookup_key` string
      - `metadata` object
      - `plan_id` string
      - `start_date` string, date-time
    - `modify_subscription_params` TypesModifySubscriptionParams
      - `line_item_modifications` TypesModifySubscriptionLineItem[]
        - `effective_date` string, date-time
        - `line_item_id` string
        - `quantity` string
      - `subscription_id` string
    - `wallet_topup_params` TypesWalletTopupParams
      - `wallet_id` string, required
      - `wallet_transaction_id` string
  - `customer_external_id` string, required
  - `failure_url` string
  - `idempotency_key` string
  - `metadata` object
  - `payment_provider` 'razorpay', required
  - `payment_provider_config` TypesCheckoutPaymentProviderConfig
    - `collection_method` 'charge_automatically' | 'send_invoice'
    - `max_mandate_limit` string
    - `payment_method` 'CARD' | 'ACH' | 'OFFLINE' | 'CREDITS' | 'PAYMENT_LINK' | 'UPI'
  - `success_url` string

## Response `201`

Created

- CheckoutSessionResponse
  - `action` 'create_subscription' | 'modify_subscription' | 'wallet_topup'
  - `cancel_url` string
  - `cancelled_at` string, date-time
  - `checkout_invoice_id` string — CheckoutInvoiceID and CheckoutPaymentID are set once the apply step creates the corresponding Flexprice entities (completed sessions only).
  - `checkout_payment_id` string
  - `checkout_status` 'initiated' | 'pending' | 'completed' | 'failed' | 'expired'
  - `completed_at` string, date-time
  - `configuration` CheckoutJSONBCheckoutConfiguration
    - `create_subscription_params` TypesCreateSubscriptionParams
      - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
      - `currency` string
      - `end_date` string, date-time
      - `lookup_key` string
      - `metadata` object
      - `plan_id` string
      - `start_date` string, date-time
    - `modify_subscription_params` TypesModifySubscriptionParams
      - `line_item_modifications` TypesModifySubscriptionLineItem[]
        - `effective_date` string, date-time
        - `line_item_id` string
        - `quantity` string
      - `subscription_id` string
    - `wallet_topup_params` TypesWalletTopupParams
      - `wallet_id` string, required
      - `wallet_transaction_id` string
  - `created_at` string, date-time
  - `created_by` string
  - `customer_id` string
  - `environment_id` string
  - `expires_at` string, date-time — ExpiresAt is required. A Temporal timer fires at this time for any session still in initiated|pending, marking it expired. The caller must create a new session after expiry (expire-and-restart model).
  - `failure_reason` string — FailureReason is a human-readable string set on failed sessions.
  - `failure_url` string
  - `id` string
  - `idempotency_key` string — IdempotencyKey is caller-supplied. It is unique only while the session is active (initiated|pending). The same key may be reused once the session reaches a terminal state (completed|failed|expired).
  - `metadata` TypesMetadata
  - `payment_action` TypesPaymentAction
    - `type` 'checkout_url' | 'payment_link'
    - `url` string
  - `payment_provider` 'razorpay'
  - `payment_provider_config` CheckoutJSONBCheckoutPaymentProviderConfig
    - `collection_method` 'charge_automatically' | 'send_invoice'
    - `max_mandate_limit` string
    - `payment_method` 'CARD' | 'ACH' | 'OFFLINE' | 'CREDITS' | 'PAYMENT_LINK' | 'UPI'
  - `provider_result` CheckoutJSONBCheckoutProviderResult
    - `expires_at` string, date-time — ExpiresAt is the provider URL expiry. When set and earlier than the session expiry, executeCheckoutAction tightens the session expiry to match.
    - `next_action` TypesPaymentAction
      - `type` 'checkout_url' | 'payment_link'
      - `url` string
    - `provider_metadata` object — ProviderMetadata holds provider-specific data not needed for business logic.
    - `provider_payment_intent_id` string — ProviderPaymentIntentID is the provider-side charge/intent ID. Stripe returns this at link creation (pi_xxx); others populate it from the webhook payload.
    - `provider_session_id` string — ProviderSessionID is stored in EntityIntegrationMapping at link creation. Stripe: Checkout Session ID (cs_xxx) Razorpay: Payment Link ID (plink_xxx) Nomod: Payment Link ID (NOTE: webhook uses Charge ID; look up by PaymentLinkID field) Moyasar: Payment ID
  - `result` CheckoutJSONBCheckoutResult
    - `create_subscription_result` TypesCreateSubscriptionResult
      - `invoice_id` string
      - `payment_id` string
      - `subscription_id` string
  - `status` 'published' | 'deleted' | 'archived'
  - `success_url` string — Redirect URLs sent to the payment provider. The provider redirects the user browser to the appropriate URL after the payment flow completes.
  - `tenant_id` string
  - `updated_at` string, date-time
  - `updated_by` string

## Other responses

- `400` — Bad Request
- `409` — Conflict
- `500` — Internal Server Error

---

[API](https://skmtc.net/flexprice/apis/flexprice-api.md) · [All operations](https://skmtc.net/flexprice/apis/flexprice-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/flexprice/flexprice-api/versions/f0601ed97bd3/schema)
