Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
173 stars 69 forks source link

Trying to check out a "stock: 1" product fails with WooPay #7256

Closed ncsramona closed 10 months ago

ncsramona commented 1 year ago

Describe the bug

When a product that has the stock level set to 1 is in the cart and I try to checkout with WooPay, I get the "WooPay is unavailable at this time. Sorry for the inconvenience." message on the Cart page. image

To Reproduce

  1. Create a product that has Stock 1 set
  2. Add this product to the cart
  3. Try to pay for it with WooPay from the cart

Actual behavior

Instead of redirecting to WooPay's checkout page, I'm getting errors.

Cart page "WooPay is unavailable at this time. Sorry for the inconvenience." message on the Cart page. image Video: https://github.com/Automattic/woocommerce-payments/assets/133644769/6192fd5b-5a2b-41f3-a955-2575f9aa3b12

Checkout page Going to the Checkout page sometimes I get an error: "There are some issues with the items in your cart. Please go back to the cart page and resolve these issues before checking out." image Going back to the cart I can see a new message now: "Sorry, we do not have enough “Stock 1” in stock to fulfill your order (0 available). We apologize for any inconvenience caused" image However, no purchase was made and the cart page before said there's 1 in stock. (The stock level is not actually reduced, but it seems like it is.)

Other times the same error is present what's on the Cart page.

Expected behavior

I should be redirected to the WooPay checkout page to pay.

Desktop:

Additional context

Occurs at #7046997-zen

csmcneill commented 1 year ago

I can reproduce this, albeit inconsistently:

5PpPfe.png

However, the stock is not actually reduced to 0 on my site:

9TWICu.png

ncsramona commented 1 year ago

Sorry for the confusion! The stock level is indeed not reduced, but WooPay thinks it was. Not sure, why.

zmaglica commented 1 year ago

This issue impacts WooPay, so assigning to team Heisenberg (based on team responsibilities Pc2DNy-3z-p2) @frosso . Assigning as part of Gamma Triage process PcreKM-yM-p2.

c-shultz commented 1 year ago

@bborman22 can we check if https://github.com/Automattic/woocommerce-payments/pull/7215 fixes this?

bborman22 commented 1 year ago

This issue is very closely related to #7257. Similarly #7215 does not fix this issue. Somewhere within the WooPay set up, it seems to set an error about inventory on the cart data that doesn't get cleared. This causes the WooPay initialization to fail and will also cause the checkout error mentioned in the issue to display.

mouligreenlaw commented 12 months ago

Hi there! I commented similarly on https://github.com/Automattic/woocommerce-payments/issues/7257

This ticket came back in the queue (7046997-zen) and and we haven't responded to them in 2 weeks I thought we should give them something. Are there any updates to this issue? Many thanks.

jacoswan commented 11 months ago

Possibly also in 7246304-zen and 7263084-zen, both have WooPayments active.

7263084-zen confirmed, when disabling WCP it resolves the issue.

While the merchants can reliably reproduce the issues, I have not been able to reproduce it at all.

gpressutto5 commented 11 months ago

As Brian said, this issue is close to #7215, but the solutions differ. The main difference is that in #7215, the stock is being updated incorrectly due to the number of times we hold the stock in the draft order that is created for WooPay, but here the problem is the draft order being created in the first place. This issue is caused by the combination of two features merged together: the Cached Requests (Automattic/woopay#1979) and the session requests combination (Automattic/woopay#2000).

When we preload the checkout response to pass to WooPay, it creates a draft order. This request is also preloaded by default by the Blocks checkout, but the regular checkout does not use the draft order id. Instead, it will try to create a new one, and that's why it fails.

I tested some different scenarios to understand how the draft orders are generated and discovered they one of them is created when the button is displayed, and another when a registered email address is verified from the input. When either draft order is created, the merchant checkout page will not place the order because it is reserved for someone else, in this case, WooPay. When only one draft order is created (meaning the button was not displayed or no registered email were typed in the email field), paying with WooPay will work. When 2 draft orders are created, it will always fail.

  1. When WooPay is disabled it always works. ✅ (no draft order)
  2. When WooPay is enabled:
    1. Using the button from the cart page always works. ✅ (1 draft order with 2 stock hold notes)
    2. Going directly to the checkout page with the WooPay button on checkout enabled does not work. ❌ (1 draft order with 1 note + 1 draft order with no notes and 2 shipped packages)
    3. Going directly to the checkout page with the WooPay button on checkout disabled, while logged in to WooPay and getting redirected to WooPay works. ✅ (1 draft order with 1 note)
    4. Going directly to the checkout page with the WooPay button on checkout disabled, while logged in to WooPay but canceling the redirection to WooPay fails. ❌ (1 draft order with 1 note + 1 draft order with no notes)
    5. Going directly to the checkout page with the WooPay button on checkout disabled, while logged out from WooPay and using an email that is not registered on WooPay works. ✅ (no draft order is created)
    6. Going directly to the checkout page with the WooPay button on checkout enabled, while logged out from WooPay and using an email that is not registered on WooPay fails. ❌ (1 draft order with 1 note)
    7. Going to the cart page, where the WooPay button is enabled, before going to the checkout page, where the WooPay button is disabled always fails. ❌ (1 draft order is created as soon as the cart page loads and the checkout page shows an error)

I'm now trying to find a better timing for the generation of the preloaded request, so only one draft order is created and only when the user is being redirected, but this will not fix this issue when the user cancels the redirection or when they choose to go back to the Merchant checkout. These 2 cases will need to be handled separately.


As a quick temporary fix, we could disable the checkout request preloading. This would require minor changes in WooPayments and WooPay, but it would significantly affect WooPay's TTL.

gpressutto5 commented 10 months ago

Correction: this is caused by the session data prefetch (Automattic/woocommerce-payments#7199), in addition to the other two mentioned features.