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

# Pay Fees to X Money

> Launch a token whose trading fees are paid out as cash to an X Money, Cash App or Venmo account

A token's creator fees normally accrue in SOL to the wallets in its fee-share config. With **Bags Payouts**, they are paid out as cash instead. You name the Bags payout wallet as the token's only fee claimer and save a payout handle, such as an X account for X Money. From then on Bags claims the fees, converts them, and sends them to that account. This guide walks through it for X Money; Cash App and Venmo work the same way.

## How it works

1. You launch the token with the **Bags payout wallet** as its only fee claimer (100%) and a `payoutCashout` handle, for example `{ "method": "xmoney", "username": "@creator" }`.
2. Every few minutes the payout wallet claims the token's fees once they reach at least **0.25 SOL**.
3. The claimed SOL is converted to USDC, and once a batch is worth at least **5 USDC** it is listed on [Peer](https://peer.xyz) as a cash order with the handle as the payee.
4. A Peer buyer sends the cash to the handle (for example through X Money), proves the payment, and receives the USDC. The account owner receives the cash directly from the buyer.

Every step is recorded and readable through the public [payout endpoints](#track-payouts).

> [!NOTE]
>
> **The Bags payout wallet is `PAY9yjtc5nkuQL3yFd6yV3M1WoX7uNfFMAQdB9tHjSR`.** Use it as the only entry in `claimersArray`, with `10000` in `basisPointsArray`. Never make it the fee-share manager (`admin`): it does not sign manager transactions, and the API refuses it.

### What the account owner receives

* **Conversion costs:** converting SOL to USDC costs about 0.5–0.7% plus a few cents, and comes out of the payout.
* **Discount:** to get orders filled quickly, an order is offered **10% below the market rate** from listing, and **20% below** once it is 24 hours old. At 10% the account receives \$0.90 per USDC listed. The current discount of every order is public (`order.discountBps`).
* **Network fees:** paid by Bags, never deducted from the payout.

### Choosing the handle

| Method | `method` | `username` | Rules |
| - | - | - | - |
| X Money | `xmoney` | X handle, `@` optional | 1–15 letters, digits or `_`. **Any existing X account** may be named, not only the creator's own; the API checks that the account exists. |
| Cash App | `cashapp` | `$cashtag`, `$` optional | 1–20 characters (letters, digits, `-`, `_`), at least one letter. |
| Venmo | `venmo` | Venmo username, `@` optional | 5–30 characters (letters, digits, `-`, `_`). |

> [!WARNING]
>
> Peer cannot check whether an X account has **X Money enabled**. A handle that cannot receive X Money produces an order no buyer can fill. Make sure the account can receive X Money before launching. X Money also has fewer buyers than Cash App, so its orders can take longer to fill.

## Prerequisites

* Completed the [Launch a Token](https://docs.bags.fm/how-to-guides/launch-token.md) guide. This guide only changes its fee-share config step.
* An API key from the [Bags Developer Portal](https://dev.bags.fm), and a funded launch wallet.
* The token must be **SOL-paired** (the default). Payouts are not available for [non-SOL quote launches](https://docs.bags.fm/how-to-guides/launch-token-non-sol-quote.md).

## 1. Create the fee-share config with a payout handle

Call [Create Fee Share Config](https://docs.bags.fm/api-reference/create-fee-share-configuration.md) with the payout wallet as the only claimer and the handle in `payoutCashout`. The launch wallet pays for the config and is its fee-share manager.

```typescript theme={null}
import { Keypair, PublicKey, VersionedTransaction, Connection } from "@solana/web3.js";
import bs58 from "bs58";

const API_BASE = "https://public-api-v2.bags.fm/api/v1";
const BAGS_PAYOUT_WALLET = "PAY9yjtc5nkuQL3yFd6yV3M1WoX7uNfFMAQdB9tHjSR";

async function createPayoutFeeShareConfig(params: {
    tokenMint: PublicKey;
    launchWallet: Keypair;
    xHandle: string;
    connection: Connection;
}): Promise<PublicKey> {
    const res = await fetch(`${API_BASE}/fee-share/config`, {
        method: "POST",
        headers: { "Content-Type": "application/json", "x-api-key": process.env.BAGS_API_KEY! },
        body: JSON.stringify({
            payer: params.launchWallet.publicKey.toBase58(),
            baseMint: params.tokenMint.toBase58(),
            claimersArray: [BAGS_PAYOUT_WALLET],
            basisPointsArray: [10000],
            payoutCashout: { method: "xmoney", username: params.xHandle },
        }),
    });
    const body = await res.json();
    if (!body.success) {
        // e.g. 400 "Could not find the X account @…", 403 when the API key's user does not own the token
        throw new Error(`fee-share config failed (${res.status}): ${body.response}`);
    }

    // One claimer needs no lookup tables, so no bundles are expected: sign and send the transactions in order.
    for (const { transaction } of body.response.transactions ?? []) {
        const tx = VersionedTransaction.deserialize(bs58.decode(transaction));
        tx.sign([params.launchWallet]);
        const signature = await params.connection.sendTransaction(tx);
        await params.connection.confirmTransaction(signature, "confirmed");
    }
    return new PublicKey(body.response.meteoraConfigKey);
}
```

The handle is validated and saved **before** any transaction is returned, so a typo fails fast with `400`. The API saves the handle as entered (`@Creator`) and matches it case-insensitively for X.

## 2. Launch the token

Continue exactly as in [Launch a Token](https://docs.bags.fm/how-to-guides/launch-token.md), using the config key from step 1:

```typescript theme={null}
const configKey = await createPayoutFeeShareConfig({ tokenMint, launchWallet: keypair, xHandle: "@creator", connection });

const launchTx = await sdk.tokenLaunch.createLaunchTransaction({
    metadataUrl: tokenInfoResponse.tokenMetadata,
    tokenMint,
    launchWallet: keypair.publicKey,
    initialBuyLamports: 0.01 * LAMPORTS_PER_SOL,
    configKey,
});
await signAndSendTransaction(connection, commitment, launchTx, keypair);
```

Nothing else is needed: the payout wallet starts claiming once trading fees reach the threshold.

> [!NOTE]
>
> The [deployer share](https://docs.bags.fm/how-to-guides/deployer-fees.md) (25% of the claimers pool on new SOL configs) still goes to the `payer` as SOL. Only the remaining claimers pool, the payout wallet's 100%, is paid out as cash.

## Track payouts

All payout reads are public and need only your API key.

| Endpoint | Use |
| - | - |
| [`GET /bags-payout/token?tokenMint=…`](https://docs.bags.fm/api-reference/get-bags-payout-token) | The token's handle, whether its fees really go to the payout wallet (`paysPayoutBot`, read on-chain), totals, and claims waiting to be paid. `null` means the token is not paid out. |
| [`GET /bags-payout/history?tokenMint=…`](https://docs.bags.fm/api-reference/get-bags-payout-history) | Payouts, newest first, with status, bridge, order, fills and timeline. |
| [`GET /bags-payout/payout?id=…`](https://docs.bags.fm/api-reference/get-bags-payout) | One payout, including the claims that funded it. |
| [`GET /bags-payout/claims?tokenMint=…`](https://docs.bags.fm/api-reference/get-bags-payout-claims) | Every claim of the token's fees. |

```bash theme={null}
curl -H "x-api-key: $BAGS_API_KEY" \
  "https://public-api-v2.bags.fm/api/v1/bags-payout/history?tokenMint=<TOKEN_MINT>"
```

A payout moves through `pending` → `bridging` → `bridged` → `listing` → `awaiting_buyer` → `matched` → `partially_paid` / `paid`. `fiatPaidCents` is the verified cash paid to the handle so far; `order.discountBps` is the order's current discount.

## Change the handle later

The token's fee-share manager can switch the handle at any time with [`POST /bags-payout/token/cashout`](https://docs.bags.fm/api-reference/create-bags-payout-token-cashout):

```bash theme={null}
curl -X POST "https://public-api-v2.bags.fm/api/v1/bags-payout/token/cashout" \
  -H "x-api-key: $BAGS_API_KEY" -H "Content-Type: application/json" \
  -d '{ "tokenMint": "<TOKEN_MINT>", "cashout": { "method": "xmoney", "username": "@new_handle" } }'
```

Fees already claimed stay with the handle that was current when they were claimed; only later claims go to the new handle.

## Troubleshooting

| Response | Cause |
| - | - |
| `400` `Could not find the X account @…` | The X handle does not exist. |
| `400` `… is not a valid X Money handle` | The handle breaks the rules in [Choosing the handle](#choosing-the-handle). |
| `400` `The payout bot must be the coin's only fee claimer (100%)` | Another wallet is in `claimersArray`, or the share is not `10000`. |
| `400` `payoutCashout requires the payout bot as the coin's fee claimer` | `payoutCashout` was sent without the payout wallet as claimer. |
| `400` `The payout bot cannot be the fee-share manager` | `admin` was set to the payout wallet. |
| `403` | The API key's user does not own the token, or is not its fee-share manager when changing the handle. |
| `409` `… change its payout handle with POST /bags-payout/token/cashout` | The token already has a fee-share config. Use [Change the handle later](#change-the-handle-later). |
| `503` | The handle or the on-chain config could not be checked right now. Retry. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.