wire docs

Confirm a PaymentIntent (create the operator invoice)

Chooses an operator, creates the payment (invoice) at that operator, records a pending Charge and moves the intent from `requires_payment_method` to `requires_action`. Show the buyer the returned `next_action` (QR code, bank-app links or a redirect). Payment completes asynchronously: the intent becomes `succeeded` and a `payment_intent.succeeded` event is sent. **Skip this call when you use hosted checkout** — the hosted page confirms the intent itself. **Operator choice**, in order: the `operator` you send → automatic routing among the project's enabled operators (when `automatic_operator` is true) → the first entry of `allowed_operators`. The operator must have an active connection and be switched on for this project. **Errors** (besides the common ones): - `404 resource_missing` — no such intent in this project. - `400 payment_intent_unexpected_state` — the intent is not in `requires_payment_method` (already confirmed, paid, canceled, or a concurrent confirm won). Re-read the intent. - `400 operator_not_allowed` (`operator`) — the operator is not in `allowed_operators`; no eligible operator was found; the operator has no active connection or is not switched on for this project. - `400 operator_unknown` (`operator`) — the operator id is not known to this API. - `402` (`type: payment_method_error`) — the operator declined; `code` is the operator's reason. - `424` (`type: operator_error`) — the operator failed or timed out (`operator_timeout`). Safe to retry with the same `Idempotency-Key`. - `403 connector_required` / `403 settlement_account_required`.

POST/v1/payment_intents/{id}/confirm

Authorization

bearerAuth
AuthorizationBearer <token>

Secret API key as a bearer token: Authorization: Bearer sk_live_…. Test keys (sk_test_…) are refused with 401 test_mode_unavailable. Keys are issued per project in the dashboard. Never expose a secret key in browser or mobile code.

In: header

Path Parameters

id*string

PaymentIntent id (pi_…).

Header Parameters

Idempotency-Key*string

Required on every POST and DELETE (missing → 400 parameter_missing; longer than 255 characters → 400 parameter_invalid). Use one stable key per logical operation, e.g. your order id plus the action. A retry with the same key and the same body returns the recorded response (header Idempotent-Replayed: true) instead of acting twice. The same key with a different body or path → 409 idempotency_key_in_use. While the first request is still running, a duplicate gets 409 idempotency_in_flight — wait a moment and retry. Successful (2xx) and declined (402) responses are recorded for 48 hours; other errors are not, so a retry after fixing a 400 runs normally. Keys are scoped to the API key's project.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Optional body for confirm. An empty body (or no body) is valid.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/payment_intents/pi_k3vq7m2xw5nbt4rj6yhc2dpa7e/confirm" \  -H "Idempotency-Key: order-1001-create" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "pi_k3vq7m2xw5nbt4rj6yhc2dpa7e",
  "object": "payment_intent",
  "amount": 15000,
  "currency": "MNT",
  "description": "Order #1001",
  "status": "requires_action",
  "client_secret": "cs_n2xk5q7mw3tz4vbr6jcy2gfa7m",
  "automatic_operator": true,
  "allowed_operators": [],
  "selected_operator": "op_example",
  "next_action": {
    "type": "qr",
    "qr": {
      "text": "0002010102121531...",
      "image_url": "https://example.invalid/qr.png"
    }
  },
  "metadata": {
    "order_id": "1001"
  },
  "livemode": true,
  "created": 1791774000,
  "expires_at": 1791774900
}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "amount is required",
    "param": "amount",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}

{
  "error": {
    "type": "api_error",
    "code": "test_mode_unavailable",
    "message": "test keys are not accepted by this API; use a live secret key",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}

{
  "error": {
    "type": "payment_method_error",
    "code": "amount_too_small",
    "message": "amount below the operator's minimum",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}
{
  "error": {
    "type": "api_error",
    "code": "connector_required",
    "message": "connect a payment operator before creating payments — see the Connectors page in your dashboard",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_missing",
    "message": "no such payment_intent",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}
{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_in_flight",
    "message": "A request with this Idempotency-Key is still being processed; retry shortly",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}
{
  "error": {
    "type": "operator_error",
    "code": "operator_timeout",
    "message": "the operator did not respond in time; please retry",
    "request_id": "req_8f3a1c9e5b7d2f4a6c0e9b1d"
  }
}