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

# Create a payment

> Turn a quote into something payable — a pool to sign against, or a one-time deposit address.

Two endpoints, one per rail. Both take a quote and return what the customer needs.

<Tabs>
  <Tab title="Connect rail">
    `POST /create-pool-connect`

    Returns your pool address for the customer's wallet to call `deposit()` on.

    <ParamField path="body.quoteId" type="string" required>
      From [create-quote](/api/create-quote).
    </ParamField>

    <ParamField path="body.payerAddress" type="string">
      The customer's connected wallet. Required if you've enabled payer screening.
    </ParamField>

    <ResponseField name="poolAddress" type="string">The contract to call. Verify this before signing.</ResponseField>
    <ResponseField name="paymentId" type="string">Pass to `deposit()` so the payment is attributable.</ResponseField>
    <ResponseField name="token" type="string">Token contract address to approve.</ResponseField>
    <ResponseField name="expectedAmount" type="string">Amount in base units.</ResponseField>
    <ResponseField name="chainId" type="number">Chain to submit on.</ResponseField>
    <ResponseField name="binding" type="object">Verification bundle. Re-prove it client-side rather than trusting it. [Why](/concepts/verification).</ResponseField>

    <Warning>
      The pool must be deployed on that chain. If it isn't, this returns `422` — offer the deposit rail instead.
    </Warning>
  </Tab>

  <Tab title="Deposit rail">
    `POST /create-pool-deposit`

    Returns a one-time address for the customer to send a plain transfer to.

    <ParamField path="body.quoteId" type="string" required>
      From [create-quote](/api/create-quote).
    </ParamField>

    <ResponseField name="id" type="string">Deposit intent ID. Use with [payment-status](/api/payment-status).</ResponseField>
    <ResponseField name="forwarderAddress" type="string">**Show this to the customer.** Unique to this invoice.</ResponseField>
    <ResponseField name="poolAddress" type="string">Where the funds ultimately settle.</ResponseField>
    <ResponseField name="token" type="string">Token contract address to send.</ResponseField>
    <ResponseField name="tokenDecimals" type="number">Decimals, for display.</ResponseField>
    <ResponseField name="expectedAmount" type="string">Amount in base units.</ResponseField>
    <ResponseField name="toleranceBps" type="number">Tolerance in basis points.</ResponseField>
    <ResponseField name="chainId" type="number">Chain to send on.</ResponseField>
    <ResponseField name="status" type="string">Starts at `waiting`.</ResponseField>
    <ResponseField name="expiresAt" type="string">Quote expiry. The address stays valid after it.</ResponseField>
  </Tab>
</Tabs>

<RequestExample>
  ```bash Connect theme={null}
  curl -X POST $CC_API_BASE/create-pool-connect \
    -H "apikey: $CC_PUBLISHABLE_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "quoteId": "q_8f2a…", "payerAddress": "0xCustomer…" }'
  ```

  ```bash Deposit theme={null}
  curl -X POST $CC_API_BASE/create-pool-deposit \
    -H "apikey: $CC_PUBLISHABLE_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "quoteId": "q_8f2a…" }'
  ```
</RequestExample>

<ResponseExample>
  ```json Deposit 200 theme={null}
  {
    "id": "dep_4c8e…",
    "forwarderAddress": "0x7A3f…",
    "poolAddress": "0x2B91…",
    "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "tokenDecimals": 6,
    "expectedAmount": "49000000",
    "toleranceBps": 50,
    "chainId": 8453,
    "status": "waiting",
    "expiresAt": "2026-08-09T15:02:11.204Z"
  }
  ```
</ResponseExample>

## Displaying a deposit address

<Steps>
  <Step title="Verify before you show it" icon="shield-check">
    Re-derive the forwarder from the chain-read pool address and confirm it matches. If it doesn't, show nothing. [Verification](/concepts/verification).
  </Step>

  <Step title="Show the address, amount, token, and chain" icon="qrcode">
    All four. Most failed payments are a customer sending the right amount of the wrong token, or the right token on the wrong chain.
  </Step>

  <Step title="Offer a QR code" icon="qrcode">
    Most customers pay from a phone.
  </Step>

  <Step title="Say the address stays valid" icon="clock">
    It reduces panic when an exchange withdrawal is slow.
  </Step>
</Steps>

<Danger>
  Never show a deposit address you haven't verified. It is the one screen where a compromised response could redirect a customer's money, which is exactly why the verification exists.
</Danger>

## Errors

| Status | Meaning                                                   |
| ------ | --------------------------------------------------------- |
| `400`  | Missing or malformed field                                |
| `404`  | Quote not found                                           |
| `409`  | Quote already used                                        |
| `422`  | Quote expired, pool not deployed, or amount below minimum |
| `429`  | Rate limited                                              |

[Full error reference](/api/errors).
