Airwallex logo

Simulate a Transaction RFI

Copy for LLMView as Markdown

A Transaction RFI is raised when a transfer is flagged for transaction monitoring review. This page walks through simulating that scenario end to end, including the important case where the transfer is declined rather than sent.

For the underlying simulation API reference, see Simulate RFI sessions. For production RFI handling, see Handle Transaction RFI.

Responding to or closing an RFI does not by itself send the transfer. Your answers let the review proceed, but the transfer outcome is decided by the review and may be SENT or FAILED. Track the transfer's own status to determine the result, and never mark a payout complete just because the RFI closed.

Flow overview

  1. Create a transfer.
  2. Simulate a Transaction RFI raised against it, linked to the transfer.
  3. Receive the rfi.action_required webhook, fetch the RFI, and present the questions to your user.
  4. Submit the answer and close the RFI.
  5. Confirm the transfer reaches its separately decided outcome: SENT or FAILED.

Before you begin

  • Complete the sandbox setup and obtain an access token.
  • Subscribe a webhook endpoint to the rfi.action_required, rfi.answered, and rfi.closed RFI webhook events.
  • Ensure you have sufficient balance and a beneficiary so you can create a transfer.

As a platform account, call the simulation and RFI APIs on behalf of the connected account using the x-on-behalf-of header.

Create a transfer

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/transfers/create \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
4 -d '{
5 "request_id": "{{REQUEST_ID}}",
6 "beneficiary_id": "{{BENEFICIARY_ID}}",
7 "source_currency": "USD",
8 "transfer_currency": "AUD",
9 "transfer_method": "SWIFT",
10 "source_amount": 10,
11 "reason": "goods_trade_online",
12 "reference": "your-reference"
13 }'

See Create a transfer API for the full set of fields. Save the transfer id so you can link the RFI to it in the next step.

Simulate a Transaction RFI

Call Create an RFI API with type: "TRANSACTION", and link it to your transfer using sources on the question.

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/simulation/rfis/create \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
4 -d '{
5 "type": "TRANSACTION",
6 "questions": [
7 {
8 "answer": {
9 "type": "TEXT"
10 },
11 "sources": [
12 {
13 "type": "TRANSFER",
14 "id": "{{TRANSFER_ID}}"
15 }
16 ]
17 }
18 ]
19 }'

The response has type: "TRANSACTION" and status ACTION_REQUIRED.

Receive the webhook and fetch the RFI

Your endpoint receives an rfi.action_required event. Read the RFI ID from data.id and confirm data.sources[0].id matches your transfer, then retrieve the full RFI to read the questions.

Shell
1curl https://api-demo.airwallex.com/api/v1/rfis/{{RFI_ID}} \
2 -H 'Authorization: Bearer {{ACCESS_TOKEN}}'

Present the questions to your user and note each question_id for the response.

Submit the response and close the RFI

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/rfis/{{RFI_ID}}/respond \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
4 -d '{
5 "questions": [
6 {
7 "id": "{{QUESTION_ID}}",
8 "answer": {
9 "type": "TEXT",
10 "text": "Payment for consulting services invoice #1234"
11 }
12 }
13 ]
14 }'

The RFI moves to ANSWERED and you receive an rfi.answered webhook. Then close the RFI to simulate the review being resolved:

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/simulation/rfis/{{RFI_ID}}/close \
2 -H 'Authorization: Bearer {{ACCESS_TOKEN}}'

The RFI moves to CLOSED and you receive an rfi.closed webhook.

Confirm the transfer outcome

The review decides whether the transfer is sent or fails. Simulate each outcome with a transfer status transition. See Simulate transfer status transition for details.

Approved:

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/simulation/transfers/{{TRANSFER_ID}}/transition \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
4 -d '{
5 "next_status": "SENT"
6 }'

Declined:

Shell
1curl -X POST https://api-demo.airwallex.com/api/v1/simulation/transfers/{{TRANSFER_ID}}/transition \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
4 -d '{
5 "next_status": "FAILED"
6 }'

Test both outcomes. When the transfer is FAILED, the RFI still reads CLOSED with its sources pointing at the transfer. This confirms your integration does not assume that a closed RFI means a sent transfer.

Was this page helpful?