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

# pay

> Send USDC payments on the Base network

export const Button = ({children, disabled, variant = "primary", size = "medium", iconName, roundedFull = false, className = '', fullWidth = false, onClick = undefined}) => {
  const variantStyles = {
    primary: 'bg-blue text-black border border-blue hover:bg-blue-80 active:bg-[#06318E] dark:text-white',
    secondary: 'bg-white border border-white text-palette-foreground hover:bg-zinc-15 active:bg-zinc-30',
    outlined: 'bg-transparent text-white border border-white hover:bg-white hover:text-black active:bg-[#E3E7E9]'
  };
  const sizeStyles = {
    medium: 'text-md px-4 py-2 gap-3',
    large: 'text-lg px-6 py-4 gap-5'
  };
  const sizeIconRatio = {
    medium: '0.75rem',
    large: '1rem'
  };
  const classes = ['text-md px-4 py-2 whitespace-nowrap', 'flex items-center justify-center', 'disabled:opacity-40 disabled:pointer-events-none', 'transition-all', variantStyles[variant], sizeStyles[size], roundedFull ? 'rounded-full' : 'rounded-lg', fullWidth ? 'w-full' : 'w-auto', className];
  const buttonClasses = classes.filter(Boolean).join(' ');
  const iconSize = sizeIconRatio[size];
  return <button type="button" disabled={disabled} className={buttonClasses} onClick={onClick}>
      <span>{children}</span>
      {iconName && <Icon name={iconName} width={iconSize} height={iconSize} color="currentColor" />}
    </button>;
};

export const BaseBanner = ({content = null, id, dismissable = true}) => {
  const LOCAL_STORAGE_KEY_PREFIX = 'cb-docs-banner';
  const [isVisible, setIsVisible] = useState(false);
  const onDismiss = () => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`, 'false');
    setIsVisible(false);
  };
  useEffect(() => {
    const storedValue = localStorage.getItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`);
    setIsVisible(storedValue !== 'false');
  }, []);
  if (!isVisible) {
    return null;
  }
  return <div className="fixed bottom-0 left-0 right-0 bg-white py-8 px-4 lg:px-12 z-50 text-black dark:bg-black dark:text-white border-t dark:border-gray-95">
      <div className="flex items-center max-w-8xl mx-auto">
        {typeof content === 'function' ? content({
    onDismiss
  }) : content}
        {dismissable && <button onClick={onDismiss} className="flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors" aria-label="Dismiss banner">
          ✕
        </button>}
      </div>
    </div>;
};

Defined in the [Base Account SDK](https://github.com/base/account-sdk)

<Info>
  The `pay` function is the core method of Base Pay that lets your users send USDC (digital dollars) on the Base network. No crypto knowledge required - we handle all the complexity. **No fees for merchants or users.**

  **Try it out:** Test the `pay` function interactively in our [Base Pay SDK Playground](https://base.github.io/account-sdk/pay-playground).
</Info>

## Parameters

<ParamField body="amount" type="string" required>
  Amount of USDC to send (e.g., "10.50" or "0.01").
</ParamField>

<ParamField body="to" type="string" required>
  Ethereum address to send USDC to (must start with 0x).

  **Pattern:** `^0x[0-9a-fA-F]{40}$`
</ParamField>

<ParamField body="testnet" type="boolean">
  Set to true to use Base Sepolia testnet instead of mainnet. Default: false
</ParamField>

<ParamField body="payerInfo" type="object">
  Optional payer information configuration for data callbacks.

  <Expandable title="PayerInfo properties">
    <ParamField body="requests" type="array" required>
      Array of information requests from the payer.

      <Expandable title="InfoRequest properties">
        <ParamField body="type" type="string" required>
          The type of information being requested.

          **Possible values:** `'email' | 'physicalAddress' | 'phoneNumber' | 'name' | 'onchainAddress'`
        </ParamField>

        <ParamField body="optional" type="boolean">
          Whether this information is optional. Default: false
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="callbackURL" type="string">
      Optional callback URL for server-side validation.
    </ParamField>
  </Expandable>
</ParamField>

## Returns

<ResponseField name="result" type="PayResult">
  Payment result on success. The function throws an error on failure.

  <Expandable title="Payment Success properties">
    <ResponseField name="id" type="string">
      Transaction hash - use this to check payment status.
    </ResponseField>

    <ResponseField name="amount" type="string">
      Amount that was sent.
    </ResponseField>

    <ResponseField name="to" type="string">
      Address that received the payment.
    </ResponseField>

    <ResponseField name="payerInfoResponses" type="object">
      Optional responses from information requests.
    </ResponseField>
  </Expandable>
</ResponseField>

## Errors

The `pay` function throws an error when the payment fails. The error object contains a message explaining what went wrong.

<RequestExample>
  ```typescript Basic Payment theme={null}
  import { pay } from '@base-org/account';

  try {
    const payment = await pay({
      amount: "10.50",
      to: "0x1234567890123456789012345678901234567890",
      testnet: false
    });
    console.log(`Payment sent! Transaction ID: ${payment.id}`);
  } catch (error) {
    console.error(`Payment failed: ${error.message}`);
  }
  ```

  ```typescript Payment with Data Collection theme={null}
  try {
    const payment = await pay({
      amount: "25.00",
      to: "0x1234567890123456789012345678901234567890",
      payerInfo: {
        requests: [
          { type: 'email', optional: false },
          { type: 'phoneNumber', optional: true },
          { type: 'physicalAddress', optional: true }
        ],
        callbackURL: "https://your-api.com/validate"
      }
    });
    
    console.log(`Payment sent! Transaction ID: ${payment.id}`);
    
    // Access collected user information
    if (payment.payerInfoResponses) {
      console.log('Email:', payment.payerInfoResponses.email);
      
      if (payment.payerInfoResponses.phoneNumber) {
        console.log('Phone:', payment.payerInfoResponses.phoneNumber.number);
        console.log('Country:', payment.payerInfoResponses.phoneNumber.country);
      }
      
      if (payment.payerInfoResponses.physicalAddress) {
        const address = payment.payerInfoResponses.physicalAddress;
        console.log('Address:', address.address1);
        console.log('City:', address.city);
        console.log('State:', address.state);
        console.log('Postal Code:', address.postalCode);
        console.log('Recipient Name:', `${address.name.firstName} ${address.name.familyName}`);
      }
    }
  } catch (error) {
    console.error(`Payment failed: ${error.message}`);
  }
  ```
</RequestExample>

<ResponseExample>
  ```typescript Basic Success Response theme={null}
  {
    id: "0xabcd1234...",
    amount: "10.50",
    to: "0x1234567890123456789012345678901234567890"
  }
  ```

  ```typescript Success Response with Data Collection theme={null}
  {
    id: "0xabcd1234...",
    amount: "25.00",
    to: "0x1234567890123456789012345678901234567890",
    payerInfoResponses: {
      email: "user@example.com",
      phoneNumber: {
        number: "+1234567890",
        country: "US"
      },
      physicalAddress: {
        address1: "123 Main St",
        city: "San Francisco",
        state: "CA",
        postalCode: "94105",
        country: "US",
        name: {
          firstName: "John",
          familyName: "Doe"
        }
      }
    }
  }
  ```

  ```typescript Error (thrown) theme={null}
  {
    "code": 4001,
    "message": "Request rejected",
    "stack": "Error: Request rejected\n    at getEthProviderError..."
  }
  ```
</ResponseExample>

## Error Handling

The `pay` function throws errors instead of returning a result. Always wrap calls to `pay` in a try-catch block to handle errors gracefully:

```typescript theme={null}
try {
  const payment = await pay({
    amount: "10.00",
    to: "0xRecipient"
  });
  // Payment succeeded, use payment.id for tracking
  console.log(`Payment sent! Transaction ID: ${payment.id}`);
} catch (error) {
  // Payment failed
  console.error(`Payment failed: ${error.message}`);
}
```

<BaseBanner
  id="privacy-policy"
  dismissable={false}
  content={({ onDismiss }) => (
<div className="flex items-center">
  <div className="mr-2">
    We're updating the Base Privacy Policy, effective July 25, 2025, to reflect an expansion of Base services. Please review the updated policy here:{" "}
    <a
      href="https://docs.base.org/privacy-policy-2025"
      target="_blank"
      className="whitespace-nowrap"
    >
      Base Privacy Policy
    </a>. By continuing to use Base services, you confirm that you have read and understand the updated policy.
  </div>
  <Button onClick={onDismiss}>I Acknowledge</Button>
</div>
)}
/>
