stripecheckoutdynamic payment methodsinvoluntary churn

Stripe Deleted payment_method_types From Checkout. What Fills the Gap Is Your Dashboard, Not Your Code.

Stripe's Sept 30 release removed payment_method_types from Checkout and PaymentIntents. Drop it with no replacement and your Dashboard decides what renews.

XY
15 October 2026 · 8 min read

Stripe's September 30 Endive release quietly deleted a parameter that a huge share of SaaS integrations have been passing on every single checkout and every saved-card setup for years: payment_method_types. Not deprecated with a grace period — removed. Send it on a PaymentIntent, a SetupIntent, or a Checkout Session created on this API version or later, and you get a 400 back. This isn't a rename exercise. The parameter that used to let your code say, explicitly, "only cards" is gone, and what replaces it isn't a drop-in substitute — it's a different decision-maker entirely.

Key stat
7.4%
Average conversion-rate lift Stripe measured when at least one payment method beyond cards is dynamically surfaced at checkout — the exact incentive now filling the gap this parameter leaves behind
Source: Stripe, "Testing the conversion impact of 50+ global payment methods" (2026)

What actually changed on three API resources

Before Endive, you told Stripe exactly which payment methods a PaymentIntent, SetupIntent, or Checkout Session would accept by passing a literal array: payment_method_types: ['card'], or whatever list matched your billing model. That array was also a safety check — pass an incompatible type for the currency or amount, and Stripe errored, which is how plenty of teams caught a misconfiguration in testing before it ever shipped.

Resource and callWhat happens now
PaymentIntent#create / #update / #confirmSending payment_method_types returns a 400 with code payment_method_types_no_longer_supported
SetupIntent#create / #updateSame 400, same error code
Checkout.Session#createSame class of 400 error on the parameter
Stripe.js Elements (deferred intent)The paymentMethodTypes option throws an integration error client-side

None of this fires until you actually move your account, SDK, or a request's Stripe-Version header onto 2026-09-30.endive or later — Stripe's versioning model pins every account to the version it integrated against, so nothing breaks behind your back. But the moment you upgrade for literally any other reason — Trial Offers, on-demand pause and resume, any of the other Endive features we've covered — every call that still passes the old parameter starts erroring immediately, across all three resources at once, because it's one parameter removed in one release, not three independent decisions you can stagger.

The part that isn't a rename

If removing a parameter just meant "use a different parameter name," this would be a find-and-replace. It doesn't. Stripe's own documentation on the replacement — dynamic payment methods — states the mechanism plainly: "only payment methods that you enabled [in the Dashboard] can be shown to your customers." Once you drop payment_method_types and don't pass allowed_payment_method_types in its place, the set of payment methods your checkout offers is no longer determined by a line in your codebase. It's determined by whatever's toggled on at dashboard.stripe.com/settings/payment_methods, filtered by currency, amount, and customer location, and then ranked by an AI model Stripe says incorporates more than 100 signals to maximize conversion.

That's a genuinely different architecture, and it's not a bad one — it's the same shift most of Stripe's product surface has been making for a while, replacing per-call configuration with Dashboard-managed defaults plus narrower API overrides. The catch is specific to subscription businesses: the old explicit list was frequently doing double duty. Engineering set payment_method_types: ['card'] not because nobody got around to adding more options, but because card is the one payment method that retries cleanly inside Stripe's Smart Retries and your own dunning schedule. That restriction lived in code specifically so it wouldn't get silently undone by someone enabling a new payment method in the Dashboard for an unrelated reason — a marketing request to boost one-time checkout conversion, say. Endive removes the code-level half of that defense and leaves only the Dashboard half standing.

Average conversion lift from dynamically surfacing a payment method beyond cards, by market
Alipay — China91%
PayPal — Germany, digital goods47%
BLIK — Poland46%
iDEAL — Netherlands39%
Konbini — Japan, digital apps27%
SEPA Direct Debit — EU12%

Source: Stripe, "Testing the conversion impact of 50+ global payment methods" — holdback experiment across 50+ eligible methods, Stripe Optimized Checkout Suite (2026)

Look at which methods are on that list. We've written separately about why BLIK recurring payments cap every off-session charge at 2,000 PLN with no split-charge workaround, why Bancontact saved for off-session billing actually converts into a SEPA Direct Debit mandate your dunning stack won't recognize as Bancontact at all, and why a PayPal subscription can silently stop renewing, or get cancelled by the customer, without your cancellation flow ever seeing it. These aren't obscure edge cases — they're exactly the payment methods Stripe's own data says convert best precisely because dynamic payment methods is built to surface them. The feature doing the surfacing was never designed to ask whether a method survives a renewal eighteen months later. It's designed to ask whether it closes today's sale.

The quieter breakage: redirects and return_url

There's a second mechanism buried in Stripe's own migration guidance that's easy to miss because it isn't phrased as a breaking change at all. Stripe's support documentation states it directly: removing payment_method_types makes redirect-based payment methods newly eligible. If you confirm a PaymentIntent or SetupIntent from your own server — common in a custom checkout or a saved-payment-method update flow — and a redirect-based method becomes part of the eligible set, that confirm call now needs a return_url. Without one, confirming a redirect-eligible method fails outright. A server-side confirm that's worked unmodified for two years can start erroring the day you drop the old parameter, for a reason that has nothing to do with the change you intended to make.

Off-session charges — the ones Smart Retries actually fires during a renewal — are exempt from that requirement, so a pure dunning retry on a card already on file isn't where this bites. It bites in the adjacent flows: a customer-present card update through a custom UI, a plan-change confirmation, anything that calls confirm server-side while someone is actually sitting in front of a screen. If you want to keep redirect-based methods out of the eligible set entirely rather than adding return_url support you don't otherwise need, Stripe gives you an explicit switch for it: automatic_payment_methods[allow_redirects] set to 'never'.

Three ways to replace the old parameter, and what each one actually buys you

ApproachHow it behavesBest fit
Drop it, change nothing elseDashboard-enabled methods, AI-ranked for conversion, apply to every flow the same wayOne-time purchases where renewal reliability is irrelevant
allowed_payment_method_typesAn explicit allowlist per request; incompatible types are filtered silently, not erroredClosest behavioral match to the old parameter, minus the error-on-mismatch safety net
excluded_payment_method_typesA denylist layered on the Dashboard-driven default; everything enabled is eligible except what you nameBlocking one or two known-bad methods while keeping the dynamic default otherwise
Payment method configurationsNamed, reusable sets of methods you can scope per use case — e.g., one set for one-time checkout, a narrower set for recurringSubscription businesses that want conversion-optimized acquisition and a locked-down renewal set, without hand-rolling the split on every call

That last row is the one worth building toward if you've read this far and recognized your own integration in the "card-only on purpose" description. Stripe's payment method configurations are explicitly designed to let one-time and recurring charges use different eligible sets without you maintaining two separate code paths by hand — which means you don't have to choose between the conversion lift in that chart and a renewal-safe billing stack. You can have both, as long as you deliberately route recurring charges to a configuration that excludes whatever your dunning logic can't retry.

What to actually check before you upgrade

  • Audit your Dashboard payment methods settings before you drop the parameter, not after. Whatever's toggled on at dashboard.stripe.com/settings/payment_methods becomes your new default eligible set the moment the code-level restriction disappears. If a growth or marketing team enabled extra methods there for a different product surface, your subscription checkout inherits them too unless you scope a configuration.
  • Separate acquisition from renewal in how you apply the replacement. Use the Dashboard default or allowed_payment_method_types broadly for new-customer checkout, where the conversion data above argues for breadth, and a narrower payment method configuration for anything that touches an existing subscription's billing.
  • Add automatic_payment_methods[allow_redirects]: 'never' to any server-side confirm call that doesn't already pass a return_url, if you want to avoid retrofitting redirect handling into a flow that never needed it.
  • Test in Workbench against 2026-09-30.endive before touching your live account's pinned version, and use the 72-hour rollback window as an active monitoring period on checkout and confirm error rates, not a formality.

None of this is an argument against the conversion case for alternative payment methods — the numbers above are real, and ignoring them costs revenue at the door. It's an argument for deciding where that trade-off applies on purpose, instead of inheriting it by accident the day an unrelated upgrade deletes the one parameter that used to make the decision explicit. If you're trying to size how much a renewal failure on an unfamiliar payment method is actually costing you before you decide how tightly to scope your recurring-billing configuration, our churn calculator is a fast way to put a number on it — and however a subscriber's payment method lets them down, a cancellation flow like CancelFlow is where you catch the save before it turns into a support ticket about a renewal nobody meant to break.

Frequently asked questions

What exactly did Stripe remove in the Sept 30 Endive release?+

The payment_method_types parameter as a writable field. It's gone from PaymentIntent's create, update, and confirm methods, from SetupIntent's create and update methods, and from Checkout Session's create method — five call sites across three API resources, plus the equivalent option in Stripe.js Elements. The field still exists as a read-only property on the response object, so code that reads it keeps working. Code that sends it breaks.

What error do I get if my integration still sends payment_method_types?+

A 400 error. On PaymentIntents and SetupIntents, Stripe names it explicitly: payment_method_types_no_longer_supported. Checkout Sessions returns the same class of 400 for the same parameter. This only happens once you move your account, your SDK, or a request's Stripe-Version header to 2026-09-30.endive or later — nothing changes on API versions before that.

What's the difference between allowed_payment_method_types and excluded_payment_method_types?+

allowed_payment_method_types is an allowlist: you name the types you want to accept, and Stripe silently filters out any that aren't compatible with the currency, amount, or customer — no error, unlike the old parameter. excluded_payment_method_types is a denylist layered on top of Stripe's dynamic, Dashboard-driven default: everything you've enabled in the Dashboard is eligible except what you name. You can't combine the two parameters, or combine either with automatic_payment_methods or payment_method_configuration, on the same request.

Does this change affect existing subscription renewals, or only new checkouts?+

Both, in different ways. New Checkout Sessions are the obvious case — drop the parameter with nothing in its place and your Dashboard's enabled methods become the eligible set, AI-ranked for conversion. Existing off-session renewal charges don't need a return_url the way a server-confirmed, redirect-eligible PaymentIntent does, so a pure card-on-file renewal is lower-risk here. But if your dunning or upgrade flow ever confirms a PaymentIntent or SetupIntent from your server for a customer who's present, removing payment_method_types without adding automatic_payment_methods[allow_redirects]: 'never' can newly make a redirect-based method eligible — and that confirm call fails without a return_url it never needed before.

Try CancelFlow

Stop losing subscribers today

One script tag. One function call. A live cancellation flow in under 10 minutes.

Start free trial →
← All postsHome