Why Base Pay?

USDC on Base is a fully-backed digital dollar that settles in seconds and costs pennies in gas. Base Pay lets you accept those dollars with a single click—no cards, no FX fees, no chargebacks.

  • Any user can pay – works with every Base Account (smart-wallet) out of the box.
  • USDC, not gas – you charge in dollars; gas sponsorship is handled automatically.
  • Fast – most payments confirm in <2 seconds on Base.
  • No extra fees – you receive the full amount.

👉 Want to poke around before coding? Open the interactive Playground.

Client-side (Browser SDK)

Browser (SDK)
import { createBaseAccountSDK, pay, getPaymentStatus } from '@base-org/account';

// Initialise SDK (defaults are fine for most apps)
const provider = createBaseAccountSDK().getProvider();

// Trigger a payment – user will see a popup from their wallet service
const { id } = await pay({
  amount: '1.00',           // USD amount (we quote USDC internally)
  to:    '0xRecipient',     // your address
  testnet: true            // set false for Mainnet
});

// Option 1: Poll until mined
const { status } = await getPaymentStatus({ id });
if (status === 'completed') console.log('🎉 payment settled');

This is what the user will see when prompted to pay:

Pay Popup

Collect user information (optional)

Need an email, phone, or shipping address at checkout? Pass a payerInfo object:

await pay({
  amount: '25.00',
  to: '0xRecipient',
  payerInfo: {
    requests: [
      { type: 'email' },
      { type: 'phoneNumber', optional: true }
    ],
    callbackURL: 'https://your-api.com/validate' // Optional - for server-side validation
  }
});

Supported request types:

typereturns
emailstring
name{ firstName, familyName }
phoneNumber{ number, country }
physicalAddressfull address object
onchainAddressstring
Required by default — set optional: true to avoid aborting the payment if the user declines.

How to validate the user’s information?

You can use the callbackURL to validate the user’s information on the server side.

Learn more about this in the callbackURL reference.

Polling example

Backend (SDK)
import { getPaymentStatus } from '@base-org/account';

export async function checkPayment(txId) {
  const status = await getPaymentStatus({ id: txId });
  if (status.status === 'completed') {
    // fulfil order
  }
}

Add the Base Pay Button

Use the pre-built component for a native look-and-feel:

Checkout.tsx
import { BasePayButton } from '@base-org/account-ui/react';
import { pay } from '@base-org/account';

export function Checkout() {
  return (
    <BasePayButton
      colorScheme="light"
      onClick={() => pay({ amount: '5.00', to: '0xRecipient' })}
    />
  );
}

See full props and theming options in the Button Reference and Brand Guidelines.

Test on Base Sepolia

  1. Get test USDC from the Circle Faucet (select “Base Sepolia”).
  2. Pass testnet: true in your pay() call.
  3. Use Sepolia BaseScan to watch the transaction.