Lista de verificación para revisar código de Stripe generado por IA
Una lista de verificación de revisión humana para el código de integración de Stripe escrito por agentes de codificación de IA: seguridad de webhooks, idempotencia, condiciones de carrera y flujos de pago.
CursorClaude CodeCodexWindsurf Next.jsTypeScriptPostgreSQL
Los errores de integración de Stripe significan pérdida de ingresos o acceso fraudulento a funciones de pago. La IA frecuentemente omite la verificación de firmas de webhooks, maneja mal la idempotencia y confunde las claves de prueba y producción.
Corrección
[ ] Webhook endpoint reads the raw request body as a Buffer or string before any JSON parsing[ ] stripe.webhooks.constructEvent() is called with the raw body, not req.body (parsed JSON breaks the signature)[ ] Webhook secret (STRIPE_WEBHOOK_SECRET) is the endpoint-specific signing secret, not the API key[ ] Each webhook event type is handled explicitly — no catch-all that processes unknown event types[ ] checkout.session.completed retrieves the full session with line_items expanded, not trusting payload data[ ] customer.subscription.updated and customer.subscription.deleted both update the local subscription record[ ] Payment intent status is confirmed server-side after client confirmation — not assumed from client callback[ ] Subscription status is stored in your database and synced from webhooks — not fetched from Stripe on every request[ ] Trial end dates are handled — trial_end on a subscription can be null or a Unix timestamp[ ] Price IDs are environment-specific — test mode prices don't work with live API keys[ ] Metadata on PaymentIntent or Customer is used to look up internal user IDs, not vice versa[ ] invoice.payment_failed is handled to downgrade or notify the user on failed renewalSeguridad
[ ] STRIPE_SECRET_KEY is read from environment variables — never hardcoded or committed[ ] Test and live keys are in separate environment variable names with explicit naming[ ] Webhook signature is verified before any business logic runs — skip and you get spoofed events[ ] Idempotency keys are sent on all create payment/charge requests to prevent double charges[ ] Fulfilled orders are tracked in the database before sending a success response to the webhook[ ] Stripe customer ID is stored against the user record — not re-created on every checkout[ ] Pricing is read from Stripe Prices API, not from user-supplied amounts in the request body[ ] Refunds and disputes are handled — partial refunds should not grant full access[ ] Connect platform charges validate the connected account ID server-side before creating a charge[ ] PCI scope is not expanded — no card numbers, CVVs, or raw PAN data ever touch your server[ ] Portal session URL is generated server-side and returned to the authenticated user only[ ] Checkout session client_reference_id is validated to belong to the authenticated userRendimiento
[ ] Webhook handler responds with 200 within 30 seconds — offload slow work to a queue[ ] Stripe API calls are not made inside a rendering or request path that does not need them[ ] Stripe customer lookup is cached in your database — do not call stripe.customers.list() to find a user[ ] Subscription reads use the local database record, not a live Stripe API call on every page load[ ] Webhook deduplication uses the event.id — events are delivered at least once, not exactly onceDespliegue
[ ] Separate Stripe webhook endpoints are created for staging and production in the Stripe dashboard[ ] STRIPE_WEBHOOK_SECRET is different per environment — each endpoint has its own signing secret[ ] Live mode keys are not present in local .env files or CI environment for non-production stages[ ] Stripe Radar rules are reviewed before going live — default rules may block legitimate cards in some regions[ ] stripe listen --forward-to is used for local webhook testing, not ngrok with default settings[ ] Webhook endpoint URL is HTTPS in production — Stripe rejects plaintext HTTP endpointsRiesgos específicos de IA
[ ] AI has not used stripe.charges.create() for new integrations — use PaymentIntents API[ ] AI has not assumed req.body is the raw buffer — most frameworks parse it before the handler runs[ ] AI has not confused the publishable key with the secret key[ ] AI has not used stripe.customers.retrieve() without handling the deleted customer case[ ] AI has not skipped idempotency keys on payment creation — critical for retry logic[ ] AI has not hardcoded price IDs — these differ between test and live mode[ ] AI has not fabricated Stripe SDK methods — verify all method names against the official docs[ ] AI has not used an outdated Stripe API version — pin the version in the Stripe client constructorSugerencia para arreglar
Review this Stripe integration code against the checklist above. Fix webhooksignature verification to use the raw request buffer, add idempotency keys toall payment creation calls, ensure all webhook event types are handled, andmove any hardcoded keys to environment variables. Return the correctedwebhook handler and checkout creation code only.