Conversation
wjrosa
left a comment
There was a problem hiding this comment.
Looks good to me! I second Dale's comment on the 3.0 query string
|
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. |
fbd3a0d to
4ee590f
Compare
|
@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 😬 |
|
E2E tests are passing after the fix in 5a598bc |
📝 WalkthroughWalkthroughThis 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
| const ENDPOINT = 'https://api.stripe.com/v1/'; | ||
| const STRIPE_API_VERSION = '2024-06-20'; | ||
| const STRIPE_API_VERSION = '2025-09-30.clover'; | ||
|
|
There was a problem hiding this comment.
🧩 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/enableRedisplaytonever. [3]
Checkout
- Removes
stripe.redirectToCheckoutsupport 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_conversionfrom Checkout Session objects (Adaptive Pricing info is now expected viapresentment_detailsfor 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=classicif you need classic). [7] - Removes
iterationsfor Subscription Schedule phases; usedurationinstead (sendingiterationsnow 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_detailstodefaults.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_reasonadds values likeacknowledged,payment_never_settled). [13] - Smart Disputes
recommended_evidencestructure 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
🧩 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->messagedirectly (which should remain stable) - Error code checks (like
authentication_required,amount_too_small) useerror->code, notdecline_code - Only ONE location relies on a specific
decline_codevalue
🔍 Recommended Actions
- Update the Amazon Pay check to handle the new granular decline codes
- Add monitoring/logging for decline codes when they occur to catch any unexpected values
- Test with sandbox using Amazon Pay declines to see what actual codes are returned
- 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()
daledupreez
left a comment
There was a problem hiding this comment.
@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.
| const ENDPOINT = 'https://api.stripe.com/v1/'; | ||
| const STRIPE_API_VERSION = '2024-06-20'; | ||
| const STRIPE_API_VERSION = '2025-09-30.clover'; | ||
|
|
There was a problem hiding this comment.
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.
|
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. |
There was a problem hiding this comment.
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 | 🟠 MajorScope 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 currentisset( $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.
|
Thanks @daledupreez for going through the changes. I have 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. This update involves the I have removed the check for
These are also related to the 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 |
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
npm installandnpm start.Changelog entry
Changelog Entry Comment
Comment
Post merge