Lovable + Stripe pre-launch checklist: payments without leaking
When you wire Stripe into a Lovable app, the publishable key belongs in the browser and the secret key belongs in a server function — and Lovable does not always know the difference. Confirm each of these before your first paying user.
12 checks
Tick through each one
Click any item to open the detailed fix guide. The detector tag shows which scanner module flips the state pass or fail when you run a SafeToShip scan.
sk_live_ key only in server-side env, never NEXT_PUBLIC_
CriticalDetector: js-secrets
pk_live_ used in client; sk_live_ never reaches the browser
CriticalDetector: js-secrets
Stripe webhook signature verified on every event
HighUse stripe.webhooks.constructEvent with STRIPE_WEBHOOK_SECRET.
Detector: js-secrets
Per-integration restricted keys instead of master secret key
MediumDetector: js-secrets
No .env exposed at the deploy URL
CriticalDetector: exposed-files
CSP allows js.stripe.com but blocks other inline scripts
HighDetector: headers
HSTS enabled — required for PCI-aware checkout
HighDetector: headers
If storing orders in Supabase, RLS scopes to customer_id
CriticalDetector: supabase
CORS allowlist excludes wildcard for /api/checkout
HighDetector: cors
Session cookies Secure + HttpOnly + SameSite=Lax
HighDetector: cookies
Rate limiting on /api/checkout and /api/portal
MediumDetector: rate-limit
Valid TLS, no mixed content on the checkout page
CriticalDetector: ssl
Paste this into Lovable
One prompt that runs the entire checklist as a code review pass.
Audit my Lovable + Stripe integration: confirm the sk_live_ key is server-only and never NEXT_PUBLIC_, confirm pk_live_ is used in the client, verify the webhook handler uses stripe.webhooks.constructEvent with the signing secret, switch from master secret keys to per-integration restricted keys, lock CSP to allow only js.stripe.com for inline scripts, enable HSTS, ensure orders/subscriptions tables in Supabase have RLS scoped to the customer, allowlist specific origins on /api/checkout CORS, add Secure+HttpOnly+SameSite=Lax on session cookies, add rate limiting on /api/checkout, and confirm no mixed content on the checkout page.FAQ
Frequently asked questions
- Do I need PCI compliance for a Lovable app using Stripe Checkout?
- Stripe Checkout (the hosted page) keeps you at SAQ-A — minimal PCI scope. You still need TLS, secure cookies, and proper webhook handling. SafeToShip checks the technical baseline but does not certify PCI compliance.
- What if the webhook handler skips signature verification?
- Anyone can post fake events to your webhook endpoint and trigger fulfillment, refunds, or balance updates. Always verify with stripe.webhooks.constructEvent. If you skipped it, fix it before processing another payment.
Per-issue depth
Fix guides for this checklist
Exposed Stripe secret key
A leaked Stripe secret key means an attacker can charge your customers, refund payments, or drain your account. Rotate immediately.
Read moreHardcoded API key in JS
Any secret in your client bundle is public. Here is how to find them, rotate them, and move the calls server-side.
Read moreMissing CSP header
A missing Content-Security-Policy header lets attackers inject scripts into your site. Here is what CSP does, why you need it, and how to add it in Next.js, Vercel, and Supabase apps.
Read moreCORS allows all origins
An Access-Control-Allow-Origin: * policy lets any site call your API. Sometimes that is fine, often it is a mistake. Here is how to decide and fix it.
Read moreRun the scan to confirm each check
60 seconds. Free. No account required.