@api-buddy/stripe
v3.0.0
Published
Stripe integration for API Buddy
Readme
API Buddy - Stripe Integration
Seamless Stripe integration for your Next.js applications. This package provides React components, API routes, and utilities to quickly integrate Stripe payments and subscriptions into your app.
Features
- 💳 Pre-built Forms: Ready-to-use forms for common Stripe operations
- 🔒 Secure: Handles sensitive data securely with Stripe Elements
- 🎨 Customizable: Style components to match your app's design system
- 🛠 Type-Safe: Full TypeScript support with comprehensive type definitions
- ⚡ CLI Tool: Easy setup of API routes with a single command
Prerequisites
- Node.js 18 or later
- Next.js 13+ with App Router
- A Stripe account (sign up here)
Installation
- Install the package and its peer dependencies:
npm install @api-buddy/stripe @stripe/stripe-js
# or
yarn add @api-buddy/stripe @stripe/stripe-js
# or
pnpm add @api-buddy/stripe @stripe/stripe-jsQuick Start
Install the package:
npm install @api-buddy/stripe @stripe/stripe-js # or yarn add @api-buddy/stripe @stripe/stripe-js # or pnpm add @api-buddy/stripe @stripe/stripe-jsSet up API routes with one command:
npx @api-buddy/stripeThis will create the required API routes in your project.
Add your Stripe API keys to
.env.local:echo 'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_publishable_key_here STRIPE_SECRET_KEY=your_secret_key_here NEXT_PUBLIC_APP_URL=http://localhost:3000' > .env.localWrap your app with
StripeProvider(see below for details)
1. Set Up Environment Variables
Create or update your .env.local file in your Next.js project root:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key_here
STRIPE_SECRET_KEY=sk_test_your_secret_key_here
NEXT_PUBLIC_APP_URL=http://localhost:3000 # Your app's URLNote: Replace the test keys with your live keys when deploying to production.
2. Set Up API Routes
After installation, you must run the CLI tool to generate the required API route files in your Next.js project:
npx @api-buddy/stripeThis one-time setup will automatically detect your project's structure and:
- Create the directory structure in either:
src/app/api/customers(for projects using thesrcdirectory)app/api/customers(for standard Next.js projects)
- Add the necessary route handler files
- Preserve any existing files in the target directories
Important: You must run this command after installing the package. This step is required for the Stripe integration to work properly.
If you need to regenerate the API routes (e.g., after an update), you can safely run the command again - it will only overwrite the files that were originally created by the package.
Directory Structure Support
The CLI automatically detects and supports both common Next.js project structures:
With
srcdirectory (recommended):your-project/ ├── src/ │ └── app/ │ └── api/ │ └── customers/route.tsStandard Next.js structure:
your-project/ └── app/ └── api/ └── customers/route.ts
The CLI will prioritize the src/app directory if it exists, falling back to app if not found.
3. Add the Stripe Provider
Wrap your app with StripeProvider in your root layout:
// app/layout.tsx
'use client';
import { StripeProvider } from '@api-buddy/stripe';
// Get your publishable key from environment variables
const stripePublishableKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!;
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<StripeProvider stripeKey={stripePublishableKey}>
{children}
</StripeProvider>
</body>
</html>
);
}Available API Routes
The following API routes are set up by the CLI tool:
POST /api/customers- Create a new customerGET /api/customers- List all customersGET /api/customers/:id- Retrieve a specific customerPOST /api/customers/:id- Update a customerDELETE /api/customers/:id- Delete a customer
Usage Examples
Creating a Payment Form
'use client';
import { useStripe, useElements, CardElement } from '@stripe/stripe-js';
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
if (!stripe || !elements) {
return;
}
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement)!,
});
if (error) {
console.error(error);
return;
}
// Handle successful payment method creation
console.log('PaymentMethod:', paymentMethod);
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button type="submit" disabled={!stripe}>
Pay
</button>
</form>
);
}Creating a Customer
'use client';
import { useState } from 'react';
export default function CreateCustomerForm() {
const [email, setEmail] = useState('');
const [name, setName] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const response = await fetch('/api/customers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, name }),
});
if (!response.ok) {
throw new Error('Failed to create customer');
}
const customer = await response.json();
console.log('Customer created:', customer);
// Handle success
} catch (error) {
console.error('Error creating customer:', error);
// Handle error
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>Name</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Creating...' : 'Create Customer'}
</button>
</form>
);
}Customization
Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Your Stripe publishable key | ✅ |
| STRIPE_SECRET_KEY | Your Stripe secret key | ✅ |
| NEXT_PUBLIC_APP_URL | Your application's URL | ✅ |
| NEXT_PUBLIC_STRIPE_API_VERSION | Stripe API version (default: 2023-10-16) | ❌ |
Styling
You can customize the appearance of the Stripe Elements by passing a stripeOptions prop to the StripeProvider:
<StripeProvider
stripeKey={stripePublishableKey}
stripeOptions={{
appearance: {
theme: 'stripe', // or 'night', 'flat', etc.
variables: {
colorPrimary: '#2563eb',
colorBackground: '#ffffff',
},
},
}}
>
{children}
</StripeProvider>Development
Adding New Routes
- Add your new route handler in the
src/routesdirectory - The file structure should match the desired API path
- Export a handler function that implements the desired functionality
Building the Package
# Install dependencies
pnpm install
# Build the package
pnpm run build
# Run tests
pnpm testTroubleshooting
API Routes Not Working
- Verify your
.env.localfile has the correct Stripe keys - Ensure you've run
npx @api-buddy/stripeafter installation - Check your browser's developer console for any errors
- Make sure your Stripe account is in test mode when using test keys
TypeScript Errors
If you encounter TypeScript errors, make sure you have the latest version of @types/node and @types/react installed.
License
MIT
export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <StripeProvider stripePublishableKey={process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || ''}> {children} ) }
## Components
### CreateCustomerForm
A ready-to-use form for creating new Stripe customers.
```tsx
'use client';
import { CreateCustomerForm } from '@api-buddy/stripe/components/forms/CreateCustomerForm';
export default function Page() {
return (
<div className="max-w-md mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Add New Customer</h1>
<CreateCustomerForm
onSuccess={(customer) => {
// Handle successful customer creation
console.log('Customer created:', customer);
}}
onError={(error) => {
// Handle errors
console.error('Error:', error);
}}
/>
</div>
);
}API Reference
StripeProvider
Makes Stripe.js available throughout your app.
Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| stripePublishableKey | string | Yes | Your Stripe publishable key |
| options | StripeConstructorOptions | No | Additional Stripe.js options |
CreateCustomerForm
A form component for creating new Stripe customers.
Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| onSuccess | (customer: Stripe.Customer) => void | Yes | Callback when customer is created |
| onError | (error: Error) => void | Yes | Callback when an error occurs |
| className | string | No | Additional CSS classes |
Example Implementation
1. Create an API Route
// app/api/customers/route.ts
import { NextResponse } from 'next/server';
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '');
export async function POST(request: Request) {
try {
const { name, email } = await request.json();
const customer = await stripe.customers.create({ name, email });
return NextResponse.json(customer);
} catch (error) {
console.error('Error creating customer:', error);
return NextResponse.json(
{ error: 'Failed to create customer' },
{ status: 500 }
);
}
}2. Create a Page
// app/customers/new/page.tsx
'use client';
import { CreateCustomerForm } from '@api-buddy/stripe/components/forms/CreateCustomerForm';
import { useRouter } from 'next/navigation';
export default function NewCustomerPage() {
const router = useRouter();
return (
<div className="container mx-auto py-12 px-4">
<div className="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6">
<h1 className="text-2xl font-bold text-gray-900 mb-6">
Add New Customer
</h1>
<CreateCustomerForm
onSuccess={(customer) => {
alert(`Customer created: ${customer.email}`);
router.push('/customers');
}}
onError={(error) => {
console.error('Error creating customer:', error);
}}
/>
</div>
</div>
);
}License
MIT © API Buddy
