Skip to main content
pay() moves money one way: user → your app. Money moves the other way — payouts, winnings, refunds — without any bridge call at all, because you already hold the one thing you need: the user’s wallet address. A payout is a plain Solana transfer of HSUSD that your server makes.

The user’s wallet is session.user.wallet

The wallet on a verified session’s user is the user’s Solana wallet address. Once a user has opened a session in your app, you can pay them at any time — no extra call, no address exchange, no custody of a separate destination. A refund is a payout. Winnings are a payout. There is no separate refund API — partial or full, you send HSUSD to session.user.wallet.

Send HSUSD to the user

Payouts settle in the same stablecoin pay() does — HSUSD (SPL mint 4FVaHEubcqws8hKwJSiW8f8CmKGUyMsBxTKUytcGdRvd, 9 decimals, 1 HSUSD = $1). Fund a treasury — this can be the same capabilities.payments wallet that pay() settles into — with the HSUSD you take in, and pay users out of it. Your server holds the treasury signer and pays the network fee.
Node.js
Payouts are merchant-operated: your app holds the HSUSD and the signer, and Bankroll is not in the path. The full loop is symmetric — you take HSUSD in with pay(), and send HSUSD out with a transfer to session.user.wallet.
Compute the payout amount and recipient on your server, from the verified identity and your own settled records — never from unverified client input. Make each payout idempotent (one payout per settled bet/order) and store the returned signature, so a retry can’t double-pay. HSUSD transfers are final and irreversible — there are no chargebacks.