Skip to content

Comments

Bump versions of Stripe JS and Stripe API#4977

Open
Mayisha wants to merge 11 commits intodevelopfrom
update/bump-versions-of-stripe-js-and-api
Open

Bump versions of Stripe JS and Stripe API#4977
Mayisha wants to merge 11 commits intodevelopfrom
update/bump-versions-of-stripe-js-and-api

Conversation

@Mayisha
Copy link
Contributor

@Mayisha Mayisha commented Feb 3, 2026

Changes proposed in this Pull Request:

Bumped the Stripe JS and Stripe API versions in this PR as groundwork for adaptive pricing implementation. These common changes will work for both classic and block implementation.

Testing instructions

  • Code review.
  • Run npm install and npm start.
  • Smoke test a few scenarios in settings, block and classic checkout pages to verify the version updates does not hamper any existing feature (no regressions)

  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Changelog entry

  • This Pull Request does not require a changelog entry. (Comment required below)
Changelog Entry Comment

Comment

Post merge

@Mayisha Mayisha requested review from a team, daledupreez and wjrosa and removed request for a team February 3, 2026 11:24
Copy link
Contributor

@wjrosa wjrosa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I second Dale's comment on the 3.0 query string

Base automatically changed from add/method-to-call-checkout-session-ajax to add/checkout-sessions-endpoint February 3, 2026 13:39
@daledupreez
Copy link
Contributor

I see that most of the e2e tests are failing, with only the Blik tests passing, so it feels like we still have some work to do.

Also, I am wondering whether it may make sense to split this PR into two: one PR to update Stripe.js and another PR to update the API version. As things stand, it is going to be tricky to work out which failures stem from the JS update, which ones stem from the API update, and which stem from both.

Base automatically changed from add/checkout-sessions-endpoint to develop February 4, 2026 16:39
@Mayisha Mayisha force-pushed the update/bump-versions-of-stripe-js-and-api branch from fbd3a0d to 4ee590f Compare February 5, 2026 14:08
@Mayisha Mayisha added this to the 10.5.0 milestone Feb 5, 2026
@Mayisha
Copy link
Contributor Author

Mayisha commented Feb 5, 2026

@daledupreez I have split the upgrade in two PRs

Apparently the E2E tests are looking good in the other PR and the update in this PR seems problematic 😬

@Mayisha
Copy link
Contributor Author

Mayisha commented Feb 11, 2026

E2E tests are passing after the fix in 5a598bc

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

This PR updates the Stripe integration from API version 2024-06-20 to 2025-09-30.clover, migrates the JavaScript SDK from the standard v3 endpoint to a Clover-specific build, removes explicit apiVersion configuration from the constructor, and adjusts UPE layout settings by disabling spaced accordion items.

Changes

Cohort / File(s) Summary
Documentation Updates
changelog.txt, readme.txt
Added changelog entry noting the Stripe API version update in v10.5.0.
Stripe API Version Configuration
includes/class-wc-stripe-api.php
Updated STRIPE_API_VERSION constant from '2024-06-20' to '2025-09-30.clover'.
Stripe JavaScript SDK Migration
includes/abstracts/abstract-wc-stripe-payment-gateway.php, includes/class-wc-stripe-blocks-support.php, includes/payment-methods/class-wc-stripe-express-checkout-element.php, includes/payment-methods/class-wc-stripe-upe-payment-gateway.php
Replaced Stripe JS URL https://js.stripe.com/v3/ with https://js.stripe.com/clover/stripe.js and changed script version parameter from '3.0' to null in script registrations.
Constructor Configuration
client/api/index.js
Removed explicit apiVersion option from the Stripe constructor in createStripe.
UPE Layout Configuration
client/blocks/upe/upe-deferred-intent-creation/payment-processor.js, client/classic/upe/payment-processing.js
When Optimized Checkout layout is used, set layout.spacedAccordionItems = false in addition to existing layout adjustments (layout.radios = false).
UPE intent & error logic
includes/payment-methods/class-wc-stripe-upe-payment-gateway.php
Broadened reusable PaymentIntent statuses (added PROCESSING, REQUIRES_CAPTURE) and loosened Amazon Pay decline_code check in error messaging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Bump versions of Stripe JS and Stripe API' accurately and concisely summarizes the main change—updating both Stripe JavaScript and API versions across the codebase.
Description check ✅ Passed The PR description clearly relates to the changeset, explaining the purpose (groundwork for adaptive pricing), scope (both classic and block implementations), and includes testing instructions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update/bump-versions-of-stripe-js-and-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@includes/class-wc-stripe-api.php`:
- Around line 16-18: The Stripe API version constant STRIPE_API_VERSION was
bumped to '2025-09-30.clover'—review and update all related integration points
in the WC_Stripe_API class and callers: ensure PaymentIntent/SetupIntent code
paths always create fresh intents where client secrets cannot be reused (update
any reuse logic), remove or replace usages of deprecated Stripe.js Elements
(affirmMessage, afterpayClearpayMessage, epsBank, fpxBank, p24Bank, idealBank),
stop calling stripe.redirectToCheckout() and migrate to the supported flow,
explicitly set subscription billing mode when creating subscriptions if you need
classic behavior (override the new default "flexible"), adjust the Payment
Element configuration to control save/redisplay behavior for saved payment
methods, and update error/decline-code handling to account for the more granular
decline codes so existing logic doesn’t break.

Comment on lines 16 to 18
const ENDPOINT = 'https://api.stripe.com/v1/';
const STRIPE_API_VERSION = '2024-06-20';
const STRIPE_API_VERSION = '2025-09-30.clover';

Copy link

@coderabbitai coderabbitai bot Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Stripe API version 2025-09-30.clover breaking changes

💡 Result:

Here are notable breaking changes introduced in Stripe API version 2025-09-30.clover (Clover release), grouped by area:

Elements / Stripe.js

  • Blocks reusing client secrets for PaymentIntents/SetupIntents in certain states (for example succeeded, canceled, processing, etc.) when initializing Elements; you must create a fresh Intent / client secret and handle the new validation errors. [1]
  • Removes deprecated Stripe.js Elements: affirmMessage, afterpayClearpayMessage, epsBank, fpxBank, p24Bank, idealBank (migrate to Payment Method Messaging Element and Payment Element). [2]
  • Elements + Checkout Sessions saved payment methods behavior changes: if saved payment methods are enabled on the Checkout Session, the Payment Element now enables collection/redisplay by default unless you explicitly set enableSave / enableRedisplay to never. [3]

Checkout

  • Removes stripe.redirectToCheckout support in Stripe.js (migrate away; for redirects use the session URL / normal redirects, or use Payment Links/Buy Buttons for client-only). [4]
  • Removes currency_conversion from Checkout Session objects (Adaptive Pricing info is now expected via presentment_details for newer sessions, with different handling depending on session creation date). [5]
  • Stops collecting postal code by default for card payments on Checkout and Payment Element in CA/UK/PR under certain “auto” configurations; you must collect it yourself if you need it. [6]

Billing / Subscriptions

  • New subscriptions default to “flexible” billing mode (set billing_mode.type=classic if you need classic). [7]
  • Removes iterations for Subscription Schedule phases; use duration instead (sending iterations now errors). [8]

Connect / Accounts

  • Adds a new Connect requirements error code: unsupported_business_type (your integration must handle it and/or ensure the business type is valid for the account’s country). [9]
  • Balance Settings API changes (new/GA behavior and field/parameter changes such as delay_days_override). [10]
  • Accounts v2 (preview) field move: some platform-specific identity fields move from identity.business_details to defaults.profile (requests using the old location fail). [11]

Other notable breaking changes in this version

  • More granular decline codes for certain payment methods (update logic that relies on last_payment_error.decline_code). [12]
  • Radar manual review enum expands (closed_reason adds values like acknowledged, payment_never_settled). [13]
  • Smart Disputes recommended_evidence structure changes (now nested arrays instead of a flat array). [14]

For the official roll-up list of what Stripe categorizes under 2025-09-30.clover, see the Clover section of the Stripe API changelog. [15]


Sources

[1] https://docs.stripe.com/changelog/clover/2025-09-30/client-secret-reuse
[2] https://docs.stripe.com/changelog/clover/2025-09-30/stripejs-deprecated-elements-removal
[3] https://docs.stripe.com/changelog/clover/2025-09-30/custom-checkout-saved-payment-method-defaults
[4] https://docs.stripe.com/changelog/clover/2025-09-30/remove-redirect-to-checkout
[5] https://docs.stripe.com/changelog/clover/2025-09-30/remove-checkout-session-currency-conversion-field
[6] https://docs.stripe.com/changelog/clover/2025-09-30/postal_code_in_card_form_for_non_us_countries
[7] https://docs.stripe.com/changelog/clover/2025-09-30/billing-mode-default-flexible
[8] https://docs.stripe.com/changelog/clover/2025-09-30/remove-iterations
[9] https://docs.stripe.com/changelog/clover/2025-09-30/business-type-error-code
[10] https://docs.stripe.com/changelog/clover/2025-09-30/balance-settings-ga
[11] https://docs.stripe.com/changelog/clover/2025-09-30/moving-identity-fields
[12] https://docs.stripe.com/changelog/clover/2025-09-30/lpm-descriptive-decline-codes
[13] https://docs.stripe.com/changelog/clover/2025-09-30/radar-manual-review-enum
[14] https://docs.stripe.com/changelog/clover/2025-09-30/restructure-smart-disputes-recommended-evidence
[15] https://docs.stripe.com/changelog


Review breaking changes introduced in Stripe API v2025-09-30.clover before integration.

This version includes significant breaking changes that require verification:

  • Client secrets for PaymentIntents/SetupIntents are blocked from reuse in certain states; fresh Intents must be created
  • Deprecated Stripe.js Elements removed (affirmMessage, afterpayClearpayMessage, epsBank, fpxBank, p24Bank, idealBank)
  • New subscriptions default to "flexible" billing mode instead of classic
  • stripe.redirectToCheckout() no longer supported
  • Payment element now enables save/redisplay collection by default for saved payment methods
  • Decline codes are more granular; update error handling logic if relying on specific codes

Ensure the integration handles these changes without breaking payment processing, subscription management, or error handling flows.

🤖 Prompt for AI Agents
In `@includes/class-wc-stripe-api.php` around lines 16 - 18, The Stripe API
version constant STRIPE_API_VERSION was bumped to '2025-09-30.clover'—review and
update all related integration points in the WC_Stripe_API class and callers:
ensure PaymentIntent/SetupIntent code paths always create fresh intents where
client secrets cannot be reused (update any reuse logic), remove or replace
usages of deprecated Stripe.js Elements (affirmMessage, afterpayClearpayMessage,
epsBank, fpxBank, p24Bank, idealBank), stop calling stripe.redirectToCheckout()
and migrate to the supported flow, explicitly set subscription billing mode when
creating subscriptions if you need classic behavior (override the new default
"flexible"), adjust the Payment Element configuration to control save/redisplay
behavior for saved payment methods, and update error/decline-code handling to
account for the more granular decline codes so existing logic doesn’t break.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decline codes are more granular; update error handling logic if relying on specific codes

Have we done a deep dive into the details for the related changes? It feels like some of our error handling could be broken or invalidated if the decline codes change. I am especially concerned because none of these issues will be found by happy path testing.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@daledupreez, you raise an excellent point. Let me investigate how decline codes are currently used in the codebase and get specific details about what changed.


🏁 Script executed:

#!/bin/bash
# Search for decline_code usage in the codebase
echo "=== Searching for decline_code usage ==="
rg -n "decline_code" --type=php -C3

echo -e "\n=== Searching for last_payment_error usage ==="
rg -n "last_payment_error" --type=php -C3

echo -e "\n=== Searching for error handling patterns with Stripe errors ==="
rg -n "error->code|error\['code'\]|->get_error_code" --type=php -C2

Length of output: 29468


🌐 Web query:

Stripe API 2025-09-30.clover decline code changes specific payment methods

💡 Result:

In Stripe API version 2025-09-30.clover, Stripe introduced a breaking change that updates/expands the decline codes returned (in PaymentIntent.last_payment_error.decline_code) for these specific payment methods: Alma, Amazon Pay, Billie, Satispay, and South Korean payment methods. The goal is to provide more granular decline reasons, so the set of possible decline codes you receive may change compared to older API versions, and any logic that branches on specific codes should be reviewed/updated. [1]

Where to look / what to update:

  • Your integration should read the updated values from PaymentIntent.last_payment_error.decline_code (and you can also see the decline reason in the Dashboard Transactions view). [1]
  • The relevant universe of Local Payment Method (LPM) decline codes is documented in Stripe’s “Local payment method decline codes” list (for example: invalid_customer_account, payment_limit_exceeded, invalid_billing_agreement, partner_generic_decline, etc.). [2]
  • “South Korean payment methods” (as a category) includes wallets like Naver Pay, Kakao Pay, Samsung Pay, PAYCO, plus local Korean cards. [3]

Sources: Stripe changelog entry for 2025-09-30.clover decline-code change [1], Stripe decline-code reference (LPM section) [2], Stripe South Korea payment methods overview [3].


@daledupreez, excellent instinct—I found a specific risk area. Here's what the deep dive revealed:

🎯 Specific Risk Identified

File: includes/payment-methods/class-wc-stripe-upe-payment-gateway.php (lines 2697-2698)

The codebase checks for generic_decline specifically for Amazon Pay:

if ( isset( $payment_intent->error->payment_intent->payment_method_types[0] ) &&
    'amazon_pay' === $payment_intent->error->payment_intent->payment_method_types[0] &&
    isset( $payment_intent->error->decline_code ) &&
    'generic_decline' === $payment_intent->error->decline_code
) {
    return __( 'Amazon Pay is not compatible for this order. Please try again later.', ... );
}

Since the 2025-09-30.clover version specifically changes decline codes for Amazon Pay to be "more granular," this exact generic_decline check may no longer match. Stripe will likely return more specific codes like invalid_customer_account, payment_limit_exceeded, or partner_generic_decline instead.

Impact: The custom Amazon Pay error message won't be displayed to users when these specific decline scenarios occur.

Good News

The rest of the error handling is more resilient:

  • Most code accesses last_payment_error->message directly (which should remain stable)
  • Error code checks (like authentication_required, amount_too_small) use error->code, not decline_code
  • Only ONE location relies on a specific decline_code value

🔍 Recommended Actions

  1. Update the Amazon Pay check to handle the new granular decline codes
  2. Add monitoring/logging for decline codes when they occur to catch any unexpected values
  3. Test with sandbox using Amazon Pay declines to see what actual codes are returned
  4. Consider a more generic fallback - perhaps check if any decline_code exists rather than matching specific values

Would you like me to create an issue to track updating this Amazon Pay decline code handling, or would you prefer to address it in this PR?


🧠 Learnings used
Learnt from: CR
Repo: woocommerce/woocommerce-gateway-stripe PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-16T07:38:09.671Z
Learning: Implement Singleton pattern for WC_Stripe and WC_Stripe_API classes

Learnt from: CR
Repo: woocommerce/woocommerce-gateway-stripe PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-16T07:38:09.671Z
Learning: Applies to includes/payment-methods/*.php : Extend WC_Stripe_UPE_Payment_Method class when creating new payment method implementations

Learnt from: Mayisha
Repo: woocommerce/woocommerce-gateway-stripe PR: 4993
File: package.json:105-106
Timestamp: 2026-02-16T07:37:54.292Z
Learning: The WooCommerce Stripe Gateway codebase's Stripe integration is compatible with stripe/react-stripe-js v5 and stripe/stripe-js v8 breaking changes - it doesn't use CheckoutProvider with fetchClientSecret pattern, doesn't rely on removed Clover Element types, deprecated BNPL/bank elements, or redirectToCheckout types.

Learnt from: CR
Repo: woocommerce/woocommerce-gateway-stripe PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-16T07:38:09.671Z
Learning: Register new payment methods in WC_Stripe::init()

@Mayisha Mayisha requested a review from daledupreez February 16, 2026 07:04
Copy link
Contributor

@daledupreez daledupreez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mayisha, on the surface, this PR looks OK, but I want to confirm that we've investigated the decline code changes that CodeRabbit alluded to. Changes in that area would be really unlikely to show up in most of our tests, but would be hugely problematic in production.

Comment on lines 16 to 18
const ENDPOINT = 'https://api.stripe.com/v1/';
const STRIPE_API_VERSION = '2024-06-20';
const STRIPE_API_VERSION = '2025-09-30.clover';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decline codes are more granular; update error handling logic if relying on specific codes

Have we done a deep dive into the details for the related changes? It feels like some of our error handling could be broken or invalidated if the decline codes change. I am especially concerned because none of these issues will be found by happy path testing.

@daledupreez
Copy link
Contributor

daledupreez commented Feb 17, 2026

After a quick look at the Stripe changelog, it looks like we may need to review the following changes:

Most of these changes look like they're unlikely to affect us in a major way, but I think we need to confirm we are not introducing incompatibilities or issues.

Also, it looks like it should be easier to block specific card brands when using Checkout Sessions, which may be something we expose in future.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
includes/payment-methods/class-wc-stripe-upe-payment-gateway.php (1)

2694-2703: ⚠️ Potential issue | 🟠 Major

Scope the "not compatible" message to specific structural-incompatibility decline codes, not all Amazon Pay declines.

The removal of the 'generic_decline' guard is correct for Stripe API 2025-09-30, which now emits granular decline codes. However, the current isset( $payment_intent->error->decline_code ) check is too broad and will display "Amazon Pay is not compatible for this order" for any Amazon Pay decline—including retryable failures like insufficient funds or processing errors. Customers will incorrectly believe Amazon Pay is blocked for their order and abandon the payment method unnecessarily.

Per Stripe's LPM decline guidance, only codes indicating structural incompatibility (e.g., currency_not_supported, invalid_amount, invalid_billing_agreement) should trigger this message. Retryable codes (e.g., insufficient_funds, processing_error, expired_card) should fall through to the generic error path (WC_Stripe_Helper::get_localized_error_message_from_response), which provides context-appropriate messaging.

Consider maintaining an allowlist of incompatible decline codes:

Suggested approach
-		if ( isset( $payment_intent->error->payment_intent->payment_method_types[0] ) &&
-			'amazon_pay' === $payment_intent->error->payment_intent->payment_method_types[0] &&
-			isset( $payment_intent->error->decline_code )
-		) {
+		// With API 2025-09-30, Amazon Pay emits specific decline codes.
+		// Only show the "not compatible" message for codes indicating structural incompatibility.
+		$incompatible_codes = [ 'currency_not_supported', 'invalid_amount', 'invalid_billing_agreement' ];
+		if ( isset( $payment_intent->error->payment_intent->payment_method_types[0] ) &&
+			'amazon_pay' === $payment_intent->error->payment_intent->payment_method_types[0] &&
+			isset( $payment_intent->error->decline_code ) &&
+			in_array( $payment_intent->error->decline_code, $incompatible_codes, true )
+		) {

Also add PHPUnit test coverage for retryable vs. non-retryable decline scenarios.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@includes/payment-methods/class-wc-stripe-upe-payment-gateway.php` around
lines 2694 - 2703, The current get_payment_intent_error_message method is
treating any Amazon Pay decline as a structural incompatibility due to the loose
isset($payment_intent->error->decline_code) check; restrict this to an explicit
allowlist of non-retryable/incompatible decline codes (e.g.,
'currency_not_supported', 'invalid_amount', 'invalid_billing_agreement') and
only return the "Amazon Pay is not compatible..." string when
payment_method_types[0] is 'amazon_pay' AND the decline_code is in that
allowlist; otherwise fall through to the existing generic path
(WC_Stripe_Helper::get_localized_error_message_from_response). Add PHPUnit tests
for both retryable declines (e.g., 'insufficient_funds', 'processing_error') and
incompatible declines to assert the correct message is returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@includes/payment-methods/class-wc-stripe-upe-payment-gateway.php`:
- Around line 2694-2703: The current get_payment_intent_error_message method is
treating any Amazon Pay decline as a structural incompatibility due to the loose
isset($payment_intent->error->decline_code) check; restrict this to an explicit
allowlist of non-retryable/incompatible decline codes (e.g.,
'currency_not_supported', 'invalid_amount', 'invalid_billing_agreement') and
only return the "Amazon Pay is not compatible..." string when
payment_method_types[0] is 'amazon_pay' AND the decline_code is in that
allowlist; otherwise fall through to the existing generic path
(WC_Stripe_Helper::get_localized_error_message_from_response). Add PHPUnit tests
for both retryable declines (e.g., 'insufficient_funds', 'processing_error') and
incompatible declines to assert the correct message is returned.

@Mayisha
Copy link
Contributor Author

Mayisha commented Feb 18, 2026

Thanks @daledupreez for going through the changes. I have

New error code for account requirements

We currently do not show any account requirements errors in the plugin. We can explore if we want to show the errors in the settings page for UX improvement.

Additional states for account review

This update involves the requirements.errors and requirements.currently_due fields. We are not using requirements.error so we are good here. The current implementation only checks whether requirements.currently_due has any value, so we are good here as well.

Decline code changes for some LPMs, including Amazon Pay

I have removed the check for generic_decline in 6494947 and am checking if the decline_code key is present.

New error codes for account verification
New error codes for account verification

These are also related to the requirements.errors in the account response which we don't use atm.

Additionally, added two additional intent status checks ('processing' and 'requires_capture') in 'get_existing_compatible_payment_intent' method 5f2cf32 as per this changelog https://docs.stripe.com/changelog/clover/2025-09-30/client-secret-reuse

@Mayisha Mayisha requested a review from daledupreez February 19, 2026 05:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants