The app picks the account by asking for a quote in the user’s currency:
USD/MYR for Malaysia, USD/IDR otherwise. Cash-outs always go through Indonesia, where the families are.
What the user sees after choosing to top up:
- Malaysia (MYR)
- Indonesia (IDR)

Xendit Malaysia checkout for a RM 50 top-up, test mode.
Money in
- The webhook only records what happened and answers at once.
- A worker in the same process does the onchain part, one transaction at a time. A crash between the two halves leaves a
PAIDpayment that the next run picks up. - The method passed to the contract comes from the channel Xendit reports, not what the user picked. See Card hold.
Money out
- The user signs an AUSD transfer to Matocard’s treasury (ERC-3009, no gas for them).
- The relayer submits it, taking the AUSD.
- Xendit pays the rupiah to the bank, with the payout ID as the idempotency key so a retry can never pay twice.
Settlements
A settlement charges the whole debt in local money, rounded up. Once paid, the relayer callsrepayFor, which closes the cycle exactly as if the borrower had repaid onchain.
Refunds and chargebacks
Safety rules
- Every webhook is verified (Xendit callback token) and processed once.
- A payment only moves
PENDING → PAID → CREDITED_ONCHAIN → SETTLED | REVERSED(orPENDING → FAILED); the database refuses any other step and logs every one. - The ledger is double-entry and append-only; each currency balances.
- Daily caps on what the relayer may credit: 1,000 AUSD per user, 20,000 AUSD in total.
- Every day’s credited top-ups are reconciled against the indexer.


