# Create a payment link (/ar/api-reference/payment-links/createPaymentLink)

Creates a new payment link — a shareable URL you can send to customers.

Features:
- Supports multiple line items with adjustable quantities
- Custom fields for collecting additional customer information
- After-completion settings (redirect or hosted confirmation)
- Automatic amount calculation from line items
- Validates currency consistency across line items

## POST /payment-links

### Request body (required)

Content type: `application/json`

- `lineItems` (Array<CreateLineItem>, required) — Line items for the payment link
  - `priceId` (string, required) — Price ID
  - `quantity` (number, required) — Quantity. May be 0 only when adjustableQuantity is enabled with minimum 0 (optional item).
  - `adjustableQuantity` (AdjustableQuantity, required) — Adjustable quantity settings
    - `enabled` (boolean, required) — Whether adjustable quantity is enabled
    - `minimum` (number) — Minimum quantity allowed
    - `maximum` (number) — Maximum quantity allowed
- `nameCollection` (boolean) — Whether to collect customer name
- `billingAddressCollection` (boolean) — Whether to collect billing address
- `shippingAddressCollection` (boolean) — Whether to collect shipping address
- `phoneNumberCollection` (boolean) — Whether to collect phone number
- `allowPromotionCodes` (boolean) — Whether to allow promotion codes
- `submitType` (enum("PAY" | "SUBSCRIBE" | "BOOK" | "DONATE")) — Submit button type
- `customerCreation` (enum("always" | "if_required")) — When to create customer
- `afterCompletion` (AfterCompletion, required) — Behavior after the purchase is complete. **type=redirect** (default): Redirect customer to your URL after payment. Requires `afterCompletion.redirect.url`. **type=hosted_confirmation**: Show a built-in XPay-hosted success page. Optionally provide `afterCompletion.hostedConfirmation.customMessage` and `afterCompletion.hostedConfirmation.returnUrl`. Example (redirect): `{ type: 'redirect', redirect: { url: 'https://example.com/success' } }` Example (hosted): `{ type: 'hosted_confirmation', hostedConfirmation: { customMessage: 'Thanks!' } }`
  - `type` (enum("redirect" | "hosted_confirmation"), required) — The behavior after the purchase is complete. - **redirect**: Customer is redirected to the URL specified in `redirect.url`. The `redirect` object is required when using this type. Cannot be combined with `hostedConfirmation`. - **hosted_confirmation**: Customer sees a built-in confirmation page hosted by XPay with a success animation, thank you message, and optional custom message. The `hostedConfirmation` object is optional. Cannot be combined with `redirect`. Not available when `uiMode` is `embedded` or `custom` — those integrations run on your own page, and there is no XPay page to show the customer.
  - `redirect` (AfterCompletionRedirect) — Configuration when type=redirect. **Required** when type is 'redirect'. Must not be provided when type is 'hosted_confirmation'.
    - `url` (string, required) — Where we hand the browser back to you. Required when afterCompletion.type is 'redirect'. - **hosted**: the customer is redirected here after a successful payment. A failed payment keeps them on the checkout page so they can retry. - **embedded**: the customer is returned here when a bank verification has to take over the whole tab. That return happens whatever the outcome, so read the session's status on arrival rather than assuming success. - **custom**: the destination `redirect: "always"` sends the customer to after a successful payment. Include `{CHECKOUT_SESSION_ID}` anywhere in the URL and we substitute the session id before the customer ever reaches it.
  - `hostedConfirmation` (AfterCompletionHostedConfirmation) — Configuration when type=hosted_confirmation. Optional — if not provided, a default confirmation page is shown. Must not be provided when type is 'redirect'.
    - `customMessage` (string) — Custom message displayed to the customer on the hosted confirmation page after payment. If not provided, a default message is shown: 'A payment to {merchant} will appear on your statement.' Max 500 characters.
    - `returnUrl` (string) — Optional URL for a "Return to {merchant}" button on the confirmation page. If not provided, no return button is shown.
- `customFields` (Array<CreateCustomField>) — Custom fields (max 3)
  - `label` (string, required) — Field label
  - `type` (enum("TEXT" | "NUMBER" | "DROPDOWN" | "CHECKBOX"), required) — Field type
  - `isOptional` (boolean, required) — Whether the field is optional
  - `hasLimits` (boolean) — Whether validation limits are enabled
  - `limitType` (enum("AT_MOST" | "BETWEEN" | "AT_LEAST" | "EXACTLY")) — Type of validation limit
  - `minCharacters` (number) — Minimum number of characters
  - `maxCharacters` (number) — Maximum number of characters
  - `dropdownOptions` (Array<CreateDropdownOption>) — Dropdown options (only for DROPDOWN type)
    - `label` (string, required) — Option label
- `expiresAt` (string) — Expiration date
- `metadata` (object) — Custom key-value metadata
- `feeConfig` (FeeConfigInput) — Fee configuration override. If not provided, merchant's default fee config will be used.
  - `feesPassThrough` (boolean, required) — Whether customer pays platform fee instead of merchant. When true, platform fee is added to customer payment.
  - `vatCollectionEnabled` (boolean, required) — Whether to collect merchant's product VAT from customer. When enabled, VAT is added to customer payment.
  - `vatCollectionRate` (number) — VAT collection rate in basis points (e.g., 1400 = 14%). Required when vatCollectionEnabled is true.
- `brandingSettings` (BrandingSettingsInput) — UI customization settings for the checkout page
  - `colorMode` (enum("light" | "dark" | "system")) — Dark mode preference
  - `borderStyle` (enum("rounded" | "sharp" | "pill")) — Border style for inputs, buttons, cards
  - `spacing` (enum("condensed" | "normal" | "spacious")) — Spacing density
  - `inputSize` (enum("small" | "medium" | "large")) — Input field size
  - `inputStyle` (enum("flat" | "outlined" | "filled")) — Input field style
  - `formLayout` (enum("compact" | "spacious")) — Form layout density
  - `colors` (ColorCustomizationInput) — Color customization options
    - `primary` (string) — Primary brand color (buttons, links, accents). Hex only, e.g. `#635bff`.
    - `primaryForeground` (string) — Primary foreground (text on primary background). Hex only.
    - `background` (string) — Page background color. Hex only.
    - `foreground` (string) — Main text color. Hex only.
    - `border` (string) — Border color. Hex only.
    - `input` (string) — Input, button, and dropdown border color. Hex only.
    - `ring` (string) — Focus ring color. Hex only.
    - `muted` (string) — Muted/secondary background. Hex only.
    - `mutedForeground` (string) — Muted text color. Hex only.
    - `accent` (string) — Accent background. Hex only.
    - `accentForeground` (string) — Accent text color. Hex only.
    - `destructive` (string) — Destructive/error color. Hex only.
  - `fontFamily` (string) — Font family override (CSS font-family value, e.g. 'Inter, sans-serif')
- `paymentMethodConfigurationId` (string) — ID of a PaymentMethodConfiguration to use. Omit to use the merchant's default configuration.

### Responses

#### 201 — Payment link created successfully

Content type: `application/json`

- `id` (string, required) — Unique identifier for this Payment Link. Always prefixed with `plink_`.
- `object` (string, required) — String identifying the object type. Always `payment_link` for this resource.
- `merchantId` (string, required) — Merchant ID
- `active` (boolean, required) — Whether the payment link is active
- `expiresAt` (string) — Expiration timestamp (ISO 8601)
- `currency` (enum("EGP" | "USD" | "EUR" | "GBP" | "SAR" | "AED" | "QAR" | "KWD" | "JOD" | "OMR" | "BHD" | "LYD" | "AUD" | "CAD" | "CNY"), required) — Currency
- `computedAmount` (number, required) — Computed total amount from line items
- `nameCollection` (boolean, required) — Whether to collect customer name
- `billingAddressCollection` (boolean, required) — Whether to collect billing address
- `shippingAddressCollection` (boolean, required) — Whether to collect shipping address
- `phoneNumberCollection` (boolean, required) — Whether to collect phone number
- `allowPromotionCodes` (boolean, required) — Whether to allow promotion codes
- `submitType` (enum("PAY" | "SUBSCRIBE" | "BOOK" | "DONATE"), required) — Submit type
- `customerCreation` (enum("always" | "if_required")) — When to create customer
- `afterCompletion` (AfterCompletionResponse) — After completion settings
  - `type` (enum("redirect" | "hosted_confirmation"), required) — After completion type
  - `redirect` (AfterCompletionRedirectResponse) — Redirect configuration
    - `url` (string, required) — Redirect URL
  - `hostedConfirmation` (AfterCompletionHostedConfirmationResponse) — Hosted confirmation configuration
    - `customMessage` (string) — Custom message
    - `returnUrl` (string) — Return URL
- `lineItems` (Array<LineItem>, required) — Line items
  - `id` (string, required) — Line item ID
  - `quantity` (number, required) — Quantity
  - `price` (Price, required) — Price information
    - `id` (string, required) — Price ID
    - `unitAmount` (number) — Price amount in smallest currency unit
    - `currency` (enum("EGP" | "USD" | "EUR" | "GBP" | "SAR" | "AED" | "QAR" | "KWD" | "JOD" | "OMR" | "BHD" | "LYD" | "AUD" | "CAD" | "CNY"), required) — Currency
    - `type` (enum("ONE_TIME" | "RECURRING" | "CUSTOM"), required) — Price type
    - `recurring` (Recurring) — Recurring configuration (for recurring prices)
    - `customUnitAmount` (CustomUnitAmount) — Custom unit amount configuration — present for CUSTOM-type prices
    - `createdAt` (string, required) — Creation timestamp (ISO 8601)
    - `active` (boolean, required) — Whether the price is active. `false` means the merchant archived it.
    - `stock` (number | null) — Remaining stock. `null` means unlimited. Decremented on PaymentIntent success. May go negative under race conditions (oversold).
    - `startDate` (string | null) — Start date (before which the price is not usable in checkout), ISO 8601
    - `expirationDate` (string | null) — Expiration date (at/after which the price is not usable in checkout), ISO 8601
    - `product` (Product, required) — Product associated with this price
  - `adjustableQuantity` (AdjustableQuantity) — Adjustable quantity settings
    - `enabled` (boolean, required) — Whether adjustable quantity is enabled
    - `minimum` (number) — Minimum quantity allowed
    - `maximum` (number) — Maximum quantity allowed
  - `amountSubtotal` (number) — Total before any discounts or taxes (unitAmount × quantity)
  - `amountTotal` (number) — Total after discounts and taxes
  - `amountDiscount` (number) — Discount amount applied to this item
  - `amountTax` (number) — Tax amount applied to this item
  - `currency` (enum("EGP" | "USD" | "EUR" | "GBP" | "SAR" | "AED" | "QAR" | "KWD" | "JOD" | "OMR" | "BHD" | "LYD" | "AUD" | "CAD" | "CNY")) — Currency for the amounts (ISO 4217)
  - `description` (string) — Description from price/product
  - `presentmentDetails` (LineItemPresentmentDetails) — Customer-facing view of this line item. Populated on checkout-session snapshots when the merchant prices in a currency different from processing. Uses the session's locked exchange rate.
    - `unitAmount` (number, required) — Unit amount in presentment smallest unit
    - `amountSubtotal` (number, required) — Line subtotal (unitAmount × quantity) in presentment smallest unit
    - `amountDiscount` (number, required) — Line discount allocated to this item, in presentment smallest unit
    - `amountTotal` (number, required) — Line total after discount + tax, in presentment smallest unit
    - `currency` (enum("EGP" | "USD" | "EUR" | "GBP" | "SAR" | "AED" | "QAR" | "KWD" | "JOD" | "OMR" | "BHD" | "LYD" | "AUD" | "CAD" | "CNY"), required) — Presentment currency for this line — matches session.presentmentDetails.currency
- `customFields` (Array<CustomField>) — Custom fields
  - `label` (string, required) — Field label
  - `type` (enum("TEXT" | "NUMBER" | "DROPDOWN" | "CHECKBOX"), required) — Field type
  - `isOptional` (boolean, required) — Whether the field is optional
  - `hasLimits` (boolean, required) — Whether validation limits are enabled
  - `limitType` (enum("AT_MOST" | "BETWEEN" | "AT_LEAST" | "EXACTLY")) — Type of validation limit
  - `minCharacters` (number) — Minimum number of characters
  - `maxCharacters` (number) — Maximum number of characters
  - `dropdownOptions` (Array<DropdownOption>) — Dropdown options (only for DROPDOWN type)
    - `label` (string, required) — Option label
- `feeConfig` (ResolvedFeeConfig) — Fee configuration
  - `feesPassThrough` (boolean, required) — Whether customer pays platform fee (false = merchant pays)
  - `vatCollectionEnabled` (boolean, required) — Whether to collect VAT from customer
  - `vatCollectionRate` (number) — VAT collection rate in basis points (e.g., 1400 = 14%)
  - `source` (enum("session" | "merchant" | "system"), required) — Where this config came from
- `metadata` (object) — Custom metadata
- `brandingSettings` (BrandingSettingsResponse) — Branding settings
  - `colorMode` (enum("light" | "dark" | "system")) — Dark mode preference
  - `borderStyle` (enum("rounded" | "sharp" | "pill")) — Border style for inputs, buttons, cards
  - `spacing` (enum("condensed" | "normal" | "spacious")) — Spacing density
  - `inputSize` (enum("small" | "medium" | "large")) — Input field size
  - `inputStyle` (enum("flat" | "outlined" | "filled")) — Input field style
  - `formLayout` (enum("compact" | "spacious")) — Form layout density
  - `colors` (ColorCustomizationResponse) — Color customization options
    - `primary` (string) — Primary brand color (buttons, links, accents). Hex only, e.g. `#635bff`.
    - `primaryForeground` (string) — Primary foreground (text on primary background). Hex only.
    - `background` (string) — Page background color. Hex only.
    - `foreground` (string) — Main text color. Hex only.
    - `border` (string) — Border color. Hex only.
    - `input` (string) — Input, button, and dropdown border color. Hex only.
    - `ring` (string) — Focus ring color. Hex only.
    - `muted` (string) — Muted/secondary background. Hex only.
    - `mutedForeground` (string) — Muted text color. Hex only.
    - `accent` (string) — Accent background. Hex only.
    - `accentForeground` (string) — Accent text color. Hex only.
    - `destructive` (string) — Destructive/error color. Hex only.
  - `fontFamily` (string) — Font family override
- `paymentMethodConfigurationId` (string) — Payment method configuration ID
- `createdAt` (string, required) — Creation timestamp (ISO 8601)
- `updatedAt` (string, required) — Last update timestamp (ISO 8601)

#### 400 — Invalid payment link payload: missing or invalid line items, currency mismatch, or after-completion misconfiguration.

Content type: `application/json`

- `error` (ApiErrorBody, required) — The structured error body. See `ApiErrorBody` for field semantics.
  - `type` (enum("invalid_request_error" | "authentication_error" | "rate_limit_error" | "api_error" | "card_error" | "idempotency_error"), required) — High-level error category. Use this for branching at the top level of your error handler (e.g. retry on `api_error`, surface a card decline on `card_error`).
  - `code` (enum("invalid_request" | "parameter_out_of_range" | "parameter_invalid" | "parameter_missing" | "parameter_unknown" | "parameters_exclusive" | "parameter_requires_another" | "validation_error" | "resource_missing" | "resource_invalid_state" | "resource_already_exists" | "resource_in_use" | "authentication_required" | "invalid_api_key" | "api_key_inactive" | "invalid_signature" | "merchant_not_activated" | "permission_denied" | "two_factor_required" | "checkout_session_expired" | "invalid_client_secret" | "creation_failed" | "payment_still_confirming" | "payment_already_completed" | "payment_link_inactive" | "payment_link_expired" | "amount_invalid" | "currency_invalid" | "product_archived" | "price_inactive" | "price_not_yet_active" | "price_expired" | "price_sold_out" | "price_date_range_invalid" | "price_stock_invalid" | "price_recurring_not_supported" | "price_immutable_while_used" | "line_item_missing_price" | "checkout_empty_cart" | "promotion_codes_not_allowed" | "promotion_code_not_found" | "promotion_code_inactive" | "promotion_code_expired" | "promotion_code_max_redemptions" | "promotion_code_customer_mismatch" | "promotion_code_minimum_amount" | "promotion_code_first_time_only" | "coupon_invalid" | "coupon_currency_mismatch" | "coupon_minimum_amount" | "coupon_customer_max_redemptions" | "too_many_discounts" | "payment_method_corrupted" | "payment_method_customer_mismatch" | "payment_intent_customer_mismatch" | "payment_method_mismatch" | "charge_not_captured" | "merchant_no_balance" | "insufficient_balance" | "charge_missing_balance_transaction" | "charge_missing_fee_data" | "charge_incomplete_fee_data" | "cannot_rename_default" | "must_have_enabled_method" | "cannot_delete_default" | "configuration_in_use" | "unsupported_currency" | "exchange_rate_not_found" | "coupon_in_use" | "promotion_code_exists" | "rate_limit" | "idempotency_key_in_use" | "internal_error" | "request_timeout")) — Stable, machine-readable code identifying the specific failure (e.g. `resource_missing`, `parameter_invalid`, `authentication_required`). Always present on documented errors. See the API Error Codes reference for the full list.
  - `message` (string, required) — Human-readable description of what went wrong. Safe to log or display, but not stable — use `code` for programmatic branching.
  - `param` (string) — Name of the request parameter that caused the error, when applicable (e.g. `amount`, `currency`).
  - `doc_url` (string) — URL to the documentation page for this specific error code. Deep-linked into the API Error Codes reference.
- `request_id` (string) — Unique identifier for this request, propagated to logs and traces. Include it when contacting support.

#### 401 — Authentication is required and the request did not present a valid API key.

Content type: `application/json`

- `error` (ApiErrorBody, required) — The structured error body. See `ApiErrorBody` for field semantics.
  - `type` (enum("invalid_request_error" | "authentication_error" | "rate_limit_error" | "api_error" | "card_error" | "idempotency_error"), required) — High-level error category. Use this for branching at the top level of your error handler (e.g. retry on `api_error`, surface a card decline on `card_error`).
  - `code` (enum("invalid_request" | "parameter_out_of_range" | "parameter_invalid" | "parameter_missing" | "parameter_unknown" | "parameters_exclusive" | "parameter_requires_another" | "validation_error" | "resource_missing" | "resource_invalid_state" | "resource_already_exists" | "resource_in_use" | "authentication_required" | "invalid_api_key" | "api_key_inactive" | "invalid_signature" | "merchant_not_activated" | "permission_denied" | "two_factor_required" | "checkout_session_expired" | "invalid_client_secret" | "creation_failed" | "payment_still_confirming" | "payment_already_completed" | "payment_link_inactive" | "payment_link_expired" | "amount_invalid" | "currency_invalid" | "product_archived" | "price_inactive" | "price_not_yet_active" | "price_expired" | "price_sold_out" | "price_date_range_invalid" | "price_stock_invalid" | "price_recurring_not_supported" | "price_immutable_while_used" | "line_item_missing_price" | "checkout_empty_cart" | "promotion_codes_not_allowed" | "promotion_code_not_found" | "promotion_code_inactive" | "promotion_code_expired" | "promotion_code_max_redemptions" | "promotion_code_customer_mismatch" | "promotion_code_minimum_amount" | "promotion_code_first_time_only" | "coupon_invalid" | "coupon_currency_mismatch" | "coupon_minimum_amount" | "coupon_customer_max_redemptions" | "too_many_discounts" | "payment_method_corrupted" | "payment_method_customer_mismatch" | "payment_intent_customer_mismatch" | "payment_method_mismatch" | "charge_not_captured" | "merchant_no_balance" | "insufficient_balance" | "charge_missing_balance_transaction" | "charge_missing_fee_data" | "charge_incomplete_fee_data" | "cannot_rename_default" | "must_have_enabled_method" | "cannot_delete_default" | "configuration_in_use" | "unsupported_currency" | "exchange_rate_not_found" | "coupon_in_use" | "promotion_code_exists" | "rate_limit" | "idempotency_key_in_use" | "internal_error" | "request_timeout")) — Stable, machine-readable code identifying the specific failure (e.g. `resource_missing`, `parameter_invalid`, `authentication_required`). Always present on documented errors. See the API Error Codes reference for the full list.
  - `message` (string, required) — Human-readable description of what went wrong. Safe to log or display, but not stable — use `code` for programmatic branching.
  - `param` (string) — Name of the request parameter that caused the error, when applicable (e.g. `amount`, `currency`).
  - `doc_url` (string) — URL to the documentation page for this specific error code. Deep-linked into the API Error Codes reference.
- `request_id` (string) — Unique identifier for this request, propagated to logs and traces. Include it when contacting support.

#### 403 — The credential is valid but lacks the permission this endpoint requires. Check the API key's allowed permissions in the dashboard.

Content type: `application/json`

- `error` (ApiErrorBody, required) — The structured error body. See `ApiErrorBody` for field semantics.
  - `type` (enum("invalid_request_error" | "authentication_error" | "rate_limit_error" | "api_error" | "card_error" | "idempotency_error"), required) — High-level error category. Use this for branching at the top level of your error handler (e.g. retry on `api_error`, surface a card decline on `card_error`).
  - `code` (enum("invalid_request" | "parameter_out_of_range" | "parameter_invalid" | "parameter_missing" | "parameter_unknown" | "parameters_exclusive" | "parameter_requires_another" | "validation_error" | "resource_missing" | "resource_invalid_state" | "resource_already_exists" | "resource_in_use" | "authentication_required" | "invalid_api_key" | "api_key_inactive" | "invalid_signature" | "merchant_not_activated" | "permission_denied" | "two_factor_required" | "checkout_session_expired" | "invalid_client_secret" | "creation_failed" | "payment_still_confirming" | "payment_already_completed" | "payment_link_inactive" | "payment_link_expired" | "amount_invalid" | "currency_invalid" | "product_archived" | "price_inactive" | "price_not_yet_active" | "price_expired" | "price_sold_out" | "price_date_range_invalid" | "price_stock_invalid" | "price_recurring_not_supported" | "price_immutable_while_used" | "line_item_missing_price" | "checkout_empty_cart" | "promotion_codes_not_allowed" | "promotion_code_not_found" | "promotion_code_inactive" | "promotion_code_expired" | "promotion_code_max_redemptions" | "promotion_code_customer_mismatch" | "promotion_code_minimum_amount" | "promotion_code_first_time_only" | "coupon_invalid" | "coupon_currency_mismatch" | "coupon_minimum_amount" | "coupon_customer_max_redemptions" | "too_many_discounts" | "payment_method_corrupted" | "payment_method_customer_mismatch" | "payment_intent_customer_mismatch" | "payment_method_mismatch" | "charge_not_captured" | "merchant_no_balance" | "insufficient_balance" | "charge_missing_balance_transaction" | "charge_missing_fee_data" | "charge_incomplete_fee_data" | "cannot_rename_default" | "must_have_enabled_method" | "cannot_delete_default" | "configuration_in_use" | "unsupported_currency" | "exchange_rate_not_found" | "coupon_in_use" | "promotion_code_exists" | "rate_limit" | "idempotency_key_in_use" | "internal_error" | "request_timeout")) — Stable, machine-readable code identifying the specific failure (e.g. `resource_missing`, `parameter_invalid`, `authentication_required`). Always present on documented errors. See the API Error Codes reference for the full list.
  - `message` (string, required) — Human-readable description of what went wrong. Safe to log or display, but not stable — use `code` for programmatic branching.
  - `param` (string) — Name of the request parameter that caused the error, when applicable (e.g. `amount`, `currency`).
  - `doc_url` (string) — URL to the documentation page for this specific error code. Deep-linked into the API Error Codes reference.
- `request_id` (string) — Unique identifier for this request, propagated to logs and traces. Include it when contacting support.

#### 404 — One or more line-item prices do not exist in this account / mode.

Content type: `application/json`

- `error` (ApiErrorBody, required) — The structured error body. See `ApiErrorBody` for field semantics.
  - `type` (enum("invalid_request_error" | "authentication_error" | "rate_limit_error" | "api_error" | "card_error" | "idempotency_error"), required) — High-level error category. Use this for branching at the top level of your error handler (e.g. retry on `api_error`, surface a card decline on `card_error`).
  - `code` (enum("invalid_request" | "parameter_out_of_range" | "parameter_invalid" | "parameter_missing" | "parameter_unknown" | "parameters_exclusive" | "parameter_requires_another" | "validation_error" | "resource_missing" | "resource_invalid_state" | "resource_already_exists" | "resource_in_use" | "authentication_required" | "invalid_api_key" | "api_key_inactive" | "invalid_signature" | "merchant_not_activated" | "permission_denied" | "two_factor_required" | "checkout_session_expired" | "invalid_client_secret" | "creation_failed" | "payment_still_confirming" | "payment_already_completed" | "payment_link_inactive" | "payment_link_expired" | "amount_invalid" | "currency_invalid" | "product_archived" | "price_inactive" | "price_not_yet_active" | "price_expired" | "price_sold_out" | "price_date_range_invalid" | "price_stock_invalid" | "price_recurring_not_supported" | "price_immutable_while_used" | "line_item_missing_price" | "checkout_empty_cart" | "promotion_codes_not_allowed" | "promotion_code_not_found" | "promotion_code_inactive" | "promotion_code_expired" | "promotion_code_max_redemptions" | "promotion_code_customer_mismatch" | "promotion_code_minimum_amount" | "promotion_code_first_time_only" | "coupon_invalid" | "coupon_currency_mismatch" | "coupon_minimum_amount" | "coupon_customer_max_redemptions" | "too_many_discounts" | "payment_method_corrupted" | "payment_method_customer_mismatch" | "payment_intent_customer_mismatch" | "payment_method_mismatch" | "charge_not_captured" | "merchant_no_balance" | "insufficient_balance" | "charge_missing_balance_transaction" | "charge_missing_fee_data" | "charge_incomplete_fee_data" | "cannot_rename_default" | "must_have_enabled_method" | "cannot_delete_default" | "configuration_in_use" | "unsupported_currency" | "exchange_rate_not_found" | "coupon_in_use" | "promotion_code_exists" | "rate_limit" | "idempotency_key_in_use" | "internal_error" | "request_timeout")) — Stable, machine-readable code identifying the specific failure (e.g. `resource_missing`, `parameter_invalid`, `authentication_required`). Always present on documented errors. See the API Error Codes reference for the full list.
  - `message` (string, required) — Human-readable description of what went wrong. Safe to log or display, but not stable — use `code` for programmatic branching.
  - `param` (string) — Name of the request parameter that caused the error, when applicable (e.g. `amount`, `currency`).
  - `doc_url` (string) — URL to the documentation page for this specific error code. Deep-linked into the API Error Codes reference.
- `request_id` (string) — Unique identifier for this request, propagated to logs and traces. Include it when contacting support.

#### 500 — Something went wrong on our end. Safe to retry idempotent requests; for non-idempotent calls, consult the `request_id` before resubmitting.

Content type: `application/json`

- `error` (ApiErrorBody, required) — The structured error body. See `ApiErrorBody` for field semantics.
  - `type` (enum("invalid_request_error" | "authentication_error" | "rate_limit_error" | "api_error" | "card_error" | "idempotency_error"), required) — High-level error category. Use this for branching at the top level of your error handler (e.g. retry on `api_error`, surface a card decline on `card_error`).
  - `code` (enum("invalid_request" | "parameter_out_of_range" | "parameter_invalid" | "parameter_missing" | "parameter_unknown" | "parameters_exclusive" | "parameter_requires_another" | "validation_error" | "resource_missing" | "resource_invalid_state" | "resource_already_exists" | "resource_in_use" | "authentication_required" | "invalid_api_key" | "api_key_inactive" | "invalid_signature" | "merchant_not_activated" | "permission_denied" | "two_factor_required" | "checkout_session_expired" | "invalid_client_secret" | "creation_failed" | "payment_still_confirming" | "payment_already_completed" | "payment_link_inactive" | "payment_link_expired" | "amount_invalid" | "currency_invalid" | "product_archived" | "price_inactive" | "price_not_yet_active" | "price_expired" | "price_sold_out" | "price_date_range_invalid" | "price_stock_invalid" | "price_recurring_not_supported" | "price_immutable_while_used" | "line_item_missing_price" | "checkout_empty_cart" | "promotion_codes_not_allowed" | "promotion_code_not_found" | "promotion_code_inactive" | "promotion_code_expired" | "promotion_code_max_redemptions" | "promotion_code_customer_mismatch" | "promotion_code_minimum_amount" | "promotion_code_first_time_only" | "coupon_invalid" | "coupon_currency_mismatch" | "coupon_minimum_amount" | "coupon_customer_max_redemptions" | "too_many_discounts" | "payment_method_corrupted" | "payment_method_customer_mismatch" | "payment_intent_customer_mismatch" | "payment_method_mismatch" | "charge_not_captured" | "merchant_no_balance" | "insufficient_balance" | "charge_missing_balance_transaction" | "charge_missing_fee_data" | "charge_incomplete_fee_data" | "cannot_rename_default" | "must_have_enabled_method" | "cannot_delete_default" | "configuration_in_use" | "unsupported_currency" | "exchange_rate_not_found" | "coupon_in_use" | "promotion_code_exists" | "rate_limit" | "idempotency_key_in_use" | "internal_error" | "request_timeout")) — Stable, machine-readable code identifying the specific failure (e.g. `resource_missing`, `parameter_invalid`, `authentication_required`). Always present on documented errors. See the API Error Codes reference for the full list.
  - `message` (string, required) — Human-readable description of what went wrong. Safe to log or display, but not stable — use `code` for programmatic branching.
  - `param` (string) — Name of the request parameter that caused the error, when applicable (e.g. `amount`, `currency`).
  - `doc_url` (string) — URL to the documentation page for this specific error code. Deep-linked into the API Error Codes reference.
- `request_id` (string) — Unique identifier for this request, propagated to logs and traces. Include it when contacting support.