Prerequisites
- The FX feature must be enabled on your account profile, with pricing configured for each currency pair you want to test. In sandbox this is provisioned by the RalioPay team — contact support if a pair you need returns
This FX quote cannot be processed at the moment. Please contact support. - A user with verified KYC/KYB and two active accounts in different currencies (e.g. an
EURwallet and aUSDwallet). - The origin account must have balance. You can fund it with a sandbox payin.
- To receive the FX webhook events, register your webhook endpoint and subscribe it to
swap_processing,swap_completed, andswap_failed.
Full test flow
1
Locate the two accounts
Call List user accounts and note the
accountId of the origin wallet (aid in the URL) and of the destination wallet (recipient.accountId in the body).2
Create a quote
Lock a rate for 60 seconds:
Response
3
Execute the swap
Reference the quote within its 60-second window:The response returns the order in
PENDING state with a detailUrl you can poll. Alternatively, execute without a quote at the market rate by omitting quoteId and sending recipient plus exactly one of fromAmount / toAmount:4
Receive the webhooks
Your endpoint receives
swap_processing when the swap is delegated to the provider, followed by swap_completed once the destination wallet is credited. In sandbox this happens within seconds.5
Verify the result
Call Get FX swap order details with the order ID and confirm
state is SETTLED and settledAt is set. The destination account balance reflects the credited amount.Testing the expired-quote error
Create a quote, wait longer than 60 seconds, then execute with itsquoteId. The API returns 422 with code QUOTE_EXPIRED — no order is created and no funds are held.
Simulating a failed swap
A
FAILED swap is triggered by the external provider rejecting the execution. Simulating a failure in sandbox is coming soon. In the meantime, make sure your integration handles the swap_failed event: when it fires, the hold on the origin funds has been released and data.amounts.creditedAmount is omitted from the payload.