npm package: @pagedotapp/page-pay-button
Description: PagePayButton - A reusable React component
Author: PageStudio
Latest version: 0.0.0-alpha.13

# PagePayButton

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

## Installation

```bash
npm install @pagedotapp/page-pay-button
```

## Usage

```tsx
import { PagePayButton } from "@pagedotapp/page-pay-button"

function App() {
	return (
		<PagePayButton
			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
<PagePayButton
	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
<PagePayButton
	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
<PagePayButton
	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
<PagePayButton
	items={items}
	isAuthenticated={user.isLoggedIn}
	onAuthRequired={async () => {
		// Show login modal
		const success = await showLoginModal()
		return success
	}}
	// ... other props
/>
```

### Custom API Headers

```tsx
<PagePayButton
	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