Skip to content

Commit 61fbf30

Browse files
authored
Fix UPE payment webhook race condition (#2540)
* Fix race condition when paying via UPE Both the webhook processing and the UPE redirect processing call the `process_response` function which marks the payment as completed. This will cause the UPE redirect processing to fail due to the order status if the webhook is processed before the customer is redirected, e.g. when the customer is on a slow network connection. This commit fixes that by adding metadata to the order that the webhook controller can check for before processing the webhook.
1 parent 628550f commit 61fbf30

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
= 7.1.0 - 2023-xx-xx =
44
* Fix - Replace some post meta methods with equivalent methods compatible with HPOS.
5+
* Fix - Rare cases of payment processing failing when webhooks arrive before customer is redirected when UPE is enabled will no longer occur.
56

67
= 7.0.2 - 2023-01-11 =
78
* Fix - Expand charges object from incoming webhooks using Stripe API version 2022-11-15.

includes/class-wc-stripe-webhook-handler.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,14 @@ public function process_payment_intent_success( $notification ) {
871871

872872
WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id succeeded for order $order_id" );
873873

874+
// TODO: This is a stop-gap to fix a critical issue, see
875+
// https://github.com/woocommerce/woocommerce-gateway-stripe/issues/2536. It would
876+
// be better if we removed the need for additional meta data in favor of refactoring
877+
// this part of the payment processing.
878+
if ( $order->get_meta( '_stripe_upe_waiting_for_redirect' ) ?? false ) {
879+
return;
880+
}
881+
874882
do_action( 'wc_gateway_stripe_process_payment', $charge, $order );
875883

876884
// Process valid response.

includes/payment-methods/class-wc-stripe-upe-payment-gateway.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,13 @@ public function process_payment( $order_id, $retry = true, $force_save_source =
575575
WC_Stripe_Helper::add_payment_intent_to_order( $payment_intent_id, $order );
576576
$order->update_status( 'pending', __( 'Awaiting payment.', 'woocommerce-gateway-stripe' ) );
577577
$order->update_meta_data( '_stripe_upe_payment_type', $selected_upe_payment_type );
578+
579+
// TODO: This is a stop-gap to fix a critical issue, see
580+
// https://github.com/woocommerce/woocommerce-gateway-stripe/issues/2536. It would
581+
// be better if we removed the need for additional meta data in favor of refactoring
582+
// this part of the payment processing.
583+
$order->update_meta_data( '_stripe_upe_waiting_for_redirect', true );
584+
578585
$order->save();
579586

580587
$this->stripe_request(
@@ -943,6 +950,13 @@ public function process_order_for_confirmed_intent( $order, $intent_id, $save_pa
943950
$this->save_intent_to_order( $order, $intent );
944951
$this->set_payment_method_title_for_order( $order, $payment_method_type );
945952
$order->update_meta_data( '_stripe_upe_redirect_processed', true );
953+
954+
// TODO: This is a stop-gap to fix a critical issue, see
955+
// https://github.com/woocommerce/woocommerce-gateway-stripe/issues/2536. It would
956+
// be better if we removed the need for additional meta data in favor of refactoring
957+
// this part of the payment processing.
958+
$order->delete_meta_data( '_stripe_upe_waiting_for_redirect' );
959+
946960
$order->save();
947961
}
948962

tests/phpunit/test-class-wc-stripe-upe-payment-gateway.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ public function test_process_payment_returns_valid_response() {
239239

240240
$order->update_meta_data( '_stripe_intent_id', $payment_intent_id );
241241
$order->update_meta_data( '_stripe_upe_payment_type', '' );
242+
$order->update_meta_data( '_stripe_upe_waiting_for_redirect', true );
242243
$order->save();
243244

244245
list( $amount, $description, $metadata ) = $this->get_order_details( $order );
@@ -1038,6 +1039,7 @@ public function test_if_order_has_subscription_payment_method_will_be_saved() {
10381039

10391040
$order->update_meta_data( '_stripe_intent_id', $payment_intent_id );
10401041
$order->update_meta_data( '_stripe_upe_payment_type', '' );
1042+
$order->update_meta_data( '_stripe_upe_waiting_for_redirect', true );
10411043
$order->save();
10421044

10431045
list( $amount, $description, $metadata ) = $this->get_order_details( $order );

0 commit comments

Comments
 (0)