---
title: Stripe API Version Upgrade Before Black Friday — Check, Test and Roll Back Safely
description: Stripe&#x27;s Endive API release removes payment_method_types and the Payment Request Button. Check your Stripe API version and upgrade webhooks safely before peak.
source: https://pingvera.com/blog/stripe-api-version-upgrade.html
---
# Stripe API Version Upgrade Before Black Friday: Check, Test and Roll Back Safely

If your store talks to Stripe through your own code, a Stripe API version upgrade is a change to checkout and should be handled like a release. Find out which version each part of the integration uses: server calls, Stripe.js in the browser, and every webhook endpoint. Upgrade them in that order, in a test environment first, and keep the old webhook endpoint alive until the new one has processed real orders cleanly.

On 30 September 2026 Stripe published `2026-09-30.endive`, a major release with breaking changes to payment method parameters and the Payment Request Button. If you want it before Black Friday (27 November 2026), finish early in November. Otherwise wait until after the peak.

## At a glance

- Stripe now ships two major releases a year with breaking changes and monthly releases without them. Endive (`2026-09-30.endive`) is a major release.
- On Endive, sending `payment_method_types` when creating a Checkout Session, Payment Intent or Setup Intent returns a 400 error, and `elements.create('paymentRequestButton')` throws an error.
- Your integration can run on several versions at once. The server SDK, Stripe.js and each webhook endpoint each carry their own version.
- Webhook endpoints cannot simply be switched over. Stripe's documented path is a second endpoint on the new version, run in parallel, then the old one disabled.
- Stripe's upgrade steps say that after you perform the upgrade in Workbench you can roll back to the previous version for 72 hours.
- If you use a hosted platform or a maintained plugin, the vendor usually pins the version. Your job is to confirm that, not to change it.

## Why this matters now

Since `2024-09-30.acacia`, Stripe has followed a release process with monthly API versions that do not break existing code, plus a major release twice a year that starts with breaking changes. Stripe's webhook versioning guide states that you can move to any monthly version safely, while a new major release may require changes to your integration.

Endive is the major release published on 30 September 2026. According to Stripe's changelog, the items most likely to affect a store are:

1. Checkout Sessions. `payment_method_types` is removed from the create call, and passing it now returns a 400 error. Stripe points to dynamic payment methods managed in the Dashboard, with `excluded_payment_method_types` or the new `allowed_payment_method_types` for per-request control.
2. Payment Intents and Setup Intents. `payment_method_types` can no longer be sent on create, update or confirm. The error code is `payment_method_types_no_longer_supported`. The field still exists on the returned object as read-only.
3. Elements. Stripe deprecates the Payment Request Button and removes support for it in Endive. `elements.create('paymentRequestButton')` throws an error, and the React `PaymentRequestButtonElement` is affected as well. Stripe recommends the Express Checkout Element and notes that Stripe.js versions up to Dahlia still support the old button.

Many older stores pass `payment_method_types: ['card']` on every payment. On Endive that line stops payments from being created, while the checkout page and your uptime monitor look normal. For the wallet side, see our guide on [Apple Pay not showing at checkout](https://pingvera.com/blog/apple-pay-button-not-showing.html).

## Where the API version comes from

Stripe's upgrade documentation describes these sources:

- The account default API version applies to any request that does not specify one. Stripe recommends setting the version in code, with the `Stripe-Version` header or a pinned SDK, so that the Dashboard setting does not decide it for you.
- Recent server SDKs send the API version that was current when that SDK release was published. Stripe lists the cut-off points: stripe-php before v11, stripe-node before v12, stripe-python before v6 and stripe-ruby before v9 fall back to the account default. In Java, Go and .NET the version is fixed to the SDK release, and Stripe advises against overriding it.
- Stripe.js picks its version from the script URL, for example `https://js.stripe.com/endive/stripe.js`, or from the major version of `@stripe/stripe-js` on npm. Each Stripe.js version uses its matching API version for the requests it makes, and you cannot override that. Stripe says `js.stripe.com/v3` remains supported and receives backported features, though it is no longer recommended for new integrations.
- Each webhook endpoint has its own API version, set when the endpoint is created. Stripe uses it to shape the event payloads it sends.

So "we are on version X" is rarely true for the whole store. In practice an old store might call the server API on one version, load Stripe.js v3 in the browser, and receive webhooks rendered in a third version from years ago.

## Step-by-step: check and upgrade without breaking orders

### 1. Inventory every version in use (30 minutes)

In the Stripe Dashboard, open Workbench and read the API versions your requests actually use. Then note the version on each webhook endpoint. In the codebase, record the server SDK name and release, any explicit `Stripe-Version` or `apiVersion` setting, and the Stripe.js URL or `@stripe/stripe-js` version.

### 2. Search the code for Endive blockers

Search for `payment_method_types`, `paymentRequestButton` and `PaymentRequestButtonElement`. Reading `payment_method_types` from a returned object is fine. Sending it in a create, update or confirm call is the problem.

### 3. Decide: upgrade now, or pin and wait

If any blocker exists and you cannot test the fix thoroughly before your code freeze, pin the current version explicitly in the SDK configuration, leave Stripe.js where it is, and put the upgrade on the January list. Pinning removes the dependency on the account default, so a later Dashboard change cannot move you by accident. Our [Black Friday code freeze guide](https://pingvera.com/blog/black-friday-code-freeze-security-patches.html) explains how to separate changes you must still ship from those that can wait.

### 4. Fix and test in a sandbox

Replace `payment_method_types` with dynamic payment methods, or with `allowed_payment_method_types` where you need a fixed list. Stripe notes one behaviour difference: the old parameter returned an error for an incompatible method, while `allowed_payment_method_types` drops incompatible methods silently. Check the methods shown for each currency you sell in. Replace the Payment Request Button with the Express Checkout Element using Stripe's migration guide. Then run test payments through every path you support: card, wallet, a 3-D Secure test card, a declined card, a refund and, if you sell subscriptions, a renewal.

### 5. Upgrade the server side

Upgrade the SDK and set the target version explicitly. Deploy, then watch API error rates in Workbench for 400 responses with `payment_method_types_no_longer_supported` or other parameter errors.

### 6. Upgrade Stripe.js

Change the script URL or the npm package major version. Stripe recommends keeping Stripe.js and the server API on the same release train, and says the two do not need to ship at the same moment.

### 7. Migrate webhook endpoints in parallel

Stripe's documented sequence:

1. Create a new endpoint with the same URL plus a query parameter, for example `?version=2026-09-30`, the same event list and the new API version. Disable it straight away.
2. Update your handler to process events from the old endpoint as before and to return 200 for events from the new one without processing them. Enable the new endpoint. Every event now arrives twice.
3. Update the handler to process events from the new endpoint and to ignore old-endpoint events with a 400 response. Stripe recommends the 400 so that it retries those events, and they are still there for the old endpoint if you need to roll back.
4. Watch the new endpoint. If processing fails, revert the code, disable the new endpoint, let the retried events reach the old one, fix, and try again.
5. Disable the old endpoint once you are satisfied. Stripe warns that leaving it active keeps returning 400s, and after you disable it Stripe does not redeliver events that got a 400.

If you use the .NET, Java or Go SDK, Stripe states the webhook endpoint version must match the SDK version, or the SDK cannot deserialize events.

### 8. Change the account default last

Once your code sets its own version, the account default only affects calls that do not specify one. Upgrade it in Workbench after everything else works, and record the time. Stripe's upgrade steps give a 72-hour rollback window after that action.

## Responsibility table

## Copyable test plan

`STRIPE API VERSION UPGRADE: TEST PLAN
Store: ____________ Date: ____________ Owner: ____________

Inventory
[ ] Server SDK + release: ____________ Pinned version: ____________
[ ] Stripe.js source (URL or npm major): ____________
[ ] Webhook endpoints (URL / version / enabled):
 1. ____________________________________________
 2. ____________________________________________
[ ] Account default API version: ____________

Code search (sandbox branch)
[ ] No payment_method_types sent on create/update/confirm
[ ] No paymentRequestButton / PaymentRequestButtonElement
[ ] Payment methods shown per currency match expectations

Sandbox payments
[ ] Card, success [ ] Card, declined
[ ] 3-D Secure challenge [ ] Wallet (Express Checkout Element)
[ ] Refund [ ] Subscription renewal (if used)
[ ] Order status in the store matches Stripe for each payment

Webhooks
[ ] New endpoint created disabled, same events, ?version= param
[ ] Parallel run: old processed, new acknowledged with 200
[ ] Switch: new processed, old answered with 400
[ ] 24h of live orders reconciled against Stripe payments
[ ] Old endpoint disabled

Rollback
[ ] Previous code tagged and deployable
[ ] Workbench upgrade time recorded (72h rollback window): ________
[ ] Contact for payment failures during the change: ____________
`
Worked scenario (illustrative)
An agency maintains a custom store built on stripe-php. The order count, prices and dates here are invented for the example. The store's code passes `payment_method_types: ['card']` to every Payment Intent and loads `js.stripe.com/v3`, and its one webhook endpoint was created on a 2023 version.

On 3 November a developer upgrades stripe-php to a release that sends Endive by default and deploys on a Tuesday afternoon. Every new Payment Intent now fails with a 400 error. The checkout page still loads and the uptime check stays green. The store normally takes around 20 orders an hour on a weekday afternoon, and over the next two hours it records none.

The inventory step would have caught this in five minutes. With the test plan in place, the developer pins the old version in the SDK configuration, ships the SDK upgrade on its own, and fixes `payment_method_types` in a sandbox branch. The Endive move goes in after Cyber Monday, together with the webhook migration.

## Common mistakes

- Upgrading the account default version in the Dashboard first. Any code that does not pin a version moves with it immediately.
- Treating an SDK upgrade as a library update only. In stripe-php 11+, stripe-node 12+, stripe-python 6+ and stripe-ruby 9+, a new SDK release can also mean a new API version.
- Editing the API version of the existing webhook endpoint in place instead of running two endpoints in parallel. That removes the rollback path.
- Forgetting idempotency. During the parallel run each event arrives twice, so a handler that creates an order or sends an email on every event will duplicate them.
- Testing only the happy path. A declined card, a 3-D Secure challenge and a refund exercise different code.
- Changing a maintained plugin's Stripe internals by hand. Ask the vendor which version the plugin pins and whether an update changes it.

This plan covers the Endive changes most stores hit. If you use Billing, Connect or Tax, read their Endive entries in the changelog too. The 72-hour rollback covers the account version in Workbench, not code you deployed or events you already processed, and a sandbox run cannot reproduce a specific bank's 3-D Secure behaviour.

## FAQ

### Do I have to upgrade to Endive before Black Friday?

No. As of October 2026, the breaking changes apply to requests made on Endive, and Stripe's changelog says Stripe.js versions up to Dahlia still support the Payment Request Button. If you cannot test the change properly before your freeze, pin your current version and upgrade in January.

### I use WooCommerce with the official Stripe plugin. Does this affect me?

Probably not directly. A maintained plugin sets its own API version, so you should not change Stripe's version settings for it. Keep the plugin updated on a staging site first, as described in our [WooCommerce update guide](https://pingvera.com/blog/update-woocommerce-safely.html), and read its changelog for Stripe-related notes. Custom code that calls Stripe alongside the plugin still needs the checks above.

### How do I know a webhook migration worked?

Compare orders in your store with successful payments in Stripe for at least a day of live traffic. Every paid payment should map to a paid order, and no order should be marked paid without a payment. Our guide to [orders marked as paid without payment](https://pingvera.com/blog/orders-marked-paid-without-payment.html) gives a reconciliation routine.

## Sources

- Stripe changelog: https://docs.stripe.com/changelog
- Stripe changelog, "Deprecates the payment request button" (2026-09-30.endive): https://docs.stripe.com/changelog/endive/2026-09-30/deprecate-payment-request-button
- Stripe changelog, removal of `payment_method_types` from Payment Intents and Setup Intents (2026-09-30.endive): https://docs.stripe.com/changelog/endive/2026-09-30/removes-the-payment-method-types-parameter-from-payment-intents-and-setup-intents
- Stripe changelog, removal of `payment_method_types` from Checkout Sessions (2026-09-30.endive): https://docs.stripe.com/changelog/endive/2026-09-30/remove-payment-method-types-checkout-sessions
- Stripe, "Upgrade your integration": https://docs.stripe.com/upgrades
- Stripe, "Manage webhook versioning": https://docs.stripe.com/webhooks/versioning
- Stripe, "Stripe.js versioning and support policy": https://docs.stripe.com/sdks/stripejs-versioning

Last reviewed: 2026-10-27

If you maintain WooCommerce stores, Pingvera's WordPress connector sends order events and compares the order rate with an hourly baseline. If a version change stops payments while the site stays up, you get an alert, and the deploy appears on the same timeline as the drop. See [WooCommerce checkout monitoring](https://pingvera.com/blog/woocommerce-checkout-monitoring.html) for how that works.
