Use when you have a written implementation plan to execute in a separate session with review checkpoints
npx skills add phrazzld/claude-config --skill "fix-stripe"
Install specific skill from multi-skill repository
# Description
|
# SKILL.md
name: fix-stripe
description: |
Run /check-stripe, then fix the highest priority Stripe issue.
Creates one fix per invocation. Invoke again for next issue.
Use /log-stripe-issues to create issues without fixing.
/fix-stripe
Fix the highest priority Stripe integration issue.
What This Does
- Invoke
/check-stripeto audit Stripe integration - Identify highest priority issue
- Fix that one issue
- Verify the fix
- Report what was done
This is a fixer. It fixes one issue at a time. Run again for next issue. Use /stripe for full lifecycle.
Process
1. Run Primitive
Invoke /check-stripe skill to get prioritized findings.
2. Fix Priority Order
Fix in this order:
1. P0: Missing webhook secret, hardcoded keys
2. P1: Webhook verification, customer portal, subscription checks
3. P2: Idempotency, error handling
4. P3: Advanced features
3. Execute Fix
Missing webhook secret (P0):
Add to .env.local:
STRIPE_WEBHOOK_SECRET=whsec_...
Get from Stripe Dashboard or CLI:
stripe listen --print-secret
Hardcoded keys (P0):
Replace hardcoded keys with environment variables:
// Before
const stripe = new Stripe('sk_test_...', { apiVersion: '2024-12-18.acacia' });
// After
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2024-12-18.acacia' });
Webhook verification missing (P1):
Update webhook handler:
export async function POST(req: Request) {
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) {
return new Response('Webhook signature verification failed', { status: 400 });
}
// Handle event...
}
No customer portal (P1):
Add billing portal endpoint:
// app/api/stripe/portal/route.ts
export async function POST(req: Request) {
const { customerId } = await req.json();
const session = await stripe.billingPortal.sessions.create({
customer: customerId,
return_url: `${process.env.NEXT_PUBLIC_APP_URL}/settings`,
});
return Response.json({ url: session.url });
}
Subscription status not checked (P1):
Add subscription check middleware:
async function requireActiveSubscription(userId: string) {
const subscription = await getSubscription(userId);
if (!subscription || subscription.status !== 'active') {
throw new Error('Active subscription required');
}
}
4. Verify
After fix:
# Test webhook verification
stripe trigger checkout.session.completed
# Check portal works
curl -X POST http://localhost:3000/api/stripe/portal \
-H "Content-Type: application/json" \
-d '{"customerId": "cus_test"}'
5. Report
Fixed: [P0] Webhook signature not verified
Updated: app/api/webhooks/stripe/route.ts
- Added signature verification with constructEvent()
- Added error handling for invalid signatures
Verified: stripe trigger checkout.session.completed → verified
Next highest priority: [P1] No customer portal
Run /fix-stripe again to continue.
Branching
Before making changes:
git checkout -b fix/stripe-$(date +%Y%m%d)
Single-Issue Focus
Payment integrations are critical. Fix one thing at a time:
- Test each change thoroughly
- Easy to rollback specific fixes
- Clear audit trail for PCI
Run /fix-stripe repeatedly to work through the backlog.
Related
/check-stripe- The primitive (audit only)/log-stripe-issues- Create issues without fixing/stripe- Full Stripe lifecycle/stripe-health- Webhook diagnostics
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.