Skip to main content
When an off-ramp payout cannot be delivered — the destination account was suspended, closed, or wrong — the crypto has already been sold, so there is nothing to refund. What is needed is a different account and another attempt. The widget lets the user do that themselves.
There is no OFF-RAMP.ORDER.REJECTED event. A rejected payout arrives as OFF-RAMP.ORDER.CANCELLED with refundable: false, usually carrying failureReason: INVALID_DESTINATION. When refundable is true instead, the trade never ran and the case is a refund — see History and refunds.

While the user is still in the widget

If the order fails while the user is in the session, the widget offers to swap the destination account and reprocess on the spot. They pick another account from their book — or register one — confirm, and the payout is attempted again. This is the same operation as Change Fiat Account and Reprocess, which documents the preconditions, the errors, and the behaviours that are not obvious from the contract: a suspended account chosen as the replacement is reactivated automatically, the customer’s active off-ramp session is repointed at the new account, and the retry does not re-emit DEPOSIT.RECEIVED or TRADE.COMPLETED.

After the user has left

Most users are long gone by the time a payout fails. For them, Ripio emails a link that opens the widget directly in a self-contained recovery flow — no session token from you, and no need for them to go back through your app.
1

They open the link from the payout-rejected email

The link authenticates them for this one task and nothing else.
2

They provide a new destination account

The same per-country forms as the normal off-ramp, with the same bank-side validation.
3

They review and confirm

The widget shows what will be reprocessed and where the money will go.
4

The order is reprocessed

They end on a success screen, or on a failure screen if the new account cannot be used either.
This flow only exists if recovery links are enabled on your account. The switch fails closed: without it no link is minted, and a rejected payout is resolved through support instead.
The token travels in the URL fragment (#_at=…) specifically so it never reaches server logs or a Referer header. It is single-purpose and expires, and there is no way for the user to request a fresh one — an expired link leads to a dead-link screen, and from there to support. If your edge or analytics layer rewrites URL fragments, the link will not work.

What this means for you

Nothing to build. But two things are worth knowing:
  • Your user may fix an order without telling you. A payout you saw fail can succeed later because they changed the account from an email. Treat the OFF-RAMP.* events as the source of truth rather than assuming a cancelled order stays cancelled.
  • The reprocess is asynchronous. You will see OFF-RAMP.WITHDRAWAL.PROCESSING and then WITHDRAWAL.COMPLETED, or ORDER.CANCELLED again if the new account also fails. See Off-Ramp Webhook Events.