> ## 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.

# BasePayButton

> Pre-built React component for accepting payments with Base Account

The `BasePayButton` is a ready-to-use React component that provides a seamless payment experience using Base Account. It handles the entire payment flow including user interaction, transaction processing, and result handling.

<Warning>
  **Please Follow the Brand Guidelines**

  If you intend on using the BasePayButton, please follow the [Brand Guidelines](/base-account/reference/ui-elements/brand-guidelines) to ensure consistency across your application.
</Warning>

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @base-org/account-ui
  ```

  ```bash pnpm theme={null}
  pnpm add @base-org/account-ui
  ```

  ```bash yarn theme={null}
  yarn add @base-org/account-ui
  ```

  ```bash bun theme={null}
  bun add @base-org/account-ui
  ```
</CodeGroup>

## Basic Usage

```tsx theme={null}
import { BasePayButton } from '@base-org/account-ui/react';

function PaymentForm() {
  const handlePaymentResult = (result) => {
    if (result.success) {
      console.log('Payment successful!', result);
    } else {
      console.error('Payment failed:', result.error);
    }
  };

  return (
    <BasePayButton 
      paymentOptions={{
        amount: '10.00',
        to: 'your-wallet.eth',
        testnet: true
      }}
      colorScheme="light"
      onPaymentResult={handlePaymentResult}
    />
  );
}
```

## Props

### paymentOptions (required)

Payment configuration object with the following properties:

<ParamField body="amount" type="string" required>
  The payment amount in USDC (e.g., "10.50" for \$10.50)
</ParamField>

<ParamField body="to" type="string" required>
  The recipient wallet address or ENS name
</ParamField>

<ParamField body="testnet" type="boolean">
  Whether to use testnet for the payment (default: false)
</ParamField>

<ParamField body="payerInfo" type="object">
  Object containing information requests to collect during payment
</ParamField>

### Styling Props

<ParamField body="colorScheme" type="'light' | 'dark' | 'system'">
  Color scheme for the button appearance (default: 'system')
</ParamField>

<ParamField body="size" type="'small' | 'medium' | 'large'">
  Button size (default: 'medium')
</ParamField>

<ParamField body="variant" type="'solid' | 'outline'">
  Button variant style (default: 'solid')
</ParamField>

<ParamField body="disabled" type="boolean">
  Whether the button is disabled (default: false)
</ParamField>

### Event Handlers

<ParamField body="onPaymentResult" type="function">
  Callback function called when payment completes (success or failure)
</ParamField>

<ParamField body="onClick" type="function">
  Custom click handler (called before payment processing)
</ParamField>

## Payment Options

### Basic Payment

```tsx theme={null}
const paymentOptions = {
  amount: '25.00',
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f6E456',
  testnet: true
};

<BasePayButton 
  paymentOptions={paymentOptions}
  colorScheme="light"
  onPaymentResult={handleResult}
/>
```

### Payment with User Info Collection

```tsx theme={null}
const paymentOptions = {
  amount: '49.99',
  to: 'store.eth',
  payerInfo: {
    requests: [
      { type: 'email', optional: false },
      { type: 'name', optional: true },
      { type: 'physicalAddress', optional: false }
    ],
    callbackURL: 'https://api.example.com/validate' // Optional
  }
};

<BasePayButton 
  paymentOptions={paymentOptions}
  onPaymentResult={(result) => {
    if (result.success) {
      console.log('Payment successful!');
      console.log('User info:', result.payerInfoResponses);
    }
  }}
/>
```

## Styling Options

### Color Schemes

```tsx theme={null}
{/* Light theme */}
<BasePayButton 
  paymentOptions={paymentOptions}
  colorScheme="light"
/>

{/* Dark theme */}
<BasePayButton 
  paymentOptions={paymentOptions}
  colorScheme="dark"
/>

{/* System theme (follows user's system preference) */}
<BasePayButton 
  paymentOptions={paymentOptions}
  colorScheme="system"
/>
```

### Sizes and Variants

```tsx theme={null}
{/* Different sizes */}
<BasePayButton size="small" paymentOptions={paymentOptions} />
<BasePayButton size="medium" paymentOptions={paymentOptions} />
<BasePayButton size="large" paymentOptions={paymentOptions} />

{/* Different variants */}
<BasePayButton variant="solid" paymentOptions={paymentOptions} />
<BasePayButton variant="outline" paymentOptions={paymentOptions} />
```

## Event Handling

### Payment Result Handling

```tsx theme={null}
const handlePaymentResult = (result) => {
  if (result.success) {
    // Payment successful
    console.log('Transaction hash:', result.transactionHash);
    console.log('Block number:', result.blockNumber);
    
    // Handle user info if collected
    if (result.userInfo) {
      console.log('User email:', result.userInfo.email);
      console.log('User name:', result.userInfo.name);
    }
    
    // Update UI, redirect, etc.
    showSuccessMessage();
    redirectToThankYouPage();
  } else {
    // Payment failed
    console.error('Payment error:', result.error);
    
    // Handle different error types
    if (result.error.includes('insufficient funds')) {
      showInsufficientFundsMessage();
    } else if (result.error.includes('user rejected')) {
      showUserCancelledMessage();
    } else {
      showGenericErrorMessage();
    }
  }
};
```

### Custom Click Handler

```tsx theme={null}
const handleClick = () => {
  // Custom logic before payment
  console.log('User clicked pay button');
  
  // Analytics tracking
  trackEvent('payment_button_clicked', {
    amount: '10.00',
    product: 'subscription'
  });
  
  // Validation
  if (!isValidPayment()) {
    alert('Please complete the form first');
    return false; // Prevent payment
  }
  
  return true; // Continue with payment
};

<BasePayButton 
  paymentOptions={paymentOptions}
  onClick={handleClick}
  onPaymentResult={handlePaymentResult}
/>
```

## Complete Example

```tsx theme={null}
import React, { useState } from 'react';
import { BasePayButton } from '@base-org/account-ui/react';

export default function CheckoutPage() {
  const [loading, setLoading] = useState(false);
  const [paymentStatus, setPaymentStatus] = useState(null);

  const paymentOptions = {
    amount: '29.99',
    to: 'merchant.eth',
    testnet: true,
    payerInfo: {
      requests: [
        { type: 'email', optional: false },
        { type: 'name', optional: true },
        { type: 'physicalAddress', optional: false }
      ]
    }
  };

  const handlePaymentResult = (result) => {
    setLoading(false);
    
    if (result.success) {
      setPaymentStatus({
        type: 'success',
        message: 'Payment successful!',
        transactionHash: result.transactionHash,
        userInfo: result.userInfo
      });
      
      // Send confirmation email
      if (result.userInfo?.email) {
        sendConfirmationEmail(result.userInfo.email, result.transactionHash);
      }
    } else {
      setPaymentStatus({
        type: 'error',
        message: `Payment failed: ${result.error}`
      });
    }
  };

  const handleClick = () => {
    setLoading(true);
    setPaymentStatus(null);
  };

  return (
    <div className="checkout-page">
      <h2>Complete Your Purchase</h2>
      <div className="product-info">
        <h3>Premium Subscription</h3>
        <p>$29.99/month</p>
      </div>
      
      <BasePayButton 
        paymentOptions={paymentOptions}
        colorScheme="light"
        size="large"
        disabled={loading}
        onClick={handleClick}
        onPaymentResult={handlePaymentResult}
      />
      
      {loading && (
        <div className="loading">
          Processing payment...
        </div>
      )}
      
      {paymentStatus && (
        <div className={`status ${paymentStatus.type}`}>
          <p>{paymentStatus.message}</p>
          {paymentStatus.transactionHash && (
            <p>Transaction: {paymentStatus.transactionHash}</p>
          )}
          {paymentStatus.userInfo && (
            <div>
              <p>Email: {paymentStatus.userInfo.email}</p>
              {paymentStatus.userInfo.name && (
                <p>Name: {paymentStatus.userInfo.name.firstName} {paymentStatus.userInfo.name.lastName}</p>
              )}
            </div>
          )}
        </div>
      )}
      
      <style jsx>{`
        .checkout-page {
          max-width: 400px;
          margin: 0 auto;
          padding: 20px;
        }
        
        .product-info {
          background: #f5f5f5;
          padding: 20px;
          border-radius: 8px;
          margin-bottom: 20px;
        }
        
        .loading {
          text-align: center;
          margin-top: 15px;
          color: #666;
        }
        
        .status {
          margin-top: 20px;
          padding: 15px;
          border-radius: 8px;
        }
        
        .status.success {
          background: #d4edda;
          border: 1px solid #c3e6cb;
          color: #155724;
        }
        
        .status.error {
          background: #f8d7da;
          border: 1px solid #f5c6cb;
          color: #721c24;
        }
      `}</style>
    </div>
  );
}
```

## TypeScript Support

The component is fully typed when using TypeScript:

```tsx theme={null}
import { BasePayButton, PaymentOptions, PaymentResult } from '@base-org/account-ui/react';

interface CheckoutProps {
  amount: string;
  recipient: string;
}

function Checkout({ amount, recipient }: CheckoutProps) {
  const paymentOptions: PaymentOptions = {
    amount,
    to: recipient,
    testnet: true
  };

  const handleResult = (result: PaymentResult) => {
    // TypeScript provides full type safety
    if (result.success) {
      console.log(result.transactionHash); // ✅ Type-safe
    }
  };

  return (
    <BasePayButton 
      paymentOptions={paymentOptions}
      onPaymentResult={handleResult}
    />
  );
}
```

## Testing

For testing your integration:

1. **Use testnet mode**: Set `testnet: true` in payment options
2. **Get test USDC**: Use [Circle's faucet](https://faucet.circle.com) on Base Sepolia
3. **Test different scenarios**: Try successful payments, cancellations, and errors
4. **Verify user info collection**: Test with different `payerInfo` configurations

The BasePayButton provides a complete, production-ready payment solution that handles all the complexity of crypto payments while providing a familiar user experience.
