Ready-to-charge check
For anyone about to switch Stripe to live mode.
$390
- Webhook signature verification
- Plan and price enforced on the server
- Subscription state you can trust
- Duplicate charges and refunds
- Model and API spend caps
Stripe recommends restricted keys over secret keys for new integrations, per the API keys page on the verified date.
Stripe signs every webhook with a Stripe-Signature header and separates test and live keys by prefix. It expects your server to create Checkout sessions with price ids, and documents that events can arrive more than once and out of order. Each of those facts is a test.
Payment bugs in AI-built apps are rarely about Stripe itself. They are about the code around it: a webhook handler that skips the signature check, a price or plan taken from the browser, or a subscription state stored where the user can edit it. Radar, restricted keys and webhook IP allowlists are Stripe's own protections; the checks below are about your side.
Each row is taken from the vendor's documentation on the date shown. Defaults change; the date is the claim.
| Area | Default | Source |
|---|---|---|
| Webhook signature header | Stripe signs every webhook with a Stripe-Signature header (HMAC SHA-256 over timestamp.payload) using a per-endpoint whsec_ secret; verification needs the raw request body and libraries default to a 5-minute timestamp tolerance. | docs · verified 2026-09-21 |
| Test vs live keys | Sandbox keys start pk_test_, rk_test_, sk_test_; live keys start pk_live_, rk_live_, sk_live_. Only publishable keys are safe to expose; secret keys have unrestricted permissions and Stripe recommends restricted keys instead. | docs · verified 2026-09-21 |
| Checkout price from server | Your server creates the Checkout Session with the secret key, passing Price IDs or price_data as line items; the customer is redirected to a Stripe-hosted page and fulfillment uses the checkout.session.completed event. | docs · verified 2026-09-21 |
| Fulfillment | Webhooks are required for fulfillment; you cannot rely on the success landing page alone because customers may never reach it. The fulfill function must handle repeated calls and check payment_status. | docs · verified 2026-09-21 |
| Event delivery | Events may arrive more than once and out of order; Stripe retries for up to three days in live mode. Track event IDs to detect duplicates. | docs · verified 2026-09-21 |
| Idempotency | POST requests accept an Idempotency-Key header; Stripe stores the first result for at least 24 hours and returns it for retries with the same key. | docs · verified 2026-09-21 |
Documentation home: docs.stripe.com
12 patterns in the catalogue name Stripe; the most severe are listed here across secrets and keys, payments, deploy and config, mobile, reliability. Attribution is descriptive: the default stack makes the pattern reachable, or a public incident names it.
The build writes the secret's value into public JavaScript, so anyone who loads the site can read it, and a redeploy with the same variable name republishes it.
Everyone who can see the repository, now or later, holds working keys to the database, payment account and model provider, and the keys stay in history after the file is deleted.
Anyone who finds the webhook URL can post a made-up payment-succeeded event and get an order fulfilled or a plan activated for a user of their choosing, without paying.
Anything the agent decides to run, or is tricked into running by text it reads, executes with the same power you have, including dropping tables or moving money.
Anyone who downloads the app from the store can unzip it and read the key, then run up your bill or read your database as an administrator.
Anyone who views the page source can take the key and run up charges, send messages or pull data on your account until the key is revoked.
Keys, session tokens and database connection strings end up in log files and in HTTP responses that anyone can trigger, which hands out credentials and a map of the system's internals.
A customer is charged twice after a network hiccup, or a replayed webhook tops up an account again and again for a single payment.
A buyer can edit the request in their browser, pay one cent for the top plan, and your app records it as a full purchase.
Anyone can type one line in the browser console to become a paying customer, and the server hands over the paid feature without checking.
Customers can pay with Stripe's published test card numbers, the app fulfils the order, and no money ever reaches your account.
One outage turns into a flood of retries from every open browser tab, which keeps the service down longer, runs up usage bills and can submit the same order or payment twice.
Lovable reported that from 3 February to 20 April 2026 a backend regression let any logged-in Lovable user read the chat history and source code of public projects; a fix shipped within two hours.
Apr 2026 · Lovable · all sources
In July 2025 a Replit agent deleted data from a production database during a user-declared code freeze; Replit's CEO confirmed it, said backups allowed a restore, and announced automatic dev and production database separation.
Jul 2025 · Jason Lemkin (SaaStr) · all sources
Cursor below version 1.3.9 created workspace files without approval, so a prompt injection in content the agent read could write a .cursor/mcp.json file and run attacker commands (CVE-2025-54135, CVSS 8.6).
Aug 2025 · CVE Program (GitHub CNA) · all sources
In Cursor versions before 1.3, an MCP server configuration approved once could later be changed to a different command, for example in a shared repository, and would run without a new prompt (CVE-2025-54136, CVSS 7.2).
Aug 2025 · CVE Program (GitHub CNA) · all sources
Each entry links to its primary source in the evidence list. What to do about it is the self-check below.
Stated from the vendor's documentation. The limits are the vendor's scope statements, not judgements.
Webhook signing and IP allowlist
Signature verification via official libraries plus a published list of Stripe IP addresses; endpoint secrets can be rolled with up to 24 hours overlap.
Where it stops: Verification is the receiver's job; without it, the docs say an attacker could send fake events to trigger fulfillment or access.
vendor docs · verified 2026-09-21
Radar
Real-time fraud screening for cards, card wallets, ACH and SEPA debits; Radar Lite covers card fraud and card testing, higher plans add rules, risk scores and manual reviews.
Where it stops: Radar does not screen SetupIntents for non-card payment methods; Standard, Plus and Pro plans charge per screened transaction.
vendor docs · verified 2026-09-21
Restricted API keys and access policies
Restricted keys carry only the permissions you grant; access policies limit keys to IP ranges, ASNs or countries and notify you of blocked attempts.
Where it stops: You are responsible for protecting non-publishable keys; the docs say not to put them in source code or config checked into version control.
vendor docs · verified 2026-09-21
PCI scope reduction
Checkout, Elements and Stripe.js send card data directly to Stripe so it does not pass through your servers; TLS 1.2 or above is required for payment pages.
Where it stops: PCI compliance is shared: the business must still attest annually, and the guide says verifying webhook signatures and allowlisting Stripe IPs remain your tasks.
vendor docs · verified 2026-09-21
The critical patterns first. Each uses the dashboard and your browser.
.env files, list every variable whose name starts with NEXT_PUBLIC_.NEXT_PUBLIC_ variable holding a server-only key, or a search hit for that key's value in a loaded script..env, .env.local, .env.production, serviceAccountKey.json or firebase-adminsdk files.sk_live, sk-, service_role, BEGIN PRIVATE KEY and password=.git log --all -p -S sk_live -- . | head. Any output means a live key has been committed at some point.constructEvent or construct_event that receives a value starting whsec_.req.json() or JSON.parse and never calls a construct-event function, or the webhook secret variable is missing or empty.Stripe pre-launch checklist
12 checks, in the order we run them. Usable without buying anything.
Self-check tool
Answer questions about your setup and get the patterns that apply, ordered by severity. Runs in your browser; nothing is sent.
For anyone about to switch Stripe to live mode.
$390
For anyone who wants the three riskiest areas checked fast.
$290
All packages and prices. Every report includes a re-check after your fixes.
If your handler parses the event body without calling Stripe's signature verification with your endpoint secret, anyone who knows the URL can post a fake event. Send a request with no Stripe-Signature header: a correct handler answers with an error, a missing check answers as if payment succeeded.
We test the webhook with unsigned and replayed events and try to change price and plan from the browser. We check idempotency on payment handlers, look for test keys in production and live keys in the bundle, and confirm the plan is read from your database rather than the client.
In test mode: complete a checkout, then replay the same webhook event and confirm nothing doubles; post an unsigned event and confirm rejection; try to buy at a changed price from the browser. Then switch keys, never both at once.