P

Payment Integration Skill

Payment processing patterns for Stripe, PayPal, and LemonSqueezy. Covers checkout flows, webhook handling, subscription management, PCI compliance, and idempotent payment operations with production-ready code examples.

SkillCommunitybackendv1.0.0MIT
0 views0 copies

Description

This skill provides expert guidance on integrating payment processors (Stripe, PayPal, LemonSqueezy) into web applications. Covers one-time payments, subscriptions, webhook handling, refunds, and PCI compliance. All patterns use idempotent operations and proper error handling for production reliability.

Instructions

  1. Choose Provider: Select the right payment processor based on requirements (geography, payment methods, pricing)
  2. Implement Flow: Build the checkout flow (client-side → server-side → webhook confirmation)
  3. Handle Webhooks: Process payment events reliably with idempotency and retry handling
  4. Manage Subscriptions: Handle upgrades, downgrades, cancellations, and proration
  5. Secure: Ensure PCI compliance, never log card data, validate webhook signatures

Rules

  • NEVER store raw card numbers, CVVs, or full card data on your server
  • ALWAYS validate webhook signatures before processing events
  • Use idempotency keys for every payment creation and update operation
  • Store the payment provider's IDs (customer ID, subscription ID) in your database
  • Implement webhook handlers as idempotent operations (safe to receive the same event twice)
  • Always use test/sandbox credentials in development -- never real payment keys in dev/staging
  • Handle all webhook event types you subscribe to, even if you just acknowledge them
  • Log payment operations for audit trail but NEVER log sensitive card data
  • Use Stripe's Payment Intents API (not the legacy Charges API)

Stripe Integration

Checkout Session (Server)

import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); async function createCheckoutSession(priceId: string, userId: string) { const session = await stripe.checkout.sessions.create({ mode: 'subscription', payment_method_types: ['card'], line_items: [{ price: priceId, quantity: 1 }], success_url: `${process.env.APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`, cancel_url: `${process.env.APP_URL}/pricing`, client_reference_id: userId, metadata: { userId }, }, { idempotencyKey: `checkout-${userId}-${priceId}-${Date.now()}`, }); return session.url; }

Webhook Handler

import { NextRequest, NextResponse } from 'next/server'; export async function POST(req: NextRequest) { const body = await req.text(); const signature = req.headers.get('stripe-signature')!; let event: Stripe.Event; try { event = stripe.webhooks.constructEvent( body, signature, process.env.STRIPE_WEBHOOK_SECRET! ); } catch (err) { console.error('Webhook signature verification failed'); return NextResponse.json({ error: 'Invalid signature' }, { status: 400 }); } // Idempotency: check if we've already processed this event const processed = await db.webhookEvent.findUnique({ where: { stripeEventId: event.id }, }); if (processed) { return NextResponse.json({ received: true }); } switch (event.type) { case 'checkout.session.completed': await handleCheckoutComplete(event.data.object); break; case 'customer.subscription.updated': await handleSubscriptionUpdate(event.data.object); break; case 'customer.subscription.deleted': await handleSubscriptionCanceled(event.data.object); break; case 'invoice.payment_failed': await handlePaymentFailed(event.data.object); break; } // Record processed event await db.webhookEvent.create({ data: { stripeEventId: event.id, type: event.type, processedAt: new Date() }, }); return NextResponse.json({ received: true }); }

Customer Portal

async function createPortalSession(customerId: string) { const session = await stripe.billingPortal.sessions.create({ customer: customerId, return_url: `${process.env.APP_URL}/dashboard`, }); return session.url; }

Provider Comparison

FeatureStripePayPalLemonSqueezy
Transaction Fee2.9% + $0.302.9% + $0.305% + $0.50
SubscriptionsBuilt-inLimitedBuilt-in
Global Payments135+ currencies200+ markets100+ countries
Tax HandlingStripe TaxManualBuilt-in (MoR)
Hosted CheckoutYesYesYes
Webhook ReliabilityExcellentGoodGood
Best ForFull controlBrand recognitionSimplicity, SaaS

Examples

"Set up Stripe subscription billing with webhooks"
"Implement a one-time payment checkout flow"
"Handle subscription upgrades and downgrades with proration"
"Add PayPal as an alternative payment method"
"Make our payment webhook handler idempotent"
Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates