Airwallex Payment
Momen uses Airwallex Drop-in to support one-time payments in multiple currencies, recurring payments, and refunds. Before you begin, read the Payment Overview to prepare an order table and learn how payment results are handled.
Before you begin
Sign in to the Airwallex demo environment or production environment . Under Settings → Developers → API Keys, create an API key and save the Client ID. The API key is shown only once, when it is created; if you lose it, generate a new one.


If your account uses a legal entity or a linked payment account, also get the Legal entity ID and the Linked payment account ID under Settings → Entities.


If you need recurring payments, create a product and a recurring price under Billing → Products in the Airwallex dashboard and copy the price ID.
Set up the payment configuration
Create a payment configuration
Open Action → Payment, select Create new, enter a name for the configuration, choose Airwallex as the Payment channel, and select Create and start configuration. If this is the project’s first payment configuration, you need to bind an order table first.
In the configuration panel, copy the Notification URL under Payment result handling. You need it in the next step.
Create an Airwallex webhook
In the Airwallex dashboard, open Settings → Webhooks and create a webhook:

- API version: Enter
2025-11-11. - Account: Select the account that matches the Linked payment account ID. If you do not use a linked payment account, select your current collection account.
- Notification URL: Enter the Notification URL shown in the payment configuration.
- Events: Select the following events.
payment_intent.succeeded
payment_intent.cancelled
invoice.finalized
subscription.in_trial
subscription.active
subscription.unpaid
subscription.cancelled
subscription.modified
refund.accepted
refund.failed
After you create the webhook, copy its webhook secret.

Enter merchant information
| Setting | Required | Input | Description |
|---|---|---|---|
| Environment | Yes | Select | DEMO for testing, PROD for production |
| Client ID | Yes | Text | The Client ID of your Airwallex account |
| API key | Yes | Secret | Your Airwallex API key |
| Webhook secret | Yes | Secret | The secret of the webhook you created in the previous step |
| Legal entity ID | No | Text | Required only if you use a legal entity |
| Linked payment account ID | No | Text | Required only if you use a linked payment account |
Environment must match the Airwallex environment of the Client ID, the API key, and the webhook. You can create one payment configuration for the demo environment and another for production.
Choose payment products and clients
Under Payment products, select Drop-in. Under Client management, select your web app client.
Set up payment result handling
Under Payment result handling, bind an Actionflow to each of On payment, On refund, On subscription status change, and On recurring billing. For details, see Set up payment result Actionflows below.
Set permissions
Open Permission management and select the payment types each role can start through this configuration:
| Payment type | Default | Recommendation |
|---|---|---|
| One-time payment | Granted to all roles | Keep it for roles that need to pay, such as logged-in users |
| Subscription | Granted to all roles | Keep it for roles that need to subscribe; it covers starting and canceling recurring payments |
| Refund | Not granted | Grant it to the roles of paying users; Airwallex refunds can only be started by the account that made the payment |
You can also review and change these permissions under Settings → Permissions → Payment.
Set up payment result Actionflows
Airwallex has four payment events: On payment, On refund, On subscription status change, and On recurring billing. If you only use one-time payments, you only need the first two. When Momen receives a notification from Airwallex, it updates the corresponding payment records first and then runs the matching Actionflow. Use these Actionflows to update orders, grant or revoke access, and handle any other business logic.
On payment
When a user’s payment succeeds, the payment record changes to SUCCESSFUL and Momen runs this Actionflow. It does not run when a payment fails or the user cancels it.
Add an input
Add an input named payment_id (Integer) to the Actionflow, and in the payment configuration, bind it to Payment callback → Payment → id.
Query the payment record
Add a Database node that queries the payment_record table where id equals payment_id.
Verify the payment amount
The amount actually paid may differ from the amount on the order, so verify the amount before you do anything else.
Do not skip this step. Without it, an attacker can tamper with the payment amount and complete an order for far less than its price, causing you a direct financial loss.
Add a Condition node that checks both of the following:
payment_record/grand_total_valueequalspayment_record/order/{amount field}.payment_record/currencyequalspayment_record/order/{currency field}.
Airwallex stores grand_total_value in the major currency unit; for example, USD 10.00 is stored as 10.
Update the order and grant access
In the branch where the condition is met:
- Add a Database node that updates the order table and sets the order status to paid.
- Grant access as your business requires, for example by activating a membership for the account, adding points, or sending a notification.
The finished Actionflow looks like this:
On refund
Once a refund has a result, the refund record changes to REFUNDED (the refund succeeded) or FAILED (the refund failed), and Momen runs this Actionflow. Because it runs in both cases, handle each one separately.
Add an input
Add an input named refund_id (Integer), and in the input configuration, bind it to Payment callback → Refund → id.
Query the refund record
Add a Database node that queries the refund table where id equals refund_id.
Handle each refund result
Add a Condition node with the following branches:
refund/statusequalsREFUNDED: The refund succeeded. Inside this branch, add another Condition node to tell a full refund from a partial one:refund/amountequalsrefund/payment_record/grand_total_value: It is a full refund. Update the order status and revoke all access that was granted.- Otherwise: It is a partial refund. Update the order status as your business requires and revoke the corresponding part of the access.
refund/statusequalsFAILED: The refund failed. Notify an administrator or the user as needed, and leave the order unchanged.
The finished Actionflow looks like this:
On subscription status change
When the status of a subscription or its cancel at period end flag changes, Momen updates the recurring_payment record and runs this Actionflow, for example when a subscription becomes active, a charge becomes overdue, or a subscription is canceled. Notifications that only move the billing period do not run it.
Add an input
Add an input named recurring_payment_id (Integer), and in the input configuration, bind it to Payment callback → Recurring payment → id. If you need to know which status the subscription changed from, add a Text input as well and bind it to Payment callback → Previous status.
Query the recurring payment record
Add a Database node that queries the recurring_payment table where id equals recurring_payment_id.
Airwallex subscription statuses are stored in the recurring_payment record as follows:
| Airwallex status | Stored status |
|---|---|
PENDING | INCOMPLETE |
IN_TRIAL | TRIALING |
ACTIVE | ACTIVE |
UNPAID | PAST_DUE |
CANCELLED | CANCELED |
Handle each subscription status
Add a Condition node with the following branches:
- Status is
ACTIVE: Activate or restore the subscriber’s access. - Status is
PAST_DUEorUNPAID: A charge did not succeed. Suspend access or remind the user as your business requires. - Status is
CANCELEDorINCOMPLETE_EXPIRED: The subscription has ended. Revoke the subscriber’s access.
When a branch adds a Database node to update data, you can filter by fields of the recurring payment record:
- To update the account, filter the account table where
idequalsrecurring_payment/account_id. - To update the order, filter the order table where
idequalsrecurring_payment/first_order_id.
When a user cancels a subscription, cancel at period end changes to true first. The subscription remains valid until the end of the current period, so you can remind the user if needed. The status changes to CANCELED only when the period ends.
The finished Actionflow looks like this:
On recurring billing
When a subscription issues a new invoice, Momen creates a payment record for that billing period and runs this Actionflow. The payment record is not yet linked to an order, and the only job of this Actionflow is to create that order and return its ID.
This Actionflow must use synchronous execution and output the ID of the new order. Otherwise, the editor reports an error and the payment record for that period cannot be linked to an order.
Set the execution mode and output
Set the Actionflow to synchronous execution, and add an Integer output that returns the ID of the new order.
Add an input
Add an input named payment_id (Integer), and in the input configuration, bind it to Payment callback → Payment → id.
Query the payment and order records
- Add a Database node that queries the
payment_recordtable whereidequalspayment_id. - Add a Database node that queries the order table where
idequalspayment_record/recurring_payment/first_order_idto get the first order of the subscription.
Create the order for this billing period
Add a Database node that inserts a new order into the order table. Fill in the amount, account, product, and other fields from the order record you queried in the previous step, and set the order status to pending payment.
Return the order ID
Assign the ID of the new order to the output. Momen writes it back to the payment record for this period.
The finished Actionflow looks like this:
Only create the order here; do not grant access. When the charge for this period succeeds, On payment runs, and that is where you update the order and grant access for the period after the amount check.
Set up frontend payment actions
One-time payments
Add an action that creates the order
Before calling the payment action, create an order in the bound order table. Keep the order amount, products, user, and other business data in the order table.
Add the payment action
Add a Payment action to the Trigger of a button or another component. Set Payment type to One-Off Payment, select the Airwallex configuration you created under Payment configuration, and select Drop-in as the Payment product.
| Parameter | Type | Required | Description |
|---|---|---|---|
| Order id | Integer | Yes | ID of the order record in the bound order table |
| Currency | Text | Yes | A currency code supported by Airwallex, such as USD or HKD |
| Amount | Decimal | Yes | Amount in the major currency unit, greater than 0; for example, enter 10 to charge USD 10.00 |
Disable the payment button as soon as the user selects it, and keep it disabled until the payment action returns or checkout closes, so that checkout does not open twice.
The On success branch of the payment action means only that the frontend call returned successfully; On payment determines the final payment status. For security reasons, actions that modify data cannot be added under On success.
Handle the completed payment
When the payment succeeds, Momen changes the payment record to SUCCESSFUL and runs the Actionflow bound to On payment, where you update the order and grant access. See On payment.
Show the final result
Query the order table or the payment_record table on the frontend to show the final status. To refresh the status promptly, use a subscription query.
Refunds
Grant the refund permission
An Airwallex refund can only be started by the account that made the payment; refunds started by any other account fail. Under Permission management in the payment configuration, select Refund for the roles of your paying users, and decide in your app when to show the refund option, for example only when the order qualifies for a refund.
Add the refund action
Add a Payment action and set Payment type to Refund.
| Parameter | Type | Required | Description |
|---|---|---|---|
| Payment id | Integer | Yes | ID of the payment record to refund, not the order ID |
| Refund Amount | Decimal | Yes | Amount in the major unit of the original currency; if it exceeds the remaining refundable amount, only the remaining amount is refunded |
To get the payment ID, query the payment_record table filtered by the order ID. Only payment records in SUCCESSFUL or PARTIALLY_REFUNDED status can be refunded.
Handle the refund result
A new refund record starts in REFUNDING status. When Airwallex sends refund.accepted or refund.failed, Momen changes the refund record to REFUNDED or FAILED and runs the Actionflow bound to On refund. See On refund.
Recurring payments
Start a subscription
Add a Payment action. Set Payment type to Recurring Payment and Type to Initiate, select the Airwallex configuration you created under Payment configuration, and select Drop-in as the Payment product.
| Parameter | Type | Required | Description |
|---|---|---|---|
| Order id | Integer | Yes | ID of the order record for the first subscription period |
| Price ID | Text | Yes | ID of the Airwallex recurring price |
After the user saves a payment method at checkout, Momen creates an auto-charging subscription, a recurring_payment record in INCOMPLETE status, and a payment record linked to the first order. The frontend branches reflect only the authorization interaction; whether the subscription is active is determined by the status of the recurring_payment record.
Cancel a subscription
Add a Payment action. Set Payment type to Recurring Payment and Type to Cancel, and bind the Recurring Payment id of the subscription to cancel. Only the subscribing account can cancel its subscription.
The subscription ends at the end of the current period. Its cancel at period end flag changes to true immediately, and its status changes to CANCELED when the period ends, which runs On subscription status change.
Troubleshooting
- Webhook verification fails: Make sure the Notification URL, webhook secret, API version, and account match the payment configuration.
- The payment status does not update: Make sure the required events are selected, Environment matches your credentials, and the payment configuration has been published.
- A canceled payment does not run an Actionflow: Canceling a payment does not trigger any event; the payment record status is
CANCELLED. - The subscription is authorized but access is not granted: Rely on the
ACTIVEstatus of therecurring_paymentrecord, not only on the frontend success branch. - A renewal creates a payment record without an order: Make sure the On recurring billing Actionflow uses synchronous execution and returns the order ID.
- A refund fails because the payment does not belong to the current user: Airwallex refunds can only be started by the account that made the payment.