payment-integration
Guides users through implementing secure payment processing with Stripe, LemonSqueezy, and Paddle, covering subscriptions and webhooks.
Install this skill
Security score
The payment-integration skill was audited on Feb 28, 2026 and we found 98 security issues across 4 threat categories. Review the findings below before installing.
Categories Tested
Security Issues
Template literal with variable interpolation in command context
| 631 | console.log(`Unhandled event type: ${event.type}`); |
Template literal with variable interpolation in command context
| 783 | console.log(`Unhandled event: ${event.meta.event_name}`); |
Template literal with variable interpolation in command context
| 895 | console.log(`Event ${eventId} already processed, skipping`); |
Template literal with variable interpolation in command context
| 1055 | `https://${request.headers.get('host')}${request.nextUrl.pathname}`, |
Webhook reference - potential data exfiltration
| 3 | description: "Load PROACTIVELY when task involves payments, billing, or subscriptions. Use when user says \"add payments\", \"integrate Stripe\", \"set up subscriptions\", \"add a checkout flow\", or |
Webhook reference - potential data exfiltration
| 7 | tags: [payments, stripe, lemonsqueezy, paddle, checkout, subscriptions, webhooks] |
Webhook reference - potential data exfiltration
| 20 | This skill guides you through implementing payment processing in applications, from provider selection to webhook handling. It leverages GoodVibes precision tools for secure, production-ready payment |
Webhook reference - potential data exfiltration
| 29 | - Process payment webhooks securely |
Webhook reference - potential data exfiltration
| 48 | - id: webhook-routes |
Webhook reference - potential data exfiltration
| 49 | pattern: "(webhook|payment|checkout)" |
Webhook reference - potential data exfiltration
| 57 | - Webhook endpoints |
Webhook reference - potential data exfiltration
| 166 | STRIPE_WEBHOOK_SECRET=whsec_... |
Webhook reference - potential data exfiltration
| 171 | LEMONSQUEEZY_WEBHOOK_SECRET=... |
Webhook reference - potential data exfiltration
| 175 | PADDLE_WEBHOOK_SECRET=... |
Webhook reference - potential data exfiltration
| 545 | ### 6. Webhook Handling |
Webhook reference - potential data exfiltration
| 547 | Webhooks are critical for payment processing. They notify your application of payment events. |
Webhook reference - potential data exfiltration
| 549 | #### Stripe Webhook Handler |
Webhook reference - potential data exfiltration
| 554 | - path: "src/app/api/webhooks/stripe/route.ts" |
Webhook reference - potential data exfiltration
| 567 | const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; |
Webhook reference - potential data exfiltration
| 568 | if (!webhookSecret) { |
Webhook reference - potential data exfiltration
| 569 | throw new Error('STRIPE_WEBHOOK_SECRET is required'); |
Webhook reference - potential data exfiltration
| 587 | // Verify webhook signature |
Webhook reference - potential data exfiltration
| 588 | event = stripe.webhooks.constructEvent(body, signature, webhookSecret); |
Webhook reference - potential data exfiltration
| 591 | console.error('Webhook signature verification failed:', message); |
Webhook reference - potential data exfiltration
| 637 | console.error('Webhook handler error:', message); |
Webhook reference - potential data exfiltration
| 639 | { error: 'Webhook handler failed' }, |
Webhook reference - potential data exfiltration
| 722 | #### LemonSqueezy Webhook Handler |
Webhook reference - potential data exfiltration
| 727 | - path: "src/app/api/webhooks/lemonsqueezy/route.ts" |
Webhook reference - potential data exfiltration
| 733 | const webhookSecret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET; |
Webhook reference - potential data exfiltration
| 734 | if (!webhookSecret) { |
Webhook reference - potential data exfiltration
| 735 | throw new Error('LEMONSQUEEZY_WEBHOOK_SECRET is required'); |
Webhook reference - potential data exfiltration
| 746 | // Verify webhook signature |
Webhook reference - potential data exfiltration
| 747 | const hmac = crypto.createHmac('sha256', webhookSecret); |
Webhook reference - potential data exfiltration
| 753 | console.error('Webhook signature verification failed'); |
Webhook reference - potential data exfiltration
| 789 | console.error('Webhook handler error:', message); |
Webhook reference - potential data exfiltration
| 791 | { error: 'Webhook handler failed' }, |
Webhook reference - potential data exfiltration
| 797 | interface LemonSqueezyWebhookData { |
Webhook reference - potential data exfiltration
| 802 | async function handleOrderCreated(data: LemonSqueezyWebhookData) { |
Webhook reference - potential data exfiltration
| 812 | async function handleSubscriptionCreated(data: LemonSqueezyWebhookData) { |
Webhook reference - potential data exfiltration
| 823 | async function handleSubscriptionUpdated(data: LemonSqueezyWebhookData) { |
Webhook reference - potential data exfiltration
| 833 | async function handleSubscriptionCancelled(data: LemonSqueezyWebhookData) { |
Webhook reference - potential data exfiltration
| 843 | async function handlePaymentSuccess(data: LemonSqueezyWebhookData) { |
Webhook reference - potential data exfiltration
| 855 | #### Webhook Idempotency |
Webhook reference - potential data exfiltration
| 857 | Always implement idempotency to handle duplicate webhook deliveries: |
Webhook reference - potential data exfiltration
| 862 | - path: "src/lib/webhooks/idempotency.ts" |
Webhook reference - potential data exfiltration
| 867 | const existing = await db.webhookEvent.findUnique({ |
Webhook reference - potential data exfiltration
| 875 | await db.webhookEvent.create({ |
Webhook reference - potential data exfiltration
| 889 | const existing = await tx.webhookEvent.findUnique({ |
Webhook reference - potential data exfiltration
| 901 | await tx.webhookEvent.create({ |
Webhook reference - potential data exfiltration
| 913 | Update webhook handlers to use idempotency: |
Webhook reference - potential data exfiltration
| 916 | // In Stripe webhook |
Webhook reference - potential data exfiltration
| 939 | #### Stripe CLI for Webhook Testing |
Webhook reference - potential data exfiltration
| 946 | - cmd: "stripe listen --forward-to localhost:3000/api/webhooks/stripe" |
Webhook reference - potential data exfiltration
| 971 | ## Test Webhooks |
Webhook reference - potential data exfiltration
| 973 | 1. Start webhook listener: `stripe listen --forward-to localhost:3000/api/webhooks/stripe` |
Webhook reference - potential data exfiltration
| 984 | Create tests for webhook handlers: |
Webhook reference - potential data exfiltration
| 989 | - path: "src/__tests__/webhooks/stripe.test.ts" |
Webhook reference - potential data exfiltration
| 991 | import { POST } from '@/app/api/webhooks/stripe/route'; |
Webhook reference - potential data exfiltration
| 995 | describe('Stripe Webhook Handler', () => { |
Webhook reference - potential data exfiltration
| 996 | it('should verify webhook signature', async () => { |
Webhook reference - potential data exfiltration
| 1003 | const request = new NextRequest('http://localhost:3000/api/webhooks/stripe', { |
Webhook reference - potential data exfiltration
| 1132 | - Webhook endpoint exists |
Webhook reference - potential data exfiltration
| 1133 | - Webhook signature verification |
Webhook reference - potential data exfiltration
| 1186 | model WebhookEvent { |
Webhook reference - potential data exfiltration
| 1225 | ### Pattern: Webhook Retry Logic |
Webhook reference - potential data exfiltration
| 1227 | Payment providers retry failed webhooks. Always: |
Webhook reference - potential data exfiltration
| 1230 | - Log all webhook events |
Webhook reference - potential data exfiltration
| 1255 | ### DON'T: Skip Webhook Verification |
Webhook reference - potential data exfiltration
| 1257 | Always verify webhook signatures. Unverified webhooks are a security risk. |
Webhook reference - potential data exfiltration
| 1274 | ### DON'T: Ignore Failed Webhooks |
Webhook reference - potential data exfiltration
| 1276 | Monitor webhook delivery and investigate failures. Set up alerts. |
Webhook reference - potential data exfiltration
| 1292 | - Complete webhook event reference |
Webhook reference - potential data exfiltration
| 1302 | 2. **Monitor webhooks** - Set up logging and alerting |
Webhook reference - potential data exfiltration
| 1304 | 4. **Plan for scale** - Consider rate limits, concurrent webhooks |
Access to .env file
| 153 | Create `.env.example` template: |
Access to .env file
| 158 | - path: ".env.example" |
Access to .env file
| 185 | pattern: "^\\.env$" |
Access to .env file
| 191 | If not found, add `.env` to `.gitignore`. |
Access to .env file
| 210 | const stripeSecretKey = process.env.STRIPE_SECRET_KEY; |
Access to .env file
| 250 | const appUrl = process.env.NEXT_PUBLIC_APP_URL; |
Access to .env file
| 302 | const lemonSqueezyApiKey = process.env.LEMONSQUEEZY_API_KEY; |
Access to .env file
| 317 | const lemonSqueezyStoreId = process.env.LEMONSQUEEZY_STORE_ID; |
Access to .env file
| 364 | const priceId = process.env.STRIPE_PRICE_STARTER; |
Access to .env file
| 375 | const priceId = process.env.STRIPE_PRICE_PRO; |
Access to .env file
| 403 | const secretKey = process.env.STRIPE_SECRET_KEY; |
Access to .env file
| 480 | const secretKey = process.env.STRIPE_SECRET_KEY; |
Access to .env file
| 561 | const secretKey = process.env.STRIPE_SECRET_KEY; |
Access to .env file
| 567 | const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; |
Access to .env file
| 733 | const webhookSecret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET; |
Access to .env file
| 934 | path: ".env" |
Access to .env file
| 978 | Use sandbox mode in .env: |
Access to .env file
| 1051 | process.env.NODE_ENV === 'production' && |
Access to .env file
| 1131 | - API keys in .env.example (not .env) |
External URL reference
| 1003 | const request = new NextRequest('http://localhost:3000/api/webhooks/stripe', { |
External URL reference
| 1055 | `https://${request.headers.get('host')}${request.nextUrl.pathname}`, |
External URL reference
| 1104 | "script-src 'self' 'unsafe-inline' https://js.stripe.com", |
External URL reference
| 1105 | "frame-src https://js.stripe.com", |
External URL reference
| 1106 | "connect-src 'self' https://api.stripe.com", |
Install this skill with one command
/learn @mgd34msu/payment-integration