Simulate payout status transition
You can conduct unit and end-to-end testing of your payouts integration using Transition Payment Status API. It is key to account for payout status scenarios as you build out your integration.
Transitioning a payout through its lifecycle triggers all production scenarios in the demo environment, including:
- Triggering webhook notification events for payouts including
payment.failed
,payment.cancellation_requested
,payment.cancelled
, andpayment.retried
- Viewing status changes for payouts on the Airwallex web app
- Retrieving payouts via get list of payments API and get payment by ID API
Payout scenarios
A payout API can be in one of the following statuses: NEW
, CANCELLED
, IN_REVIEW
, READY_FOR_DISPATCH
, SUSPENDED
, DISPATCHED
, FAILED
, CANCELLATION_REQUESTED
, and RETRIED
.
The Payouts production API endpoints only allow you to Cancel a payment API and Retry a payment API. With Transition Payment Status API simulation endpoint, you can emulate the following payout lifecycle scenarios in the demo environment:
Scenario | Status transition |
---|---|
Success | NEW => IN_REVIEW => READY_FOR_DISPATCH => DISPATCHED |
Failed & retried | FAILED => RETRIED (use existing Retry a payment API) or CANCELLED (use existing Cancel a payment API) |
Cancel | NEW => CANCELLATION_REQUESTED => CANCELLED (use existing Cancel a payment API) |
Suspended | NEW => IN_REVIEW => SUSPENDED => CANCELLED (using existing Cancel a payment API) |
A platform account can call Transition Payment Status API on behalf of a connected account using the x-on-behalf-of
header.
Step 1: Obtain your access token
Use obtain access token API to obtain an access token to call our API endpoints.
Example request
curl --location --request POST 'https://api-demo.airwallex.com/api/v1/authentication/login' \
--header 'Content-Type: application/json' \
--header 'x-client-id: [client_id]' \
--header 'x-api-key: [api_key]' \
--header 'Authorization: Bearer null' \
--data-raw ''
Example response
{
"expires_at": "2022-02-22T06:48:39+0000",
"token": "[jwt_token]"
}
Step 2: Create a payout
Use create a new payment API to create a new outbound payout. The status of this new payout will be either in NEW
or IN_REVIEW
depending on your account configuration.
Example request
curl --location --request POST 'https://api-demo.airwallex.com/api/v1/payments/create' \
--header 'Authorization: Bearer [jwt_token]' \
--header 'Content-Type: application/json' \
--data-raw '{
"beneficiary_id": “string”,
"payment_amount": 1000,
"payment_currency": "CNY",
"payment_method": "SWIFT",
"reason": "professional_business_services",
"reference": "Test df62a7d9-b884-489d-a8ed-391641b1f96f",
"request_id": "7cb56588-f38f-4cba-afda-0715e429775c",
"source_amount": null,
"source_currency": "USD",
"swift_charge_option": "SHARED"
}'
Example response
{
"amount_beneficiary_receives": 1000.0,
"amount_payer_pays": 173.72,
"beneficiary": {
"address": {
"city": "West Bradley",
"country_code": "CN",
"postcode": "25000",
"state": "Lake Winfieldmouth",
"street_address": "80766 Parisian Park"
},
"bank_details": {
"account_currency": "CNY",
"account_name": "Dr. Sherri Jaskolski",
"account_number": "21811154",
"bank_country_code": "CN",
"bank_name": "Huel and Sons",
"swift_code": "ABOCCNBJ"
},
"company_name": "Lueilwitz Inc",
"entity_type": "COMPANY"
},
"created_at": "2022-03-02T02:59:19+0000",
"fee_amount": 15,
"fee_currency": "USD",
"fee_paid_by": "PAYER",
"last_updated_at": "2022-03-02T02:59:19+0000",
"payer": {
"additional_info": {
"business_incorporation_date": "1986-04-22",
"business_registration_number": "665-01-1109",
"business_registration_type": "COMPANY"
},
"address": {
"city": "Shanghai",
"country_code": "CN",
"postcode": "SH-09090",
"state": "SH",
"street_address": "Shanghai St"
},
"company_name": "Alan API Test",
"entity_type": "COMPANY"
},
"payment_amount": 1000.0,
"payment_currency": "CNY",
"payment_date": "2022-03-02",
"payment_id": "49c9469b-e392-4fe6-931f-72b6d3f278dd",
"payment_method": "SWIFT",
"reason": "professional_business_services",
"reference": "Test dff593c7-974a-4403-8016-38bf64555c4b",
"request_id": "92881d6f-0f45-457e-89f3-8c0ecac60fb8",
"selling": true,
"short_reference_id": "P220302-OSKZ0UD",
"source_amount": 158.72,
"source_currency": "USD",
"status": "NEW",
"swift_charge_option": "SHARED",
"underlying_conversion_id": "c45c73bc-e73d-45b4-9842-890a6f8d6c28"
}
Step 3: Transition the payout status
Use Transition Payment Status API to specify the next status you would like the payout to transition to.
You must provide the following parameters in the request:
next_status
: Specifies the next status the payout will transition to. Possible statuses areDISPATCHED
,FAILED
,IN_REVIEW
,READY_FOR_DISPATCH
, andSUSPENDED
.- If you specify
DISPATCHED
orFAILED
, then the status will automatically transition through intermediary statuses intoDISPATCHED
orFAILED
as part of the “Success” and “Failed & retried” payout scenarios respectively. - If you specify
IN_REVIEW
,READY_FOR_DISPATCH
,SUSPENDED
, then the status can only be transitioned if it is the next valid status in a payout flow, see payout scenarios.
- If you specify
failure_type
: Ifnext_status
isFAILED
, specify the failure reason token from the table below to simulate a specific failure reason, which is returned in thefailure_reason
field in the response.
Failure reason token | “failure reason” |
---|---|
INVALID_ACCOUNT_NAME_OR_NUMBER | 90101: Invalid account name/number |
INVALID_BANK_OR_BRANCH_CODE | 90201: Invalid bank/branch code |
INVALID_SWIFT_BIC_CODE | 90202: Invalid SWIFT/BIC code |
INVALID_CORRESPONDENT_BANK_INFORMATION | 90203: Invalid correspondent bank information |
INVALID_BANK_INFORMATION | 90204: Invalid bank information |
BENEFICIARY_NAME_MISMATCH | 90302: Account currency mismatch |
ACCOUNT_CURRENCY_MISMATCH | 90301: Beneficiary name mismatch |
INVALID_BENEFICIARY_DETAILS | 90401: Invalid beneficiary details |
INVALID_SPECIAL_CHARACTER | 90402: Invalid special character |
CHANNEL_POLICY | 90501: Channel policy |
TM_SUSPENDED | 90502: TM suspended |
EXCEEDED_TRANSACTION_AMOUNT_OR_LIMIT | 90601: Exceeded transaction amount or limit |
INSUFFICIENT_FUNDS | 90602: Insufficient funds |
TRANSACTION_AMOUNT_NOT_COVERING_FEE | 90603: Transaction amount not covering fee |
ACCOUNT_CLOSED | 90701: Account closed |
ACCOUNT_INACTIVE_OR_DORMANT | 90702: Account inactive or dormant |
ACCOUNT_UNDER_RESTRICTION | 90703: Account under restriction |
BENEFICIARY_REQUESTED | 90801: Beneficiary requested |
BENEFICIARY_BANK_RETURNED | 90802: Beneficiary bank returned |
INBOUND_BENFICIARY_VALIDATION_ERROR | 90901: Inbound benficiary validation error |
INBOUND_ORDER_ERROR | 90902: Inbound order error |
INBOUND_2B_CARD_NOT_SUPPORTED | 90903: Inbound 2B card not supported |
INBOUND_COMPANY_REGISTRATION_NUMBER_ERROR | 90904: Inbound company registration number error |
RECALL_REQUESTED | 91001: Recall requested |
CLIENT_REQUESTED | 91002: Client requested |
INVALID_PAYMENT_PURPOSE | 91101: Invalid payment purpose |
CARD_ISSUER_ERROR | 91201: Card issuer error |
DUPLICATION_RETURN | 91301: Duplication return |
SYSTEM_ERROR | 91401: System error |
CHANNEL_TIMEOUT | 91402: Channel timeout |
UNABLE_TO_APPLY | 99901: Unable to apply |
OTHER | 99902: Other |
Example request (success scenario)
curl --location --request POST 'https://api-demo.airwallex.com/api/v1/simulation/payments/{payment_id}/transition' \
--header 'Authorization: Bearer [jwt_token]' \
--header 'Content-Type: application/json' \
--data-raw '{
"next_status": "DISPATCHED"
}'
Example response (success scenario)
{
"amount_beneficiary_receives": 99996,
"amount_payer_pays": 10004,
"beneficiary": {
"additional_info": {
"business_area": "Travel",
"business_phone_number": "689342234",
"business_registration_number": "IT593003",
"legal_rep_first_name_in_chinese": "小芳",
"legal_rep_id_number": "110108199304203520",
"legal_rep_last_name_in_chinese": "刘",
"personal_email": "john.walker@gmail.com",
"personal_first_name_in_chinese": "大明",
"personal_id_number": "1234567890",
"personal_id_type": "CHINESE_NATIONAL_ID",
"personal_last_name_in_chinese": "李",
"personal_mobile_number": "+861234123412"
},
"address": {
"city": "Melbourne",
"country_code": "AU",
"postcode": "3000",
"state": "VIC",
"street_address": "15 William Street"
},
"bank_details": {
"account_currency": "AUD",
"account_name": "Lee Da Ming",
"account_number": "12750852",
"account_routing_type1": "bsb",
"account_routing_type2": "sort_code",
"account_routing_value1": "083064",
"account_routing_value2": "123456",
"bank_branch": "Melbourne",
"bank_country_code": "AU",
"bank_name": "National Australia Bank",
"bank_street_address": "500 Bourke Street, Melbourne 3000, Australia",
"binding_mobile_number": "654897612345",
"fingerprint": "2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c",
"iban": "ES8023100001180000012345",
"local_clearing_system": "ACH",
"swift_code": "CTBAAU2S",
"transaction_reference": "4140110135"
},
"company_name": "Complete Concrete Pty Ltd",
"date_of_birth": "1976-08-26",
"entity_type": "COMPANY",
"first_name": "John",
"last_name": "Walker"
},
"beneficiary_id": "string",
"created_at": "2017-03-22T16:08:02+1100",
"failure_reason": "Insufficient funds",
"failure_type": "UNKNOWN",
"fee_amount": 4,
"fee_currency": "AUD",
"fee_paid_by": "PAYER",
"last_updated_at": "2017-03-24T18:00:02+1100",
"payer": {
"additional_info": {
"business_registration_number": "EU300503",
"business_registration_type": "Partnership",
"external_id": "1234567890",
"personal_email": "james.smith@google.com",
"personal_id_number": "1234567890"
},
"address": {
"city": "Melbourne",
"country_code": "AU",
"postcode": "3000",
"state": "VIC",
"street_address": "15 William Street"
},
"company_name": "Complete Concrete Pty Ltd",
"date_of_birth": "1976-08-26",
"entity_type": "COMPANY",
"first_name": "James",
"last_name": "Smith"
},
"payer_id": "string",
"payment_amount": 10000,
"payment_currency": "AUD",
"payment_date": "2017-03-24",
"payment_id": "d9af1614-a6a1-4d45-aae7-6858fc6d9ede",
"payment_method": "SWIFT",
"reason": "travel",
"reference": "PMT1936398",
"request_id": "7f687fe6-dcf4-4462-92fa-80335301d9d2",
"short_reference_id": "20170322-9F6ML2",
"source_amount": 10000,
"source_currency": "CNY",
"status": "DISPATCHED",
"swift_charge_option": "SHARED",
"underlying_conversion_id": "d9af1614-a6a1-4d45-aae7-6858fc6d9ede"
}
Example request (failure scenario)
curl --location --request POST 'https://api-demo.airwallex.com/api/v1/simulation/payments//transition' \
--header 'Authorization: Bearer <your_bearer_token>' \
--header 'Content-Type: application/json' \
--data-raw ' {
"next_status": "FAILED",
"failure_type": "INVALID_SWIFT_BIC_CODE"
}'
Example response (failure scenario)
{
"request_id": "41d31fc5-2072-42f7-b00b-7ea53e2fdf8e",
"payment_id": "da5eea76-014e-4f6c-a26c-70d4204aab4b",
"payment_currency": "CNY",
"payment_amount": 1000.0,
"source_amount": 157.2,
"fee_currency": "USD",
"fee_amount": 15,
"fee_paid_by": "PAYER",
"amount_payer_pays": 172.2,
"amount_beneficiary_receives": 1000.0,
"payment_date": "2022-03-25",
"reason": "professional_business_services",
"reference": "Test 37327415-c8ef-4ec5-9476-89e16f11e874",
"payer": {
"entity_type": "COMPANY",
"company_name": "Alan API Test",
"address": {
"street_address": "Shanghai St, Shanghai St",
"country_code": "CN",
"postcode": "SH-09090",
"state": "SH",
"city": "Shanghai"
},
"additional_info": {
"business_registration_type": "COMPANY",
"business_registration_number": "665-01-1109",
"business_incorporation_date": "1986-04-22"
}
},
"beneficiary": {
"entity_type": "COMPANY",
"company_name": "Gulgowski and Sons",
"address": {
"street_address": "46894 Kevin Extensions",
"country_code": "CN",
"postcode": "25000",
"state": "Olgaburgh",
"city": "Arecibo"
},
"bank_details": {
"bank_name": "Harvey - Wilkinson",
"bank_country_code": "CN",
"swift_code": "ABOCCNBJ",
"account_name": "Robyn Quigley",
"account_number": "39595870",
"account_currency": "CNY"
}
},
"short_reference_id": "P220325-066UTIE",
"status": "FAILED",
"failure_reason": "90202: Invalid SWIFT/BIC code",
"failure_type": "INCORRECT_ROUTING",
"created_at": "2022-03-25T01:33:19+0000",
"last_updated_at": "2022-03-25T01:33:33+0000",
"payment_method": "SWIFT",
"swift_charge_option": "SHARED",
"source_currency": "USD",
"underlying_conversion_id": "a4272fc7-35b4-48f2-bf7a-33d20860a0e9",
"additional_info": {
"order_info_type1": [],
"underlying_payments": []
},
"selling": true
}
Next steps
- Call Transition Payment Status API if you would like to transition the status into another valid state.
- Cancel a payment API or retry a payment API with our existing endpoints.