diff --git a/changelog.txt b/changelog.txt index 9acb462bac0..ec139f830ba 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,35 @@ *** WooPayments Changelog *** += 7.7.0 - 2024-05-29 = +* Add - Add share key query param when sending data to Stripe KYC. +* Add - Add the WooPay Direct Checkout flow to the blocks mini cart widget. +* Add - feat: add multi-currency support to Store API. +* Add - feat: error message on 1M+ amount. +* Add - feat: tokenized cart PRBs on PDPs via feature flag. +* Add - Render ECE buttons behind a feature flag. +* Fix - Charm pricing and rounding options corrected for all currencies that aren't presented with decimal points. +* Fix - Fix "Pay for order" infinite loading when submitting form without payment details. +* Fix - fix: remove WooPay checkout pages scripts from non-checkout pages. +* Fix - fix: settings notices consistency. +* Fix - fix: Store API tokenized cart nonce verification. +* Fix - Fix a bug in Tracks where shopper events are not fired properly. +* Fix - Fix ECE error in the blocks checkout when PRBs are disabled. +* Fix - Fix Payment block render error while editing the block checkout page. +* Fix - Fix shortcode orders when using WooPay Direct Checkout. +* Fix - Improve visibility of WooPay button on light and outline button themes. +* Fix - Updating saved payment method billing address before processing the payment. +* Update - Do not auto-redirect to WooPay on page load. +* Update - Pass previous exception with exception. +* Update - Removed deprecated deposit_status key from account status. +* Update - Remove public key encryption setting from WooPayments settings. +* Update - Update XPF currency formatting. +* Dev - Add command to run QIT PHPStan tests. +* Dev - Add local release package support for PHPStan. +* Dev - Bump tested up to version for WP to 6.5 and WC to 8.9.1. +* Dev - Fix Klarna E2E tests. +* Dev - Guarantee REST intialization on REST request context (avoiding rest_preload_api_request context). +* Dev - Upgrade jetpack sync package version. + = 7.6.0 - 2024-05-08 = * Add - Add additional data to Compatibility service * Add - Add User Satisfaction Survey for Payments Overview Widget diff --git a/changelog/8520-fix-failing-e2e-test-for-adding-deleting-payment-methods b/changelog/8520-fix-failing-e2e-test-for-adding-deleting-payment-methods deleted file mode 100644 index e5f59c97a2a..00000000000 --- a/changelog/8520-fix-failing-e2e-test-for-adding-deleting-payment-methods +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Omitted changelog entry since this PR only fixes an e2e test. - - diff --git a/changelog/add-8779-unit-test-get-reporting-payment-activity b/changelog/add-8779-unit-test-get-reporting-payment-activity deleted file mode 100644 index 2c3223efb96..00000000000 --- a/changelog/add-8779-unit-test-get-reporting-payment-activity +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: Unit test for Get_Reporting_Payment_Activity. - - diff --git a/changelog/add-8797-conditional-rest-apis-init b/changelog/add-8797-conditional-rest-apis-init deleted file mode 100644 index ba4955b6606..00000000000 --- a/changelog/add-8797-conditional-rest-apis-init +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: dev - -Guarantee REST intialization on REST request context (avoiding rest_preload_api_request context). diff --git a/changelog/add-new-process-payment-exception b/changelog/add-new-process-payment-exception new file mode 100644 index 00000000000..f2ac469fefc --- /dev/null +++ b/changelog/add-new-process-payment-exception @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add New_Process_Payment_Exception diff --git a/changelog/add-order-id-mismatch-exception b/changelog/add-order-id-mismatch-exception new file mode 100644 index 00000000000..22938c21145 --- /dev/null +++ b/changelog/add-order-id-mismatch-exception @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add Order_ID_Mismatch_Exception diff --git a/changelog/add-phpstan-qit-tests-command b/changelog/add-phpstan-qit-tests-command deleted file mode 100644 index dc254406fca..00000000000 --- a/changelog/add-phpstan-qit-tests-command +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: dev - -Add command to run QIT PHPStan tests. diff --git a/changelog/add-phpstan-support-for-local-zip b/changelog/add-phpstan-support-for-local-zip deleted file mode 100644 index 1932e956ae9..00000000000 --- a/changelog/add-phpstan-support-for-local-zip +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: dev - -Add local release package support for PHPStan. diff --git a/changelog/add-woopay-direct-checkout-to-minicart b/changelog/add-woopay-direct-checkout-to-minicart deleted file mode 100644 index 031f5132dfa..00000000000 --- a/changelog/add-woopay-direct-checkout-to-minicart +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: add - -Add the WooPay Direct Checkout flow to the blocks mini cart widget. diff --git a/changelog/as-remove-auto-redirect b/changelog/as-remove-auto-redirect deleted file mode 100644 index 1e38d2fdb0b..00000000000 --- a/changelog/as-remove-auto-redirect +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: update - -Do not auto-redirect to WooPay on page load. diff --git a/changelog/chore-incompatibility-notice-wrapping b/changelog/chore-incompatibility-notice-wrapping new file mode 100644 index 00000000000..cad615b4fd1 --- /dev/null +++ b/changelog/chore-incompatibility-notice-wrapping @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +chore: update incompatibility notice wrapping diff --git a/changelog/chore-remove-unused-upe-js-methods b/changelog/chore-remove-unused-upe-js-methods deleted file mode 100644 index eb708546f4a..00000000000 --- a/changelog/chore-remove-unused-upe-js-methods +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: chore: remove unused UPE JS methods - - diff --git a/changelog/delete-4710-remove-deposit_status b/changelog/delete-4710-remove-deposit_status deleted file mode 100644 index 34d940a66d8..00000000000 --- a/changelog/delete-4710-remove-deposit_status +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: update - -Removed deprecated deposit_status key from account status diff --git a/changelog/dev-finish-setup-cta b/changelog/dev-finish-setup-cta new file mode 100644 index 00000000000..0902b7fd4c6 --- /dev/null +++ b/changelog/dev-finish-setup-cta @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Fixes some cases where redirects to the onboarding will open in a new tab. diff --git a/changelog/feat-8772-render-ece-buttons b/changelog/feat-8772-render-ece-buttons deleted file mode 100644 index 37b3185b0ff..00000000000 --- a/changelog/feat-8772-render-ece-buttons +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: add - -Render ECE buttons behind a feature flag. diff --git a/changelog/feat-add-multi-currency-support-to-store-api b/changelog/feat-add-multi-currency-support-to-store-api deleted file mode 100644 index ab6688147c6..00000000000 --- a/changelog/feat-add-multi-currency-support-to-store-api +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: add - -feat: add multi-currency support to Store API diff --git a/changelog/feat-error-notice-on-1m-amount b/changelog/feat-error-notice-on-1m-amount deleted file mode 100644 index dfb938d19d1..00000000000 --- a/changelog/feat-error-notice-on-1m-amount +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: add - -feat: error message on 1M+ amount diff --git a/changelog/fix-5150-xpf-currency b/changelog/fix-5150-xpf-currency deleted file mode 100644 index 8030f1f982b..00000000000 --- a/changelog/fix-5150-xpf-currency +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: update - -Update XPF currency formatting. diff --git a/changelog/fix-5223-payment-activity-adjustment b/changelog/fix-5223-payment-activity-adjustment deleted file mode 100644 index cf8ae9298a7..00000000000 --- a/changelog/fix-5223-payment-activity-adjustment +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Added adjustment type to charges data highlight on Payment Activity Card - - diff --git a/changelog/fix-8611-3DS-subscription-pm b/changelog/fix-8611-3DS-subscription-pm deleted file mode 100644 index d2248adf5d0..00000000000 --- a/changelog/fix-8611-3DS-subscription-pm +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Small change to ensure tokens are stored on 3DS subscriptions. - - diff --git a/changelog/fix-8704-fix-disputes-view-report-link b/changelog/fix-8704-fix-disputes-view-report-link deleted file mode 100644 index b7a114349e3..00000000000 --- a/changelog/fix-8704-fix-disputes-view-report-link +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Fix for the `View report` link on Disputes tile of Payment activity widget. Changes behind a feature flag. - - diff --git a/changelog/fix-8716-duplicate-query-checkout b/changelog/fix-8716-duplicate-query-checkout deleted file mode 100644 index 0e0cffd161e..00000000000 --- a/changelog/fix-8716-duplicate-query-checkout +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: A small defensive check for PRB gateway title filtering. - - diff --git a/changelog/fix-8742-merchant-timezone-payment-activity b/changelog/fix-8742-merchant-timezone-payment-activity deleted file mode 100644 index 08dc0462916..00000000000 --- a/changelog/fix-8742-merchant-timezone-payment-activity +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: Adding some fixes to the Payment Activity component, reporting controller aand associated classes. - - diff --git a/changelog/fix-8775-direct-checkout-shortcode-orders b/changelog/fix-8775-direct-checkout-shortcode-orders deleted file mode 100644 index 28379f9ff19..00000000000 --- a/changelog/fix-8775-direct-checkout-shortcode-orders +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Fix shortcode orders when using WooPay Direct Checkout. diff --git a/changelog/fix-8883-pay-for-order-blocked-ui b/changelog/fix-8883-pay-for-order-blocked-ui new file mode 100644 index 00000000000..b74ba9e179f --- /dev/null +++ b/changelog/fix-8883-pay-for-order-blocked-ui @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Fix "Pay for order" infinite loading when submitting form without payment details. diff --git a/changelog/fix-afterpay-virtual-produts b/changelog/fix-afterpay-virtual-produts deleted file mode 100644 index d2ca394a745..00000000000 --- a/changelog/fix-afterpay-virtual-produts +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Fixed Afterpay for virtual products that was not released yet - - diff --git a/changelog/fix-blocks-checkout-ece-error-when-prb-disabled b/changelog/fix-blocks-checkout-ece-error-when-prb-disabled deleted file mode 100644 index 499093828a2..00000000000 --- a/changelog/fix-blocks-checkout-ece-error-when-prb-disabled +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Fix ECE error in the blocks checkout when PRBs are disabled. diff --git a/changelog/fix-blocks-page-detection-for-woopay b/changelog/fix-blocks-page-detection-for-woopay deleted file mode 100644 index a348ffea544..00000000000 --- a/changelog/fix-blocks-page-detection-for-woopay +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Fixes an unreleased bug - - diff --git a/changelog/fix-escaping-from-8650 b/changelog/fix-escaping-from-8650 deleted file mode 100644 index 07871fd960d..00000000000 --- a/changelog/fix-escaping-from-8650 +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: PR related to another issue already in changelog. - - diff --git a/changelog/fix-link-setup-intent-pm-title b/changelog/fix-link-setup-intent-pm-title deleted file mode 100644 index 9f4972b0948..00000000000 --- a/changelog/fix-link-setup-intent-pm-title +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: fix -Comment: Minor change to Link payment method display. - - diff --git a/changelog/fix-mccy-charm-and-rounding-for-non-decimal-currencies b/changelog/fix-mccy-charm-and-rounding-for-non-decimal-currencies deleted file mode 100644 index b878e62b409..00000000000 --- a/changelog/fix-mccy-charm-and-rounding-for-non-decimal-currencies +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Charm pricing and rounding options corrected for all currencies that aren't presented with decimal points. diff --git a/changelog/fix-rule-exclusion b/changelog/fix-rule-exclusion deleted file mode 100644 index 619f8aa1e5e..00000000000 --- a/changelog/fix-rule-exclusion +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: PHPCS rules only - - diff --git a/changelog/fix-settings-notices-consistency b/changelog/fix-settings-notices-consistency deleted file mode 100644 index fe7952a69be..00000000000 --- a/changelog/fix-settings-notices-consistency +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -fix: settings notices consistency diff --git a/changelog/fix-shopper-bump-stats-conditions b/changelog/fix-shopper-bump-stats-conditions deleted file mode 100644 index e0f8df51ac0..00000000000 --- a/changelog/fix-shopper-bump-stats-conditions +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Fix a bug in Tracks where shopper events are not fired properly. diff --git a/changelog/fix-store-api-tokenized-cart-nonce-verification b/changelog/fix-store-api-tokenized-cart-nonce-verification deleted file mode 100644 index bd8bebc9c68..00000000000 --- a/changelog/fix-store-api-tokenized-cart-nonce-verification +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -fix: Store API tokenized cart nonce verification diff --git a/changelog/fix-stripe-pmme-editor-error b/changelog/fix-stripe-pmme-editor-error deleted file mode 100644 index e2fcbe79516..00000000000 --- a/changelog/fix-stripe-pmme-editor-error +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Fix Payment block render error while editing the block checkout page. diff --git a/changelog/fix-update-jetpack-sync-package b/changelog/fix-update-jetpack-sync-package deleted file mode 100644 index 1909a0c52ad..00000000000 --- a/changelog/fix-update-jetpack-sync-package +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: dev - -Upgraded jetpack sync package version. diff --git a/changelog/fix-update-request-classes-docs b/changelog/fix-update-request-classes-docs deleted file mode 100644 index ea03df09449..00000000000 --- a/changelog/fix-update-request-classes-docs +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: Updated the parent link in request classes documentation - - diff --git a/changelog/fix-woopay-button-submit-when-enter-pressed b/changelog/fix-woopay-button-submit-when-enter-pressed new file mode 100644 index 00000000000..0b89f8eed90 --- /dev/null +++ b/changelog/fix-woopay-button-submit-when-enter-pressed @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Make it so that the WooPay button is not triggered on Checkout pages when the "Enter" key is pressed on a keyboard. diff --git a/changelog/fix-woopay-save-user-on-non-checkout-pages b/changelog/fix-woopay-save-user-on-non-checkout-pages deleted file mode 100644 index cf81892c65c..00000000000 --- a/changelog/fix-woopay-save-user-on-non-checkout-pages +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -fix: remove WooPay checkout pages scripts from non-checkout pages diff --git a/changelog/refactor-pdp-payment-request-tokenized-cart b/changelog/refactor-pdp-payment-request-tokenized-cart deleted file mode 100644 index 97b25e0c121..00000000000 --- a/changelog/refactor-pdp-payment-request-tokenized-cart +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: add - -feat: tokenized cart PRBs on PDPs via feature flag. diff --git a/changelog/remove-8839-public-key-encryption b/changelog/remove-8839-public-key-encryption deleted file mode 100644 index 76000116590..00000000000 --- a/changelog/remove-8839-public-key-encryption +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: update - -Remove public key encryption setting from WooPayments settings diff --git a/changelog/update-8733-move-payment-activity-data-fetching b/changelog/update-8733-move-payment-activity-data-fetching deleted file mode 100644 index 028f5a0a4af..00000000000 --- a/changelog/update-8733-move-payment-activity-data-fetching +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: update -Comment: Moved data fetching for Payment Activity widget to the parent's component so it can be used by the to-be-implemented filters. - - diff --git a/changelog/update-billing-address-saved-card b/changelog/update-billing-address-saved-card deleted file mode 100644 index 52d6490bca3..00000000000 --- a/changelog/update-billing-address-saved-card +++ /dev/null @@ -1,4 +0,0 @@ -Significance: minor -Type: fix - -Updating saved payment method billing address before processing the payment diff --git a/changelog/update-parameterize-xdebug-host-dockerfile b/changelog/update-parameterize-xdebug-host-dockerfile deleted file mode 100644 index c2b53bb94a0..00000000000 --- a/changelog/update-parameterize-xdebug-host-dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: dev -Comment: Parameterize Xdebug remote host in Dockerfile. This is only needed for debugging PHP. No production code was updated. - - diff --git a/changelog/update-pass-previous-exception-with-exception b/changelog/update-pass-previous-exception-with-exception deleted file mode 100644 index c3bab3e269c..00000000000 --- a/changelog/update-pass-previous-exception-with-exception +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: update - -Pass previous exception with exception diff --git a/changelog/update-sandbox-mode-notice-tooltip-copy b/changelog/update-sandbox-mode-notice-tooltip-copy deleted file mode 100644 index 871db6fff50..00000000000 --- a/changelog/update-sandbox-mode-notice-tooltip-copy +++ /dev/null @@ -1,5 +0,0 @@ -Significance: patch -Type: update -Comment: Just updating the copy of the tooltip. - - diff --git a/changelog/update-woopay-button-color b/changelog/update-woopay-button-color deleted file mode 100644 index 52d48a01752..00000000000 --- a/changelog/update-woopay-button-color +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Improve visibility of WooPay button on light and outline button themes diff --git a/changelog/upgrade-jetpack-packages b/changelog/upgrade-jetpack-packages deleted file mode 100644 index 5cb0b8586fb..00000000000 --- a/changelog/upgrade-jetpack-packages +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: dev - -Upgrade jetpack sync package version. diff --git a/client/checkout/classic/payment-processing.js b/client/checkout/classic/payment-processing.js index 74ab31c7e36..204a84adc10 100644 --- a/client/checkout/classic/payment-processing.js +++ b/client/checkout/classic/payment-processing.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + /** * Internal dependencies */ @@ -63,8 +68,8 @@ async function initializeAppearance( api ) { * * @param {Object} $form The jQuery object for the form. */ -export function blockUI( $form ) { - $form.addClass( 'processing' ).block( { +export async function blockUI( $form ) { + await $form.addClass( 'processing' ).block( { message: null, overlayCSS: { background: '#fff', @@ -515,18 +520,24 @@ export const processPayment = ( return; } - const { elements, isPaymentInformationComplete } = gatewayUPEComponents[ - paymentMethodType - ]; - if ( ! isPaymentInformationComplete ) { - showErrorCheckout( 'Your payment information is incomplete.' ); - return false; - } - - blockUI( $form ); - ( async () => { try { + await blockUI( $form ); + + const { + elements, + isPaymentInformationComplete, + } = gatewayUPEComponents[ paymentMethodType ]; + + if ( ! isPaymentInformationComplete ) { + throw new Error( + __( + 'Your payment information is incomplete.', + 'woocommerce-payments' + ) + ); + } + await validateElements( elements ); const paymentMethodObject = await createStripePaymentMethod( api, diff --git a/client/checkout/classic/test/payment-processing.test.js b/client/checkout/classic/test/payment-processing.test.js index 0dd6a9ef2a4..ad8a24315b9 100644 --- a/client/checkout/classic/test/payment-processing.test.js +++ b/client/checkout/classic/test/payment-processing.test.js @@ -457,6 +457,8 @@ describe( 'Payment processing', () => { }; await processPayment( apiMock, checkoutForm, 'card' ); + // Wait for promises to resolve. + await new Promise( ( resolve ) => setImmediate( resolve ) ); expect( mockCreatePaymentMethod ).toHaveBeenCalledWith( { elements: expect.any( Object ), @@ -499,6 +501,8 @@ describe( 'Payment processing', () => { }; await processPayment( apiMock, checkoutForm, 'card' ); + // Wait for promises to resolve. + await new Promise( ( resolve ) => setImmediate( resolve ) ); expect( mockCreatePaymentMethod ).toHaveBeenCalledWith( { elements: expect.any( Object ), @@ -537,6 +541,8 @@ describe( 'Payment processing', () => { }; await processPayment( apiMock, checkoutForm, 'card' ); + // Wait for promises to resolve. + await new Promise( ( resolve ) => setImmediate( resolve ) ); expect( mockCreatePaymentMethod ).toHaveBeenCalledWith( { elements: expect.any( Object ), @@ -572,6 +578,8 @@ describe( 'Payment processing', () => { }; await processPayment( apiMock, checkoutForm, 'card' ); + // Wait for promises to resolve. + await new Promise( ( resolve ) => setImmediate( resolve ) ); expect( mockCreatePaymentMethod ).toHaveBeenCalledWith( { elements: expect.any( Object ), @@ -605,6 +613,8 @@ describe( 'Payment processing', () => { }; await processPayment( apiMock, addPaymentMethodForm, 'card' ); + // Wait for promises to resolve. + await new Promise( ( resolve ) => setImmediate( resolve ) ); expect( mockCreatePaymentMethod ).toHaveBeenCalledWith( { elements: expect.any( Object ), diff --git a/client/checkout/woopay/express-button/woopay-express-checkout-button.js b/client/checkout/woopay/express-button/woopay-express-checkout-button.js index 2220a1422e6..00b8a38b2c4 100644 --- a/client/checkout/woopay/express-button/woopay-express-checkout-button.js +++ b/client/checkout/woopay/express-button/woopay-express-checkout-button.js @@ -346,6 +346,7 @@ export const WoopayExpressCheckoutButton = ( { data-width-type={ buttonWidthType } style={ { height: `${ height }px` } } disabled={ isLoading } + type="button" > { isLoading ? ( diff --git a/client/components/account-status/account-tools/index.tsx b/client/components/account-status/account-tools/index.tsx index e417d4349ed..34886cc95c3 100644 --- a/client/components/account-status/account-tools/index.tsx +++ b/client/components/account-status/account-tools/index.tsx @@ -56,7 +56,6 @@ export const AccountTools: React.FC< Props > = ( props: Props ) => { ) } href={ accountLink } - target={ '_blank' } > { strings.finish } diff --git a/client/components/account-status/account-tools/test/__snapshots__/index.test.tsx.snap b/client/components/account-status/account-tools/test/__snapshots__/index.test.tsx.snap index b5b1f5eb8fc..988d1e2d7fe 100644 --- a/client/components/account-status/account-tools/test/__snapshots__/index.test.tsx.snap +++ b/client/components/account-status/account-tools/test/__snapshots__/index.test.tsx.snap @@ -24,7 +24,6 @@ exports[`AccountTools should render in live mode 1`] = ` Finish setup @@ -63,7 +62,6 @@ exports[`AccountTools should render in sandbox mode 1`] = ` Finish setup diff --git a/client/components/account-status/test/__snapshots__/index.js.snap b/client/components/account-status/test/__snapshots__/index.js.snap index 97a0ae5fc41..8c3367a63fc 100644 --- a/client/components/account-status/test/__snapshots__/index.js.snap +++ b/client/components/account-status/test/__snapshots__/index.js.snap @@ -189,7 +189,6 @@ exports[`AccountStatus renders normal status 1`] = ` Finish setup diff --git a/client/globals.d.ts b/client/globals.d.ts index 38df02b35a6..c64240cd04f 100644 --- a/client/globals.d.ts +++ b/client/globals.d.ts @@ -168,6 +168,11 @@ declare global { woocommerce_default_country: string; }; }; + siteVisibilitySettings: { + woocommerce_share_key: string; + woocommerce_coming_soon: string; + woocommerce_private_link: string; + }; }; adminUrl: string; countries: Record< string, string >; diff --git a/client/onboarding/index.tsx b/client/onboarding/index.tsx index 4100d0426d9..375c0bbd4e2 100644 --- a/client/onboarding/index.tsx +++ b/client/onboarding/index.tsx @@ -46,13 +46,27 @@ const OnboardingStepper = () => { ); }; +const getComingSoonShareKey = () => { + const { + woocommerce_share_key: shareKey, + woocommerce_coming_soon: comingSoon, + woocommerce_private_link: privateLink, + } = wcSettings?.admin?.siteVisibilitySettings || {}; + + if ( comingSoon !== 'yes' || privateLink === 'no' ) { + return ''; + } + + return shareKey ? '?woo-share=' + shareKey : ''; +}; + const initialData = { business_name: wcSettings?.siteTitle, mcc: getMccFromIndustry(), url: location.hostname === 'localhost' ? 'https://wcpay.test' - : wcSettings?.homeUrl, + : wcSettings?.homeUrl + getComingSoonShareKey(), country: wcpaySettings?.connect?.country, }; diff --git a/client/overview/task-list/tasks/update-business-details-task.tsx b/client/overview/task-list/tasks/update-business-details-task.tsx index 3d1061311be..2de66b9890f 100644 --- a/client/overview/task-list/tasks/update-business-details-task.tsx +++ b/client/overview/task-list/tasks/update-business-details-task.tsx @@ -27,6 +27,7 @@ export const getUpdateBusinessDetailsTask = ( const accountDetailsPastDue = 'restricted' === status && pastDue; const hasMultipleErrors = 1 < errorMessages.length; const hasSingleError = 1 === errorMessages.length; + const connectUrl = wcpaySettings.connectUrl; const accountLinkWithSource = addQueryArgs( accountLink, { source: 'overview-page__update-business-details-task', } ); @@ -113,7 +114,14 @@ export const getUpdateBusinessDetailsTask = ( recordEvent( 'wcpay_account_details_link_clicked', { source: 'overview-page__update-business-details-task', } ); - window.open( accountLinkWithSource, '_blank' ); + + // If the onboarding isn't complete use the connectUrl instead, + // as the accountLink doesn't handle redirecting back to the overview page. + if ( ! detailsSubmitted ) { + window.location.href = connectUrl; + } else { + window.open( accountLinkWithSource, '_blank' ); + } } }; diff --git a/client/settings/settings-warnings/incompatibility-notice.js b/client/settings/settings-warnings/incompatibility-notice.js index 52d9d07f098..c3a388f8df6 100644 --- a/client/settings/settings-warnings/incompatibility-notice.js +++ b/client/settings/settings-warnings/incompatibility-notice.js @@ -7,13 +7,11 @@ import interpolateComponents from '@automattic/interpolate-components'; /** * Internal dependencies */ -import './style.scss'; import InlineNotice from 'wcpay/components/inline-notice'; const IncompatibilityNotice = ( { message, learnMoreLinkHref } ) => ( - { message } -
+ { message }{ ' ' } { interpolateComponents( { mixedString: __( '{{learnMoreLink}}Learn More{{/learnMoreLink}}', diff --git a/client/settings/settings-warnings/style.scss b/client/settings/settings-warnings/style.scss deleted file mode 100644 index e401acb1e5e..00000000000 --- a/client/settings/settings-warnings/style.scss +++ /dev/null @@ -1,5 +0,0 @@ -.components-notice { - &__content { - display: flex; - } -} diff --git a/client/transactions/list/index.tsx b/client/transactions/list/index.tsx index a4b2108f308..d1ff4d2f4f2 100644 --- a/client/transactions/list/index.tsx +++ b/client/transactions/list/index.tsx @@ -103,10 +103,11 @@ const getPaymentSourceDetails = ( txn: Transaction ) => { switch ( txn.source ) { case 'giropay': - return { txn.source_identifier }; + return   { txn.source_identifier }; case 'p24': return ( +    { p24BankList[ txn.source_identifier ] ?? '' } ); diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index f20c1b15f1b..0ca27dd3788 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -18,7 +18,7 @@ use WCPay\Constants\Intent_Status; use WCPay\Constants\Payment_Type; use WCPay\Constants\Payment_Method; -use WCPay\Exceptions\{ Add_Payment_Method_Exception, Amount_Too_Small_Exception, Process_Payment_Exception, Intent_Authentication_Exception, API_Exception, Invalid_Address_Exception, Fraud_Prevention_Enabled_Exception, Invalid_Phone_Number_Exception, Rate_Limiter_Enabled_Exception }; +use WCPay\Exceptions\{ Add_Payment_Method_Exception, Amount_Too_Small_Exception, Process_Payment_Exception, Intent_Authentication_Exception, API_Exception, Invalid_Address_Exception, Fraud_Prevention_Enabled_Exception, Invalid_Phone_Number_Exception, Rate_Limiter_Enabled_Exception, Order_ID_Mismatch_Exception, Order_Not_Found_Exception, New_Process_Payment_Exception }; use WCPay\Core\Server\Request\Cancel_Intention; use WCPay\Core\Server\Request\Capture_Intention; use WCPay\Core\Server\Request\Create_And_Confirm_Intention; @@ -1072,8 +1072,8 @@ function_exists( 'wcs_order_contains_subscription' ) * and if the answer is yes, uses it and returns the result. * * @param WC_Order $order Order that needs payment. - * @return array|null Array if processed, null if the new process is not supported. - * @throws Exception If the payment process could not be completed. + * @return array|null Array if processed, null if the new process is not supported. + * @throws Exception Error processing the payment. */ public function new_process_payment( WC_Order $order ) { $manual_capture = $this->get_capture_type() === Payment_Capture_Type::MANUAL(); @@ -1119,7 +1119,14 @@ public function new_process_payment( WC_Order $order ) { ]; } - throw new Exception( __( 'The payment process could not be completed.', 'woocommerce-payments' ) ); + throw new Exception( + __( 'The payment process could not be completed.', 'woocommerce-payments' ), + 0, + new New_Process_Payment_Exception( + __( 'The payment process could not be completed.', 'woocommerce-payments' ), + 'new_process_payment' + ) + ); } /** @@ -1409,9 +1416,12 @@ public function update_saved_payment_method( $payment_method, $order_id, $is_tes * @param WCPay\Payment_Information $payment_information Payment info. * @param bool $scheduled_subscription_payment Used to determinate is scheduled subscription payment to add more fields into API request. * - * @return array|null An array with result of payment and redirect URL, or nothing. + * @return array|null An array with result of payment and redirect URL, or nothing. * @throws API_Exception - * @throws Intent_Authentication_Exception When the payment intent could not be authenticated. + * @throws Exception When amount too small. + * @throws Invalid_Address_Exception + * @throws Order_Not_Found_Exception + * @throws Order_ID_Mismatch_Exception When the payment intent could not be authenticated. * @throws \WCPay\Core\Exceptions\Server\Request\Extend_Request_Exception When request class filter filed to extend request class because of incompatibility. * @throws \WCPay\Core\Exceptions\Server\Request\Immutable_Parameter_Exception When immutable parameter gets changed in request class. * @throws \WCPay\Core\Exceptions\Server\Request\Invalid_Request_Parameter_Exception When you send incorrect request value via setters. @@ -1514,7 +1524,7 @@ public function process_payment_for_order( $cart, $payment_information, $schedul $intent_meta_order_id_raw = $intent->get_metadata()['order_id'] ?? ''; $intent_meta_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0; if ( $intent_meta_order_id !== $order_id ) { - throw new Intent_Authentication_Exception( + throw new Order_ID_Mismatch_Exception( sprintf( /* translators: %s: metadata. We do not need to translate WooPayMeta */ esc_html( __( 'We\'re not able to process this payment. Please try again later. WooPayMeta: intent_meta_order_id: %1$s, order_id: %2$s', 'woocommerce-payments' ) ), @@ -1625,7 +1635,7 @@ public function process_payment_for_order( $cart, $payment_information, $schedul $intent_meta_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0; if ( $intent_meta_order_id !== $order_id ) { - throw new Intent_Authentication_Exception( + throw new Order_ID_Mismatch_Exception( __( "We're not able to process this payment. Please try again later.", 'woocommerce-payments' ), 'order_id_mismatch' ); @@ -4487,6 +4497,7 @@ private function handle_afterpay_shipping_requirement( WC_Order $order, Create_A * @param Create_And_Confirm_Intention $request The request object for creating and confirming intention. * @param Payment_Information $payment_information The payment information object. * @param WC_Order $order The order object. + * @throws Invalid_Address_Exception * * @return void */ diff --git a/includes/class-wc-payments.php b/includes/class-wc-payments.php index c5445e2894a..a4923818438 100644 --- a/includes/class-wc-payments.php +++ b/includes/class-wc-payments.php @@ -428,7 +428,9 @@ public static function init() { include_once __DIR__ . '/exceptions/class-invalid-price-exception.php'; include_once __DIR__ . '/exceptions/class-fraud-ruleset-exception.php'; include_once __DIR__ . '/exceptions/class-fraud-prevention-enabled-exception.php'; + include_once __DIR__ . '/exceptions/class-new-process-payment-exception.php'; include_once __DIR__ . '/exceptions/class-order-not-found-exception.php'; + include_once __DIR__ . '/exceptions/class-order-id-mismatch-exception.php'; include_once __DIR__ . '/exceptions/class-rate-limiter-enabled-exception.php'; include_once __DIR__ . '/constants/class-base-constant.php'; include_once __DIR__ . '/constants/class-country-code.php'; diff --git a/includes/exceptions/class-new-process-payment-exception.php b/includes/exceptions/class-new-process-payment-exception.php new file mode 100644 index 00000000000..742c1415b98 --- /dev/null +++ b/includes/exceptions/class-new-process-payment-exception.php @@ -0,0 +1,16 @@ + { beforeAll( async () => { await merchant.login(); @@ -51,7 +49,7 @@ describe( 'Klarna checkout', () => { if ( element ) { element.click(); } - }, 'button[aria-label="Open Learn More Modal"]' ); + }, 'a[aria-label="Open Learn More Modal"]' ); // Wait for the iframe to be added by Stripe JS after clicking on the element. await page.waitFor( 1000 ); @@ -85,17 +83,23 @@ describe( 'Klarna checkout', () => { // https://docs.klarna.com/resources/test-environment/sample-customer-data/#united-states-of-america email: 'customer@email.us', phone: '+13106683312', + firstname: 'Test', + lastname: 'Person-us', }, [ [ 'Beanie', 3 ] ] ); await uiUnblocked(); - await page.waitForXPath( checkoutPaymentMethodSelector ); - const [ paymentMethodLabel ] = await page.$x( - checkoutPaymentMethodSelector - ); - await paymentMethodLabel.click(); + await page.evaluate( async () => { + const paymentMethodLabel = document.querySelector( + 'label[for="payment_method_woocommerce_payments_klarna"]' + ); + if ( paymentMethodLabel ) { + paymentMethodLabel.click(); + } + } ); + await shopper.placeOrder(); // Klarna is rendered in an iframe, so we need to get its reference. @@ -112,66 +116,64 @@ describe( 'Klarna checkout', () => { let klarnaIframe = await getNewKlarnaIframe(); const frameNavigationHandler = async ( frame ) => { - const newKlarnaIframe = await getNewKlarnaIframe(); - if ( frame === newKlarnaIframe ) { - klarnaIframe = newKlarnaIframe; + if ( frame.url().includes( 'klarna.com' ) ) { + const newKlarnaIframe = await getNewKlarnaIframe(); + + if ( frame === newKlarnaIframe ) { + klarnaIframe = newKlarnaIframe; + } } }; // Add frame navigation event listener. page.on( 'framenavigated', frameNavigationHandler ); - // waiting for the redirect & the Klarna iframe to load within the Stripe test page. + // Waiting for the redirect & the Klarna iframe to load within the Stripe test page. // this is the "confirm phone number" page - we just click "continue". - await klarnaIframe.waitForSelector( '#collectPhonePurchaseFlow' ); - ( - await klarnaIframe.waitForSelector( - '#onContinue[data-testid="kaf-button"]' - ) - ).click(); - // this is where the OTP code is entered. - await klarnaIframe.waitForSelector( '#phoneOtp' ); - await expect( klarnaIframe ).toFill( - '[data-testid="kaf-field"]', - '000000' - ); - - await klarnaIframe.waitForSelector( - 'button[data-testid="select-payment-category"' - ); + await klarnaIframe.waitForSelector( '#phone' ); + await klarnaIframe + .waitForSelector( '#onContinue' ) + .then( ( button ) => button.click() ); - await klarnaIframe.waitForSelector( '.skeleton-wrapper' ); - await klarnaIframe.waitFor( - () => ! document.querySelector( '.skeleton-wrapper' ) - ); + // This is where the OTP code is entered. + await klarnaIframe.waitForSelector( '#phoneOtp' ); + await expect( klarnaIframe ).toFill( 'input#otp_field', '123456' ); // Select Payment Plan - 4 weeks & click continue. await klarnaIframe - .waitForSelector( 'input[type="radio"][id*="pay_in_n"]' ) - .then( ( input ) => input.click() ); + .waitForSelector( 'button#pay_over_time__label' ) + .then( ( button ) => button.click() ); + + await page.waitFor( 2000 ); + await klarnaIframe .waitForSelector( 'button[data-testid="select-payment-category"' ) .then( ( button ) => button.click() ); + await page.waitFor( 2000 ); + // Payment summary page. Click continue. await klarnaIframe .waitForSelector( 'button[data-testid="pick-plan"]' ) .then( ( button ) => button.click() ); - // at this point, the event listener is not needed anymore. + await page.waitFor( 2000 ); + + // At this point, the event listener is not needed anymore. page.removeListener( 'framenavigated', frameNavigationHandler ); + await page.waitFor( 2000 ); + // Confirm payment. await klarnaIframe - .waitForSelector( - 'button[data-testid="confirm-and-pay"]:not(:disabled)' - ) + .waitForSelector( 'button#buy_button' ) .then( ( button ) => button.click() ); // Wait for the order confirmation page to load. await page.waitForNavigation( { waitUntil: 'networkidle0', } ); + await expect( page ).toMatch( 'Order received' ); } ); } ); diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay.php b/tests/unit/test-class-wc-payment-gateway-wcpay.php index 0628ec6384d..e39a0c73b91 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay.php @@ -22,10 +22,12 @@ use WCPay\Exceptions\API_Exception; use WCPay\Exceptions\Fraud_Prevention_Enabled_Exception; use WCPay\Exceptions\Process_Payment_Exception; +use WCPay\Exceptions\Order_ID_Mismatch_Exception; use WCPay\Fraud_Prevention\Fraud_Prevention_Service; use WCPay\Internal\Payment\Factor; use WCPay\Internal\Payment\Router; use WCPay\Internal\Payment\State\CompletedState; +use WCPay\Internal\Payment\State\PaymentErrorState; use WCPay\Internal\Service\Level3Service; use WCPay\Internal\Service\OrderService; use WCPay\Internal\Service\PaymentProcessingService; @@ -2559,6 +2561,31 @@ public function test_process_payment_for_order_rejects_with_cached_minimum_amoun $this->card_gateway->process_payment_for_order( WC()->cart, $pi ); } + public function test_process_payment_for_order_rejects_with_order_id_mismatch() { + $order = WC_Helper_Order::create_order(); + $intent_meta_order_id = 0; + $woopay_intent_id = 'woopay_invalid_intent_id_mock'; + $payment_intent = WC_Helper_Intention::create_intention( + [ + 'status' => 'success', + 'metadata' => [ 'order_id' => (string) $intent_meta_order_id ], + ] + ); + + $_POST['platform-checkout-intent'] = $woopay_intent_id; + + $payment_information = new Payment_Information( 'pm_test', $order, null, null, null, null, null, '', 'card' ); + + $this->mock_wcpay_request( Get_Intention::class, 1, $woopay_intent_id ) + ->expects( $this->once() ) + ->method( 'format_response' ) + ->willReturn( $payment_intent ); + + $this->expectException( 'WCPay\Exceptions\Order_ID_Mismatch_Exception' ); + $this->expectExceptionMessage( 'We're not able to process this payment. Please try again later. WooPayMeta: intent_meta_order_id: ' . $intent_meta_order_id . ', order_id: ' . $order->get_id() ); + $this->card_gateway->process_payment_for_order( WC()->cart, $payment_information ); + } + public function test_set_mandate_data_to_payment_intent_if_not_required() { $payment_method = 'woocommerce_payments_sepa_debit'; $order = WC_Helper_Order::create_order(); @@ -3635,6 +3662,34 @@ public function test_new_process_payment() { ); } + public function test_new_process_payment_throw_exception() { + // The new payment process is only accessible in dev mode. + WC_Payments::mode()->dev(); + + $mock_service = $this->createMock( PaymentProcessingService::class ); + $mock_router = $this->createMock( Router::class ); + $order = WC_Helper_Order::create_order(); + $mock_state = $this->createMock( PaymentErrorState::class ); + + wcpay_get_test_container()->replace( PaymentProcessingService::class, $mock_service ); + wcpay_get_test_container()->replace( Router::class, $mock_router ); + + $mock_router->expects( $this->once() ) + ->method( 'should_use_new_payment_process' ) + ->willReturn( true ); + + // Assert: The new service is called. + $mock_service->expects( $this->once() ) + ->method( 'process_payment' ) + ->with( $order->get_id() ) + ->willReturn( $mock_state ); + + $this->expectException( Exception::class ); + $this->expectExceptionMessage( 'The payment process could not be completed.' ); + + $this->card_gateway->process_payment( $order->get_id() ); + } + public function test_process_payment_rate_limiter_enabled_throw_exception() { $order = WC_Helper_Order::create_order(); diff --git a/woocommerce-payments.php b/woocommerce-payments.php index f6c14d6d5c3..cdb84deb13a 100644 --- a/woocommerce-payments.php +++ b/woocommerce-payments.php @@ -8,10 +8,10 @@ * Text Domain: woocommerce-payments * Domain Path: /languages * WC requires at least: 7.6 - * WC tested up to: 8.7.0 + * WC tested up to: 8.9.1 * Requires at least: 6.0 * Requires PHP: 7.3 - * Version: 7.6.0 + * Version: 7.7.0 * Requires Plugins: woocommerce * * @package WooCommerce\Payments