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

Check intent attached to order before processing payment #5346

Merged
merged 20 commits into from
Jan 6, 2023

Conversation

htdat
Copy link
Member

@htdat htdat commented Dec 29, 2022

Fixes #5187

Changes proposed in this Pull Request

  • Check the status of attached intent during the payment processing.
  • Mark the order successful if the intent is one of successful statuses, and redirect customers to the order-received of this order.

Testing instructions

Prep

Start

Screenshot:
Markup on 2023-01-06 at 17:35:02


  • 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

@github-actions
Copy link
Contributor

github-actions bot commented Dec 29, 2022

Size Change: +112 B (0%)

Total Size: 1.14 MB

Filename Size Change
release/woocommerce-payments/dist/blocks-checkout.js 36.9 kB +16 B (0%)
release/woocommerce-payments/dist/checkout.js 27.8 kB +15 B (0%)
release/woocommerce-payments/dist/payment-request.js 11.7 kB +21 B (0%)
release/woocommerce-payments/dist/platform-checkout-express-button.js 13.4 kB +21 B (0%)
release/woocommerce-payments/dist/upe_checkout.js 32.7 kB +22 B (0%)
release/woocommerce-payments/dist/upe-blocks-checkout.js 38.8 kB +17 B (0%)
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 913 B
release/woocommerce-payments/assets/css/success.css 401 B
release/woocommerce-payments/dist/blocks-checkout.css 2.13 kB
release/woocommerce-payments/dist/checkout.css 2.21 kB
release/woocommerce-payments/dist/index.css 36 kB
release/woocommerce-payments/dist/index.js 307 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 771 B
release/woocommerce-payments/dist/multi-currency-switcher-block.js 56.2 kB
release/woocommerce-payments/dist/multi-currency.css 14.7 kB
release/woocommerce-payments/dist/multi-currency.js 72.6 kB
release/woocommerce-payments/dist/order.css 248 B
release/woocommerce-payments/dist/order.js 12.4 kB
release/woocommerce-payments/dist/payment-gateways.css 1.2 kB
release/woocommerce-payments/dist/payment-gateways.js 47 kB
release/woocommerce-payments/dist/platform-checkout.css 4.02 kB
release/woocommerce-payments/dist/platform-checkout.js 75.1 kB
release/woocommerce-payments/dist/settings.css 47.4 kB
release/woocommerce-payments/dist/settings.js 112 kB
release/woocommerce-payments/dist/subscription-edit-page.js 392 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 7.18 kB
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 12.6 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 434 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 298 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 44.1 kB
release/woocommerce-payments/dist/tos.css 236 B
release/woocommerce-payments/dist/tos.js 15.5 kB
release/woocommerce-payments/dist/upe_checkout.css 2.21 kB
release/woocommerce-payments/dist/upe-blocks-checkout.css 2.13 kB
release/woocommerce-payments/includes/platform-checkout/assets/css/platform-checkout-express-button.css 247 B
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 633 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 720 B
release/woocommerce-payments/vendor/automattic/jetpack-admin-ui/src/css/jetpack-icon.css 224 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-identity-crisis/babel.config.js 160 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.css 2.27 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.js 13.3 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.rtl.css 2.27 kB
release/woocommerce-payments/vendor/automattic/jetpack-tracking/src/js/tracks-ajax.js 789 B
release/woocommerce-payments/vendor/automattic/jetpack-tracking/src/js/tracks-callables.js 925 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.2 kB
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.43 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 8.97 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.35 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 387 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.06 kB

compressed-size-action

- Update the main gateway to try reusing the attached intent_id
- Change from create_and_confirm_intention
to create_or_update_intention_with_confirmation: Support a new parameter $intent_id, add one more test.
- Update to re-use the valid attached intent_id for UPE_Payment_Gateway
- Update from handlePreviousOrderPaid to handleDuplicatePayments
- Add redirection for wcpay_upe_previous_successful_intent
@htdat htdat force-pushed the add/check-intent-attached-to-order-before-payment branch from 8706dda to 08b841d Compare December 30, 2022 18:46
@htdat htdat marked this pull request as ready for review December 31, 2022 11:22
@htdat htdat requested review from RadoslavGeorgiev and a team December 31, 2022 11:22
@htdat
Copy link
Member Author

htdat commented Jan 3, 2023

FYI. I am still looking into this E2E test failure, which seems consistent:

FAIL tests/e2e/specs/subscriptions/shopper/shopper-subscriptions-manage-payments.spec.js (125.827s)
Shopper > Subscriptions > Manage Payment Methods
✓ should be able to purchase a subscription (13312ms)
✓ should change a default payment method to a new one (8541ms)
✕ should set a payment method to an already saved card (100007ms)

Update

This is debug.log from the E2E run above.

[03-Jan-2023 06:10:49 UTC] PHP Fatal error: Uncaught Exception: Error: No route was found matching the URL and request method. in /var/www/html/wp-content/plugins/woocommerce-payments/includes/class-wc-payment-gateway-wcpay.php:797
Stack trace:
#0 /var/www/html/wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-change-payment-gateway.php(334): WC_Payment_Gateway_WCPay->process_payment(93)

This error happens when a customer is trying to change a subscription (not order, its post type is shop_subscription in wp_posts) from the current payment method to another existing payment.

With a subscription, we're saving a setup intent (starting with seti_) as order meta _intent_id. Without checking this fact, we will send a GET request for a setup intention to the payment intention endpoint.

$intent = $this->payments_api_client->get_intent( $intent_id );

I fixed it in this commit by checking intent ID prefix before processing further. f3f7b5e

client/checkout/api/index.js Outdated Show resolved Hide resolved
includes/class-wc-payment-gateway-wcpay.php Outdated Show resolved Hide resolved
Copy link
Contributor

@RadoslavGeorgiev RadoslavGeorgiev left a comment

Choose a reason for hiding this comment

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

Code goods very well overall, a couple of nitpicks, but the approach seems bulletproof 🥳

Just curious, are you planning to move the saving/storage of intents closer to API calls in a different PR?

@htdat
Copy link
Member Author

htdat commented Jan 4, 2023

Thanks for the awesome feedback!

@RadoslavGeorgiev - I've addressed your comments, and accepted all of them. This PR is ready for review again.

Regarding:

Just curious, are you planning to move the saving/storage of intents closer to API calls in a different PR?

Good question but I would have mentioned earlier. In UPE gateway, attach_intent_info_to_order in process_payment and process_redirect_payment has already been close to the API calls

For the main gateway, in this attach method is also already close to the API call in update_order_status already.

The only remaining attach method in process_payment_for_order of the main gateway can be moved earlier, right after create_and_confirm_intention. However, reviewing all the complex code between the current position and the potential earlier position, I think it's acceptable to keep it in the current position. Otherwise, there are some pitfalls:

  • In many cases, we still need to call this attach method in the same position, then that's double database update calls.
  • The code block between this method and two other methods update_order_status_from_intent and attach_exchange_info_to_order will be separated while they would be close to each other.

@htdat
Copy link
Member Author

htdat commented Jan 4, 2023

E2E Tests - Pull Request / WC - latest | blocks - shopper (pull_request) - Details

This E2E test failure is similar to a recent scheduled E2E run for the develop branch - E2E Tests - All.

@htdat
Copy link
Member Author

htdat commented Jan 4, 2023

E2E Tests - Pull Request / WC - latest | blocks - shopper (pull_request) - Details

This E2E test failure is similar to a recent scheduled E2E run for the develop branch - E2E Tests - All.

Update: Discussion regarding this: p1672840161807159-slack-C04D1QU76PK

Copy link
Contributor

@RadoslavGeorgiev RadoslavGeorgiev left a comment

Choose a reason for hiding this comment

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

The code looks and works great 🥳 🚢

I've tested:

  • UPE & non-UPE
  • Blocks vs classic
  • 3DS vs non-3DS. When testing with a 3DS card, I let it fail and then switched to 4242 to make sure the original payment method remains.

In many cases, we still need to call this attach method in the same position, then that's double database update calls.

I think it's still worth simply storing the intent ID as early as possible. $order->update_meta_data() does not trigger a database update call by itself, that only happens when $order->save() or $order->save_meta_data() is called. Those would be called before marking the order as failed anyway, so adding a single update method call after the API call would make a lot of sense without any practical overhead. I'll leave that up to you though, the PR is approved anyway :)

@htdat htdat merged commit 71f5db5 into develop Jan 6, 2023
@htdat htdat deleted the add/check-intent-attached-to-order-before-payment branch January 6, 2023 09:50
@htdat htdat changed the title Add/check intent attached to order before payment Check intent attached to order before processing payment Jan 6, 2023
@jessy-p jessy-p mentioned this pull request Jul 5, 2023
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix Duplicate Charges: Store intent IDs whenever possible, check status
2 participants