UNPKG

@paykit-sdk/stripe

Version:
239 lines (195 loc) 6 kB
# @paykit-sdk/stripe Stripe provider for PayKit ## Quick Start ```typescript import { createEndpointHandlers, PayKit } from '@paykit-sdk/core'; import { stripe, createStripe } from '@paykit-sdk/stripe'; // Method 1: Using environment variables const provider = stripe(); // Ensure STRIPE_API_KEY environment variable is set // Method 2: Direct configuration const provider = createStripe({ apiKey: process.env.STRIPE_API_KEY, apiVersion: '2024-12-18.acacia', }); export const paykit = new PayKit(provider); export const endpoints = createEndpointHandlers(paykit); ``` ### Next.js Catch All API Route (/api/paykit/[...endpoint]/route.ts) ```typescript import { paykit } from '@/lib/paykit'; import { EndpointPath } from '@paykit-sdk/core'; export async function POST( request: NextRequest, { params }: { params: { endpoint: string[] } }, ) { try { // Construct the endpoint path with full type safety const endpoint = ('/' + params.endpoint.join('/')) as EndpointPath; const handler = endpoints[endpoint]; if (!handler) { return NextResponse.json( { message: 'Endpoint not found' }, { status: 404 }, ); } // Parse request body const body = await request.json(); const { args } = body; const result = await handler(...args); return NextResponse.json({ result }); } catch (error) { console.error('PayKit API Error:', error); return NextResponse.json( { message: error instanceof Error ? error.message : 'Internal server error', }, { status: 500 }, ); } } ``` ### Next.js Webhooks (/api/paykit/webhooks/route.ts) ```typescript import { paykit } from '@/lib/paykit'; import { NextRequest } from 'next/server'; export async function POST(request: NextRequest) { const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; if (!webhookSecret) { return NextResponse.json({ error: 'Webhook secret not configured' }, { status: 500 }); } const webhook = paykit.webhooks .setup({ webhookSecret }) .on('customer.created', async event => { console.log('Customer created:', event.data); }); .on('subscription.created', async event => { console.log('Subscription created:', event.data); }); .on('payment.created', async event => { console.log('Payment created:', event.data); }); .on('refund.created', async event => { console.log('Refund created:', event.data); }); .on('invoice.generated', async event => { console.log('Invoice generated:', event.data); }); const body = await request.text(); const headers = Object.fromEntries(request.headers.entries()); const url = request.url; try { console.log('Webhook handled'); await webhook.handle({ body, headers, fullUrl: url }); return NextResponse.json({ success: true }); } catch (error) { console.log('Webhook Error', error); return NextResponse.json({ success: false }); } } ``` ### Express.js with Webhook Handler ```typescript import { paykit, endpoints } from '@/lib/paykit'; import { createEndpointHandlers, EndpointPath, } from '@paykit-sdk/core'; import express from 'express'; const app = express(); // IMPORTANT: Webhook route must come BEFORE express.json() middleware // This ensures we get the raw body for signature verification app.post( '/api/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => { try { const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; if (!webhookSecret) { return res .status(500) .json({ error: 'Webhook secret not configured' }); } const webhook = paykit.webhooks .setup({ webhookSecret }) .on('customer.created', async event => { console.log('Customer created:', event.data); }) .on('subscription.created', async event => { console.log('Subscription created:', event.data); }) .on('payment.created', async event => { console.log('Payment created:', event.data); }) .on('refund.created', async event => { console.log('Refund created:', event.data); }) .on('invoice.generated', async event => { console.log('Invoice generated:', event.data); }); const body = req.body; // Raw buffer from express.raw() const headers = req.headers; const url = request.url; await webhook.handle({ body, headers, fullUrl: url }); // Return immediately, processing happens in background res.json({ success: true }); } catch (error) { console.error('Webhook error:', error); res.status(500).json({ message: error instanceof Error ? error.message : 'Webhook processing failed', }); } }, ); // Regular API routes use JSON middleware app.use(express.json()); app.post('/api/paykit/*', async (req, res) => { try { const endpoint = req.path.replace( '/api/paykit', '', ) as EndpointPath; const handler = endpoints[endpoint]; if (!handler) { return res.status(404).json({ message: 'Endpoint not found' }); } const { args } = req.body; const result = await handler(...args); res.json({ result }); } catch (error) { res.status(500).json({ message: error instanceof Error ? error.message : 'Internal server error', }); } }); app.listen(3000, () => { console.log('Server running on port 3000'); }); ``` ## Subscription Management ```typescript // Update subscription await paykit.subscriptions.update('sub_123', { metadata: { plan: 'enterprise' }, }); // Cancel subscription await paykit.subscriptions.cancel('sub_123'); ``` ## Environment Variables ```bash STRIPE_SECRET_KEY=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_... ``` ## Support - [Stripe Documentation](https://stripe.com/docs) ## License ISC