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

# Pay-ins

> Receive stablecoin payments from customers and partners

This guide walks you through how to receive payments from third parties. By the end, you will be able to:

* Generate a wallet address to receive funds
* Assign dedicated addresses to payers or payment requests
* Track incoming transfers in real time
* Sweep deposits into a central treasury for reconciliation

## Prerequisites

* A Crossmint **server API key** with the scopes `wallets.create`, `wallets.read`, `wallets:transactions.create`, `wallets:transactions.sign`
* The <a href="https://www.npmjs.com/package/@crossmint/wallets-sdk" target="_blank">Crossmint Wallets SDK</a> installed

<Snippet file="wallets-sdk-installation-cmd.mdx" />

***

## Step 1 — Choose a Collection Strategy

There are two common ways to receive payments:

* **Shared treasury address:** Use a single wallet address for all incoming payments. This is the simplest approach but may require additional reconciliation work.
* **Dedicated deposit addresses:** Create a unique wallet for each payer or payment request, then sweep funds into your treasury wallet via webhooks and internal transfers. This simplifies reconciliation by associating each address with a specific customer or invoice.

***

## Step 2 — Create a Receiving Wallet

Create a wallet to receive stablecoin payments:

* For a **shared treasury address**, set up a company-owned wallet using the [Treasury Wallets](/wallets/guides/treasury-wallets) guide
* For **dedicated deposit addresses**, create a wallet per payer using the [Create Wallet](/wallets/guides/create-wallet) guide

***

## Step 3 — Share the Payment Address

Provide the wallet address to the payer. Once the transaction settles on-chain, the funds become available in the receiving wallet.

***

## Step 4 — Listen for Incoming Payments with Webhooks

Once a payer sends stablecoins to the wallet address, Crossmint fires a `wallets.transfer.in` webhook event. Set up a webhook endpoint to receive these notifications in real time.

1. **Configure a webhook endpoint** in the <a href="https://www.crossmint.com/console" target="_blank">Crossmint Console</a> by following the [Add an Endpoint](/introduction/platform/webhooks/add-endpoint) guide. Select the `wallets.transfer.in` event type.

2. **Verify the webhook signature** to ensure the request is legitimate. See [Verify Webhooks](/introduction/platform/webhooks/verify-webhooks).

3. **Process the event** in your handler. The payload includes the sender address, recipient address, token, amount, and on-chain transaction details:

<Accordion title="Example webhook payload">
  ```json theme={null}
  {
    "id": "whevnt_12324",
    "type": "wallets.transfer.in",
    "data": {
      "transferId": "660e8400-e29b-41d4-a716-446655440002",
      "sender": {
        "address": "0x1234567890123456789012345678901234567890",
        "chain": "base-sepolia",
        "locator": "base-sepolia:0x1234567890123456789012345678901234567890"
      },
      "recipient": {
        "address": "0x0987654321098765432109876543210987654321",
        "chain": "base-sepolia",
        "locator": "base-sepolia:0x0987654321098765432109876543210987654321",
        "owner": "email:customer@example.com"
      },
      "token": {
        "type": "fungible",
        "chain": "base-sepolia",
        "locator": "base-sepolia:0x036CbD53842c5426634e7929541eC2318f3dCF7e",
        "amount": "250.00",
        "rawAmount": "250000000",
        "contractAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
        "decimals": 6,
        "symbol": "USDC"
      },
      "status": "succeeded",
      "completedAt": "2025-10-21T12:34:56.789Z",
      "onChain": {
        "txId": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abc1",
        "explorerLink": "https://sepolia.basescan.org/tx/0xabc123def456abc123def456abc123def456abc123def456abc123def456abc1"
      }
    }
  }
  ```
</Accordion>

For the full webhook schema and best practices, see the [Wallet Webhooks](/wallets/guides/webhooks) guide.

***

## (Optional) Step 5 — Sweep Deposits into Your Treasury

If you created dedicated deposit addresses, you may want to consolidate received funds into a single treasury wallet. To do this, transfer tokens from each deposit wallet to your treasury whenever a payment arrives.

A common pattern is to trigger a sweep automatically from your webhook handler: when you receive a `wallets.transfer.in` event for a deposit wallet, initiate a transfer from that wallet to your treasury.

<Accordion title="Example sweep transfer">
  <CodeGroup>
    ```typescript Node.js theme={null}
    import { CrossmintWallets, createCrossmint } from "@crossmint/wallets-sdk";

    const crossmint = createCrossmint({
        apiKey: "YOUR_SERVER_API_KEY",
    });

    const crossmintWallets = CrossmintWallets.from(crossmint);

    const depositWallet = await crossmintWallets.getWallet(
        "DEPOSIT_WALLET_ADDRESS",
        { chain: "base-sepolia" }
    );

    await depositWallet.useSigner({
        type: "server",
        secret: process.env.WALLET_SIGNER_SECRET!,
    });

    const { hash, explorerLink } = await depositWallet.send(
        "evm:smart:alias:treasury",
        "usdc",
        "250"
    );
    ```

    ```bash cURL theme={null}
    curl --request POST \
        --url 'https://staging.crossmint.com/api/2025-06-09/wallets/DEPOSIT_WALLET_ADDRESS/tokens/base-sepolia:usdc/transfers' \
        --header 'X-API-KEY: YOUR_SERVER_API_KEY' \
        --header 'Content-Type: application/json' \
        --data '{
            "recipient": "evm:smart:alias:treasury",
            "amount": "250"
        }'
    ```

    ```python Python theme={null}
    import requests

    deposit_wallet = "DEPOSIT_WALLET_ADDRESS"
    token_locator = "base-sepolia:usdc"

    url = f"https://staging.crossmint.com/api/2025-06-09/wallets/{deposit_wallet}/tokens/{token_locator}/transfers"

    payload = {
        "recipient": "evm:smart:alias:treasury",
        "amount": "250"
    }
    headers = {
        "X-API-KEY": "YOUR_SERVER_API_KEY",
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)
    ```
  </CodeGroup>
</Accordion>

For more details on transferring tokens between wallets, see the [Internal Transfers](/stablecoin-orchestration/guides/internal-transfers) guide.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Wallet Webhooks" icon="bell" href="/wallets/guides/webhooks">
    Full schema and best practices for monitoring transfers
  </Card>

  <Card title="Check Balances" icon="wallet" href="/wallets/guides/check-balances">
    Query token balances across your wallets
  </Card>

  <Card title="Payouts" icon="arrow-right" href="/stablecoin-orchestration/regulated-transfers/overview">
    Send stablecoins to your customers
  </Card>

  <Card title="Internal Transfers" icon="arrow-right-arrow-left" href="/stablecoin-orchestration/guides/internal-transfers">
    Move funds between your own treasury wallets
  </Card>
</CardGroup>
