Overview
Custodial corridor remittance is separate from the P2P-stylePOST /api/v1/auth/remittance/off-ramp/orders path. The customer already holds USDT or USDC in a custodial platform wallet. They enter how much KES the beneficiary should receive. The app resolves pricing and FX. The backend creates a draft with a unique escrow address. On Confirm, the server creates an order with order_subtype = custodial_remittance_offramp, then broadcasts the priced stablecoin (USDT or USDC) from the custodial wallet to that escrow. After confirmations, mobile money B2C pays beneficiary_phone.
Prerequisites
- Run database migration
000031_corridors_custodial_remittanceon your environment. - Create offramp
pricing_profilesandfx_rate_quotesfor USDT or USDC (paired with KES) on the sender network (for example tron). fiat_currencyvalues must reference an active row in the sharedfiat_currenciestable. Enumerate allowed codes withGET /api/v1/auth/fiat-currencies(same catalog OTC and other products use).
Mobile sequence
POST /api/v1/auth/pricing/resolveorPOST /api/v1/auth/pricing/fx-quotes(and profiles) as you do today — obtainpricing_profile_idandfx_rate_quote_idforflow_type=offramp.POST /api/v1/auth/remittance/custodial/drafts— body includescustodial_wallet_id,beneficiary_fiat_amount,fiat_currency, beneficiary and sender KYC fields,fee_bearer, and the pricing IDs. The response includesusdt_total_debit(total stablecoin debit for USDT- or USDC-priced flows. Field name is historical) andescrow_wallet_addressfor the summary screen.POST /api/v1/auth/remittance/custodial/drafts/{id}/confirm— empty JSON body is fine. The server creates the order and submits the on-chain transfer from the custodial wallet to the draft escrow.
REMITTANCE_DRAFT_EXPIRY_MINUTES (default 15 minutes). If the chain send fails, the order may move to failed while the draft stays draft with a linked order_id. A second confirm retries the transfer for the same order.
Order shape
Confirmed orders useorder_type = OFF_RAMP_SELL, payment_method = custodial_remittance_escrow, and order_subtype = custodial_remittance_offramp. Payout orchestration uses beneficiary_phone for mobile money, same as remittance_offramp.