From c058cd38c87fd54b00ce40b077fae27c863f70c1 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Fri, 15 Mar 2024 15:53:29 +0100 Subject: [PATCH] Ensure payment token exist for customer --- .../src/Endpoint/PaymentTokensEndpoint.php | 37 +++++++++++++++++++ modules/ppcp-wc-subscriptions/services.php | 3 +- .../src/RenewalHandler.php | 25 ++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php index bfe05d1b5..d59584095 100644 --- a/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php @@ -92,4 +92,41 @@ class PaymentTokensEndpoint { throw new PayPalApiException( $json, $status_code ); } } + + /** + * Returns all payment tokens for the given customer. + * + * @param string $customer_id + * @return array + */ + public function payment_tokens_for_customer( string $customer_id ): array { + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v3/vault/payment-tokens?customer_id=' . $customer_id; + $args = array( + 'method' => 'GET', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + ), + ); + + $response = $this->request( $url, $args ); + if ( $response instanceof WP_Error ) { + throw new RuntimeException( $response->get_error_message() ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 200 !== $status_code ) { + throw new PayPalApiException( $json, $status_code ); + } + + $tokens = array(); + $payment_tokens = $json->payment_tokens ?? array(); + foreach ( $payment_tokens as $payment_token ) { + $tokens[] = $payment_token->id; + } + + return $tokens; + } } diff --git a/modules/ppcp-wc-subscriptions/services.php b/modules/ppcp-wc-subscriptions/services.php index bab617b04..c3f5796f1 100644 --- a/modules/ppcp-wc-subscriptions/services.php +++ b/modules/ppcp-wc-subscriptions/services.php @@ -44,7 +44,8 @@ return array( $authorized_payments_processor, $funding_source_renderer, $container->get( 'wc-subscriptions.helpers.real-time-account-updater' ), - $container->get( 'wc-subscriptions.helper' ) + $container->get( 'wc-subscriptions.helper' ), + $container->get( 'api.endpoint.payment-tokens' ) ); }, 'wc-subscriptions.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository { diff --git a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php index 7e83218e9..1d66685c3 100644 --- a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php +++ b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php @@ -13,6 +13,7 @@ use WC_Order; use WC_Subscription; use WC_Payment_Tokens; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; @@ -132,6 +133,13 @@ class RenewalHandler { */ private $subscription_helper; + /** + * Payment tokens endpoint + * + * @var PaymentTokensEndpoint + */ + private $payment_tokens_endpoint; + /** * RenewalHandler constructor. * @@ -147,6 +155,7 @@ class RenewalHandler { * @param FundingSourceRenderer $funding_source_renderer The funding source renderer. * @param RealTimeAccountUpdaterHelper $real_time_account_updater_helper Real Time Account Updater helper. * @param SubscriptionHelper $subscription_helper Subscription helper. + * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. */ public function __construct( LoggerInterface $logger, @@ -160,7 +169,8 @@ class RenewalHandler { AuthorizedPaymentsProcessor $authorized_payments_processor, FundingSourceRenderer $funding_source_renderer, RealTimeAccountUpdaterHelper $real_time_account_updater_helper, - SubscriptionHelper $subscription_helper + SubscriptionHelper $subscription_helper, + PaymentTokensEndpoint $payment_tokens_endpoint ) { $this->logger = $logger; @@ -175,6 +185,7 @@ class RenewalHandler { $this->funding_source_renderer = $funding_source_renderer; $this->real_time_account_updater_helper = $real_time_account_updater_helper; $this->subscription_helper = $subscription_helper; + $this->payment_tokens_endpoint = $payment_tokens_endpoint; } /** @@ -236,8 +247,18 @@ class RenewalHandler { // 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 ); + $customer_id = get_user_meta( $user_id, '_ppcp_target_customer_id', true ); + if ( ! $customer_id ) { + $customer_id = get_user_meta( $user_id, 'ppcp_customer_id', true ); + } + + $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, PayPalGateway::ID ); + $customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id ); foreach ( $wc_tokens as $token ) { + if ( ! in_array( $token->get_token(), $customer_tokens, true ) ) { + continue; + } + $name = 'paypal'; $properties = array( 'vault_id' => $token->get_token(),