> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joinbankroll.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Paying a user

> Winnings, payouts, and refunds are one plain HSUSD transfer to the user's wallet — no extra API to learn.

`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](/build/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.

```ts Node.js theme={null}
import {
  Connection, Keypair, PublicKey, Transaction, sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
  getOrCreateAssociatedTokenAccount, createTransferCheckedInstruction,
} from "@solana/spl-token";

const connection = new Connection(RPC_URL, "confirmed"); // your own Solana RPC
const HSUSD_MINT = new PublicKey("4FVaHEubcqws8hKwJSiW8f8CmKGUyMsBxTKUytcGdRvd");
const HSUSD_DECIMALS = 9;
const BASE_UNITS_PER_CENT = 10n ** 7n; // HSUSD has 9 decimals; amounts are in cents

// treasury = your funded HSUSD signer, kept server-side.
async function payUser(treasury: Keypair, wallet: string, amountCents: number) {
  const recipient = new PublicKey(wallet); // session.user.wallet, from your verified session

  // Your HSUSD account, and the recipient's — created if it doesn't exist yet,
  // with your treasury paying the one-time account rent.
  const from = await getOrCreateAssociatedTokenAccount(connection, treasury, HSUSD_MINT, treasury.publicKey);
  const to = await getOrCreateAssociatedTokenAccount(connection, treasury, HSUSD_MINT, recipient);

  const ix = createTransferCheckedInstruction(
    from.address, HSUSD_MINT, to.address, treasury.publicKey,
    BigInt(amountCents) * BASE_UNITS_PER_CENT, HSUSD_DECIMALS,
  );
  return sendAndConfirmTransaction(connection, new Transaction().add(ix), [treasury]);
}
```

<Note>
  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`.
</Note>

<Warning>
  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.
</Warning>
