stripe-billing
SKILL.md
Stripe Billing
Implement subscriptions, invoicing, and flexible pricing models for recurring revenue.
Rule Priority
| Priority | Rule | Impact | Description |
|---|---|---|---|
| 1 | sub-use-checkout-for-creation |
HIGH | Create subscriptions via Checkout for built-in payment collection, SCA, and tax |
| 2 | sub-check-payment-behavior |
HIGH | Use default_incomplete for SCA-compliant API-created subscriptions |
| 3 | sub-expand-latest-invoice |
HIGH | Expand latest_invoice.payment_intent to get client secret in one call |
| 4 | webhook-verify-signatures |
HIGH | Always verify webhook signatures to prevent forged events |
| 5 | webhook-handle-subscription-updated |
HIGH | Sync state on every subscription.updated for plan changes, cancellations, status |
| 6 | invoice-listen-paid-event |
HIGH | Use invoice.paid (not payment_intent.succeeded) for subscription fulfillment |
| 7 | webhook-idempotent-handlers |
HIGH | Design handlers for at-least-once delivery with event deduplication |
| 8 | webhook-return-200-quickly |
HIGH | Acknowledge webhooks immediately, process asynchronously |
| 9 | price-use-lookup-keys |
HIGH | Use lookup_key for price references instead of hardcoded IDs |
| 10 | dunning-enable-smart-retries |
HIGH | Enable ML-powered Smart Retries for optimal payment recovery |
| 11 | sub-cancel-at-period-end |
HIGH | Cancel at period end for better UX and win-back opportunity |
| 12 | trial-collect-payment-method |
HIGH | Collect payment method during trial for higher conversion |
| 13 | usage-report-idempotently |
HIGH | Include idempotency keys with usage records to prevent double-counting |
| 14 | usage-flush-before-period-end |
HIGH | Flush usage buffers before period end to prevent revenue leakage |
| 15 | portal-configure-allowed-products |
HIGH | Explicitly list products/prices in portal configuration |
| 16 | price-use-decimal-for-subcent |
HIGH | Use unit_amount_decimal for sub-cent pricing |
| 17 | invoice-preview-before-changes |
MEDIUM | Preview upcoming invoice before applying subscription changes |
| 18 | trial-handle-will-end-webhook |
MEDIUM | Handle trial_will_end for pre-expiry reminders |
| 19 | usage-prefer-billing-meters |
MEDIUM | Use Billing Meters over legacy usage records for new integrations |
| 20 | portal-use-deep-links |
MEDIUM | Use flow_data for targeted portal actions |
| 21 | sub-pause-not-cancel |
MEDIUM | Pause subscriptions instead of canceling for temporary stops |
| 22 | dunning-escalate-communications |
MEDIUM | Escalate dunning communications over retry attempts |
| 23 | price-deactivate-not-delete |
MEDIUM | Deactivate old prices instead of deleting them |
Pricing Model Decision Tree
What pricing model fits your product?
|
+-- Fixed monthly/annual fee?
| -> Flat-rate pricing (references/pricing-models.md)
|
+-- Per-seat / per-unit?
| -> Per-unit pricing (references/pricing-models.md)
|
+-- Volume tiers (price decreases with quantity)?
| -> Tiered pricing (references/pricing-models.md)
|
+-- Pay for what you use (API calls, storage)?
| -> Usage-based / metered (references/usage-based.md)
|
+-- Hybrid (base fee + usage)?
-> Multiple prices on one subscription (references/pricing-models.md)
Quick Start: SaaS Subscription
1. Create Product + Price (once, or via Dashboard)
const product = await stripe.products.create({
name: 'Pro Plan',
description: 'Full access to all features',
});
const price = await stripe.prices.create({
product: product.id,
unit_amount: 2900, // $29/month
currency: 'usd',
recurring: { interval: 'month' },
lookup_key: 'pro_monthly',
});
2. Create Subscription via Checkout
const session = await stripe.checkout.sessions.create({
customer: 'cus_xxx', // or let Checkout create one
line_items: [{ price: price.id, quantity: 1 }],
mode: 'subscription',
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
});
3. Or Create Subscription Directly (with existing payment method)
const subscription = await stripe.subscriptions.create({
customer: 'cus_xxx',
items: [{ price: price.id }],
default_payment_method: 'pm_xxx',
payment_behavior: 'default_incomplete', // requires client confirmation
expand: ['latest_invoice.payment_intent'],
});
// Return subscription.latest_invoice.payment_intent.client_secret to frontend
Subscription Lifecycle
incomplete -> active -> past_due -> canceled
-> canceled (immediate)
-> paused
trialing -> active (payment succeeds)
-> incomplete (payment fails)
-> canceled (trial ends, no payment method)
Customer Portal (Self-Service)
// One-time setup in Dashboard or API
const configuration = await stripe.billingPortal.configurations.create({
features: {
subscription_update: { enabled: true, products: [{ product: 'prod_xxx', prices: ['price_basic', 'price_pro'] }] },
subscription_cancel: { enabled: true, mode: 'at_period_end' },
payment_method_update: { enabled: true },
invoice_history: { enabled: true },
},
});
// Generate portal session per customer
const portalSession = await stripe.billingPortal.sessions.create({
customer: 'cus_xxx',
return_url: 'https://example.com/account',
});
// Redirect to portalSession.url
Critical Webhooks
| Event | Action |
|---|---|
customer.subscription.created |
Provision access |
customer.subscription.updated |
Handle plan changes, cancellation scheduling, status transitions |
customer.subscription.deleted |
Revoke access |
customer.subscription.trial_will_end |
Remind user (3 days before) |
invoice.paid |
Confirm payment, extend access |
invoice.payment_failed |
Notify user, trigger dunning escalation |
invoice.upcoming |
Preview next charge |
Quick Reference
| Topic | Key Concept | Reference |
|---|---|---|
| Flat/tiered pricing | Products have multiple Prices; use lookup_key |
references/pricing-models.md |
| Subscription creation | Prefer Checkout; use default_incomplete for API |
references/subscription-lifecycle.md |
| Usage billing | Billing Meters (modern) or Usage Records (legacy) | references/usage-based.md |
| Trials | trial_period_days or trial_end; collect payment method |
references/trials.md |
| Invoices | invoice.paid is authoritative; preview before changes |
references/invoices.md |
| Customer portal | Configure products explicitly; use deep links | references/customer-portal.md |
| Dunning | Smart Retries + escalating communications | references/dunning.md |
| Coupons | Coupons (internal) + Promotion Codes (customer-facing) | references/coupons.md |
| Proration | always_invoice for immediate; none for period-end |
references/proration.md |
| Schedules | Phase-based automation; max 10 phases | references/schedules.md |
References
- references/pricing-models.md - Flat, tiered, per-unit, graduated, volume pricing
- references/subscription-lifecycle.md - Create, update, cancel, pause, resume
- references/usage-based.md - Metered billing, usage records, aggregation
- references/trials.md - Free trials with/without payment method, trial conversions
- references/invoices.md - Invoice generation, customization, hosted page
- references/customer-portal.md - Self-service configuration and customization
- references/dunning.md - Smart retries, failed payment emails, recovery
- references/coupons.md - Coupons, promotion codes, discounts
- references/proration.md - Mid-cycle upgrades/downgrades, proration behavior
- references/schedules.md - Subscription schedules for future changes
Weekly Installs
3
Repository
zef-computers/driversFirst Seen
Feb 24, 2026
Security Audits
Installed on
gemini-cli3
codex3
cursor3
opencode3
qoder2
codebuddy2