checkout-components
Checkout Components
Purpose
Production-ready Next.js UI components for Stripe payment integration with TypeScript, Tailwind CSS, and accessibility features. Provides complete checkout flows, subscription management, and payment form components.
Security Requirements
CRITICAL: API Key Handling
When using these components:
- Never hardcode Stripe publishable keys in components
- ALWAYS use environment variables:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY - Use placeholders in all examples:
pk_test_your_stripe_publishable_key_here - Never commit actual API keys to git
- Always add
.envfiles to.gitignore
Example .env.local:
# NEVER COMMIT THIS FILE
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key_here
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here
Activation Triggers
- Creating checkout pages
- Implementing payment forms
- Building subscription management UI
- Adding customer portal components
- Integrating Stripe Elements
- Creating payment history displays
- Setting up pricing tables
Component Overview
Provider Components
- StripeProvider.tsx - Wraps app with Stripe Elements context
Payment Components
- CheckoutForm.tsx - Complete checkout form with card input
- PaymentMethodForm.tsx - Standalone payment method input
- SubscriptionCard.tsx - Subscription display and management
- PricingTable.tsx - Pricing tier comparison table
- PaymentHistory.tsx - Transaction history component
Quick Start
1. Install Dependencies
# Install Stripe React libraries
bash scripts/install-stripe-react.sh
Installs:
@stripe/stripe-js- Stripe.js loader@stripe/react-stripe-js- React Elements components- Type definitions for TypeScript
2. Setup Stripe Provider
# Create provider wrapper in your app
bash scripts/setup-stripe-provider.sh
Creates:
lib/stripe-client.ts- Stripe client initializationcomponents/providers/stripe-provider.tsx- Elements provider wrapper- Environment variable configuration
3. Generate Components
# Generate specific payment component
bash scripts/generate-component.sh checkout-form
bash scripts/generate-component.sh subscription-card
bash scripts/generate-component.sh pricing-table
4. Validate Setup
# Validate component structure and configuration
bash scripts/validate-components.sh
Checks:
- Environment variables configured
- Dependencies installed
- Component structure valid
- TypeScript types correct
- Accessibility compliance
Component Templates
StripeProvider Template
Wraps your app with Stripe Elements context:
import { StripeProvider } from '@/components/providers/stripe-provider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<StripeProvider>
{children}
</StripeProvider>
</body>
</html>
);
}
Features:
- Automatic Stripe.js loading
- Error boundary handling
- Loading states
- Theme customization
CheckoutForm Template
Complete payment form with card input:
import { CheckoutForm } from '@/components/payments/checkout-form';
export default function CheckoutPage() {
return (
<div className="max-w-md mx-auto p-6">
<h1 className="text-2xl font-semibold mb-6">Complete Purchase</h1>
<CheckoutForm
amount={4999}
onSuccess={() => router.push('/success')}
onError={(error) => console.error(error)}
/>
</div>
);
}
Features:
- Card Element with validation
- Real-time error display
- Loading states
- Success/error callbacks
- Responsive design
- ARIA labels
PaymentMethodForm Template
Standalone payment method collection:
import { PaymentMethodForm } from '@/components/payments/payment-method-form';
export default function AddPaymentMethod() {
return (
<PaymentMethodForm
onComplete={(paymentMethodId) => {
console.log('Payment method created:', paymentMethodId);
}}
customerId="cus_xxx"
/>
);
}
Features:
- Save cards for future use
- Update existing payment methods
- Validation and error handling
- Loading indicators
SubscriptionCard Template
Display and manage subscriptions:
import { SubscriptionCard } from '@/components/payments/subscription-card';
export default function SubscriptionPage() {
return (
<SubscriptionCard
subscription={{
id: 'sub_xxx',
status: 'active',
currentPeriodEnd: new Date('2025-12-01'),
plan: { name: 'Pro Plan', amount: 2999 }
}}
onCancel={() => handleCancellation()}
onUpdate={() => handleUpdate()}
/>
);
}
Features:
- Status badge display
- Renewal date
- Cancel/upgrade actions
- Usage tracking
- Billing history link
PricingTable Template
Compare pricing tiers:
import { PricingTable } from '@/components/payments/pricing-table';
const plans = [
{
id: 'price_free',
name: 'Free',
price: 0,
features: ['10 API calls/month', 'Basic support']
},
{
id: 'price_pro',
name: 'Pro',
price: 2999,
features: ['1000 API calls/month', 'Priority support', 'Advanced features']
}
];
export default function Pricing() {
return <PricingTable plans={plans} onSelectPlan={(planId) => handleCheckout(planId)} />;
}
Features:
- Responsive grid layout
- Feature comparison
- Call-to-action buttons
- Highlight recommended plan
- Annual/monthly toggle
PaymentHistory Template
Display transaction history:
import { PaymentHistory } from '@/components/payments/payment-history';
export default function BillingPage() {
return (
<PaymentHistory
customerId="cus_xxx"
limit={10}
onLoadMore={() => loadMorePayments()}
/>
);
}
Features:
- Paginated transaction list
- Invoice download links
- Status indicators
- Date formatting
- Search and filter
Styling Customization
All components use Tailwind CSS and support customization:
Element Styling
Customize Stripe Elements appearance:
const appearance = {
theme: 'stripe',
variables: {
colorPrimary: '#0070f3',
colorBackground: '#ffffff',
colorText: '#000000',
colorDanger: '#df1b41',
fontFamily: 'system-ui, sans-serif',
spacingUnit: '4px',
borderRadius: '4px'
}
};
<Elements stripe={stripePromise} options={{ appearance }}>
<CheckoutForm />
</Elements>
Component Classes
Override default Tailwind classes:
<CheckoutForm
className="custom-checkout"
buttonClassName="bg-blue-600 hover:bg-blue-700"
errorClassName="text-red-600 text-sm"
/>
TypeScript Types
All components include full TypeScript support:
import type {
CheckoutFormProps,
PaymentMethodFormProps,
SubscriptionCardProps,
PricingTableProps,
PaymentHistoryProps
} from '@/types/payments';
Type Definitions:
- Props interfaces
- Stripe object types
- Event handlers
- Error types
- Response types
Error Handling
Components provide comprehensive error handling:
<CheckoutForm
onError={(error) => {
switch (error.type) {
case 'card_error':
// Show user-friendly message
toast.error(error.message);
break;
case 'validation_error':
// Handle validation errors
break;
default:
// Generic error handling
console.error(error);
}
}}
/>
Error Types:
- Card validation errors
- Payment processing errors
- Network errors
- Configuration errors
Accessibility Features
All components follow WCAG 2.1 AA standards:
- Proper ARIA labels
- Keyboard navigation support
- Focus management
- Screen reader friendly
- Error announcements
- Color contrast compliance
Example:
<button
type="submit"
aria-label="Complete payment"
aria-disabled={isProcessing}
className="focus:ring-2 focus:ring-blue-500"
>
{isProcessing ? 'Processing...' : 'Pay Now'}
</button>
Testing
Component Testing
# Validate all components
bash scripts/validate-components.sh
# Test specific component
bash scripts/validate-components.sh CheckoutForm
Integration Testing
Use Stripe test cards:
4242 4242 4242 4242 - Success
4000 0000 0000 0002 - Decline
4000 0000 0000 9995 - Insufficient funds
Examples
Example 1: Complete Checkout Page
Full checkout implementation with cart summary:
// See: examples/checkout-page-example.tsx
// Complete page with:
// - Order summary
// - Checkout form
// - Success/error handling
// - Loading states
// - Receipt generation
Example 2: Subscription Management
Subscription portal with upgrade/downgrade:
// See: examples/subscription-management-example.tsx
// Complete portal with:
// - Current plan display
// - Pricing comparison
// - Upgrade/downgrade flow
// - Cancellation handling
// - Invoice history
Example 3: Payment Form Integration
Integrate payment form in multi-step flow:
// See: examples/payment-form-integration-example.tsx
// Multi-step checkout with:
// - Shipping information
// - Payment details
// - Order confirmation
// - Progress indicator
Environment Setup
Required environment variables:
# .env.local (NEVER commit this file)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_key_here
STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here
# Optional
NEXT_PUBLIC_STRIPE_CURRENCY=usd
NEXT_PUBLIC_APP_URL=http://localhost:3000
Add to .gitignore:
.env.local
.env.*.local
.env
Requirements
Dependencies:
- Next.js 13+ with App Router
- React 18+
- TypeScript 5+
- Tailwind CSS 3+
- @stripe/stripe-js
- @stripe/react-stripe-js
Stripe Setup:
- Stripe account (test mode works)
- Publishable key
- Secret key
- Webhook endpoint configured
Security Best Practices
-
Never expose secret keys client-side
- Only use
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYin components - Secret key stays server-side only
- Only use
-
Validate on server
- Always verify payments server-side
- Use webhooks for payment confirmations
- Never trust client-side data
-
Use HTTPS in production
- Required for Stripe integration
- Protects payment data in transit
-
Implement CSP headers
- Allow Stripe.js domain
- Restrict other script sources
-
Handle PCI compliance
- Never store card numbers
- Use Stripe Elements (SAQ A compliant)
- Let Stripe handle card data
Troubleshooting
Stripe.js Not Loading
Check environment variable:
echo $NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
Verify format starts with pk_test_ or pk_live_
Payment Intent Creation Fails
Ensure server-side API route exists:
// app/api/create-payment-intent/route.ts
import { stripe } from '@/lib/stripe-server';
export async function POST(req: Request) {
const { amount } = await req.json();
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'usd',
});
return Response.json({ clientSecret: paymentIntent.client_secret });
}
Component Not Rendering
Verify StripeProvider wraps component:
// Must be wrapped
<StripeProvider>
<CheckoutForm />
</StripeProvider>
Resources
Scripts:
scripts/install-stripe-react.sh- Install dependenciesscripts/setup-stripe-provider.sh- Configure providerscripts/generate-component.sh- Generate new componentsscripts/validate-components.sh- Validate setup
Templates:
templates/StripeProvider.tsx- Provider wrappertemplates/CheckoutForm.tsx- Checkout formtemplates/PaymentMethodForm.tsx- Payment method inputtemplates/SubscriptionCard.tsx- Subscription displaytemplates/PricingTable.tsx- Pricing comparisontemplates/PaymentHistory.tsx- Transaction history
Examples:
examples/checkout-page-example.tsx- Complete checkoutexamples/subscription-management-example.tsx- Subscription UIexamples/payment-form-integration-example.tsx- Multi-step flow
Plugin: payments Version: 1.0.0 Category: UI Components Framework: Next.js + Stripe Elements