---
title: "POST /user/invoices/{invoice_id}/payment-session/confirm"
method: POST
path: "/user/invoices/{invoice_id}/payment-session/confirm"
---

# POST /user/invoices/{invoice_id}/payment-session/confirm

`POST /user/invoices/{invoice_id}/payment-session/confirm`

## Request

- Base URL: `https://developers.whmcs.com/api/v2`
- URL: `https://developers.whmcs.com/api/v2/user/invoices/{invoice_id}/payment-session/confirm`
- Auth: none declared

Settle a headless payment the buyer has approved in your own integration. You **must** call this for any payment session where the `settlement` value is `sync_confirm`.

Behavior varies for each payment gateway:
- **PayPal** confirmation captures the approved order. If you skip it, the buyer's approval expires uncaptured, no payment occurs, and no webhook recovers it.
- **Stripe** confirmation records payment that has already occurred. If you skip it, the `charge.succeeded` webhook settles the payment.

The `payment.status` value has four outcomes:

- `paid` — The gateway accepted the payment.
- `pending` — The gateway took the payment but has not settled it (a PayPal `PENDING` capture, or a Stripe payment method still clearing, such as a bank debit or a redirect method) and the status is `Payment Pending`. Keep polling the `GET /user/invoices/{invoice_id}` endpoint.
- `declined` — The gateway declined the payment method. Present another payment method.
- `failed` — The attempt did not complete. Try again.

## Path parameters

- `invoice_id` integer, required

## Request body

- object
  - `provider_reference` string, required: The gateway's identifier for the approved payment: - For PayPal, this is the `onApprove` order ID. - For Stripe, this is the `params.paymentIntentId` value from the payment session. WHMCS passes this identifier to the gateway without reading it.

## Response `200`

The gateway's outcome.

A `200` status indicates that the system attempted confirmation and received a response, **not** that payment succeeded.

- object
  - `data` object, required
    - `payment` object, required
      - `status` 'paid' | 'pending' | 'declined' | 'failed', required: - `paid` is the only accepted state. - `pending` indicates that the payment is still in progress. Continue polling the invoice. - `declined` indicates that the payment method was declined. - `failed` indicates that the attempt did not complete.
      - `message` string: For `declined` and `failed` outcomes, the reason that the payment gateway reported for why payment was declined or failed.

## Other responses

- `401`: Access Not Authorized
- `403`: The caller is authenticated but does not have permission to use this resource (the _View & Pay Invoices_ permission).
- `404`: Entity Not Found
- `409`: Settlement for this invoice is in progress.
- `422`: This status indicates that the `provider_reference` value is missing, the gateway does not settle using confirmation, or the gateway refused confirmation.
- `429`: Too many confirmation requests have occurred (more than 30 within five minutes). This error prevents unbounded callers from exceeding the merchant's API quota, which could block valid requests.
- `default`: General Error

---

[API](https://skmtc.dev/whmcs/apis/whmcs-api.md) - [All operations](https://skmtc.dev/whmcs/apis/whmcs-api/llms.txt) - [OpenAPI document](https://skmtc.dev/whmcs/apis/whmcs-api/revisions/bd3848ddbc3f?raw)
