From 5fe89aa90c8502f9f7f0144a24380036b3318595 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 21 Dec 2023 14:40:37 +0100 Subject: [PATCH] Use vault v3 first on renewal handler --- .../src/SavePaymentMethodsModule.php | 2 - .../src/RenewalHandler.php | 189 ++++++++++-------- 2 files changed, 101 insertions(+), 90 deletions(-) diff --git a/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php index 5b6bb1aa8..3501d71aa 100644 --- a/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php +++ b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php @@ -11,7 +11,6 @@ namespace WooCommerce\PayPalCommerce\SavePaymentMethods; use Psr\Log\LoggerInterface; use WC_Order; -use WC_Payment_Tokens; use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; @@ -172,7 +171,6 @@ class SavePaymentMethodsModule implements ModuleInterface { ); add_filter( 'woocommerce_paypal_payments_disable_add_payment_method', '__return_false' ); - add_filter( 'woocommerce_paypal_payments_subscription_renewal_return_before_create_order_without_token', '__return_false' ); add_filter( 'woocommerce_paypal_payments_should_render_card_custom_fields', '__return_false' ); add_action( diff --git a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php index 3742607dd..636de372d 100644 --- a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php +++ b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcSubscriptions; +use WC_Order; use WC_Subscription; use WC_Payment_Tokens; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; @@ -196,32 +197,59 @@ class RenewalHandler { 'renewal' ); + // Vault v3. + $payment_source = null; + if ( $wc_order->get_payment_method() === PayPalGateway::ID ) { + $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), PayPalGateway::ID ); + foreach ( $wc_tokens as $token ) { + $payment_source = new PaymentSource( + 'paypal', + (object) array( + 'vault_id' => $token->get_token(), + ) + ); + + break; + } + } + + if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) { + $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), CreditCardGateway::ID ); + foreach ( $wc_tokens as $token ) { + $payment_source = $this->card_payment_source( $token->get_token(), $wc_order ); + } + } + + if ( $payment_source ) { + $order = $this->order_endpoint->create( + array( $purchase_unit ), + $shipping_preference, + $payer, + null, + '', + ApplicationContext::USER_ACTION_CONTINUE, + '', + array(), + $payment_source + ); + + $this->handle_paypal_order( $wc_order, $order ); + + $this->logger->info( + sprintf( + 'Renewal for order %d is completed.', + $wc_order->get_id() + ) + ); + + return; + } + // Vault v2. $token = $this->get_token_for_customer( $customer, $wc_order ); if ( $token ) { if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) { - $stored_credentials = array( - 'payment_initiator' => 'MERCHANT', - 'payment_type' => 'RECURRING', - 'usage' => 'SUBSEQUENT', - ); - - $subscriptions = wcs_get_subscriptions_for_renewal_order( $wc_order ); - foreach ( $subscriptions as $post_id => $subscription ) { - $previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' ); - if ( $previous_transaction_reference ) { - $stored_credentials['previous_transaction_reference'] = $previous_transaction_reference; - break; - } - } - - $payment_source = new PaymentSource( - 'card', - (object) array( - 'vault_id' => $token->id(), - 'stored_credential' => $stored_credentials, - ) - ); + $payment_source = $this->card_payment_source( $token->id(), $wc_order ); $order = $this->order_endpoint->create( array( $purchase_unit ), @@ -247,79 +275,24 @@ class RenewalHandler { return; } - $order = $this->order_endpoint->create( - array( $purchase_unit ), - $shipping_preference, - $payer, - $token - ); - - $this->handle_paypal_order( $wc_order, $order ); - - $this->logger->info( - sprintf( - 'Renewal for order %d is completed.', - $wc_order->get_id() - ) - ); - - return; - } - - if ( apply_filters( 'woocommerce_paypal_payments_subscription_renewal_return_before_create_order_without_token', true ) ) { - return; - } - - // Vault v3. - $payment_source = null; - if ( $wc_order->get_payment_method() === PayPalGateway::ID ) { - $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), PayPalGateway::ID ); - foreach ( $wc_tokens as $token ) { - $payment_source = new PaymentSource( - 'paypal', - (object) array( - 'vault_id' => $token->get_token(), - ) + if ( $wc_order->get_payment_method() === PayPalGateway::ID ) { + $order = $this->order_endpoint->create( + array( $purchase_unit ), + $shipping_preference, + $payer, + $token ); - break; - } - } + $this->handle_paypal_order( $wc_order, $order ); - if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) { - $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), CreditCardGateway::ID ); - foreach ( $wc_tokens as $token ) { - $payment_source = new PaymentSource( - 'card', - (object) array( - 'vault_id' => $token->get_token(), + $this->logger->info( + sprintf( + 'Renewal for order %d is completed.', + $wc_order->get_id() ) ); } } - - if ( $payment_source ) { - $order = $this->order_endpoint->create( - array( $purchase_unit ), - $shipping_preference, - $payer, - null, - '', - ApplicationContext::USER_ACTION_CONTINUE, - '', - array(), - $payment_source - ); - - $this->handle_paypal_order( $wc_order, $order ); - - $this->logger->info( - sprintf( - 'Renewal for order %d is completed.', - $wc_order->get_id() - ) - ); - } } /** @@ -427,4 +400,44 @@ class RenewalHandler { $this->authorized_payments_processor->capture_authorized_payment( $wc_order ); } } + + /** + * Returns a Card payment source. + * + * @param string $token Vault token id. + * @param WC_Order $wc_order WC order. + * @return PaymentSource + * @throws NotFoundException If setting is not found. + */ + private function card_payment_source( string $token, WC_Order $wc_order ): PaymentSource { + $properties = array( + 'vault_id' => $token, + ); + + if ( + $this->settings->has( '3d_secure_contingency' ) + && ( $this->settings->get( '3d_secure_contingency' ) === 'SCA_ALWAYS' || $this->settings->get( '3d_secure_contingency' ) === 'SCA_WHEN_REQUIRED' ) + ) { + $stored_credentials = array( + 'payment_initiator' => 'MERCHANT', + 'payment_type' => 'RECURRING', + 'usage' => 'SUBSEQUENT', + ); + + $subscriptions = wcs_get_subscriptions_for_renewal_order( $wc_order ); + foreach ( $subscriptions as $post_id => $subscription ) { + $previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' ); + if ( $previous_transaction_reference ) { + $stored_credentials['previous_transaction_reference'] = $previous_transaction_reference; + $properties['stored_credentials'] = $stored_credentials; + break; + } + } + } + + return new PaymentSource( + 'card', + (object) $properties + ); + } }