Skip to content
Back to skills

Billing Security

ASecurity

Apply billing and security best practices for payment/auth integrations. Invoke when: setting up Stripe/Clerk/auth, debugging payment issues, configuring webhooks, before prod deployment, after billing incidents.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
code-qualitytypescriptbashdebuggingapidatabasesecurity

Works with

  • api

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned September 27, 2026

npx -y skills add David-Li0406/meta-skill-evloving --skill billing-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Billing Security?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Billing Security
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/david-li0406-billing-security/badge)](https://www.skillsdirectory.com/skills/david-li0406-billing-security)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: billing-security
description: |
  Apply billing and security best practices for payment/auth integrations.
  Invoke when: setting up Stripe/Clerk/auth, debugging payment issues,
  configuring webhooks, before prod deployment, after billing incidents.
keywords:
  - stripe
  - payment
  - webhook
  - billing
  - checkout
  - subscription
  - customer_creation
  - webhook_secret
---

# Billing & Security Integration Patterns

> "Configuration is not reality. Verification must be active, not passive."

This skill codifies lessons from 3 prod incidents (chrondle, bibliomnomnom, volume) where Stripe integrations failed despite passing code review.

## Core Principle

**Code reviews catch code bugs, not configuration bugs.** External service integrations require:
1. Format validation (API key patterns, URL formats)
2. Reachability verification (can we actually reach the webhook URL?)
3. Cross-deployment parity (Vercel and Convex must have same config)
4. Runtime reconciliation (compare external state vs database state)

---

## Critical Patterns

### 1. Environment Variable Hygiene

**Always trim env vars:**
```typescript
// WRONG - trailing whitespace causes "Invalid character in header"
const key = process.env.STRIPE_SECRET_KEY;

// RIGHT - always trim
const key = process.env.STRIPE_SECRET_KEY?.trim();
```

**Validate format before use:**
```typescript
const STRIPE_KEY_PATTERN = /^sk_(test|live)_[a-zA-Z0-9]+$/;
if (!STRIPE_KEY_PATTERN.test(key)) {
  throw new Error("Invalid STRIPE_SECRET_KEY format");
}
```

### 2. Webhook URL Validation

**Stripe does NOT follow redirects for POST requests.** If your webhook URL returns 3xx, webhooks silently fail.

```bash
# Check for redirects BEFORE configuring webhook
curl -s -o /dev/null -w "%{http_code}" -I -X POST "https://your-domain.com/api/webhooks/stripe"
# Must return 4xx or 5xx, NOT 3xx
```

**Use canonical domain:**
- If `example.com` redirects to `www.example.com`, configure webhook for `www.example.com`

### 3. Cross-Deployment Parity

When using Vercel + Convex (or similar split architectures):
- Env vars must be set on BOTH platforms
- Use `--prod` flag: `npx convex env set --prod KEY value`
- Verify parity: compare `vercel env ls` with `npx convex env list --prod`

### 4. Stripe Parameter Constraints

**Mode-dependent parameters:**
| Parameter | Valid Modes | Invalid Modes |
|-----------|-------------|---------------|
| `customer_creation` | payment, setup | subscription |
| `subscription_data` | subscription | payment, setup |

**Common trap:** Using `customer_creation: "always"` in subscription mode throws an error at checkout time, not at compile time.

---

## Pre-Deployment Checklist

Before deploying any billing integration:

- [ ] All env vars trimmed at read time
- [ ] API key formats validated
- [ ] Webhook URL returns non-3xx status
- [ ] Vercel and Convex have matching config
- [ ] Signature verification enabled
- [ ] Error handling returns 200 (prevent Stripe infinite retries)

---

## Debugging Workflow (OODA-V)

When billing integration fails:

1. **Observe** - Check if request reaches server (look for logs)
2. **Orient** - If no logs, it is network/redirect, not code
3. **Decide** - Run `curl -I` on webhook URL
4. **Act** - Fix configuration
5. **Verify** - Resend event, watch `pending_webhooks` decrease

---

## References

- [Stripe Constraints](references/stripe-constraints.md) - API parameter rules
- [Env Var Hygiene](references/env-var-hygiene.md) - Validation patterns
- [Incident Patterns](references/incident-patterns.md) - Real failures from 3 projects

## Scripts

- `scripts/verify-webhook-url.sh <url>` - Check for redirects
- `scripts/verify-env-parity.sh` - Compare Vercel/Convex config
- `scripts/audit-stripe-config.py` - Full Stripe diagnostic

Files in this skill

  • SKILL.md3.7 KB
  • references/env-var-hygiene.md3.1 KB
  • references/incident-patterns.md4.7 KB
  • references/stripe-constraints.md3.1 KB
  • scripts/audit-stripe-config.py5.8 KB
  • scripts/verify-env-parity.sh3.2 KB
  • scripts/verify-webhook-url.sh2.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…