A Payment Intent is the server-side record for one payment attempt. Use it when you need to separate creating a payment from confirming customer action, capture an authorization later, or recover an uncertain result without creating a duplicate payment.

Create the intent on your server

Resolve the final order amount and currency before creating the intent. The API key and internal order data stay on the server.
Return the intent ID and its short-lived client token through an authenticated server response. Never return x-api-key or the webhook secret to browser code.

Confirm the payment

Use the secure SDK or the confirm endpoint to collect payment details and complete customer action. The confirmation response describes the next state; it does not guarantee settlement.
Handle these states explicitly:
  • requires_payment_method: ask for another method or show a validation error
  • requires_action: keep the customer in the secure flow
  • processing: show pending and wait for the verified event
  • succeeded: compare amount, currency, and order ID before fulfillment
  • cancelled: close the unpaid order and release reserved inventory

Capture an authorization

Set captureMethod: "manual" when you need to authorize now and capture later, such as after inventory or fraud review. Capture the full amount or a lower amount before the authorization expires.
Capture once. If the request times out, retrieve the intent before retrying with the same idempotency key. A partial capture must agree with the order and inventory policy you stored before authorization.

Cancel or recover

Cancel an intent only when the order is abandoned, expired, or rejected before capture. If a create, confirm, or capture request returns a timeout, retrieve the intent by ID and reconcile its status. Never create a replacement intent because a response was lost. Fulfill only from a verified payment.confirmed event or an authoritative terminal retrieval. For delayed bank methods, keep the order pending and use the reconciliation guide when the browser and event timelines differ.