Should Claude Write Your SaaS Login and Billing Code?
Claude shouldn't write them from scratch. Use an established auth provider and a payment provider such as Stripe, and have Claude do the integration: the wiring, webhooks and tests. These areas fail silently and expensively, and a working demo tells you nothing about whether they're safe. Have a person review this code before launch.
Add [Stripe subscriptions / sign-in] using [provider]. Don't write your own password storage, session tokens or card handling. First, read the provider's current docs, and list the steps you'll take before changing anything. For the webhook handler: - Verify the Stripe-Signature header against the raw request body. - Treat duplicate events as normal, by recording processed event IDs. - Don't depend on event order. - Return 2xx quickly, and do slow work afterward. Add tests for: a bad signature, the same event sent twice, and events arriving out of order. List every file that touches money or identity, so I can review them.
- password hashing
- session handling
- card and retry logic
- hosted auth and checkout
- webhook signature checks
- tests for failure paths
- 19 MiBArgon2id minimum memoryOWASP, with 2 iterations
- 3 daysStripe's live-mode retry window
- 3 retriesin a Stripe sandboxover a few hours
- 5 minStripe's default replay tolerance
Try it now
- 1Add this deny rule to
.claude/settings.json, so Claude can't read your keys:"deny": ["Read(./.env)", "Read(./.env.local)"]. Use test keys only during the build. - 2Paste the prompt above into Claude Code.
- 3Forward test events locally with
stripe listen --forward-to localhost:4242/webhook, then send one withstripe trigger payment_intent.succeeded. - 4Send the same event again. You'll know it worked if the customer isn't charged or upgraded twice, and a request with a bad signature is rejected.
Use it when
Use this for any product that takes real logins or real money, as soon as you reach those slices. It also applies when you find Claude has already started writing a users table with a password column.
Skip it when
A local prototype with a hard-coded user needs none of this yet. Rolling your own may be right if you have security staff and a specific need a provider can't meet, but that's a decision to make deliberately, with a review plan.
Why it works
The details here are easy to get subtly wrong, and code can run fine while being unsafe. OWASP's password guide sets a minimum of Argon2id with 19 MiB of memory, 2 iterations and 1 degree of parallelism, and treats bcrypt as for legacy systems only. Stripe's webhook docs say verification needs the raw request body, that the same event can arrive more than once, and that delivery order isn't guaranteed. In live mode it retries for up to three days. A happy-path demo exercises none of those. Stated as a rule of thumb, not a vendor figure: let a provider own these rules, and spend your review time on the seam.
Example
Your SaaS has one paid plan. Claude adds a hosted checkout link and a webhook that turns on the plan when payment succeeds. Then you test the awkward cases. A renewal fails, so what does the account show? The same event arrives twice, so is the user credited twice? invoice.paid arrives before the subscription event, so does the handler crash? Those tests matter more than the checkout page.
Going further
Remember that CLAUDE.md is context, not enforcement. To block Claude from reading secrets, use a deny rule, since Claude Code's docs say these hold in every permission mode. On webhooks, Stripe's libraries default to a 5-minute timestamp tolerance against replay attacks, and a tolerance of 0 turns that check off entirely. Frameworks that parse JSON before your handler are the classic cause of signature failures, because any change to the raw body breaks verification. CSRF middleware can also block webhooks, so you may need to exempt that route. Sandbox retries are only three over a few hours, so don't assume live behavior from a sandbox test.
Common mistakes
- Accepting a generated
userstable with a password column because it worked in the demo. - Fixing a signature error by turning off verification. Stripe warns that without it, attackers can send fake events that grant access or fulfill orders.
- Testing only successful payments, and never a failed renewal, a duplicate or an out-of-order event.
- Pasting live keys into the chat. Anything Claude reads goes into the conversation.
Sources
- Password Storage Cheat Sheet, OWASP
- Receive Stripe events in your webhook endpoint, Stripe Docs
- Best practices, Claude Code Docs
- Configure permissions, Claude Code Docs
- How Claude remembers your project, Claude Code Docs
Checked 6 November 2026. Products change often, so confirm details with the vendor.