npm package: @simpledotstudio/simple-pay-button
Description: SimplePayButton - A reusable React component
Author: SimpleStudio
Latest version: 2.0.0-alpha.3

# SimplePayButton

A payment button component that integrates with Stripe Express Checkout for easy one-time payments and subscriptions.

## Installation

```bash
npm install @simpledotstudio/simple-pay-button
```

## Usage

```tsx
import { SimplePayButton } from '@simpledotstudio/simple-pay-button';

function App() {
  return (
    <SimplePayButton
      service="stripe"
      mode="payment"
      stripeKey="pk_test_..."
      apiEndpoint="https://api.example.com/create-payment-intent"
      items={[
        {
          id: 'prod_123',
          name: 'Premium Subscription',
          price: 999, // $9.99
          currency: 'usd',
          quantity: 1
        }
      ]}
      onSuccess={(details) => console.log('Payment successful!', details)}
      onError={(error) => console.error('Payment failed:', error)}
    />
  );
}
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `service` | `'stripe' \| 'paypal'` | `'stripe'` | Payment service provider (only Stripe is implemented) |
| `mode` | `'payment' \| 'subscription'` | `'payment'` | Payment mode |
| `items` | `PaymentItem[]` | - | Items to purchase (required) |
| `stripeKey` | `string` | - | Stripe publishable key (required for Stripe) |
| `apiEndpoint` | `string` | - | API endpoint for creating payment intents (required) |
| `metadata` | `Record<string, any>` | - | Additional metadata to send with the payment |
| `onSuccess` | `function` | - | Callback when payment succeeds |
| `onError` | `function` | - | Callback when payment fails |
| `onCancel` | `function` | - | Callback when payment is cancelled |
| `buttonHeight` | `number` | `40` | Custom button height |
| `className` | `string` | `''` | Additional CSS class name |
| `isAuthenticated` | `boolean` | `false` | Whether the user is authenticated |
| `onAuthRequired` | `function` | - | Callback to handle authentication |
| `apiHeaders` | `Record<string, string>` | `{}` | Custom headers for API requests |

## PaymentItem Type

```typescript
interface PaymentItem {
  id: string;              // Unique identifier
  name: string;            // Display name
  description?: string;    // Optional description
  price: number;           // Price in cents (e.g., $10.00 = 1000)
  currency: string;        // Currency code (e.g., 'usd')
  quantity?: number;       // Quantity (default: 1)
  image?: string;          // Optional image URL
}
```

## Examples

### One-time Payment

```tsx
<SimplePayButton
  service="stripe"
  mode="payment"
  stripeKey={process.env.REACT_APP_STRIPE_KEY}
  apiEndpoint="/api/create-payment-intent"
  items={[
    {
      id: 'book_123',
      name: 'JavaScript Book',
      price: 2999, // $29.99
      currency: 'usd',
      quantity: 1
    }
  ]}
  onSuccess={(details) => {
    console.log('Payment successful!', details);
    // Redirect to success page
  }}
/>
```

### Subscription

```tsx
<SimplePayButton
  service="stripe"
  mode="subscription"
  stripeKey={stripeKey}
  apiEndpoint="/api/create-subscription"
  items={[
    {
      id: 'price_monthly',
      name: 'Monthly Subscription',
      description: 'Billed monthly',
      price: 1999, // $19.99/month
      currency: 'usd'
    }
  ]}
  metadata={{
    planType: 'premium',
    billingCycle: 'monthly'
  }}
  onSuccess={(details) => {
    // Handle successful subscription
  }}
/>
```

### Multiple Items

```tsx
<SimplePayButton
  items={[
    {
      id: 'course_001',
      name: 'React Course',
      price: 4999,
      currency: 'usd',
      quantity: 1
    },
    {
      id: 'book_002',
      name: 'React Handbook',
      price: 2499,
      currency: 'usd',
      quantity: 2
    }
  ]}
  // ... other props
/>
```

### With Authentication

```tsx
<SimplePayButton
  items={items}
  isAuthenticated={user.isLoggedIn}
  onAuthRequired={async () => {
    // Show login modal
    const success = await showLoginModal();
    return success;
  }}
  // ... other props
/>
```

### Custom API Headers

```tsx
<SimplePayButton
  items={items}
  apiHeaders={{
    'Authorization': `Bearer ${authToken}`,
    'X-Custom-Header': 'value'
  }}
  // ... other props
/>
```

## API Endpoint Requirements

Your API endpoint should:

1. Accept a POST request with the following body:
```json
{
  "mode": "payment" | "subscription",
  "amount": 1000,
  "currency": "usd",
  "items": [...],
  "metadata": {...}
}
```

2. Return a response with:
```json
{
  "clientSecret": "pi_..._secret_..." // or "client_secret"
}
```

## Styling

The component uses CSS modules for styling. The Stripe Express Checkout button will automatically adapt to fit the container width.

```css
/* Custom styling example */
.paymentContainer {
  max-width: 400px;
  margin: 0 auto;
}
```

## Error Handling

The component validates all required props and will return `null` if:
- No items are provided
- Stripe key is missing (for Stripe service)
- API endpoint is missing
- Total amount is zero
- Service is set to 'paypal' (not implemented)

## Development

To run the component in development mode:

```bash
npm run storybook
```

To run tests:

```bash
npm run test
```

To lint the component:

```bash
npm run lint
```

## Notes

- PayPal integration is not yet implemented. The component returns `null` when `service="paypal"`
- Prices should be provided in cents (e.g., $10.00 = 1000)
- The component handles both one-time payments and subscriptions
- Stripe Express Checkout provides Apple Pay, Google Pay, and card payment options