Airwallex logo

PaymentIntents

Copy for LLMView as Markdown

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 as 9.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.
Shell
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 the customer object.
  • Use the metadata object 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.

Was this page helpful?