Skip to main content
Every payment lands in the intent’s own deposit account, so a payment that does not fund the intent stays attributed to it and can always be sent back. Refunds are paid from that deposit account by a Useroutr worker.

Refunds that happen on their own

You do not need to do anything for these. Each fires refund.created, then refund.completed or refund.failed. Each payment is refunded at most once, and never for more than it brought in or than its deposit account still holds. A payment Useroutr cannot refund safely on its own, such as one whose funds have already moved or an amount too small to be worth sending, is left for you to refund by request.

Where a refund goes, and when it waits for you

A refund goes back to the account the payment came from, but only when that is safe. If it is not, the refund waits in PENDING with no destination.address, its failure.code says why, and refund.destination_required fires when a refund that was about to pay out is stopped. Sending an exchange’s shared account a refund without the customer’s memo would credit nobody, so Useroutr never does. Ask your user where they want the refund, then give it a destination, with the memo their exchange showed them if there is one:
A memo is text (at most 28 bytes), id (an unsigned 64-bit integer in decimal) or hash (32 bytes in hex). The destination is checked when you set it: an account that does not exist, cannot hold the asset, or requires a memo you did not give is refused with INVALID_DESTINATION.

Payments made on Base, Arbitrum or Ethereum

A payment your user made to a deposit address on an EVM network is refunded on that network, in the asset they sent, with the refund’s destination.network set to that network. Useroutr refunds on its own:
  • what is left at the address after the payment went through, as OVERPAYMENT or ROUTE_REMAINDER;
  • a payment that could not be converted or delivered, once its deposit address allows it to be taken back (seven days after the address was handed out), as SETTLEMENT_FAILED, EXPIRED_INTENT, UNDERPAYMENT or DUPLICATE_PAYMENT. The payment is recorded as rejected, so the refund has a payment to belong to.
The refund goes to the address that sent the tokens. A payment in the network’s native currency, or a deposit that more than one address paid, names no single sender, so the refund waits with NO_DESTINATION for you to give it an address on that network (no memo):
The refunded amount is what the deposit address actually held when it was taken back, which is what the refund reports once it completes.

Refund a payment yourself

Refund a rejected payment, or the confirmed payments of an intent that will not complete, by naming the payment:
The refund returns whatever of the payment has not been refunded already. Pass destination_address, and destination_memo if it needs one, to send it somewhere other than where it came from. One refund can be in progress per payment and asset at a time.

Lifecycle

PENDING → PROCESSING → COMPLETED or FAILED. A completed refund carries the payout’s transaction_hash; a failed one carries its failure.