Merge pull request #2891 from woocommerce/PCP-3949-changing-subscription-payment-method-to-acdc-results-in-an-error

Changing subscription payment method to ACDC results in an error (3949)
This commit is contained in:
Emili Castells 2025-01-23 10:56:01 +01:00 committed by GitHub
commit 1a1d896ba8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 76 additions and 53 deletions

View file

@ -444,28 +444,27 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
}
}
if ( $this->is_customer_changing_subscription_payment( $this->subscription_helper, $wc_order ) ) {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$wc_payment_token_id = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
if ( ! $wc_payment_token_id ) {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$wc_payment_token_id = wc_clean( wp_unslash( $_POST['saved_credit_card'] ?? '' ) );
}
if ( $wc_payment_token_id ) {
return $this->add_payment_token_to_order( $wc_order, (int) $wc_payment_token_id, $this->get_return_url( $wc_order ), $this->session_handler );
}
}
/**
* Vault v3 (save payment methods).
* If customer has chosen a saved credit card payment from checkout page.
*/
if ( $card_payment_token_id ) {
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id(), self::ID );
if ( $customer_tokens && empty( $wc_tokens ) ) {
$this->wc_payment_tokens->create_wc_tokens( $customer_tokens, get_current_user_id() );
}
$customer_token_ids = array();
foreach ( $customer_tokens as $customer_token ) {
$customer_token_ids[] = $customer_token['id'];
}
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() );
foreach ( $tokens as $token ) {
if ( $token->get_id() === (int) $card_payment_token_id ) {
if ( ! in_array( $token->get_token(), $customer_token_ids, true ) ) {
$token->delete();
continue;
}
$custom_id = (string) $wc_order->get_id();
$invoice_id = $this->prefix . $wc_order->get_order_number();
$create_order = $this->capture_card_payment->create_order( $token->get_token(), $custom_id, $invoice_id, $wc_order );
@ -514,40 +513,6 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
}
}
/**
* If customer is changing subscription payment.
*/
if (
// phpcs:disable WordPress.Security.NonceVerification.Missing
isset( $_POST['woocommerce_change_payment'] )
&& $this->subscription_helper->has_subscription( $wc_order->get_id() )
&& $this->subscription_helper->is_subscription_change_payment()
) {
$saved_credit_card = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
if ( ! $saved_credit_card ) {
$saved_credit_card = wc_clean( wp_unslash( $_POST['saved_credit_card'] ?? '' ) );
// phpcs:enable WordPress.Security.NonceVerification.Missing
}
if ( $saved_credit_card ) {
$payment_token = WC_Payment_Tokens::get( $saved_credit_card );
if ( $payment_token ) {
$wc_order->add_payment_token( $payment_token );
$wc_order->save();
return $this->handle_payment_success( $wc_order );
}
}
wc_add_notice( __( 'Could not change payment.', 'woocommerce-paypal-payments' ), 'error' );
return array(
'result' => 'failure',
'redirect' => wc_get_checkout_url(),
'errorMessage' => __( 'Could not change payment.', 'woocommerce-paypal-payments' ),
);
}
/**
* If the WC_Order is paid through the approved webhook.
*/
@ -676,4 +641,53 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
protected function settings_renderer(): SettingsRenderer {
return $this->settings_renderer;
}
/**
* Check whether customer is changing subscription payment.
*
* @param SubscriptionHelper $subscription_helper Subscription helper.
* @param WC_Order $wc_order WC order.
* @return bool
*/
private function is_customer_changing_subscription_payment( SubscriptionHelper $subscription_helper, WC_Order $wc_order ): bool {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
return isset( $_POST['woocommerce_change_payment'] ) && $subscription_helper->has_subscription( $wc_order->get_id() ) && $subscription_helper->is_subscription_change_payment();
}
/**
* Adds the given WC payment token into the given WC Order.
*
* @param WC_Order $wc_order WC order.
* @param int $wc_payment_token_id WC payment token ID.
* @param string $return_url Return url.
* @param SessionHandler $session_handler Session handler.
* @return array{result: string, redirect: string, errorMessage?: string}
*/
private function add_payment_token_to_order(
WC_Order $wc_order,
int $wc_payment_token_id,
string $return_url,
SessionHandler $session_handler
): array {
$payment_token = WC_Payment_Tokens::get( $wc_payment_token_id );
if ( $payment_token ) {
$wc_order->add_payment_token( $payment_token );
$wc_order->save();
$session_handler->destroy_session_data();
return array(
'result' => 'success',
'redirect' => $return_url,
);
}
wc_add_notice( __( 'Could not change payment.', 'woocommerce-paypal-payments' ), 'error' );
return array(
'result' => 'failure',
'redirect' => wc_get_checkout_url(),
'errorMessage' => __( 'Could not change payment.', 'woocommerce-paypal-payments' ),
);
}
}