Skip to main content

Create an Intent

Your backend creates the intent when the customer reaches checkout, using the amount you calculated from the cart. This is the step that authorizes the charge.

Endpoint: POST /v1/payment_intents

Authentication: Secret key

POST /v1/payment_intents
{
"amount": 10000,
"currency": "SAR",
"description": "Order #1234",
"callback_url": "https://example.com/checkout/payer-return"
}

The response includes the client_secret and the expiry:

{
"id": "8f4d1c3e-6a52-4f0b-9a1e-2c7b5d8e0f31",
"amount": 10000,
"currency": "SAR",
"description": "Order #1234",
"callback_url": "https://example.com/checkout/payer-return",
"status": "created",
"client_secret": "pi_secret_7Kq2mXbN9vT4wPzR1sYcHdLjF6aGuE8oQ3iK5nB0xVtZrWyM",
"expires_at": "2026-08-19T13:20:44.000Z",
"fulfilled_at": null,
"created_at": "2026-08-19T12:20:44.000Z"
}

Fields​

FieldRequiredNotes
amountYesInteger, in the currency's smallest unit. Locked.
currencyNoISO-4217 code. Defaults to SAR. Locked.
descriptionNoShown to you, never to the payer. Up to 8000 characters. Locked.
callback_urlNoWhere the payer returns after the payment. Locked. Required for card and token payments — see below.

All four are fixed at creation. The fulfillment request cannot override them.

Set callback_url here, not at fulfillment

Card and saved-token payments require a callback_url, and because the field is locked to the intent, it has to be set when you create the intent. An intent created without one cannot be fulfilled with a creditcard or token source — the fulfillment fails validation, and no payment is created.

Handing the secret to your frontend​

Return only what the browser needs — the intent id and the client_secret — from your own checkout endpoint:

Your backend's response to your frontend
{
"intent_id": "8f4d1c3e-6a52-4f0b-9a1e-2c7b5d8e0f31",
"client_secret": "pi_secret_7Kq2mXbN9vT4wPzR1sYcHdLjF6aGuE8oQ3iK5nB0xVtZrWyM"
}

Treat the client_secret as a credential for that one payment. It is all a browser needs, alongside your publishable key, to charge the approved amount — so send it only to the customer whose checkout it belongs to, over HTTPS, and never log it or put it in a URL.

Errors​

The secret key is required. A request made with the publishable key, or from a dashboard session, is rejected with 403.

Validation failures return 400 with "type": "validation_error" and the offending fields in errors — for example an amount below the minimum, a non-integer amount, or an unsupported currency.

Next​

Fulfill the intent from the browser.