woocommerce / woocommerce-gateway-stripe

The official Stripe Payment Gateway for WooCommerce
https://wordpress.org/plugins/woocommerce-gateway-stripe/
229 stars 197 forks source link

Defer webhook processing when a webhook is received but we're expecting a UPE redirect #3217

Closed james-allan closed 1 week ago

james-allan commented 1 week ago

Fixes #3192

Changes proposed in this Pull Request:

We've had reports from a number of merchants experiencing an issue where orders are being left as pending-payment. After investigating, it turns out the issue is that successful webhooks are being received but are being skipped with the Stripe log entry:

"Stripe UPE waiting for redirect. The status for order {$order_id} might need manual adjustment."

I haven't been able to fully understand what causes this myself, however, what we do know is that this impacts payment methods like P24, iDEAL etc where the customer is redirected offsite and redirected back to the site where we'd process the payment via args in redirect URL.

I suspect what is happening is:

  1. The customer isn't being redirected by their bank. These payment methods integrate with a number of banking institutes across Europe and so any one of them could have a different flow that doesn't end in them being redirected back.
  2. Similar to above, if the process of completing the payment has the customer use their mobile, the redirect that eventually occurs may be invalid because the nonce in the URL is only valid for the logged in user session on the original device.
  3. Any another reason the URL redirect may be invalid.

This PR fixes this by making sure we process the successful webhook, but we wait at least 2 minutes to allow a potential redirect to occur. Given the successful payment webhook has been received, 2 minutes should be more than enough time for the redirect to occur if it's going to. We could adjust this if we want to give more or less time.

Testing instructions

Reproducing the bug

  1. Make sure you have webhooks set up and your store is publicly accessible so they can be processed. ie use a JN site or ngrok.
  2. Set your Stripe plugin API credentials to a EU account.
  3. Set your store currency to EUR.
  4. Enable a payment method with a redirect involved eg Przelewy24, iDEAL, EPS, giropay etc.
  5. Add a product to your cart.
  6. On checkout select the redirect payment method.
  7. Once you're at the Stripe site where you can choose to authorize or deny the payment, copy the URL.
  8. Put that url into your mobile device to simulate the customer using a different device to complete the payment.
  9. Click "Authorize payment" on your phone.
  10. Go back to your browser and open up the order list table in WP admin.
  11. Notice the order is set to pending payment.
  12. View the Stripe logs and you should see the Stripe UPE waiting for redirect. The status for order 7674 might need manual adjustment. message.

Confirm the fix

  1. Checkout this branch.
  2. Repeat the steps above.
  3. At step 11 you will see a slightly different log entry: Stripe UPE waiting for redirect. Scheduled deferred webhook processing. The status for order 7675 might need manual adjustment.
  4. Go to WooCommerce → Status → Scheduled actions (tab).
  5. Search for wc_stripe_deferred_webhook.
  6. You should see a pending scheduled action for the order.

    Screenshot 2024-06-24 at 4 49 36 PM

  7. Wait the 2 minutes or manually run the action.
  8. When that action runs, the order should be processing.

Post merge

james-allan commented 1 week ago

❓ Is scheduling an action in the following cases something we'd like to avoid? Using authorize and capture. Using a 3DS card and authorizing the transaction.

Yeah good question. Can you explain how you tested this with Cards? Because cards respond instantly I wasn't able to simulate a situation where the webhook was skipped.

a-danae commented 1 week ago

Can you explain how you tested this with Cards?

Using a non-saved 3DS card scheduled the action for me. This is what I did:

Using authorize and capture

Btw, scratch this one. I was trying again with authorize and capture and wasn't able to replicate the behavior here.

stevenolsthoorn commented 1 week ago

Are these issues expected to be solved in the next plugin update? When can that be expected?

james-allan commented 4 days ago

Are these issues expected to be solved in the next plugin update

Yes, this should be fixed in the next version of WooCommerce Stripe which is scheduled for July 11.