home / skills / phrazzld / claude-config / billing-security
This skill helps you secure Stripe and Clerk integrations by validating env vars, webhook URLs, and cross-deployment parity before production.
npx playbooks add skill phrazzld/claude-config --skill billing-securityReview the files below or copy the command above to add this skill to your agents.
---
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
effort: max
---
# 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
This skill applies billing and security best practices for payment and auth integrations, focusing on Stripe, Clerk, and similar services. It codifies production-proven checks and workflows to catch configuration and runtime mismatches that code review alone misses. Use it to validate keys, webhooks, cross-deployment parity, and to run a repeatable debugging flow before and after incidents.
The skill runs automated validations and runtime inspections: format checks for API keys and env vars, HTTP checks for webhook reachability and redirects, parity comparisons across deployment platforms, and runtime reconciliation between external service state and the application database. It also guides a concise OODA-style debugging workflow and includes scripts for quick diagnostics.
Why trim env vars?
Trailing whitespace can corrupt headers or keys; trimming at read time prevents hard-to-detect errors.
How do I detect webhook redirect problems?
Run an HTTP POST or HEAD check (curl -I -X POST) and ensure the status is not 3xx; configure the webhook to the canonical domain.