Stripe breaking changes, updated weekly
Every verified Stripe trap in Footgun: changes and behaviors that break code or give wrong results, newest first. Each one has the error you see, the fix, and the date it was last checked. The list updates when the weekly check adds or retires a trap. For the full cause and sources, open the trap, or see all Stripe traps.
fg-0568· added 2026-10-27· last checked 2026-10-27
A Stripe webhook handler that skips constructEvent accepts fake payment events from anyone
Symptom
The webhook handler parses the JSON body directly and never reads the Stripe-Signature header
Fix
Verify every event with stripe.webhooks.constructEvent, passing the raw body, the Stripe-Signature header and the endpoint's whsec_ signing secret, and return 400 when it throws. In a Next.js App Router handler read the body with request.text(), not request.json(). The secret printed by stripe listen differs from the Dashboard endpoint's secret, so use the one that matches where events come from. Stripe also recommends accepting webhook requests only from its published IP addresses, alongside signature verification.
fg-0146· added 2026-10-15· last checked 2026-10-15
Checkout Session create returns 400 for payment_method_types on API version 2026-09-30.endive
Symptom
400 invalid_request_error naming the payment_method_types parameter on checkout.sessions.create
Fix
Remove payment_method_types. Either let dynamic payment methods from the Dashboard decide, or pass allowed_payment_method_types, which quietly filters out methods that do not fit the currency or amount instead of failing.
fg-0148· added 2026-10-15· last checked 2026-10-15
latest_invoice.payment_intent is gone, so a new subscription has no client_secret to confirm
Symptom
expand latest_invoice.payment_intent returns an invoice with no payment_intent field
Fix
Expand latest_invoice.confirmation_secret and hand its client_secret to the Payment Element. To link payments and invoices, read invoice.payments or the Invoice Payments list endpoint.
fg-0149· added 2026-10-15· last checked 2026-10-15
metadata.get() raises AttributeError after upgrading stripe-python to v15
Symptom
AttributeError when calling .get(), .keys() or .values() on a Stripe object
Fix
Use getattr with a default, or call to_dict() first. Build test events with StripeObject.construct_from so tests match production.
fg-0151· added 2026-10-15· last checked 2026-10-15
Stripe.Customer and other namespace types vanish after upgrading stripe-node to v22 in a CommonJS project
Symptom
TS2694: Namespace 'StripeConstructor' has no exported member 'Customer'
Fix
Upgrade to 22.3.0 or later. Switching the project to ESM also restores the types.
fg-0152· added 2026-10-15· last checked 2026-10-15
Stripe has no API to delete a Price, and deleting its Product then fails
Symptom
AttributeError: type object 'Price' has no attribute 'delete'
Fix
Archive instead: set active to false on the price, and on the product if you want it hidden too.
fg-0153· added 2026-10-15· last checked 2026-10-15
stripe listen forwards events in your account's default API version, not the version your code pins
Symptom
unknown flag: --api-version
Fix
Use --latest when your code targets the newest version, or upgrade the account default. For an exact older version, tunnel to a real webhook endpoint created with that api_version.
fg-0154· added 2026-10-15· last checked 2026-10-15
stripe-node calls hang or bypass MSW and Nock 14 mocks in tests
Symptom
Stripe requests hang until timeout when MSW is active
Fix
Upgrade to stripe-node 23, or switch the client to the fetch based HTTP client in tests.
fg-0156· added 2026-10-15· last checked 2026-10-15
subscription.items is a dict method, not the line items, in stripe-python before v15
Symptom
TypeError: 'builtin_function_or_method' object is not iterable
Fix
Use bracket access for the field. On v15 and later sub.items returns the line items and key iteration moves to to_dict().
fg-0155· added 2026-10-15· last checked 2026-10-15
subscription.current_period_end is undefined after upgrading to Stripe API 2025-03-31.basil
Symptom
subscription.current_period_end and current_period_start come back undefined with a 200 response
Fix
Read current_period_start and current_period_end from subscription.items.data. If you need one renewal date, take the latest item end.
fg-0158· added 2026-10-15· last checked 2026-10-15
Webhook signature check fails with 'No signatures found matching the expected signature for payload'
Symptom
No signatures found matching the expected signature for payload
Fix
Give the webhook route the raw body and register it before the global JSON parser. In the Next.js App Router read await request.text(). Use the secret that belongs to the endpoint actually sending the event.
fg-0147· added 2026-10-15· last checked 2026-10-15
json.dumps fails and price comparisons stop matching after stripe-python v15 returns Decimal
Symptom
TypeError: Object of type Decimal is not JSON serializable
Fix
Serialize with to_dict(for_json=True), compare against Decimal values, and pass Decimal when setting these fields.
fg-0150· added 2026-10-15· last checked 2026-10-15
Resend on an event in the Stripe Dashboard never reaches your stripe listen session
Symptom
Dashboard Resend reports a delivery but nothing arrives at localhost
Fix
Resend from the CLI, which targets the local listener by default, or pass --webhook-endpoint for a specific endpoint.
fg-0157· added 2026-10-15· last checked 2026-10-15
Webhook event payloads have a different shape than the objects your upgraded Stripe SDK returns
Symptom
event.data.object still carries fields your SDK types say were removed, or lacks new ones
Fix
Create a second endpoint on the new api_version with a distinguishing query string, process both in parallel while you switch code, then disable the old one. Thin events avoid versioning altogether.
Have your agent check Stripe changes before it codes