# Begin the checkout process.

The request body dete

Begin the checkout process.

The request body determines the behavior:

- An empty or omitted body preserves the legacy cart.php redirect response (no changes).
- A non-empty JSON body runs the gateway-agnostic checkout: it places the order, resolves or registers the client, screens for fraud, and dispatches to the payment strategy for the gateway.

The payment strategies are:
- Already paid.
- Fraud hold.
- Nothing payable, when the order created no invoice.
- Stored-token capture.
- Offline or pending.
- A headless payment session, when the request sets the payment.mode value to headless and the gateway supports it.
- A hand-off that requires the shopper to complete payment using the returned next_action.url value.

Endpoint: POST /cart/{cart_id}/checkout
Version: 2.1.0

## Path parameters:

  - `cart_id` (string, required)
    Cart ID

## Response 200 fields (application/json):

  - `data` (any, required) — one of:
    - variant 1:
      - `url` (string, required)
        Example: "https://example.com/"
    - CheckoutResult:
      - `order_id` (integer, required)
        Example: 123
      - `invoice_id` (integer, required)
        0 when the order created no invoice. Do not treat 0 as an error and do not request the invoice. A payment.status of not_required is the ordinary case; a free-cycle order held for fraud review reports pending with the same 0.
        Example: 456
      - `client_id` (integer, required)
        Example: 789
      - `service_ids` (array)
      - `addon_ids` (array)
      - `domain_ids` (array)
      - `domain_renewal_ids` (array)
        The domains the checkout renewed. A renewal reuses the client's existing domain, so these identifiers are not new.
      - `service_renewal_ids` (array)
        The services the checkout renewed. A renewal reuses the client's existing service, so these identifiers are not new.
      - `addon_renewal_ids` (array)
        The addons the checkout renewed. A renewal reuses the client's existing addon, so these identifiers are not new.
      - `upgrade_ids` (array)
        The upgrades the checkout created.
      - `order_status` (string, required)
        Example: "Pending"
      - `payment` (object, required)
      - `payment.method` (string, required)
        Example: "stripe_dynamic"
      - `payment.status` (string, required)
        not_required means the order created no invoice and there is nothing to collect, so invoice_id is 0 and next_action is null. A free billing cycle produces no invoice; an order discounted to zero is invoiced and answers paid.

failed means the capture of the stored payment method did not succeed: the gateway declined it, or the attempt did not complete. Under a payment.mode value of headless, next_action carries a payment_session so that another method can be collected in place, and the request answers a 422 error status instead when no session can be minted; otherwise it carries a redirect to the hosted pay page.

failed describes the attempt that did not succeed. Checking the same cart out again answers paid if the invoice settled in the meantime, pending once a payment is in flight, action_required with a freshly minted session while it is neither, and a 422 error status if a session cannot be minted again.
        Enum: "paid", "pending", "action_required", "not_required", "failed"
      - `payment.next_action` (object,null) — one of:
        How to proceed with payment.

- redirect returns a single-use hand-off url value (the default).
- payment_session returns a session object that your integration passes to the matching gateway SDK and carries no url value.
        - NextActionRedirect:
          - `type` (string, required)
            Enum: "redirect"
          - `url` (string, required)
            Example: "https://example.com/oauth/singlesignon.php?access_token=..."
        - NextActionPaymentSession:
          - `type` (string, required)
            Enum: "payment_session"
          - `session` (object, required)
            A gateway-specific object of client-side parameters. The params keys depend on the provider value.
          - `session.provider` (string, required)
            A discriminator that tells your integration which gateway SDK to drive.
            Example: "stripe"
          - `session.params` (object, required)
            The keys that the provider's SDK accepts.
            Example: {"publishableKey":"pk_live_...","clientSecret":"pi_3Abc..._secret_XyZ","paymentIntentId":"pi_3Abc...","mode":"payment"}
          - `session.settlement` (string, required)
            The method to use to settle payment. Branch on the value you receive rather than assuming one:

- sync_confirm — Call the confirmation endpoint (POST /user/invoices/{invoice_id}/payment-session/confirm), which records the outcome in WHMCS.
- async_webhook — Do not call the confirmation endpoint. The gateway module records the outcome when the provider's signed webhook arrives, so poll the GET /user/invoices/{invoice_id} endpoint until the status reaches Paid.

After a pending result, poll regardless of this value. Success does not indicate that payment cleared.
            Enum: "async_webhook", "sync_confirm"
          - `session.sdk` (object, required)
            The method to use to load the SDK that renders this session.
            Example: {"scriptUrl":"https://js.stripe.com/v3/","apiVersion":"2023-10-16"}
          - `session.sdk.scriptUrl` (string, required)
            The provider CDN URL your integration loads the SDK from.
            Example: "https://js.stripe.com/v3/"
          - `session.sdk.apiVersion` (string)
            The gateway API version your integration must use so that the browser and WHMCS agree. The system returns this value for providers that accept it.
            Example: "2023-10-16"
      - `url` (string,null)
        Mirrors the payment.next_action.url value, for single-page application compatibility.

## Response 202 fields (application/json):

  - `data` (object, required)

  - `data.order_id` (integer, required)
    Example: 123

  - `data.invoice_id` (integer, required)
    0 when the order created no invoice. Do not treat 0 as an error and do not request the invoice. A payment.status of not_required is the ordinary case; a free-cycle order held for fraud review reports pending with the same 0.
    Example: 456

  - `data.client_id` (integer, required)
    Example: 789

  - `data.service_ids` (array)

  - `data.addon_ids` (array)

  - `data.domain_ids` (array)

  - `data.domain_renewal_ids` (array)
    The domains the checkout renewed. A renewal reuses the client's existing domain, so these identifiers are not new.

  - `data.service_renewal_ids` (array)
    The services the checkout renewed. A renewal reuses the client's existing service, so these identifiers are not new.

  - `data.addon_renewal_ids` (array)
    The addons the checkout renewed. A renewal reuses the client's existing addon, so these identifiers are not new.

  - `data.upgrade_ids` (array)
    The upgrades the checkout created.

  - `data.order_status` (string, required)
    Example: "Pending"

  - `data.payment` (object, required)

  - `data.payment.method` (string, required)
    Example: "stripe_dynamic"

  - `data.payment.status` (string, required)
    not_required means the order created no invoice and there is nothing to collect, so invoice_id is 0 and next_action is null. A free billing cycle produces no invoice; an order discounted to zero is invoiced and answers paid.

failed means the capture of the stored payment method did not succeed: the gateway declined it, or the attempt did not complete. Under a payment.mode value of headless, next_action carries a payment_session so that another method can be collected in place, and the request answers a 422 error status instead when no session can be minted; otherwise it carries a redirect to the hosted pay page.

failed describes the attempt that did not succeed. Checking the same cart out again answers paid if the invoice settled in the meantime, pending once a payment is in flight, action_required with a freshly minted session while it is neither, and a 422 error status if a session cannot be minted again.
    Enum: same as `payment.status` in "CheckoutResult" (5 values)

  - `data.payment.next_action` (object,null) — one of:
    How to proceed with payment.

- redirect returns a single-use hand-off url value (the default).
- payment_session returns a session object that your integration passes to the matching gateway SDK and carries no url value.
    - NextActionRedirect:
      - `type` (string, required)
        Enum: same as `type` in "NextActionRedirect" (1 values)
      - `url` (string, required)
        Example: "https://example.com/oauth/singlesignon.php?access_token=..."
    - NextActionPaymentSession:
      - `type` (string, required)
        Enum: same as `type` in "NextActionPaymentSession" (1 values)
      - `session` (object, required)
        A gateway-specific object of client-side parameters. The params keys depend on the provider value.
      - `session.provider` (string, required)
        A discriminator that tells your integration which gateway SDK to drive.
        Example: "stripe"
      - `session.params` (object, required)
        The keys that the provider's SDK accepts.
        Example: {"publishableKey":"pk_live_...","clientSecret":"pi_3Abc..._secret_XyZ","paymentIntentId":"pi_3Abc...","mode":"payment"}
      - `session.settlement` (string, required)
        The method to use to settle payment. Branch on the value you receive rather than assuming one:

- sync_confirm — Call the confirmation endpoint (POST /user/invoices/{invoice_id}/payment-session/confirm), which records the outcome in WHMCS.
- async_webhook — Do not call the confirmation endpoint. The gateway module records the outcome when the provider's signed webhook arrives, so poll the GET /user/invoices/{invoice_id} endpoint until the status reaches Paid.

After a pending result, poll regardless of this value. Success does not indicate that payment cleared.
        Enum: same as `session.settlement` in "NextActionPaymentSession" (2 values)
      - `session.sdk` (object, required)
        The method to use to load the SDK that renders this session.
        Example: {"scriptUrl":"https://js.stripe.com/v3/","apiVersion":"2023-10-16"}
      - `session.sdk.scriptUrl` (string, required)
        The provider CDN URL your integration loads the SDK from.
        Example: "https://js.stripe.com/v3/"
      - `session.sdk.apiVersion` (string)
        The gateway API version your integration must use so that the browser and WHMCS agree. The system returns this value for providers that accept it.
        Example: "2023-10-16"

  - `data.url` (string,null)
    Mirrors the payment.next_action.url value, for single-page application compatibility.

## Response 400 fields (application/json):

  - `data` (object, required)

  - `data.validation_errors` (array)

  - `data.validation_errors.item_id` (string)

  - `data.validation_errors.errors` (array)
    - `id` (integer)
    - `type` (string)
      Enum: "product", "addon", "service", "customfield", "configoption", "bundle"
    - `error` (string)

## Response 401 fields (application/json):

  - `message` (string)


