> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-docs-devrel-859-new-docs-org-pages-pr-branch.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Request a Payment

> Request and settle an immediate escrow-backed charge on Base.

Request an immediate payment with the `charge` operation. The payer approves the payment terms and token collection, then your operator collects, settles, and records the amount as refundable in one transaction.

<Info>
  This guide's payment flow is based on the [Commerce Payments Protocol](https://github.com/base/commerce-payments).
</Info>

<Note>
  These examples use the v1.1.0 `AuthCaptureEscrow` at `0xf96815976523E00e65Be8f34cA5e64b4f41EB19c`. The same CREATE2 address is deployed on Base and Base Sepolia.
</Note>

## Charge and Verify the Payment

The complete fixture creates a unique `PaymentInfo`, derives its payer-agnostic hash, and asks the payer to sign an ERC-3009 `ReceiveWithAuthorization` for the deployed collector. The operator then submits `charge`.

| Collector | Best for |
| - | - |
| ERC-3009 | USDC and other tokens with native transfer authorizations |
| Permit2 | Broader ERC-20 support after the payer approves Permit2 |
| Pre-approval | Standard ERC-20 allowance plus a payment-specific pre-approval |
| Spend permission | Wallet-based repeated billing workflows |

B20 and other ERC-20 tokens can use Permit2 or the pre-approval collector when their transfer policies allow the collector, operator token store, receiver, and fee receiver to participate.

```typescript TypeScript lines wrap expandable highlight={2,7,11-12} theme={null}
export async function requestPayment(receiver: Address, orderId: string) {
  const payment = await prepareErc3009Payment(receiver, orderId, "5.00");
  const simulation = await publicClient.simulateContract({
    account,
    address: AUTH_CAPTURE_ESCROW,
    abi: authCaptureEscrowAbi,
    functionName: "charge",
    args: [
      payment.paymentInfo,
      payment.paymentInfo.maxAmount,
      ERC3009_PAYMENT_COLLECTOR,
      payment.collectorData,
      0n,
      zeroAddress,
    ],
  });
  const hash = await operatorWallet.writeContract(simulation.request);
  const receipt = await publicClient.waitForTransactionReceipt({ hash, confirmations: 2 });
  if (receipt.status !== "success") throw new Error("Payment charge reverted");
  return { hash, paymentInfoHash: payment.paymentInfoHash };
}
```

The protocol sends `amount - feeAmount` to `paymentInfo.receiver`, sends the fee separately, and increases `refundableAmount` by the full charged amount.

<Check>
  Confirm `PaymentCharged`, match its `paymentInfoHash` to the order, and atomically claim the event before fulfillment.
</Check>

<Warning>
  A payer signature is not settlement. Only a successful `charge` receipt proves that collection and distribution completed. Keep `maxFeeBps` narrow and fix `feeReceiver` unless your operator needs to replace a denylisted recipient.
</Warning>

## See Also

<CardGroup cols={2}>
  <Card title="Authorize a Payment" icon="signature" href="/build-on-base/accept-payments/authorize-a-payment">
    Reserve funds in escrow and capture after fulfillment.
  </Card>

  <Card title="Verify a Payment" icon="shield-check" href="/build-on-base/accept-payments/verify-a-payment">
    Confirm protocol events before you fulfill.
  </Card>
</CardGroup>
