# Create an Off Session Payment

Creates an OffSessionPayment object.

## Request

```curl
curl -X POST https://api.stripe.com/v2/payments/off_session_payments \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-08-26.preview" \
  --json '{
    "amount": {
        "value": 2000,
        "currency": "usd"
    },
    "retry_details": {
        "retry_strategy": "best_available"
    },
    "cadence": "recurring",
    "customer": "{{CUSTOMER_ID}}",
    "payment_method": "{{PAYMENT_METHOD_ID}}",
    "metadata": {}
  }'
```

### Response

```json
{
  "amount_requested": {
    "value": 2000,
    "currency": "usd"
  },
  "cadence": "recurring",
  "created": "2025-01-01T00:00:00.000Z",
  "customer": "cus_SJjFsJvGPQKfH1",
  "failure_reason": null,
  "id": "osp_test_6pO5OrRN03IzV8rd3BaY",
  "last_authorization_attempt_error": null,
  "latest_payment_attempt_record": null,
  "livemode": false,
  "metadata": {},
  "object": "v2.payments.off_session_payment",
  "on_behalf_of": null,
  "payment_method": "pm_1RP6TAG7mvlzf7RNfspLoGQ9",
  "payment_record": null,
  "payments_orchestration": null,
  "retry_details": {
    "attempts": 0,
    "retry_strategy": "smart"
  },
  "statement_descriptor": null,
  "statement_descriptor_suffix": null,
  "status": "pending",
  "test_clock": null,
  "transfer_data": null
}
```

## Parameters

- [`amount`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=amount&api-version=2026-08-26.preview) (object, required)
  Amount intended to be collected by this payment.

- `cadence` (enum, required)
  The frequency of the underlying payment.
Possible enum values:
  - `recurring`
    Indicates a transaction occurring on a regular interval.

  - `unscheduled`
    Indicates a transaction occurring at irregular periods.

- `customer` (string, required)
  ID of the Customer to which this OffSessionPayment belongs.

- [`application_fee_amount`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=application_fee_amount&api-version=2026-08-26.preview) (object, optional)
  The amount of the application fee (if any) that will be requested to be applied to the payment and transferred to the application owner’s Stripe account.

- `description` (string, optional)
  An arbitrary string attached to the object. Often useful for displaying to users.

- `metadata` (map, optional)
  Set of [key-value pairs](https://docs.stripe.com/api/metadata.md?api-version=2026-08-26.preview) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Learn more about [storing information in metadata](https://docs.stripe.com/payments/payment-intents.md?api-version=2026-08-26.preview#storing-information-in-metadata).

- `on_behalf_of` (string, optional)
  The account (if any) for which the funds of the OffSessionPayment are intended.

- `payment_method` (string, optional)
  ID of the payment method used in this OffSessionPayment.

- [`payment_method_data`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=payment_method_data&api-version=2026-08-26.preview) (object, optional)
  If provided, this hash will be used to create a PaymentMethod. The new PaymentMethod will appear in the payment_method property on the OffSessionPayment.

- [`payment_method_options`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=payment_method_options&api-version=2026-08-26.preview) (object, optional)
  Payment method options for the off-session payment.

- [`retry_details`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=retry_details&api-version=2026-08-26.preview) (object, optional)
  Details about the OffSessionPayment retries.

- `statement_descriptor` (string, optional)
  Text that appears on the customer’s statement as the statement descriptor for a non-card charge. This value overrides the account’s default statement descriptor. For information about requirements, including the 22-character limit, see the [Statement Descriptor docs](https://docs.stripe.com/get-started/account/statement-descriptors.md?api-version=2026-08-26.preview).

- `statement_descriptor_suffix` (string, optional)
  Provides information about a card charge. Concatenated to the account’s [statement descriptor prefix](https://docs.stripe.com/get-started/account/statement-descriptors.md?api-version=2026-08-26.preview#static) to form the complete statement descriptor that appears on the customer’s statement.

- `test_clock` (string, optional)
  Test clock that can be used to advance the retry attempts in a sandbox.

- [`transfer_data`](https://docs.stripe.com/api/v2/payments/off-session-payments/create.md?query=transfer_data&api-version=2026-08-26.preview) (object, optional)
  The data that automatically creates a Transfer after the payment finalizes. Learn more about the use case for [connected accounts](https://docs.stripe.com/payments/connected-accounts.md?api-version=2026-08-26.preview).

## Returns

Returns an [Off Session Payment object](https://docs.stripe.com/api/v2/payments/off-session-payments/object.md?api-version=2026-08-26.preview).

## Error Codes

| HTTP status code | Code | Description |
| --- | --- | --- |
| 400 | invalid_date_string | The target_date string is not a valid date format. |
| 400 | off_session_payment_amount_details_amount_mismatch | The total value of amount_details does not match the amount on the OffSessionPayment. |
| 400 | off_session_payment_amount_details_line_items_limit_exceeded | More than 10 line items were provided in amount_details. |
| 400 | off_session_payment_amount_details_line_items_unit_cost_must_be_greater_than_zero | The unit_cost of a line item in amount_details is not greater than zero. |
| 400 | off_session_payment_amount_details_tax_shipping_discount_greater_than_amount | The value of tax + shipping - discount is greater than the amount on the OffSessionPayment. |
| 400 | off_session_payment_application_fee_amount_incorrect_currency | The application_fee_amount must use the same currency as amount. |
| 400 | off_session_payment_application_fee_amount_too_high | The value of application_fee_amount must be less than or equal to that of amount. |
| 400 | off_session_payment_heuristic_retries_not_supported_for_cards | Card payment methods do not support heuristic retries. |
| 400 | off_session_payment_incorrect_payment_method_type_for_options | You may not provide payment method options that do not match the payment method type. |
| 400 | off_session_payment_invalid_mcc | The MCC value provided is not valid for this merchant or payment method. |
| 400 | off_session_payment_mcc_not_allowed_with_on_behalf_of | MCC is not an allowed parameter for on behalf of transactions. |
| 400 | off_session_payment_missing_network_transaction_id | Raw PANs cannot be passed to the Off-Session Payments API without explicitly passing a network transaction ID. |
| 400 | off_session_payment_raw_pans_not_allowed | Raw PANs cannot be passed to the Off-Session Payments API without explicit approval from Stripe. |
| 400 | off_session_payment_retry_policy_not_supported_for_debit_payment_methods | Debit payment methods do not support custom retry policies. |
| 400 | off_session_payment_retry_policy_strategy_mutually_exclusive | You may not specify both a retry_policy and retry_strategy. These parameters are mutually exclusive. |
| 400 | off_session_payment_smart_retries_not_supported_for_debit_payment_methods | Debit payment methods do not support smart retries. |
| 400 | off_session_payment_test_clock_in_livemode | Test clocks may not be used with the Off-Session Payments API in livemode. Please use your sandbox keys to test with test clocks. |
| 400 | off_session_payment_transfer_data_not_supported_with_stripe_context | The transfer_data parameter is not supported when using the Stripe-Context header. |
| 400 | osp_ach_retries_not_enabled | To schedule ACH payment retries with the Off-Session Payments API, you must first enable ACH retries on the Stripe dashboard. |
| 400 | osp_amount_too_large | The Off-Session Payments API has limits on the maximum amount you may charge in each currency. |
| 400 | osp_amount_too_small | The Off-Session Payments API has limits on the minimum amount you may charge in each currency. |
| 400 | osp_generic_invalid_request | A generic error occurred during payment. See error message for more details. |
| 400 | osp_invalid_payment_method_type | Indicates that the payment method you provided is not compatible with the Off-Session Payments API. The Off-Session Payments API currently only supports card payment methods, including ones generated from wallets. |
| 400 | osp_payment_method_not_attached | To use the Off-Session Payments API, you must first attach the PaymentMethod to the Customer via the Setup Intents API. |
| 400 | osp_payments_orchestration_not_supported_with_connect | Payments orchestration is not supported with connect integrations. |
| 400 | osp_payments_orchestration_not_supported_with_raw_card_data | Payments orchestration is not supported with raw card data. |
| 400 | osp_payments_orchestration_not_supported_with_smart_retries | Smart retries are not supported for orchestrated OSPs at this time. |
| 400 | osp_payments_orchestration_only_supported_for_cards | Payments orchestration is currently only supported for card payment method types. |
| 400 | osp_pm_not_setup_for_off_session | To use the Off-Session Payments API, you must first set up the PaymentMethod for off-session usage via the Setup Intents API. |
| 400 | osp_pm_set_up_only_on_connected_account | To use the Off-Session Payments API, you must first set up the PaymentMethod for off-session usage via the Setup Intents API. You must use the same value for `on_behalf_of` when calling into the SetupIntent API as what you use in the Off-Session Payments API. |
| 400 | osp_pm_set_up_only_on_platform | To use the Off-Session Payments API, you must first set up the PaymentMethod for off-session usage via the Setup Intents API. You must use the same value for `on_behalf_of` when calling into the SetupIntent API as what you use in the Off-Session Payments API. |
| 400 | osp_sepa_debit_retries_not_enabled | To schedule SEPA Debit payment retries with the Off-Session Payments API, you must first enable SEPA Debit retries on the Stripe dashboard. |
| 400 | parameter_pair_exclusive | Two mutually exclusive parameters were provided in the request. |
| 400 | target_date_in_past | The target_date provided is in the past. |
| 400 | target_date_too_close | The target_date provided is too close to today (less than 3 business days away). |
| 400 | target_date_too_far | The target_date provided is too far in the future (more than 15 calendar days away). |
