/stripe
World-class Stripe integration. Audit, fix, verify—every time.
What This Does
Examines your Stripe integration, identifies every gap, implements fixes, and verifies checkout flows work end-to-end. No partial modes. Every run does the full cycle.
Branching
Assumes you start on master /main . Before making code changes:
git checkout -b fix/stripe-$(date +%Y%m%d)
Configuration-only changes (env vars, dashboard settings) don't require a branch. Code changes do.
Process
- Environment Check
Detect environment mismatch first. Before any Stripe operations:
~/.claude/skills/stripe/scripts/detect-environment.sh
This compares your app's STRIPE_SECRET_KEY account with CLI profiles. If mismatched, resources created via CLI won't be visible to your app.
Fix mismatches:
-
Use correct CLI profile: stripe -p sandbox or stripe -p production
-
Or update .env.local to match your CLI account
Billing invariant (Next.js + Convex):
-
CONVEX_WEBHOOK_TOKEN must be set in Next runtime (Vercel) and Convex env.
-
Values must match (token parity). If drift: payments may succeed but access never unlocks.
-
Local dev: .env.local changes require restart; exported env var overrides .env.local (run unset CONVEX_WEBHOOK_TOKEN if set).
- Audit
Spawn the auditor. Use the stripe-auditor subagent for deep parallel analysis. It examines:
-
Configuration (env vars on all deployments, cross-platform parity)
-
Webhook health (endpoints registered, URL returns non-3xx, pending_webhooks = 0)
-
Subscription logic (trial handling, access control, idempotency)
-
Security (no hardcoded keys, secrets not logged)
-
Business model compliance (single tier, trial honored on upgrade)
-
Subscription management UX (settings page, billing history, portal integration)
Run automated checks:
~/.claude/skills/stripe/scripts/stripe_audit.sh
Research first. Before assuming current patterns are correct, check Stripe docs for current best practices. Use Gemini. What was right last year may be deprecated.
- Plan
From audit findings, build a complete remediation plan. Don't just list issues—plan the fixes.
For each finding:
-
Configuration issues → Fix directly (env vars, dashboard settings)
-
Code issues → Delegate to Codex with clear specs
-
Design issues → May require rethinking approach, consult stripe-design
Prioritize:
-
Critical — Blocks checkout or causes payment failures
-
High — Security issues, data integrity problems
-
Medium — Missing UX, suboptimal patterns
- Execute
Fix everything. Don't stop at a report.
Configuration fixes (do directly):
Missing env var
bunx convex env set --prod CONVEX_WEBHOOK_TOKEN "$(printf '%s' 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')"
Vercel (Next runtime): set the SAME value (production + preview + dev)
vercel env add CONVEX_WEBHOOK_TOKEN production vercel env add CONVEX_WEBHOOK_TOKEN preview vercel env add CONVEX_WEBHOOK_TOKEN development
Verify
bunx convex env list --prod | rg "^(STRIPE_|CONVEX_WEBHOOK_TOKEN=)"
Code fixes (delegate to Codex):
codex exec --full-auto "Fix [specific issue].
File: [path]. Problem: [what's wrong].
Solution: [what it should do].
Reference: [pattern file].
Verify: bun run typecheck && bun run test"
--output-last-message /tmp/codex-fix.md 2>/dev/null
Then validate: git diff --stat && bun run typecheck
Webhook URL fixes: Update in Stripe Dashboard to canonical domain. If redirects exist, use the final URL.
Missing subscription management UX: Per stripe-subscription-ux , every integration needs:
-
Settings page showing plan, status, next billing date
-
Payment method display (brand + last4)
-
"Manage Subscription" button (Stripe Portal)
-
Billing history with downloadable invoices
-
State-specific messaging (trialing, canceled, past_due)
If missing, create it. This is non-negotiable.
- Verify
Prove it works. Not "looks right"—actually works.
Configuration verification:
bunx convex env list | rg "^(STRIPE_|CONVEX_WEBHOOK_TOKEN=)" bunx convex env list --prod | rg "^(STRIPE_|CONVEX_WEBHOOK_TOKEN=)" curl -s -o /dev/null -w "%{http_code}" -I -X POST "$WEBHOOK_URL"
Checkout flow test:
-
Create test checkout session
-
Complete with card 4242 4242 4242 4242
-
Verify webhook received (check logs)
-
Verify subscription created in Stripe Dashboard
-
Verify user state updated in database
-
Verify access granted
Webhook delivery test:
stripe events list --limit 5 | jq '.data[] | {id, type, pending_webhooks}'
All should have pending_webhooks: 0
Subscription management UX test:
-
Navigate to settings page
-
Verify plan and status displayed
-
Click "Manage Subscription" → Portal opens
-
Verify billing history accessible
Business model compliance:
-
Single pricing tier? ✓
-
Trial honored on upgrade? (Check Stripe subscription has trial_end) ✓
-
No freemium logic? (Expired trial = no access) ✓
If any verification fails, go back and fix it. Don't declare done until everything passes.
Business Model Compliance
Reference business-model-preferences throughout. Key constraints:
-
Single pricing tier (no complex tier logic)
-
Trial completion honored on upgrade (pass trial_end to Stripe)
-
No freemium (expired trial = no access, not limited access)
Default Stack
Assumes Next.js + TypeScript + Convex + Vercel + Clerk. Adapts gracefully to other stacks—concepts are the same, only framework specifics change.
What You Get
When complete:
-
Working checkout flow (test card succeeds, subscription created)
-
Webhook handling with signature verification (pending_webhooks = 0)
-
Subscription state management with proper trial handling
-
Access control based on subscription status
-
Subscription management UX (settings page, portal, billing history)
-
All configuration in place (dev and prod)
-
Deep verification passing
User can:
-
Run test checkout with 4242 4242 4242 4242
-
See subscription state update
-
Access gated features
-
See trial honored on mid-trial upgrade
-
View and manage subscription in settings
-
See payment method and billing history
-
Cancel, resume, or update payment method via Portal