From a211553e4bee0a65c31ed4e3785c2ce6d9cc2a82 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 3 Aug 2023 12:28:20 +0200 Subject: [PATCH] Check if guest customer id exist in user meta when checking if payment exist on PayPal --- .../src/Endpoint/PaymentTokenEndpoint.php | 64 ++++++++++++++++++- modules/ppcp-vaulting/services.php | 1 + .../ppcp-vaulting/src/PaymentTokenChecker.php | 42 +++++++++++- 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php index a268d6ee9..5cabf04d7 100644 --- a/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php @@ -97,7 +97,7 @@ class PaymentTokenEndpoint { } /** - * Returns the payment tokens for a user. + * Returns the payment tokens for the given user id. * * @param int $id The user id. * @@ -118,7 +118,67 @@ class PaymentTokenEndpoint { $response = $this->request( $url, $args ); if ( is_wp_error( $response ) ) { $error = new RuntimeException( - __( 'Could not fetch payment token.', 'woocommerce-paypal-payments' ) + __( 'Could not fetch payment token for customer id.', 'woocommerce-paypal-payments' ) + ); + $this->logger->log( + 'warning', + $error->getMessage(), + array( + 'args' => $args, + 'response' => $response, + ) + ); + throw $error; + } + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 200 !== $status_code ) { + $error = new PayPalApiException( + $json, + $status_code + ); + $this->logger->log( + 'warning', + $error->getMessage(), + array( + 'args' => $args, + 'response' => $response, + ) + ); + throw $error; + } + + $tokens = array(); + foreach ( $json->payment_tokens as $token_value ) { + $tokens[] = $this->factory->from_paypal_response( $token_value ); + } + + return $tokens; + } + + /** + * Returns the payment tokens for the given guest customer id. + * + * @param string $customer_id The guest customer id. + * + * @return PaymentToken[] + * @throws RuntimeException If the request fails. + */ + public function for_guest( string $customer_id ): array { + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v2/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 ( is_wp_error( $response ) ) { + $error = new RuntimeException( + __( 'Could not fetch payment token for guest customer id.', 'woocommerce-paypal-payments' ) ); $this->logger->log( 'warning', diff --git a/modules/ppcp-vaulting/services.php b/modules/ppcp-vaulting/services.php index 1c0b6a742..c274c4549 100644 --- a/modules/ppcp-vaulting/services.php +++ b/modules/ppcp-vaulting/services.php @@ -30,6 +30,7 @@ return array( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.processor.authorized-payments' ), $container->get( 'api.endpoint.payments' ), + $container->get( 'api.endpoint.payment-token' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, diff --git a/modules/ppcp-vaulting/src/PaymentTokenChecker.php b/modules/ppcp-vaulting/src/PaymentTokenChecker.php index cd57e9426..4e95e268a 100644 --- a/modules/ppcp-vaulting/src/PaymentTokenChecker.php +++ b/modules/ppcp-vaulting/src/PaymentTokenChecker.php @@ -14,6 +14,8 @@ use Psr\Log\LoggerInterface; use RuntimeException; use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository; use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; @@ -67,6 +69,13 @@ class PaymentTokenChecker { */ protected $payments_endpoint; + /** + * The payment token endpoint. + * + * @var PaymentTokenEndpoint + */ + protected $payment_token_endpoint; + /** * The logger. * @@ -82,6 +91,7 @@ class PaymentTokenChecker { * @param Settings $settings The settings. * @param AuthorizedPaymentsProcessor $authorized_payments_processor The authorized payments processor. * @param PaymentsEndpoint $payments_endpoint The payments endpoint. + * @param PaymentTokenEndpoint $payment_token_endpoint The payment token endpoint. * @param LoggerInterface $logger The logger. */ public function __construct( @@ -90,6 +100,7 @@ class PaymentTokenChecker { Settings $settings, AuthorizedPaymentsProcessor $authorized_payments_processor, PaymentsEndpoint $payments_endpoint, + PaymentTokenEndpoint $payment_token_endpoint, LoggerInterface $logger ) { $this->payment_token_repository = $payment_token_repository; @@ -97,6 +108,7 @@ class PaymentTokenChecker { $this->settings = $settings; $this->authorized_payments_processor = $authorized_payments_processor; $this->payments_endpoint = $payments_endpoint; + $this->payment_token_endpoint = $payment_token_endpoint; $this->logger = $logger; } @@ -130,7 +142,7 @@ class PaymentTokenChecker { return; } - $tokens = $this->payment_token_repository->all_for_user_id( $customer_id ); + $tokens = $this->tokens_for_user( $customer_id ); if ( $tokens ) { try { $this->capture_authorized_payment( $wc_order ); @@ -231,4 +243,32 @@ class PaymentTokenChecker { } } } + + /** + * Returns customer tokens either from guest or customer id. + * + * @param int $customer_id The customer id. + * @return PaymentToken[] + */ + private function tokens_for_user( int $customer_id ): array { + $tokens = array(); + + $guest_customer_id = get_user_meta( $customer_id, 'ppcp_guest_customer_id', true ); + if ( $guest_customer_id ) { + $tokens = $this->payment_token_endpoint->for_guest( $guest_customer_id ); + } + + if ( ! $tokens ) { + $guest_customer_id = get_user_meta( $customer_id, 'ppcp_customer_id', true ); + if ( $guest_customer_id ) { + $tokens = $this->payment_token_endpoint->for_guest( $guest_customer_id ); + } + } + + if ( ! $tokens ) { + $tokens = $this->payment_token_repository->all_for_user_id( $customer_id ); + } + + return $tokens; + } }