-
Notifications
You must be signed in to change notification settings - Fork 69
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
Resolve renewal failures for subscription orders with the UPE #6965
Changes from 8 commits
68a8fa0
dda322b
48dbfa8
10ac3e7
d18663f
8a86452
40fa9cc
476d104
1465f1a
178d076
08e0daa
4061bb7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: fix | ||
|
||
Fixes subscription renewals with the UPE enabled. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1084,7 +1084,7 @@ public function process_payment_for_order( $cart, $payment_information, $schedul | |
throw new Exception( WC_Payments_Utils::get_filtered_error_message( $e ) ); | ||
} | ||
|
||
$payment_methods = $this->get_payment_methods_from_request(); | ||
$payment_methods = $this->get_payment_method_types( $payment_information ); | ||
// The sanitize_user call here is deliberate: it seems the most appropriate sanitization function | ||
// for a string that will only contain latin alphanumeric characters and underscores. | ||
// phpcs:ignore WordPress.Security.NonceVerification.Missing | ||
|
@@ -1231,7 +1231,7 @@ public function process_payment_for_order( $cart, $payment_information, $schedul | |
Payment_Method::CARD === $this->get_selected_stripe_payment_type_id() && | ||
in_array( Payment_Method::LINK, $this->get_upe_enabled_payment_method_ids(), true ) | ||
) { | ||
$request->set_payment_method_types( $this->get_payment_methods_from_request() ); | ||
$request->set_payment_method_types( $this->get_payment_method_types( $payment_information ) ); | ||
$request->set_mandate_data( $this->get_mandate_data() ); | ||
} | ||
|
||
|
@@ -1375,28 +1375,52 @@ public function process_payment_for_order( $cart, $payment_information, $schedul | |
*/ | ||
public function get_payment_method_to_use_for_intent() { | ||
if ( WC_Payments_Features::is_upe_deferred_intent_enabled() ) { | ||
return $this->get_payment_methods_from_request()[0]; | ||
$request_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification | ||
return $this->get_payment_methods_from_gateway_id( $request_payment_method )[0]; | ||
} | ||
} | ||
|
||
/** | ||
* Get the payment methods used in the request. | ||
* Get payment method types to attach to intention request. | ||
* | ||
* @param Payment_Information $payment_information Payment information object for transaction. | ||
* @return array List of payment methods. | ||
*/ | ||
private function get_payment_methods_from_request() { | ||
$upe_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification | ||
public function get_payment_method_types( $payment_information ) { | ||
$request_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naming proposal: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense--added in 178d076. |
||
$token = $payment_information->get_payment_token(); | ||
|
||
if ( ! empty( $request_payment_method ) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we prioritize posted PM over token? Can we add a comment explaining the order in which are trying to pick PMs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm basically prioritising checkout transactions over subscription renewals, since I believe the former will be more common: explained over here. |
||
$payment_methods = $this->get_payment_methods_from_gateway_id( $request_payment_method ); | ||
} elseif ( ! is_null( $token ) ) { | ||
$order = $payment_information->get_order(); | ||
$order_id = is_a( $order, 'WC_Order' ) ? $order->get_id() : null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call--updated in 178d076. |
||
$payment_methods = $this->get_payment_methods_from_gateway_id( $token->get_gateway_id(), $order_id ); | ||
} else { | ||
$payment_methods = WC_Payments::get_gateway()->get_payment_method_ids_enabled_at_checkout( null, true ); | ||
} | ||
|
||
return $payment_methods; | ||
} | ||
|
||
if ( ! empty( $upe_payment_method ) && 'woocommerce_payments' !== $upe_payment_method ) { | ||
$payment_methods = [ str_replace( 'woocommerce_payments_', '', $upe_payment_method ) ]; | ||
/** | ||
* Get the payment methods used in the request. | ||
* | ||
* @param string $gateway_id ID of processing payment gateway. | ||
* @param int $order_id ID of related order, if applicable. | ||
* @return array List of payment methods. | ||
*/ | ||
public function get_payment_methods_from_gateway_id( $gateway_id, $order_id = null ) { | ||
if ( 'woocommerce_payments' !== $gateway_id ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we should check here is the id start with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I lack a comment here explaining which gateways have this sort of IDs. Can you add it, please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At this point, we know that the ID will start with I simplified this (with a few explanatory comments) in 178d076 by simply checking whether the ID begins with |
||
$payment_methods = [ str_replace( 'woocommerce_payments_', '', $gateway_id ) ]; | ||
} elseif ( WC_Payments_Features::is_upe_split_enabled() || WC_Payments_Features::is_upe_deferred_intent_enabled() ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's difficult to understand can we introduce separate ifs for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate the clauses in 178d076. |
||
$payment_methods = [ 'card' ]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a constant for card PM. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good shout--amended in 178d076. |
||
if ( WC_Payments_Features::is_upe_deferred_intent_enabled() && | ||
in_array( Payment_Method::LINK, $this->get_upe_enabled_payment_method_ids(), true ) ) { | ||
$payment_methods[] = Payment_Method::LINK; | ||
} | ||
} else { | ||
$payment_methods = WC_Payments::get_gateway()->get_payment_method_ids_enabled_at_checkout( null, true ); | ||
$payment_methods = WC_Payments::get_gateway()->get_payment_method_ids_enabled_at_checkout( $order_id, true ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a comment explaining when we get into this branch please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
return $payment_methods; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess for the supported PHP versions we can harden this method a bit:
public function get_payment_method_types( Payment_Information $payment_information ): array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing--added in 178d076.