Stripe
Open registry of community-contributed AI coding skills (SKILL.md files) — daily-synced to skills-hub.ai. Install across Claude Code, Cursor, Codex CLI, Windsurf, Copilot, and any MCP-compatible tool with one command.
npx -y skills add tinh2/skills-hub-registry --skill stripeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Add Stripe payments to my app — set up checkout sessions, payment intents, webhook handling with signature verification, subscription billing with plan management, customer portal, and idempotent event processing for any backend framework
SKILL.md
14.6 KB, as published. Nobody here has run it
You are in AUTONOMOUS MODE. Do NOT ask questions. Execute the full pipeline below without pausing for user input. Make reasonable decisions using sensible defaults.
PURPOSE: Set up a complete Stripe payment integration in the current project. This includes SDK installation, API key configuration, checkout flow, webhook handling with signature verification, and optionally subscription billing and customer portal.
INPUT: $ARGUMENTS
The user may specify:
- Payment type: "one-time", "subscription", "both" (default: "both")
- Specific products/prices to configure
- A provider preference (always Stripe for this skill) If no arguments, default to a complete setup with both one-time and subscription support.
=== PHASE 1: PROJECT DETECTION ===
Step 1.1 — Detect Framework
Scan for project files to determine the tech stack:
| File | Framework | Server Library |
|---|---|---|
| package.json with "next" | Next.js | Built-in API routes |
| package.json with "fastify" | Fastify | Fastify routes |
| package.json with "express" | Express | Express routes |
| package.json with "nestjs" | NestJS | NestJS controllers |
| package.json with "hono" | Hono | Hono routes |
| requirements.txt with "django" | Django | Django views |
| requirements.txt with "fastapi" | FastAPI | FastAPI routes |
| requirements.txt with "flask" | Flask | Flask routes |
| Gemfile with "rails" | Rails | Rails controllers |
| go.mod with "gin" | Gin | Gin handlers |
Record: FRAMEWORK, LANGUAGE, PROJECT_ROOT, SRC_DIR, ROUTES_DIR
Step 1.2 — Check Existing Stripe Setup
Search for any existing Stripe integration:
- Package installed: stripe, @stripe/stripe-js, stripe-node
- Env vars: STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET
- Existing webhook endpoint
- Existing checkout or payment intent code
If a complete Stripe integration already exists, report it and exit. If a partial integration exists, identify gaps and fill them.
=== PHASE 2: SDK INSTALLATION ===
Step 2.1 — Install Server-Side SDK
Based on the detected language:
- Node.js/TypeScript:
npm install stripe(or yarn/pnpm based on lockfile) - Python:
pip install stripe(add to requirements.txt) - Ruby: Add
gem 'stripe'to Gemfile - Go:
go get github.com/stripe/stripe-go/v80 - PHP:
composer require stripe/stripe-php
Step 2.2 — Install Client-Side SDK (if applicable)
If the project has a frontend:
- Next.js / React:
npm install @stripe/stripe-js @stripe/react-stripe-js - Flutter: Add
flutter_stripeto pubspec.yaml - No separate frontend: Skip client SDK
Step 2.3 — Configure Environment Variables
Add to .env.example (create if it does not exist):
# Stripe
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
If .env exists, add the same keys with placeholder values. If the project uses a config validation system (e.g., Zod env schema), update it.
=== PHASE 3: STRIPE CLIENT MODULE ===
Step 3.1 — Create Stripe Client Singleton
Create a Stripe client module at the appropriate location based on the framework:
- Next.js:
lib/stripe.tsorsrc/lib/stripe.ts - Fastify/Express:
src/config/stripe.tsorsrc/lib/stripe.ts - Django/FastAPI:
app/services/stripe_client.pyorconfig/stripe.py - Rails:
config/initializers/stripe.rb
The client module MUST:
- Import the Stripe SDK
- Initialize with the secret key from environment variables
- Set the API version explicitly (use the latest stable version)
- Export a singleton instance
- Include TypeScript types if applicable
Step 3.2 — Create Stripe Service Layer
Create a service module that encapsulates all Stripe operations:
Location: src/services/stripe.service.ts (adjust path for framework)
The service MUST include these methods:
createCheckoutSession(params):
- Accepts: priceId, customerId (optional), successUrl, cancelUrl, mode (payment | subscription)
- Creates a Stripe Checkout Session
- Returns the session URL and ID
createPaymentIntent(params):
- Accepts: amount, currency, customerId (optional), metadata
- Creates a Payment Intent for custom payment flows
- Returns the client secret
createCustomer(params):
- Accepts: email, name, metadata
- Creates a Stripe Customer
- Returns the customer object
getCustomerPortalSession(params):
- Accepts: customerId, returnUrl
- Creates a Billing Portal Session
- Returns the portal URL
constructWebhookEvent(payload, signature):
- Accepts: raw request body, Stripe-Signature header value
- Verifies the webhook signature using STRIPE_WEBHOOK_SECRET
- Returns the verified event object
- Throws on invalid signature
Every method MUST:
- Use try/catch with meaningful error messages
- Log errors (using the project's logger if one exists)
- Never expose raw Stripe errors to clients — wrap in application errors
=== PHASE 4: CHECKOUT FLOW ===
Step 4.1 — Create Checkout Endpoint
Create an API endpoint for initiating checkout:
Route: POST /api/payments/checkout (or framework equivalent)
The endpoint MUST:
- Accept: priceId, mode (payment | subscription), successUrl, cancelUrl
- Optionally accept customerId (link to existing customer)
- Call stripeService.createCheckoutSession()
- Return the session URL to the client
- Require authentication if the project has auth middleware
Step 4.2 — Create Payment Intent Endpoint (for custom UI)
Route: POST /api/payments/create-intent
The endpoint MUST:
- Accept: amount, currency (default "usd")
- Call stripeService.createPaymentIntent()
- Return the client secret
- Require authentication
Step 4.3 — Create Success/Cancel Handlers
If the project has a frontend:
- Create a success page/route that displays confirmation
- Create a cancel page/route that allows retry
- Both should handle the session_id query parameter from Stripe redirect
=== PHASE 5: WEBHOOK HANDLER ===
Step 5.1 — Create Webhook Endpoint
Route: POST /api/webhooks/stripe
This is the MOST CRITICAL part of the integration. The webhook MUST:
- Read the raw request body (NOT parsed JSON — Stripe needs the raw body for verification)
- Extract the Stripe-Signature header
- Call stripeService.constructWebhookEvent() to verify the signature
- Return 400 immediately if signature verification fails
- Handle events in a switch/case block
- Return 200 quickly — do async processing outside the request if needed
Framework-specific raw body handling:
- Next.js App Router: Use the raw request body from the Request object
- Next.js Pages Router: Disable body parser for the webhook route
- Express: Use express.raw() middleware on the webhook route only
- Fastify: Use addContentTypeParser for the webhook route to get raw body
- Django: Use request.body (already raw bytes)
- FastAPI: Use Request.body() directly
- Rails: Use request.body.read
Step 5.2 — Handle Core Webhook Events
Implement handlers for these events:
checkout.session.completed:
- Extract session data
- Link payment to user/order in your database
- Send confirmation email if email service exists
payment_intent.succeeded:
- Update payment status in database
- Fulfill the order
payment_intent.payment_failed:
- Update payment status
- Notify the user of failure
customer.subscription.created:
- Store subscription details in database
- Update user's plan/tier
customer.subscription.updated:
- Update stored subscription details
- Handle plan changes (upgrade/downgrade)
customer.subscription.deleted:
- Mark subscription as canceled in database
- Downgrade user's plan/tier
- Handle grace period if applicable
invoice.payment_succeeded:
- Record successful invoice payment
- Extend subscription access
invoice.payment_failed:
- Notify user of payment failure
- Begin dunning process (retry logic)
Each handler should call a dedicated function — do NOT put business logic inline in the switch.
Step 5.3 — Webhook Idempotency
Every webhook handler MUST be idempotent:
- Check if the event has already been processed (store event IDs in database)
- If already processed, return 200 without re-processing
- Use database transactions where applicable
=== PHASE 6: SUBSCRIPTION BILLING (if requested) ===
Skip this phase if the user only requested one-time payments.
Step 6.1 — Price Configuration
Create a prices/products configuration file:
// src/config/stripe-prices.ts
export const PRICES = {
FREE: { id: null, name: 'Free', features: [...] },
PRO: { id: 'price_xxx', name: 'Pro', features: [...] },
ENTERPRISE: { id: 'price_xxx', name: 'Enterprise', features: [...] },
} as const;
Step 6.2 — Customer Portal Endpoint
Route: POST /api/payments/portal
The endpoint MUST:
- Require authentication
- Look up the Stripe customer ID for the authenticated user
- Call stripeService.getCustomerPortalSession()
- Return the portal URL
- Handle the case where the user has no Stripe customer record
Step 6.3 — Subscription Status Middleware
Create middleware or a helper function that:
- Checks the user's current subscription status
- Can be used to gate premium features
- Caches the subscription status to avoid excessive Stripe API calls
- Falls back gracefully if Stripe is unreachable
=== PHASE 7: VERIFICATION ===
Step 7.1 — Static Verification
Run the project's type checker and linter:
- TypeScript:
tsc --noEmit - Python:
mypyorpyrightif configured - Linter: ESLint, Ruff, Rubocop, etc.
Fix all errors introduced by the Stripe integration.
Step 7.2 — Integration Checklist
Verify and report:
- Stripe SDK installed (server + client if applicable)
- Environment variables documented in .env.example
- Stripe client singleton created with explicit API version
- Checkout session endpoint functional
- Webhook endpoint with raw body parsing
- Webhook signature verification implemented
- Core webhook events handled
- Webhook idempotency implemented
- Subscription billing configured (if requested)
- Customer portal endpoint created (if subscriptions)
- All errors wrapped — no raw Stripe errors leaked to clients
- Type checking passes
=== OUTPUT ===
Print the following summary:
Stripe Integration Complete
Framework: [detected framework] Payment types: [one-time | subscription | both]
Files Created/Modified
| File | Purpose |
|---|---|
| [path] | [description] |
Environment Variables Required
| Variable | Purpose | Where to get it |
|---|---|---|
| STRIPE_SECRET_KEY | Server-side API key | Stripe Dashboard > API Keys |
| STRIPE_PUBLISHABLE_KEY | Client-side API key | Stripe Dashboard > API Keys |
| STRIPE_WEBHOOK_SECRET | Webhook verification | Stripe Dashboard > Webhooks |
Endpoints Added
| Method | Path | Purpose |
|---|---|---|
| POST | /api/payments/checkout | Create checkout session |
| POST | /api/payments/create-intent | Create payment intent |
| POST | /api/payments/portal | Customer billing portal |
| POST | /api/webhooks/stripe | Stripe webhook handler |
Webhook Events Handled
[List of events with brief description]
Test Mode Setup
- Use
sk_test_...andpk_test_...keys from Stripe Dashboard - Run
stripe listen --forward-to localhost:[PORT]/api/webhooks/stripefor local testing - Use Stripe CLI to trigger test events:
stripe trigger payment_intent.succeeded
Going Live Checklist
- Switch to live API keys in production environment
- Configure webhook endpoint URL in Stripe Dashboard
- Set up Stripe Tax if required
- Configure Stripe Radar for fraud protection
- Test the complete flow with Stripe test cards
=== NEXT STEPS ===
After Stripe integration:
- "Run
/auth-providerto add user authentication (needed to link payments to users)." - "Run
/emailto add transactional email for payment receipts and invoices." - "Run
/analytics-trackingto track conversion funnels and payment events." - "Run
/integrate auditto check overall integration health."
=== DO NOT ===
- Do NOT store raw credit card numbers or sensitive payment data — Stripe handles this.
- Do NOT skip webhook signature verification — this is a security requirement.
- Do NOT parse the webhook request body as JSON before signature verification.
- Do NOT use deprecated Stripe APIs (Charges API) — use Payment Intents and Checkout Sessions.
- Do NOT hardcode Stripe API keys in source code — always use environment variables.
- Do NOT log full Stripe event payloads in production — they may contain PII.
- Do NOT ignore webhook delivery failures — implement proper error handling and retry logic.
- Do NOT create Stripe resources (products, prices) via code — configure them in the Dashboard and reference by ID, unless the user specifically requests programmatic product creation.
- Do NOT skip the raw body configuration for the webhook route — this is the most common source of "signature verification failed" errors.
============================================================ SELF-HEALING VALIDATION (max 3 iterations)
After completing the integration, validate:
- Run the project's test suite to verify the integration works end-to-end.
- Run build/compile to confirm no breakage.
- Verify the integration responds correctly (health checks, test calls, smoke tests).
- If failures occur, diagnose from error output and apply minimal fixes.
- Repeat up to 3 iterations.
IF STILL FAILING after 3 iterations:
- Document the integration state and what's blocking
- Include error output and attempted fixes
============================================================ SELF-EVOLUTION TELEMETRY
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
- Look for the project path in
~/.claude/projects/ - If found, append to
skill-telemetry.mdin that memory directory
Entry format:
### /stripe — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}
Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.