Partner API

One partner API for onboarding, KYB, balances, virtual accounts, payins, FX, payouts and webhooks across all your organizations. Same shapes as api.finmo.net. Calls marked Sandbox only are test helpers.

Base URL
https://sandbox.finmotreasury.net/v1
Auth
HTTP Basic: base64(access_key:secret_key). Finmo issues the keys over a secure channel.
Act for an organization
x-on-behalf-of-org-id: <org_id> on wallet, virtual account, customer, payin, FX, beneficiary, payout and transaction calls.
Idempotency
X-Idempotency-Key (UUID v4) on every POST. The same key and body replays the original response with x-cached-request-id. The same key with a different body returns 409 (100010). Keys are kept 8 days.
Pagination
limit (max 100) and page on list endpoints. data is a plain array.
Envelope
{ request_id, request_time, success, status_code, status_text, data | error } Amounts are JSON numbers. Timestamps are ISO 8601 UTC.

Use it in Postman

  1. 1Import the collection. Download the Postman collection and import it with File, Import.
  2. 2Set two collection variables. baseUrl is already https://sandbox.finmotreasury.net. Put your sandbox access key (AK_FINMO_SBX_…) in accessKey and the secret in secretKey. Finmo sends this key pair over a secure channel, and it only works on the sandbox.
  3. 3Leave auth as it is. Every request inherits Basic auth from those variables. X-Idempotency-Key and x-on-behalf-of-org-id: {{orgId}} are set on the requests that need them.
  4. 4Run Happy path from top to bottom. Ids are captured as you go. Step 3 approves the organization at once. Run step 12 within 20 seconds of step 11, or quote again.
  5. 5Watch the webhooks. Point webhook_url at your own HTTPS endpoint in step 4. The sandbox also ships a hosted listener with a listener inbox. That listener is a sandbox add-on and does not exist in production.

The flow

From a new organization to a reconciled payout. Each call links to its reference below.

Onboarding

Create an organization, send its KYB and read it back.

POST/v1/partner/invite-organizationLive

Create organization

Creates a merchant organization under your partner account and its admin user. KYB status starts at NOT_STARTED. Send KYB with PATCH /v1/partner/kyb/save.

first_name*string
First name of the organization's primary user
last_name*string
Last name of the organization's primary user
org_name*string
Business name of the organization
org_country*string
Country of incorporation, ISO 3166-1 alpha-2
email*string
Email of the organization's user. It becomes the org's admin user
  • In production, Finmo emails this user a link to set a Finmo dashboard password. The sandbox has no merchant dashboard and sends no email.
  • The email you pass becomes the org's admin user. Use your client's own address, not yours.
curl -X POST 'https://sandbox.finmotreasury.net/v1/partner/invite-organization' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "first_name": "Test",
       "last_name": "Merchant",
       "org_name": "Test Org Pte Ltd",
       "org_country": "SG",
       "email": "merchant@example.com"
     }'
GET/v1/partner/organizationLive

List organizations

Your merchant organizations with their KYB status, newest first. Paged: data[] plus _metadata.

limitnumber, query
pagenumber, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/partner/organization' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
GET/v1/partner/organization/{org_id}Live

Get organization

The organization's KYB profile, business owners and KYB status.

curl -X GET 'https://sandbox.finmotreasury.net/v1/partner/organization/{org_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
PATCH/v1/partner/kyb/save/{org_id}Live

Save and submit KYB

Creates or updates the organization's KYB application. Send submit: true with all required fields to submit it for review.

submitboolean
true submits the application
legal_namestring
company_registration_numberstring
incorporation_datestring
address_line1string
business_owner[]array
Include business_owner_id to update an owner already saved
  • Sandbox only: submit: true approves the organization at once, opens its wallet and accounts, and sends VIRTUAL_ACCOUNT_CREATED webhooks. In production, Finmo compliance reviews the application before approving it.
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/partner/kyb/save/{org_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'content-type: application/json' \
  -d '{
       "submit": true,
       "name": "Acme Pte Ltd",
       "legal_name": "Acme Pte Ltd",
       "business_type": 1,
       "company_registration_number": "202012345A",
       "incorporation_date": "2020-01-15",
       "address_line1": "1 Raffles Place",
       "address_city": "Singapore",
       "address_zip_code": "048616",
       "company_registration_document_id": "{{org_document_id}}",
       "business_owner": [
         {
           "business_owner_type": "1",
           "first_name": "Jane",
           "last_name": "Doe",
           "dob": "1985-06-15",
           "nationality": "SG",
           "shareholder_percentage": "100",
           "identification_type": "PASSPORT",
           "identification_value": "E1234567X",
           "identification_document_id": "{{org_document_id}}"
         }
       ]
     }'
POST/v1/partner/organization-document/{org_id}Live

Request a document upload URL

Two-step upload: this returns org_document_id + upload_url (valid 30 seconds); PUT the file bytes to upload_url.

file_type*string
image/png, image/jpeg, image/jpg, application/pdf
doc_type*string
KYB_DOCUMENT or CUSTOMER_DOCUMENT
curl -X POST 'https://sandbox.finmotreasury.net/v1/partner/organization-document/{org_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "file_type": "application/pdf",
       "doc_type": "KYB_DOCUMENT"
     }'

Balances

What the organization holds, and every money movement with its fee.

GET/v1/walletx-on-behalf-of-org-idLive

List wallets

Wallet ids for the organization. One multi-currency wallet (category GCA) per organization. Header x-on-behalf-of-org-id: <organization org_id>.

curl -X GET 'https://sandbox.finmotreasury.net/v1/wallet' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/wallet/{wallet_id}x-on-behalf-of-org-idLive

Get wallet balances

wallet_account[] carries actual_balance and available_balance per currency. Available drops when a payout is created (funds reserved); actual drops when it completes.

curl -X GET 'https://sandbox.finmotreasury.net/v1/wallet/{wallet_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/balancex-on-behalf-of-org-idLive

Balances by currency

Currency map of actual and available balance for the organization.

curl -X GET 'https://sandbox.finmotreasury.net/v1/balance' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/transactionx-on-behalf-of-org-idLive

Transactions (reconciliation)

One record per money movement with fees, net amount and settlement flags.

event_typestring, query
PAYOUT, VIRTUAL_ACCOUNT
currencystring, query
start_timestring, query
end_timestring, query
limitnumber, query
pagenumber, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/transaction' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/transaction/{txn_id}x-on-behalf-of-org-idLive

Get transaction

One transaction.

curl -X GET 'https://sandbox.finmotreasury.net/v1/transaction/{txn_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'

Funding

The organization's virtual accounts, and a sandbox call that simulates money arriving.

GET/v1/virtual-accountx-on-behalf-of-org-idLive

List virtual accounts

The organization's collection accounts. The sandbox opens USD, EUR and GBP (SWIFT), SGD (SWIFT and FAST) and AUD accounts on approval, with the bank details shape production returns.

curl -X GET 'https://sandbox.finmotreasury.net/v1/virtual-account' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/virtual-account/{va_id}x-on-behalf-of-org-idLive

Get account details

One virtual account.

curl -X GET 'https://sandbox.finmotreasury.net/v1/virtual-account/{va_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'

Customers

The payers an organization collects from.

POST/v1/customerx-on-behalf-of-org-idLive

Create customer

An individual or company customer of the organization. With only first_name + last_name (individual) or name (company) the customer is PENDING_INFO; with every mandatory field it is APPROVED.

type*string
individual | company
account_usage_purposestring
individual | company*object
organization_reference_idstring
metadataobject
  • Sandbox: a customer with every mandatory field is APPROVED at once. In production it goes UNDER_REVIEW first.
curl -X POST 'https://sandbox.finmotreasury.net/v1/customer' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "type": "individual",
       "account_usage_purpose": "Receive payments from overseas clients",
       "individual": {
         "first_name": "Jane",
         "last_name": "Tan"
       }
     }'
GET/v1/customerx-on-behalf-of-org-idLive

List customers

Newest first.

typestring, query
limitnumber, query
pagenumber, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/customer' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/customer/{customer_id}x-on-behalf-of-org-idLive

Get customer

One customer.

curl -X GET 'https://sandbox.finmotreasury.net/v1/customer/{customer_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
PATCH/v1/customer/{customer_id}x-on-behalf-of-org-idLive

Update customer

type and account_usage_purpose are required; other fields are merged.

type*string
account_usage_purpose*string
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/customer/{customer_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "type": "individual",
       "account_usage_purpose": "Receive payments from overseas clients",
       "description": "Updated"
     }'

Payins

Collect from customers, and list the payin methods available.

GET/v1/payin-method/allx-on-behalf-of-org-idLive

Payin methods for a country

Payin methods enabled for a country and currency. The sandbox offers au_bank_npp (PayID, AUD) and sg_bank_paynowqr_sgd (PayNow QR, SGD) for direct payins, as Finmo's merchant sandbox does.

country*string, query
currency*string, query
is_va_allowedboolean, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/payin-method/all' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
POST/v1/payinx-on-behalf-of-org-idLive

Create payin

A payment request your payer completes. Returns PENDING with pay_code (a PayID for au_bank_npp, a QR for sg_bank_paynowqr_sgd). Expires after 48 hours.

amount*number
currency*string
payin_method_name*string
payin_method_paramobject
redirect_url*string
Or advanced_redirect_url
customer_idstring
organization_reference_idstring
curl -X POST 'https://sandbox.finmotreasury.net/v1/payin' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "amount": 100,
       "currency": "AUD",
       "payin_method_name": "au_bank_npp",
       "payin_method_param": {},
       "redirect_url": "https://example.com/return"
     }'
GET/v1/payinx-on-behalf-of-org-idLive

List payins

Includes virtual account top-ups (payin_type GCA_TOPUP).

statusstring, query
customer_idstring, query
payin_method_namestring, query
limitnumber, query
pagenumber, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/payin' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/payin/{payin_id}x-on-behalf-of-org-idLive

Get payin

One payin.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payin/{payin_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'

FX & payouts

Build the beneficiary form, save the beneficiary, quote, convert, pay and track.

GET/v1/payout-method/allx-on-behalf-of-org-idLive

Payout methods for a corridor

Rails available to a destination. beneficiary_country and beneficiary_currency are required.

beneficiary_country*string, query
beneficiary_currency*string, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-method/all' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/payout-method/param/{name}x-on-behalf-of-org-idLive

Fields a method needs

payout_beneficiary_param lists base_param (bank fields), company and individual fields with regex. Build the 'add supplier' form from this.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-method/param/{name}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
POST/v1/payout-beneficiaryx-on-behalf-of-org-idLive

Create beneficiary (supplier)

Saves an overseas supplier on the organization. Common suppliers are created once per organization, ideally at onboarding.

curl -X POST 'https://sandbox.finmotreasury.net/v1/payout-beneficiary' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "type": "company",
       "beneficiary_name": "Ubud Jungle Retreat",
       "currency": "IDR",
       "bank_country": "ID",
       "account_number": "1234567890",
       "bic_swift": "CENAIDJA",
       "company": {
         "name": "Ubud Jungle Retreat",
         "registration_number": "REG123456",
         "address_line1": "1 Jl Raya Ubud",
         "address_city": "Gianyar",
         "address_country": "ID"
       }
     }'
GET/v1/payout-beneficiaryx-on-behalf-of-org-idLive

List beneficiaries

Suppliers saved on the organization.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-beneficiary' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/payout-beneficiary/{ben_id}x-on-behalf-of-org-idLive

Get beneficiary

One supplier.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-beneficiary/{ben_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
PATCH/v1/payout-beneficiary/{ben_id}x-on-behalf-of-org-idLive

Update beneficiary

Changes a saved supplier's details. The payout_beneficiary_id stays the same, so nothing that references it changes. Validate the new details first with POST /payout-beneficiary/validate.

curl -X PATCH 'https://sandbox.finmotreasury.net/v1/payout-beneficiary/{ben_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "beneficiary_name": "Ubud Jungle Retreat",
       "account_number": "9876543210",
       "company": {
         "name": "Ubud Jungle Retreat",
         "address_line1": "1 Jl Raya Ubud",
         "address_city": "Gianyar",
         "address_country": "ID"
       }
     }'
POST/v1/payout-beneficiary/validatex-on-behalf-of-org-idLive

Validate bank details

Checks fields against the method's rules (IBAN mod-97, ABA checksum, SWIFT format) before money moves.

  • Try payout_method_name de_bank_sct_eur with iban DE74123456784000000030 (two digits swapped) to see a 400 FAILED_TO_VALIDATE_BENEFICIARY_DETAILS_ERROR
curl -X POST 'https://sandbox.finmotreasury.net/v1/payout-beneficiary/validate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "payout_method_name": "gb_bank_fps_gbp",
       "is_beneficiary_name_match_enabled": true,
       "payout_beneficiary": {
         "type": "company",
         "beneficiary_name": "Thames Corporate Travel",
         "sort_code": "601613",
         "account_number": "31926819",
         "company": {
           "name": "Thames Corporate Travel",
           "address_line1": "1 King St",
           "address_city": "London",
           "address_country": "GB",
           "address_zip_code": "EC2V 8AU"
         }
       }
     }'
POST/v1/fx-ratex-on-behalf-of-org-idLive

Live FX quote

Returns fx_rate_id held for about 20 seconds. The rate already includes the organization's pricing.

source_currency*string
target_currency*string
source_amountnumber
Send exactly one of source_amount / target_amount
target_amountnumber
  • Sandbox mirrors live limits: IDR, THB, PHP, MYR and INR can be bought but not sold (406 104607).
curl -X POST 'https://sandbox.finmotreasury.net/v1/fx-rate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "source_currency": "USD",
       "target_currency": "EUR",
       "source_amount": 1000
     }'
GET/v1/fx-rate/{fx_id}x-on-behalf-of-org-idLive

Get quote

One quote.

curl -X GET 'https://sandbox.finmotreasury.net/v1/fx-rate/{fx_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
POST/v1/payoutx-on-behalf-of-org-idLive

Create payout

Pays a supplier. Attach fx_rate_id for a cross-currency payout; the rate locks. Status goes CREATED, PENDING, then COMPLETED, FAILED or RETURNED, each with a webhook.

payout_method_name*string
sender_currency*string
beneficiary_currency*string
beneficiary_countrystring
sender_amount | beneficiary_amount*number
fx_rate_idstring
debit_wallet_id*string
payout_beneficiary_id | payout_beneficiary_param*string | object
purpose_code*string
e.g. GOODS_AND_SERVICES
organization_reference_idstring
  • Send X-Idempotency-Key (UUID v4). A retry with the same key returns the original payout and an x-cached-request-id header.
curl -X POST 'https://sandbox.finmotreasury.net/v1/payout' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "payout_method_name": "de_bank_sct_eur",
       "sender_currency": "USD",
       "beneficiary_currency": "EUR",
       "beneficiary_country": "DE",
       "beneficiary_amount": 900,
       "fx_rate_id": "{{fx_rate_id}}",
       "debit_wallet_id": "{{wallet_id}}",
       "payout_beneficiary_id": "{{payout_beneficiary_id}}",
       "purpose_code": "GOODS_AND_SERVICES",
       "organization_reference_id": "INV-88213"
     }'
GET/v1/payoutx-on-behalf-of-org-idLive

List payouts

Filter by status, payout_method_name, organization_reference_id, start_time, end_time.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/payout/{payout_id}x-on-behalf-of-org-idLive

Get payout

Status and details.

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout/{payout_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/payout/{payout_id}/get-payout-pdfx-on-behalf-of-org-idLive

Payment confirmation

download_url to a payment confirmation (sandbox serves an HTML memo).

curl -X GET 'https://sandbox.finmotreasury.net/v1/payout/{payout_id}/get-payout-pdf' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
POST/v1/fx-conversionx-on-behalf-of-org-idLive

Create FX conversion

Converts between two currencies in the organization's wallet. Pass fx_rate_id to use a quote, or omit it for the live rate. Returns PENDING and holds the source amount.

source_currency*string
target_currency*string
source_amount | target_amount*number
Exactly one
fx_rate_idstring
organization_reference_idstring
  • Sandbox: the conversion stays PENDING until PATCH /fx-conversion/simulate, like Finmo's merchant sandbox. In production it completes on its own, usually within 2 minutes, and sends FX_CONVERSION_COMPLETED.
curl -X POST 'https://sandbox.finmotreasury.net/v1/fx-conversion' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{
       "source_currency": "USD",
       "target_currency": "EUR",
       "source_amount": 100,
       "fx_rate_id": "{{fx_rate_id}}"
     }'
GET/v1/fx-conversionx-on-behalf-of-org-idLive

List FX conversions

Newest first.

statusstring, query
limitnumber, query
pagenumber, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/fx-conversion' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/fx-conversion/{fx_conversion_id}x-on-behalf-of-org-idLive

Get FX conversion

One conversion.

curl -X GET 'https://sandbox.finmotreasury.net/v1/fx-conversion/{fx_conversion_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'

Webhooks

Where Finmo sends events, and how to see or re-send a delivery.

PUT/v1/partner/organization-setting/{org_id}Live

Set webhook URL

One webhook URL per organization. Every event carries org_id, so all organizations can point to the same listener. Deliveries carry your account's security token in the x-security-token header.

key*string
webhook_url
value*string
curl -X PUT 'https://sandbox.finmotreasury.net/v1/partner/organization-setting/{org_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'content-type: application/json' \
  -d '{
       "key": "webhook_url",
       "value": "https://listener.example.com/finmo"
     }'
GET/v1/webhook-notificationx-on-behalf-of-org-idLive

List webhook deliveries

Every notification with status and attempt count.

event_typestring, query
event_idstring, query
event_namestring, query
statusstring, query
curl -X GET 'https://sandbox.finmotreasury.net/v1/webhook-notification' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
GET/v1/webhook-notification/{webhook_id}x-on-behalf-of-org-idLive

Get webhook delivery

One notification with its attempts.

curl -X GET 'https://sandbox.finmotreasury.net/v1/webhook-notification/{webhook_id}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'
PATCH/v1/webhook-notification/{webhook_id}/retriggerx-on-behalf-of-org-idLive

Re-send a webhook

Queues an immediate delivery attempt. Picks up the current webhook_url.

curl -X PATCH 'https://sandbox.finmotreasury.net/v1/webhook-notification/{webhook_id}/retrigger' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…'

Sandbox tools

Test helpers that only exist in the sandbox.

PUT/v1/upload/{token}Sandbox only

Upload file bytes

Stands in for the presigned storage URL production returns. PUT the raw file; max 5 MB; expires 30 seconds after it was issued.

curl -X PUT 'https://sandbox.finmotreasury.net/v1/upload/{token}' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
PATCH/v1/virtual-account/simulate-payinx-on-behalf-of-org-idSandbox only

Simulate funds arriving

Same endpoint as Finmo's merchant sandbox. Credits a virtual account as if funds arrived: returns a GCA_TOPUP payin (fee 0.33 in the account currency) and emits the GCA_TOPUP webhook.

virtual_account_id*string
amount*number
currency*string
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/virtual-account/simulate-payin' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "virtual_account_id": "{{virtual_account_id}}",
       "amount": 25000,
       "currency": "USD"
     }'
PATCH/v1/payout/simulatex-on-behalf-of-org-idSandbox only

Simulate payout outcome

Same endpoint as Finmo's sandbox. COMPLETED/FAILED need status PENDING; RETURNED needs COMPLETED (406 100006 otherwise).

payout_id*string
status*string
COMPLETED | FAILED | RETURNED
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/payout/simulate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "payout_id": "{{payout_id}}",
       "status": "FAILED"
     }'
PATCH/v1/fx-conversion/simulatex-on-behalf-of-org-idSandbox only

Complete an FX conversion

Same endpoint as Finmo's merchant sandbox. Moves a PENDING conversion to COMPLETED: debits the source, credits the target and emits FX_CONVERSION_COMPLETED.

fx_conversion_id*string
statusstring
COMPLETED (default)
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/fx-conversion/simulate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "fx_conversion_id": "{{fx_conversion_id}}",
       "status": "COMPLETED"
     }'
PATCH/v1/payin/simulatex-on-behalf-of-org-idSandbox only

Complete or cancel a payin

Same endpoint as Finmo's merchant sandbox. COMPLETED credits the wallet less a 0.45 fee; CANCELLED needs a cancellable payin (PayNow QR payins are not). Only PENDING payins (406 100006 otherwise).

payin_id*string
status*string
COMPLETED | CANCELLED
amountnumber
Partial payment
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/payin/simulate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of-org-id: org_…' \
  -H 'content-type: application/json' \
  -d '{
       "payin_id": "{{payin_id}}",
       "status": "COMPLETED"
     }'

Webhook events

Finmo POSTs to the organization's webhook_url with the header x-security-token. There is one token per partner account, and it is the same for all your organizations. Reply 2xx within 5 seconds. Retries run at 15 min, 45 min, 2 h, 3 h, 6 h and 12 h, and PATCH /webhook-notification/{id}/retrigger re-sends any delivery. Deliveries are at least once: dedupe on webhook_notification_id or event_id. Names match Finmo production; branch on event_name.

Money into a virtual account arrives as GCA_TOPUP. Treat it as a reason to re-read the balance with GET /wallet/{wallet_id}, not as an amount to add to a balance you keep yourself.

event_nameevent_typeWhen
VIRTUAL_ACCOUNT_CREATED
Sent by the sandbox Live
VIRTUAL_ACCOUNTOne per virtual account Finmo opens. KYB approval opens six: USD, EUR, GBP and SGD over SWIFT, SGD over FAST, and AUD
GCA_TOPUP
Sent by the sandbox Live
PAYINFunds received on a virtual account and credited to the wallet. PATCH /v1/virtual-account/simulate-payin sends this in the sandbox
PAYIN_CREATED
Sent by the sandbox Live
PAYINPayin recorded, status pending
PAYIN_COMPLETED
Sent by the sandbox Live
PAYINPayin funds credited. Settlement is based on this
PAYIN_CANCELLED
Sent by the sandbox Live
PAYINPayin cancelled before funds arrived
PAYOUT_CREATED
Sent by the sandbox Live
PAYOUTPayout accepted; funds reserved (available balance drops)
PAYOUT_COMPLETED
Sent by the sandbox Live
PAYOUTProcessed from Finmo's end; actual balance debited. Not proof the beneficiary has the funds (on SWIFT, completed means sent)
PAYOUT_FAILED
Sent by the sandbox Live
PAYOUTPayout failed; reserved funds released to the balance
PAYOUT_RETURNED
Sent by the sandbox Live
PAYOUTCompleted earlier, then returned by the beneficiary's bank; amount credited back
FX_CONVERSION_COMPLETED
Sent by the sandbox Live
FX_CONVERSIONFX conversion settled; both currency balances updated
CUSTOMER_CREATED
Sent by the sandbox Live
CUSTOMERCustomer created with POST /v1/customer
CUSTOMER_UPDATED
Sent by the sandbox Live
CUSTOMERCustomer details changed
VIRTUAL_ACCOUNT_DELETED LiveVIRTUAL_ACCOUNTA virtual account was deleted
WALLET_CREATED LiveWALLETWallet created for the organization
PAYIN_SUCCEEDED / PAYIN_EXPIRED LivePAYINOther payin outcomes (checkout payins)
WALLET_FUND_TRANSFER LiveWALLET_FUND_TRANSFERWallet fund transfer completed
REFUND_CREATED / REFUND_COMPLETED / REFUND_FAILED LiveREFUNDRefund lifecycle
FEES_PAYMENT LivePAYINPayment to the fee wallet against a Finmo invoice
Delivered body
{
"webhook_notification_id": "webhook_…",
"org_id": "org_…",
"event_id": "payout_…",
"event_type": "PAYOUT",
"event_name": "PAYOUT_COMPLETED",
"event_description": "PAYOUT",
"event_detail": {
"…": "full payout object, same shape as GET /payout/{id}"
},
"attempt_count": 1,
"created_at": "2026-10-29T00:12:31.000Z"
}

Errors

Errors use the same envelope as a success, with success: false and an error object. Branch on error.name, never on the message text. error.message is a string, or an array with one entry per field problem. Quote request_id when you contact Finmo. Production uses the same envelope and names.

Fix, then send
400, 401, 403, 404, 406, 409, 410, 422. The request itself is wrong. Sending it again unchanged gets the same error.

Retry, same key
429, 500, 502. Back off (1 s, 2 s, 4 s, up to about 5 tries) and resend with the same X-Idempotency-Key, so a request that did land never runs twice.

Check first
504 and FX_RATE_ALREADY_USED_ERROR. The outcome is unknown. Look it up (for example GET /payout?organization_reference_id=...) before resending.

Wait for event
The request is fine but the account isn't ready: KYB not approved, or not enough balance. Act on the webhook, then call again.

Error envelope
{
"request_id": "fe67e4d883ec631410b5d4da398b7d55",
"request_time": "2026-11-13T11:04:40.034Z",
"success": false,
"status_code": 400,
"status_text": "Internal Server Error",
"error": {
"code": 110102,
"name": "INVALID_REQUEST_HEADER_ERROR",
"message": "x-on-behalf-of-org-id header is required"
}
}
400100400
INVALID_FIELD_OR_VALUE_ERROR
Fix, then send
Captured from Finmo
When
The body, query or headers fail validation. message is an array with one entry per problem, e.g. "email must be an email", "property foo should not exist".
What to do
Fix every field listed and send again. Don't retry unchanged.
Try it
POST /partner/invite-organization without email.
Endpoints
Any
400100001
FAILED_TO_VALIDATE_BENEFICIARY_DETAILS_ERROR
Fix, then send
Captured from Finmo
When
Bank details fail the method's rules: IBAN checksum, ABA checksum, bank code not in the directory, wrong length, or a required field missing.
What to do
Show the message to the organization so they can correct the beneficiary's bank details. Validate before saving; nothing has moved.
Try it
de_bank_sct_eur with iban DE74123456784000000030 (two digits swapped).
Endpoints
POST /payout-beneficiary/validate, POST /payout-beneficiary, POST /payout (inline beneficiary)
400100009
INSUFFICIENT_AMOUNT_IN_WALLET
Wait for event
Captured from Finmo
When
The organization's available balance is less than the payout amount plus fee.
What to do
Fund the organization with a bank transfer into one of its virtual accounts (sandbox: PATCH /virtual-account/simulate-payin). Wait for the GCA_TOPUP webhook or check GET /wallet/{wallet_id}, then get a fresh quote and create the payout again.
Try it
Create a payout larger than the wallet balance in the sender currency.
Endpoints
POST /payout
400106051
CURRENCY_NOT_ENABLED_FOR_ORG
Fix, then send
Captured from Finmo
When
sender_currency isn't a currency this organization holds.
What to do
Use a currency the organization's wallet holds (see GET /wallet).
Endpoints
POST /fx-rate, POST /payout
400104610
FX_RATE_EXPIRED_ERROR
Fix, then send
Sandbox name
When
fx_rate_id is older than its expire_at (about 20 seconds).
What to do
Get a new quote with POST /fx-rate, show the new rate to the merchant, then create the payout with the new fx_rate_id.
Try it
Wait 20 seconds between POST /fx-rate and POST /payout.
Endpoints
POST /payout
400104611
FX_RATE_MISMATCH_ERROR
Fix, then send
Sandbox name
When
The payout's currencies or amount differ from the quote behind fx_rate_id.
What to do
Send the same currencies and the quote's target_amount (or source_amount) unchanged.
Endpoints
POST /payout
400104612
FX_RATE_ALREADY_USED_ERROR
Check first
Sandbox name
When
Another payout already consumed this fx_rate_id.
What to do
If this is your own retry, resend with the original X-Idempotency-Key to get the original payout back. Otherwise get a new quote.
Endpoints
POST /payout
400110102
INVALID_REQUEST_HEADER_ERROR
Fix, then send
Captured from Finmo
When
A merchant route was called without the x-on-behalf-of-org-id header (or with x-on-behalf-of, which production ignores). status_text reads "Internal Server Error", as in production.
What to do
Send x-on-behalf-of-org-id: <organization org_id>.
Endpoints
Any call with x-on-behalf-of-org-id
401110101
AUTH_MIDDLEWARE_ERROR
Fix, then send
Captured from Finmo
When
HTTP Basic credentials are missing or wrong, or sandbox keys were sent to production (or the reverse). message: "Not Authorized".
What to do
Check the access key / secret key pair for this environment.
Endpoints
Any
403110103
AUTH_MIDDLEWARE_ERROR
Fix, then send
Captured from Finmo
When
x-on-behalf-of-org-id is an org_id that isn't one of your organizations. message: "Invalid organization specified in x-on-behalf-of header" (production wording); status_text "Internal Server Error".
What to do
Use the org_id returned by POST /partner/invite-organization for that merchant.
Endpoints
Any call with x-on-behalf-of-org-id
404100600 / 100601
<OBJECT>_NOT_FOUND_ERROR
Fix, then send
Captured from Finmo
When
The id doesn't exist for the organization in x-on-behalf-of-org-id. Objects: PAYOUT, WALLET, VIRTUAL_ACCOUNT, FX_RATE, PAYOUT_BENEFICIARY, PAYOUT_METHOD, TRANSACTION, WEBHOOK_NOTIFICATION, ORGANIZATION.
What to do
Check the id and that x-on-behalf-of-org-id is the merchant that owns it.
Endpoints
GET / PATCH by id
404100600
ROUTE_NOT_FOUND_ERROR
Fix, then send
Sandbox name
When
Unknown method or path. In production, also every sandbox-only endpoint (simulate-payin, payout/simulate, kyb/simulate).
What to do
Check the path. Sandbox-only tools have no production equivalent.
Endpoints
Any
406104607
UNSUPPORTED_CURRENCY_PAIR_ERROR
Fix, then send
Captured from Finmo
When
Finmo doesn't quote this pair, e.g. selling IDR, THB or PHP, or the same currency on both sides.
What to do
Quote from a currency the organization holds into the beneficiary's currency.
Endpoints
POST /fx-rate, POST /payout
406100006
PAYOUT_STATUS_MISMATCH_ERROR
Fix, then send
Captured from Finmo
When
The requested transition isn't allowed from the payout's current status.
What to do
Check GET /payout/{id} first; COMPLETED, FAILED and RETURNED are final.
Endpoints
PATCH /payout/simulate (sandbox)
406100701
VIRTUAL_ACCOUNT_NOT_ACTIVE_ERROR
Wait for event
Sandbox name
When
Virtual accounts open and activate only after KYB approval.
What to do
Wait for VIRTUAL_ACCOUNT_CREATED, or poll GET /partner/organization/{org_id} until kyb_status is APPROVED.
Endpoints
PATCH /virtual-account/simulate-payin (sandbox)
409100010
IDEMPOTENCY_KEY_CONFLICT_ERROR
Fix, then send
Captured from Finmo
When
The same X-Idempotency-Key was sent with a different body.
What to do
Don't retry. Reuse a key only for the exact same request; use a new key for a new request.
Endpoints
Any POST / PUT / PATCH with X-Idempotency-Key
410100801
UPLOAD_URL_EXPIRED_ERROR
Fix, then send
Sandbox name
When
The presigned upload_url is older than 30 seconds.
What to do
Request a new one with POST /partner/organization-document/{org_id} and upload straight away.
Endpoints
PUT upload_url
500100500
INTERNAL_SERVER_ERROR
Retry, same key
Sandbox name
When
Unexpected error. Nothing was created.
What to do
Retry with the same X-Idempotency-Key after a short backoff.
Endpoints
Any

Failures after a 2xx

These never come back as an HTTP error. They arrive later, by webhook and on the object's status, so the listener has to handle them.

WhatHow it arrivesWhat to do
Payout failedstatus FAILED with reason_for_failure; webhook PAYOUT_FAILEDFunds go back to the balance the payout was debited from, in the source currency. Show the reason; fix the beneficiary and pay again with a new quote.
Payout returned by the receiving bankstatus RETURNED with reason_for_return; webhook PAYOUT_RETURNED (can follow COMPLETED)Amount is credited back. Treat COMPLETED on SWIFT as sent, not final.
Your listener was downWebhook retried after 15, 45, 120, 180, 360 and 720 minutes (retry_interval)Return 2xx within 5 s; dedupe on webhook_notification_id. Re-send any delivery with PATCH /webhook-notification/{id}/retrigger.
409 captured from the api.finmo.net sandbox
{
"request_id": "3223a7b82120aa34ee3abffa8e904483",
"request_time": "2026-10-24T16:48:22.000Z",
"success": false,
"status_code": 409,
"status_text": "CONFLICT",
"error": {
"code": 100010,
"name": "IDEMPOTENCY_KEY_CONFLICT_ERROR",
"message": "Cannot process request with same X-Idempotency-Key: 90a04c9e-407f-4ef9-bc43-b4f6e9672ab8"
}
}

Test data

Onboarding

  • PATCH /partner/kyb/save/{org_id} with submit: true approves the organization at once and opens its wallet and accounts. In production, Finmo compliance reviews the application first.
  • No emails are sent. In production, the invited user gets a link to set a Finmo dashboard password.

Payout outcomes

  • PATCH /payout/simulate: COMPLETED or FAILED from PENDING, RETURNED from COMPLETED.
  • IBAN GB82WEST12345698765432 fails validation (unknown bank). GB29NWBK60161331926819 passes.

Payout methods in the sandbox

171 methods.

MethodDestination
ae_bank_acct_aed AE, AED
ae_bank_swift_aed AE, AED
ae_bank_transfer_aed AE, AED
au_bank_acct AU, AUD
au_bank_auspaynet_aud AU, AUD
au_bank_payid AU, AUD
au_bank_swift_aud AU, AUD
bg_bank_swift_bgn BG, BGN
br_bank_acct_brl BR, BRL
ca_bank_eft_cad CA, CAD
ca_bank_swift_cad CA, CAD
ch_bank_acct_chf CH, CHF
ch_bank_swift_chf CH, CHF
cn_bank_acct_cny CN, CNY
cn_bank_swift_cny CN, CNY
cn_ewallet_alipay_cny CN, CNY
cz_bank_certis_czk CZ, CZK
cz_bank_swift_czk CZ, CZK
dk_bank_straksclearing_dkk DK, DKK
dk_bank_swift_dkk DK, DKK
at_bank_sct_eur AT, EUR
at_bank_swift_eur AT, EUR
be_bank_sct_eur BE, EUR
be_bank_swift_eur BE, EUR
bg_bank_sct_eur BG, EUR
bg_bank_swift_eur BG, EUR
ch_bank_sct_eur CH, EUR
ch_bank_swift_eur CH, EUR
cy_bank_sct_eur CY, EUR
cy_bank_swift_eur CY, EUR
cz_bank_sct_eur CZ, EUR
cz_bank_swift_eur CZ, EUR
de_bank_sct_eur DE, EUR
de_bank_swift_eur DE, EUR
dk_bank_sct_eur DK, EUR
dk_bank_swift_eur DK, EUR
ee_bank_sct_eur EE, EUR
ee_bank_swift_eur EE, EUR
es_bank_sct_eur ES, EUR
es_bank_swift_eur ES, EUR
fi_bank_sct_eur FI, EUR
fi_bank_swift_eur FI, EUR
fr_bank_sct_eur FR, EUR
fr_bank_swift_eur FR, EUR
gb_bank_sct_eur GB, EUR
gb_bank_swift_eur GB, EUR
gr_bank_sct_eur GR, EUR
gr_bank_swift_eur GR, EUR
hr_bank_sct_eur HR, EUR
hr_bank_swift_eur HR, EUR
hu_bank_sct_eur HU, EUR
hu_bank_swift_eur HU, EUR
ie_bank_sct_eur IE, EUR
ie_bank_swift_eur IE, EUR
it_bank_sct_eur IT, EUR
it_bank_swift_eur IT, EUR
lt_bank_sct_eur LT, EUR
lt_bank_swift_eur LT, EUR
lu_bank_sct_eur LU, EUR
lu_bank_swift_eur LU, EUR
lv_bank_sct_eur LV, EUR
lv_bank_swift_eur LV, EUR
mt_bank_sct_eur MT, EUR
mt_bank_swift_eur MT, EUR
nl_bank_sct_eur NL, EUR
nl_bank_swift_eur NL, EUR
no_bank_sct_eur NO, EUR
no_bank_swift_eur NO, EUR
pl_bank_sct_eur PL, EUR
pl_bank_swift_eur PL, EUR
pt_bank_sct_eur PT, EUR
pt_bank_swift_eur PT, EUR
ro_bank_sct_eur RO, EUR
ro_bank_swift_eur RO, EUR
se_bank_sct_eur SE, EUR
se_bank_swift_eur SE, EUR
si_bank_sct_eur SI, EUR
si_bank_swift_eur SI, EUR
sk_bank_sct_eur SK, EUR
sk_bank_swift_eur SK, EUR
us_bank_aba_eur US, EUR
us_bank_swift_eur US, EUR
gb_bank_chaps_gbp GB, GBP
gb_bank_fps_gbp GB, GBP
gb_bank_swift_gbp GB, GBP
hk_bank_chats_hkd HK, HKD
hk_bank_swift_hkd HK, HKD
hu_bank_swift_huf HU, HUF
hu_bank_zrt_huf HU, HUF
id_bank_acct_idr ID, IDR
id_bank_nobu_idr ID, IDR
id_bank_skn_idr ID, IDR
id_ewallet_dana_idr ID, IDR
id_ewallet_gopay_idr ID, IDR
id_ewallet_linkaja_idr ID, IDR
id_ewallet_mobile_idr ID, IDR
id_ewallet_ovo_idr ID, IDR
id_ewallet_shopeepay_idr ID, IDR
il_bank_swift_ils IL, ILS
in_bank_impsneft_inr IN, INR
in_ewallet_upi_inr IN, INR
jp_bank_acct_jpy JP, JPY
jp_bank_swift_jpy JP, JPY
ke_bank_swift_kes KE, KES
kr_bank_acct_krw KR, KRW
kr_bank_paygate_krw KR, KRW
mx_bank_acct_mxn MX, MXN
my_bank_acct_myr MY, MYR
my_bank_ibg_myr MY, MYR
my_ewallet_bigpay_myr MY, MYR
my_ewallet_duitnow_myr MY, MYR
my_ewallet_finexus_myr MY, MYR
my_ewallet_tng_myr MY, MYR
no_bank_nics_nok NO, NOK
no_bank_swift_nok NO, NOK
np_bank_acct_npr NP, NPR
nz_bank_acct_nzd NZ, NZD
nz_bank_directcredit_nzd NZ, NZD
nz_bank_swift_nzd NZ, NZD
ph_bank_acct_php PH, PHP
ph_bank_pbb_php PH, PHP
ph_bank_pesonet_php PH, PHP
ph_ewallet_mobile_php PH, PHP
pl_bank_elixir_pln PL, PLN
pl_bank_swift_pln PL, PLN
qa_bank_swift_qar QA, QAR
ro_bank_swift_ron RO, RON
ro_bank_transfondsent_ron RO, RON
sa_bank_swift_sar SA, SAR
se_bank_rix_sek SE, SEK
se_bank_swift_sek SE, SEK
sg_bank_acct_sgd SG, SGD
sg_bank_fast_sgd SG, SGD
sg_bank_fastpayment_sgd SG, SGD
sg_bank_giro_sgd SG, SGD
sg_bank_giropayment_sgd SG, SGD
sg_bank_meps_sgd SG, SGD
sg_bank_mepspayment_sgd SG, SGD
sg_bank_paynow_sgd SG, SGD
sg_bank_paynowproxy_sgd SG, SGD
sg_bank_swift_sgd SG, SGD
th_bank_accnt_thb TH, THB
th_bank_acct_thb TH, THB
th_bank_promptpay_thb TH, THB
th_bank_swift_thb TH, THB
tr_bank_fast_try TR, TRY
tr_bank_swift_try TR, TRY
ae_bank_swift_usd AE, USD
br_bank_swift_usd BR, USD
ca_bank_swift_usd CA, USD
cn_bank_swift_usd CN, USD
gb_bank_swift_usd GB, USD
hk_bank_swift_usd HK, USD
id_bank_swift_usd ID, USD
in_bank_swift_usd IN, USD
mx_bank_swift_usd MX, USD
my_bank_swift_usd MY, USD
ph_bank_swift_usd PH, USD
sg_bank_swift_usd SG, USD
th_bank_swift_usd TH, USD
us_bank_aba_usd US, USD
us_bank_ach_usd US, USD
us_bank_fedach_usd US, USD
us_bank_rtp_usd US, USD
us_bank_samedayach_usd US, USD
us_bank_swift_usd US, USD
vn_bank_swift_usd VN, USD
vn_bank_acct_vnd VN, VND
vn_bank_earthport_vnd VN, VND
za_bank_acct_zar ZA, ZAR
za_bank_swift_zar ZA, ZAR