Quickstart: Split card element
Complete a minimal end-to-end card payment in the sandbox using Airwallex.js and the Split card elements (Card Number JS, Card Expiry JS, and Card CVC JS). By the end of this tutorial, you will have a working checkout page and a successful test payment in the sandbox.
You'll do the following:
- Authenticate to Airwallex and generate an access token.
- Create a PaymentIntent on your server.
- Build a checkout page that mounts the split card fields and confirms the PaymentIntent from the browser.
- Verify the result in the Airwallex web app, via API, or with webhooks.
Airwallex AgentOS can accelerate your integration. Connect your coding assistant to the Developer MCP for API and SDK guidance while you build, or use the airwallex CLI for production reads and writes.
Before you begin
- You must have a sandbox account for testing.
- Payments must be enabled on your Airwallex account with at least one payment method activated under Payments > Payment methods in the web app.
- You must have your Client ID and API key from Developer > API keys in the sandbox web app.
- You must be able to make HTTP requests from a backend server and serve a simple HTML page (or equivalent) that loads the Airwallex.js script from the CDN.
- Install Airwallex.js JS from the CDN (as in this tutorial) or via
@airwallex/components-sdk. If you currently use Airwallex Payment elements , see the upgrade guide.
Step 1: Get an access token on your server
Payment APIs require an access token generated from your Client ID and API key.
Request
1curl -X POST https://api-demo.airwallex.com/api/v1/authentication/login \2 -H 'Content-Type: application/json' \3 -H 'x-api-key: {{YOUR_SANDBOX_API_KEY}}' \4 -H 'x-client-id: {{YOUR_SANDBOX_CLIENT_ID}}'
Response
1{2 "token": "your_access_token",3 "expires_at": "2025-12-31T23:59:59Z"4}
Save the token in your backend and reuse it until it expires.
Keep your Client ID, API key, and access tokens on your server only. Do not expose them in frontend code or mobile apps.
Step 2: Create a PaymentIntent on your server
A PaymentIntent represents your intent to collect a specific amount from a shopper. The split card elements collect details against that intent; you confirm it when the shopper submits payment.
End-to-end flow (sequence diagram)
When the shopper begins checkout, call Create a PaymentIntent API on your server with request_id, amount, currency, and merchant_order_id. Always decide how much to charge on the server so shoppers cannot alter the amount.
Provide return_url so Airwallex can return the shopper to your site after flows that require a redirect (for example some 3D Secure authentication or wallet flows). Learn more about the PaymentIntents API.
Request
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 "request_id": "b01737e5-c5ab-4765-8834-cbd92dfeaf81",6 "amount": 100,7 "currency": "USD",8 "merchant_order_id": "D202503210001",9 "return_url": "https://www.example.com/payment-return"10 }'
Response
The API returns a PaymentIntent object. See Create a PaymentIntent API for the full response schema.
1{2 "id": "int_your_payment_intent_id",3 "request_id": "b01737e5-c5ab-4765-8834-cbd92dfeaf81",4 "amount": 100,5 "currency": "USD",6 "merchant_order_id": "D202503210001",7 "status": "REQUIRES_PAYMENT_METHOD",8 "created_at": "2024-01-30T03:31:29+0000",9 "updated_at": "2024-01-30T03:31:29+0000",10 "client_secret": "your_client_secret"11}
For the checkout page in Step 3, you will need:
id: The PaymentIntent ID (intent_idon the client).client_secret: Used on the client to attach card details and confirm securely.currency: The same currency you passed when creating the PaymentIntent.
Step 3: Build a basic checkout page with Split card elements
Build a simple HTML page that loads Airwallex.js from the CDN, initializes the SDK, creates the Card Number JS, Card Expiry JS, and Card CVC JS elements, mounts them into containers, and calls confirm() JS on the card number element when the shopper clicks Pay. Mount each element only once per payment flow.
Add the SDK, containers, and script
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="utf-8" />5 <title>Quickstart — Split card element</title>6 <script src="https://static.airwallex.com/components/sdk/v1/index.js"></script>7</head>8<body>9 <h1>Split card element integration</h1>10 <p>Enter card details, then click Pay to confirm the PaymentIntent.</p>1112 <div>13 <div>Card number</div>14 <div id="cardNumber"></div>15 </div>1617 <div>18 <div>Expiry</div>19 <div id="expiry"></div>20 </div>2122 <div>23 <div>CVC</div>24 <div id="cvc"></div>25 </div>2627 <button id="submit" type="button">Pay</button>2829 <script async>30 const intent_id = 'replace-with-your-intent-id';31 const client_secret = 'replace-with-your-client-secret';32 const currency = 'replace-with-your-currency';3334 (async () => {35 await window.AirwallexComponentsSDK.init({36 env: 'demo',37 enabledElements: ['payments'],38 });3940 const cardNumber = await window.AirwallexComponentsSDK.createElement('cardNumber', {41 intent_id,42 client_secret,43 currency,44 });4546 const expiry = await window.AirwallexComponentsSDK.createElement('expiry');47 const cvc = await window.AirwallexComponentsSDK.createElement('cvc');4849 cardNumber.mount('cardNumber');50 expiry.mount('expiry');51 cvc.mount('cvc');5253 document.getElementById('submit').addEventListener('click', () => {54 cardNumber55 .confirm({56 intent_id,57 client_secret,58 })59 .then((response) => {60 // Inspect response; always verify PaymentIntent status on your server61 console.log(response);62 })63 .catch((err) => {64 console.error(err);65 });66 });67 })();68 </script>69</body>70</html>
Replace replace-with-your-intent-id, replace-with-your-client-secret, and replace-with-your-currency with the values from the PaymentIntent you created in Step 2.
Optionally, omit intent_id, client_secret, and currency from createElement('cardNumber', …) and pass them only in confirm() after you create the PaymentIntent when the shopper clicks Pay. You can pass additional options in createElement() (for example style JS or 3DS-related fields such as authFormContainer JS). For all options, see Card Number JS, Card Expiry JS, and Card CVC JS.
Using npm instead of the CDN
If you bundle your frontend with npm, use the same flow with module imports:
1import { init, createElement } from '@airwallex/components-sdk';23await init({4 env: 'demo',5 enabledElements: ['payments'],6});78const cardNumber = createElement('cardNumber', {9 intent_id: 'replace-with-your-intent-id',10 client_secret: 'replace-with-your-client-secret',11 currency: 'replace-with-your-currency',12});1314const expiry = createElement('expiry');15const cvc = createElement('cvc');1617cardNumber.mount('cardNumber');18expiry.mount('expiry');19cvc.mount('cvc');2021document.getElementById('submit').addEventListener('click', () => {22 cardNumber23 .confirm({24 intent_id: 'replace-with-your-intent-id',25 client_secret: 'replace-with-your-client-secret',26 })27 .then((response) => {28 console.log(response);29 })30 .catch((err) => {31 console.error(err);32 });33});
Step 4: Test with sandbox cards and verify the payment
Use test cards in the sandbox
Use the test card numbers to test success, failure, and 3DS flows. Create a new PaymentIntent for each test case and use the new id and client_secret on your checkout page.
Run at least:
- One successful card payment.
- One failed payment (invalid card or insufficient funds).
- One 3DS scenario.
Verify the PaymentIntent status
Verify that the payment worked in one of these ways:
-
Airwallex web app
Go to Payments > Payments Activity in the web app and confirm that your payments appear.
-
Retrieve PaymentIntent via API
Shell1curl -G https://api-demo.airwallex.com/api/v1/pa/payment_intents/int_your_payment_intent_id \2 -H 'Authorization: Bearer {{ACCESS_TOKEN}}'Check for
status: "SUCCEEDED"on a successful test payment. -
Webhooks (recommended for production)
Configure a webhook endpoint for
payment_intent.succeededand related events. Use it to trigger order fulfillment, emails, or internal workflows instead of relying only on the clientconfirm()response—the shopper may close the browser before your handler runs. For details, see Listen for webhook events.
Next steps
-
Prepare for production
Implement idempotency on create and confirm calls, add robust error handling for declines and network errors, and validate 3DS flows in your key markets. See Airwallex.js error codes.
-
Customize checkout
-
Try the single-field Card element or other checkout options
For one multi-field control, follow Quickstart: Card element. For Korean local card fields, see Quickstart: Korean local card elements. For a pre-built multi-method block, see Quickstart: Drop-in element. For the redirect-based Hosted Payment Page, see Quickstart: Your first online payment. For more options, see Web checkout overview.
Complete the Test and go-live checklist before going live.
