Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid WooPay duplicate charges when order cannot be completely processed #7968

Merged
merged 2 commits into from
Jan 4, 2024

Conversation

cesarcosta99
Copy link
Contributor

Fixes https://github.com/Automattic/woopay/issues/2199

Changes proposed in this Pull Request

Adds a check for WooPay orders in the duplicate payment prevention service. This check is needed because the WooPay order IDs doesn't match the order ID in the context, but the order number instead.

See https://github.com/Automattic/woopay/issues/2199 and https://github.com/Automattic/woopay/pull/2408 for more context.

Testing instructions

Pre-requisite

You will need to apply these changes directly to WooPay in docker/wordpress/wp-content/plugins/woocommerce-payments/includes/class-duplicate-payment-prevention-service.php. Building the plugin is not an alternative because the WCPay version on WooPay is different and that might break things.

Tests

Run the same tests described in https://github.com/Automattic/woopay/pull/2408, including the pre-requisite.

The only difference is in the last three steps of the Test: the fix prevent duplicate charges, which should be

  1. You should see an error alert saying "Merchant store order creation failed with the following error: We're not able to process this payment. Please try again later.".
  2. Go to the merchant site WP Admin and confirm a new order has been created. This new order should have a failed charge attempt and order status Failed.
  3. Go to the WooPay WP Admin and confirm two things: a) there's no new order, only the one created in step 3, and b) this order was updated, but it's still with status Failed and with just a single charge.

  • Run npm run changelog to add a changelog file, choose patch to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

@cesarcosta99 cesarcosta99 requested review from a team and lovo-h and removed request for a team January 3, 2024 18:08
@botwoo
Copy link
Collaborator

botwoo commented Jan 3, 2024

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 7968 or branch name fix/2199-woopay-duplicate-payments in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments

Option 2. Jurassic Ninja - available for logged-in A12s

🚀 Launch a JN site with this branch 🚀

ℹ️ Install this Tampermonkey script to get more options.


Build info:

  • Latest commit: d10e238
  • Build time: 2024-01-03 18:11:17 UTC

Note: the build is updated when a new commit is pushed to this PR.

Copy link
Contributor

github-actions bot commented Jan 3, 2024

Size Change: 0 B

Total Size: 1.27 MB

ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.06 kB
release/woocommerce-payments/assets/css/success.css 158 B
release/woocommerce-payments/dist/blocks-checkout-rtl.css 1.8 kB
release/woocommerce-payments/dist/blocks-checkout.css 1.8 kB
release/woocommerce-payments/dist/blocks-checkout.js 85.5 kB
release/woocommerce-payments/dist/checkout-rtl.css 318 B
release/woocommerce-payments/dist/checkout.css 319 B
release/woocommerce-payments/dist/checkout.js 37 kB
release/woocommerce-payments/dist/index-rtl.css 37.8 kB
release/woocommerce-payments/dist/index.css 37.9 kB
release/woocommerce-payments/dist/index.js 289 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.05 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 3.4 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 60.7 kB
release/woocommerce-payments/dist/multi-currency.css 3.4 kB
release/woocommerce-payments/dist/multi-currency.js 55.9 kB
release/woocommerce-payments/dist/order-rtl.css 676 B
release/woocommerce-payments/dist/order.css 679 B
release/woocommerce-payments/dist/order.js 42.3 kB
release/woocommerce-payments/dist/payment-gateways-rtl.css 1.31 kB
release/woocommerce-payments/dist/payment-gateways.css 1.31 kB
release/woocommerce-payments/dist/payment-gateways.js 39.5 kB
release/woocommerce-payments/dist/payment-request-rtl.css 153 B
release/woocommerce-payments/dist/payment-request.css 153 B
release/woocommerce-payments/dist/payment-request.js 13.4 kB
release/woocommerce-payments/dist/product-details.js 919 B
release/woocommerce-payments/dist/settings-rtl.css 10.4 kB
release/woocommerce-payments/dist/settings.css 10.4 kB
release/woocommerce-payments/dist/settings.js 234 kB
release/woocommerce-payments/dist/subscription-edit-page.js 669 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 519 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 519 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 20.5 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 710 B
release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css 117 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 117 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 19.6 kB
release/woocommerce-payments/dist/tos-rtl.css 230 B
release/woocommerce-payments/dist/tos.css 231 B
release/woocommerce-payments/dist/tos.js 22 kB
release/woocommerce-payments/dist/woopay-express-button-rtl.css 153 B
release/woocommerce-payments/dist/woopay-express-button.css 153 B
release/woocommerce-payments/dist/woopay-express-button.js 52.5 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.18 kB
release/woocommerce-payments/dist/woopay.css 4.19 kB
release/woocommerce-payments/dist/woopay.js 71.9 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 622 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 812 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.43 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.01 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 522 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 581 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/babel.config.js 160 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.css 2.32 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.js 13.8 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.rtl.css 2.32 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.03 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 291 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 403 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.6 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 299 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 742 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 572 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 411 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 544 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.4 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.8 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.83 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 544 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.52 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.6 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 502 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 355 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 429 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 781 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.27 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 392 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.05 kB

compressed-size-action

Copy link
Contributor

@lovo-h lovo-h left a comment

Choose a reason for hiding this comment

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

Code changes look good and work as intended. I left some comments but they were mainly suggestions.

These changes fix the "prevent the customer from being charged twice", as requested in
2199-gh-Automattic/woopay. But it may leave the customer believing that the order did not go through.

With this fix, we prevent the customer from being charged twice for the same order in WooPay. However, since the customer might believe that the order did not go through, there's a chance that the shopper might attempt to checkout through the merchant site.

I noticed we intend to create an issue (2199-gh-Automattic/woopay#issuecomment-1866910080) to fill the remaining gap.

Testing Instructions

  • ✅ Test: reproduce the issue.
  • ✅ Test: the fix prevents duplicate charges.
  • ✅ Fixes Automattic/woopay#2199.

Comment on lines +105 to +111
$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;
$intent_meta_order_number_raw = $intent->get_metadata()['order_number'] ?? '';
$intent_meta_order_number = is_numeric( $intent_meta_order_number_raw ) ? intval( $intent_meta_order_number_raw ) : 0;
$paid_on_woopay = filter_var( $intent->get_metadata()['paid_on_woopay'] ?? false, FILTER_VALIDATE_BOOLEAN );
$is_woopay_order = $order->get_id() === $intent_meta_order_number;
if ( ! ( $paid_on_woopay && $is_woopay_order ) && $intent_meta_order_id !== $order->get_id() ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: No changes are necessary but what do you think about renaming the variables as follows:

Suggested change
$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;
$intent_meta_order_number_raw = $intent->get_metadata()['order_number'] ?? '';
$intent_meta_order_number = is_numeric( $intent_meta_order_number_raw ) ? intval( $intent_meta_order_number_raw ) : 0;
$paid_on_woopay = filter_var( $intent->get_metadata()['paid_on_woopay'] ?? false, FILTER_VALIDATE_BOOLEAN );
$is_woopay_order = $order->get_id() === $intent_meta_order_number;
if ( ! ( $paid_on_woopay && $is_woopay_order ) && $intent_meta_order_id !== $order->get_id() ) {
$intent_meta_order_id_raw = $intent->get_metadata()['order_id'] ?? '';
$intent_meta_merchant_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0;
$intent_meta_order_number_raw = $intent->get_metadata()['order_number'] ?? '';
$intent_meta_woopay_order_id = is_numeric( $intent_meta_order_number_raw ) ? intval( $intent_meta_order_number_raw ) : 0;
$paid_on_woopay = filter_var( $intent->get_metadata()['paid_on_woopay'] ?? false, FILTER_VALIDATE_BOOLEAN );
$is_woopay_order = $order->get_id() === $intent_meta_woopay_order_id;
$is_merchant_order = $intent_meta_merchant_order_id === $order->get_id();
if ( ! ( $paid_on_woopay && $is_woopay_order ) && ! $is_merchant_order ) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this renaming is beneficial because depending on the context we're analyzing the intent order ID may belong to WooPay order instead of the merchant's, and that may cause confusion. I only named is_woopay_order like that because it seems the order_number was created especially to distinguish WooPay orders and merchant orders.

Type: fix
Comment: Fix WooPay duplicate charges.


Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Remove the additional empty line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is automatically generated and will be removed in the release process, so that's fine 🙂

@cesarcosta99
Copy link
Contributor Author

I'm going ahead and adding this to the merge queue. The e2e test check failure is unrelated to this PR.

@cesarcosta99 cesarcosta99 added this pull request to the merge queue Jan 4, 2024
Merged via the queue into develop with commit 9e30129 Jan 4, 2024
27 of 28 checks passed
@cesarcosta99 cesarcosta99 deleted the fix/2199-woopay-duplicate-payments branch January 4, 2024 21:25
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