PaymentIntents
PaymentIntent is the core object of your Payments integration. It allows you to create a stateful object that tracks a payment from initial checkout to final settlement.
This guide covers how to create, manage, and secure your PaymentIntents.
Set up the server to create a PaymentIntent
When the shopper begins the checkout process, you will need to create a PaymentIntent object API to indicate your intent to collect payment from the shopper.
When the checkout page loads, on your server, call Create a PaymentIntent API with the required fields. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious shoppers from being able to alter the payment amount.
To initialize a payment, you must provide:
amount: The amount to charge specified in major units as defined by ISO 4217. For example, $9.99 is represented as9.99.currency: The 3-letter ISO 4217 currency code, for example, USD, AUD.merchant_order_id: Your unique internal reference ID.request_id: Your unique idempotency key (v4 UUID) used to prevent duplicate transactions by ensuring that retried API calls with the same ID are only processed once.
1curl -X POST https://api-demo.airwallex.com/api/v1/pa/payment_intents/create \2 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \3 -H 'Content-Type: application/json' \4 -d '{5 "amount": 100,6 "currency": "USD",7 "merchant_order_id": "D202503210001",8 "request_id": "b01737e5-c5ab-4765-8834-cbd92dfeaf81",9 "descriptor": "Airwallex - Test Descriptor",10 "return_url": "https://www.airwallex.com",11 "metadata": {12 "foo": "bar"13 }14 }'
The id and client_secret of the created PaymentIntent object API are returned in the response.
Handle the client secret
The client_secret is a secure key returned in the API response when you successfully create a PaymentIntent. It serves as the secure handshake between your backend and the Airwallex SDK on your frontend.
It allows the frontend SDK to authenticate the session, collect payment details, and trigger any 3D Secure challenges without exposing your private API keys.
You must pass the client_secret string directly to your frontend SDK configuration. See Quickstart: Your first online payment.
Validity and expiry
The client secret acts as a temporary session token. It is critical to handle its lifecycle correctly:
-
The secret is valid for 60 minutes from the moment the PaymentIntent is created. If a customer stays on your checkout page for longer than 60 minutes, the secret will expire, and the SDK will fail to process the payment. You must handle this scenario in your frontend logic and trigger your backend to create a new PaymentIntent to obtain a fresh client secret.
-
The secret cannot be refreshed or extended on an existing PaymentIntent.
Never log the client_secret in plain text server logs. Never expose your main API keys (Client ID / API Key) to the frontend. Only the client_secret is safe to be visible in the browser code.
Best practices for creating PaymentIntents
Use request_id for idempotency
If you try to create a PaymentIntent and the network times out, retrying without a request_id might create a duplicate order. However, if you retry with the unique request_id from the original create request, Airwallex will return the original successful response instead of creating a duplicate.
Pass customer metadata early
Attaching data at creation time improves fraud detection and reporting.
- If you have a
customer_id, pass it during PaymentIntent creation to enable saved card payments. Alternatively, you can provide customer details via thecustomerobject. - Use the
metadataobject to store your internal IDs, for example,{"campaign_id": "summer_sale"}. This data persists on the transaction report for easy reconciliation.
Manage order changes
Shoppers often change their mind after the checkout page loads, for example, adding a coupon or changing shipping.
Do not create a new PaymentIntent. Instead, update the existing PaymentIntent using the Update PaymentIntent API endpoint before the payment is confirmed, i.e., before the user clicks Pay. This avoids duplicate PaymentIntents and makes reconciliation easier.
Handling payment confirmation
When you confirm the PaymentIntent, Airwallex attempts to authorize the amount. Airwallex recommends automatic confirmation using integration options powered by Airwallex.js, that is, Hosted Payment Page, Drop-in Element, Embedded Elements, as the SDK handles confirmation automatically when the user clicks Pay. You do not need to call Confirm a PaymentIntent API endpoint from your server.
Handling asynchronous results
Not all payments succeed immediately. Local payment methods like direct debits or 3D Secure transactions may stay in a PENDING or REQUIRES_CUSTOMER_ACTION status respectively. Rather than relying on the API response alone, always listen to webhooks (payment_intent.succeeded) to fulfill orders. This ensures you capture successful payments even if the user closes their browser window early. See Payment statuses for webhooks emitted for each status.