Merge pull request #2106 from woocommerce/PCP-2786-do-not-save-payment-token-for-guest-users

Payment tokens fixes and adjustments (2786)
This commit is contained in:
Emili Castells 2024-03-25 17:03:55 +01:00 committed by GitHub
commit f97baa941d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 304 additions and 64 deletions

View file

@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WP_Error;
@ -92,4 +93,53 @@ class PaymentTokensEndpoint {
throw new PayPalApiException( $json, $status_code );
}
}
/**
* Returns all payment tokens for the given customer.
*
* @param string $customer_id PayPal customer id.
* @return array
*
* @throws RuntimeException When something went wrong with the request.
* @throws PayPalApiException When something went wrong getting the payment tokens.
*/
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 ) {
$name = array_key_first( (array) $payment_token->payment_source ) ?? '';
if ( $name ) {
$tokens[] = array(
'id' => $payment_token->id,
'payment_source' => new PaymentSource(
$name,
$payment_token->payment_source->$name
),
);
}
}
return $tokens;
}
}

View file

@ -241,7 +241,6 @@ document.addEventListener(
if (!typeof (PayPalCommerceGateway)) {
console.error('PayPal button could not be configured.');
return;
return;
}
if (

View file

@ -9,7 +9,6 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Helper\SavePaymentMethodsApplies;
@ -805,31 +804,11 @@ return array(
$container->get( 'api.endpoint.payment-method-tokens' )
);
},
'save-payment-methods.wc-payment-tokens' => static function( ContainerInterface $container ): WooCommercePaymentTokens {
return new WooCommercePaymentTokens(
$container->get( 'vaulting.payment-token-helper' ),
$container->get( 'vaulting.payment-token-factory' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
},
'save-payment-methods.endpoint.create-payment-token' => static function ( ContainerInterface $container ): CreatePaymentToken {
return new CreatePaymentToken(
$container->get( 'button.request-data' ),
$container->get( 'api.endpoint.payment-method-tokens' ),
$container->get( 'save-payment-methods.wc-payment-tokens' )
);
},
'save-payment-methods.endpoint.capture-card-payment' => static function( ContainerInterface $container ): CaptureCardPayment {
return new CaptureCardPayment(
$container->get( 'api.host' ),
$container->get( 'api.bearer' ),
$container->get( 'api.factory.order' ),
$container->get( 'api.factory.purchase-unit' ),
$container->get( 'api.endpoint.order' ),
$container->get( 'session.handler' ),
$container->get( 'wc-subscriptions.helpers.real-time-account-updater' ),
$container->get( 'wcgateway.settings' ),
$container->get( 'woocommerce.logger.woocommerce' )
$container->get( 'vaulting.wc-payment-tokens' )
);
},
);

View file

@ -14,9 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
use WooCommerce\PayPalCommerce\SavePaymentMethods\WooCommercePaymentTokens;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
/**
* Class CreatePaymentToken

View file

@ -19,9 +19,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
@ -197,7 +197,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id );
$wc_payment_tokens = $c->get( 'save-payment-methods.wc-payment-tokens' );
$wc_payment_tokens = $c->get( 'vaulting.wc-payment-tokens' );
assert( $wc_payment_tokens instanceof WooCommercePaymentTokens );
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {

View file

@ -56,4 +56,12 @@ return array(
$container->get( 'woocommerce.logger.woocommerce' )
);
},
'vaulting.wc-payment-tokens' => static function( ContainerInterface $container ): WooCommercePaymentTokens {
return new WooCommercePaymentTokens(
$container->get( 'vaulting.payment-token-helper' ),
$container->get( 'vaulting.payment-token-factory' ),
$container->get( 'api.endpoint.payment-tokens' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
},
);

View file

@ -7,18 +7,15 @@
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
namespace WooCommerce\PayPalCommerce\Vaulting;
use Exception;
use Psr\Log\LoggerInterface;
use stdClass;
use WC_Payment_Token_CC;
use WC_Payment_Tokens;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenApplePay;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenFactory;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenHelper;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenPayPal;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenVenmo;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
@ -41,6 +38,13 @@ class WooCommercePaymentTokens {
*/
private $payment_token_factory;
/**
* Payment tokens endpoint.
*
* @var PaymentTokensEndpoint
*/
private $payment_tokens_endpoint;
/**
* The logger.
*
@ -51,18 +55,21 @@ class WooCommercePaymentTokens {
/**
* WooCommercePaymentTokens constructor.
*
* @param PaymentTokenHelper $payment_token_helper The payment token helper.
* @param PaymentTokenFactory $payment_token_factory The payment token factory.
* @param LoggerInterface $logger The logger.
* @param PaymentTokenHelper $payment_token_helper The payment token helper.
* @param PaymentTokenFactory $payment_token_factory The payment token factory.
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
PaymentTokenHelper $payment_token_helper,
PaymentTokenFactory $payment_token_factory,
PaymentTokensEndpoint $payment_tokens_endpoint,
LoggerInterface $logger
) {
$this->payment_token_helper = $payment_token_helper;
$this->payment_token_factory = $payment_token_factory;
$this->logger = $logger;
$this->payment_token_helper = $payment_token_helper;
$this->payment_token_factory = $payment_token_factory;
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
$this->logger = $logger;
}
/**
@ -80,6 +87,10 @@ class WooCommercePaymentTokens {
string $email
): int {
if ( $customer_id === 0 ) {
return 0;
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenPayPal::class ) ) {
return 0;
@ -128,6 +139,10 @@ class WooCommercePaymentTokens {
string $email
): int {
if ( $customer_id === 0 ) {
return 0;
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenVenmo::class ) ) {
return 0;
@ -174,6 +189,10 @@ class WooCommercePaymentTokens {
string $token
): int {
if ( $customer_id === 0 ) {
return 0;
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenApplePay::class ) ) {
return 0;
@ -212,6 +231,10 @@ class WooCommercePaymentTokens {
* @return int
*/
public function create_payment_token_card( int $customer_id, stdClass $payment_token ): int {
if ( $customer_id === 0 ) {
return 0;
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, CreditCardGateway::ID );
if ( $this->payment_token_helper->token_exist( $wc_tokens, $payment_token->id ) ) {
return 0;
@ -219,7 +242,7 @@ class WooCommercePaymentTokens {
$token = new WC_Payment_Token_CC();
$token->set_token( $payment_token->id );
$token->set_user_id( get_current_user_id() );
$token->set_user_id( $customer_id );
$token->set_gateway_id( CreditCardGateway::ID );
$token->set_last4( $payment_token->payment_source->card->last_digits ?? '' );
@ -243,4 +266,61 @@ class WooCommercePaymentTokens {
$token->save();
return $token->get_id();
}
/**
* Returns PayPal payment tokens for the given WP user id.
*
* @param int $user_id WP user id.
* @return array
*/
public function customer_tokens( int $user_id ): array {
$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 );
}
try {
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
} catch ( RuntimeException $exception ) {
$customer_tokens = array();
}
return $customer_tokens;
}
/**
* Creates WC payment tokens for the given WP user id using PayPal payment tokens as source.
*
* @param array $customer_tokens PayPal customer payment tokens.
* @param int $user_id WP user id.
* @return void
*/
public function create_wc_tokens( array $customer_tokens, int $user_id ): void {
foreach ( $customer_tokens as $customer_token ) {
if ( $customer_token['payment_source']->name() === 'paypal' ) {
$this->create_payment_token_paypal(
$user_id,
$customer_token['id'],
$customer_token['payment_source']->properties()->email_address ?? ''
);
}
if ( $customer_token['payment_source']->name() === 'card' ) {
/**
* Suppress ArgumentTypeCoercion
*
* @psalm-suppress ArgumentTypeCoercion
*/
$this->create_payment_token_card(
$user_id,
(object) array(
'id' => $customer_token['id'],
'payment_source' => (object) array(
$customer_token['payment_source']->name() => $customer_token['payment_source']->properties(),
),
)
);
}
}
}
}

View file

@ -23,6 +23,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderReauthorizeAction;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
@ -132,8 +133,10 @@ return array(
$vaulted_credit_card_handler,
$container->get( 'onboarding.environment' ),
$container->get( 'api.endpoint.order' ),
$container->get( 'save-payment-methods.endpoint.capture-card-payment' ),
$container->get( 'wcgateway.endpoint.capture-card-payment' ),
$container->get( 'api.prefix' ),
$container->get( 'api.endpoint.payment-tokens' ),
$container->get( 'vaulting.wc-payment-tokens' ),
$logger
);
},
@ -1586,4 +1589,17 @@ return array(
)
);
},
'wcgateway.endpoint.capture-card-payment' => static function( ContainerInterface $container ): CaptureCardPayment {
return new CaptureCardPayment(
$container->get( 'api.host' ),
$container->get( 'api.bearer' ),
$container->get( 'api.factory.order' ),
$container->get( 'api.factory.purchase-unit' ),
$container->get( 'api.endpoint.order' ),
$container->get( 'session.handler' ),
$container->get( 'wc-subscriptions.helpers.real-time-account-updater' ),
$container->get( 'wcgateway.settings' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
},
);

View file

@ -7,7 +7,7 @@
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
namespace WooCommerce\PayPalCommerce\WcGateway\Endpoint;
use Psr\Log\LoggerInterface;
use RuntimeException;

View file

@ -15,23 +15,25 @@ use WC_Order;
use WC_Payment_Tokens;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler;
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
/**
* Class CreditCardGateway
@ -154,6 +156,20 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
*/
private $prefix;
/**
* Payment tokens endpoint.
*
* @var PaymentTokensEndpoint
*/
private $payment_tokens_endpoint;
/**
* WooCommerce payment tokens factory.
*
* @var WooCommercePaymentTokens
*/
private $wc_payment_tokens;
/**
* The logger.
*
@ -179,6 +195,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param CaptureCardPayment $capture_card_payment Capture card payment.
* @param string $prefix The prefix.
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens factory.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
@ -197,6 +215,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
OrderEndpoint $order_endpoint,
CaptureCardPayment $capture_card_payment,
string $prefix,
PaymentTokensEndpoint $payment_tokens_endpoint,
WooCommercePaymentTokens $wc_payment_tokens,
LoggerInterface $logger
) {
$this->id = self::ID;
@ -215,6 +235,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
$this->order_endpoint = $order_endpoint;
$this->capture_card_payment = $capture_card_payment;
$this->prefix = $prefix;
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
$this->wc_payment_tokens = $wc_payment_tokens;
$this->logger = $logger;
if ( $state->current_state() === State::STATE_ONBOARDED ) {
@ -433,9 +455,27 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$card_payment_token_id = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
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 = $wc_order->get_order_number();
$invoice_id = $this->prefix . $wc_order->get_order_number();
$create_order = $this->capture_card_payment->create_order( $token->get_token(), $custom_id, $invoice_id );

View file

@ -44,7 +44,9 @@ 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' ),
$container->get( 'vaulting.wc-payment-tokens' )
);
},
'wc-subscriptions.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {

View file

@ -9,10 +9,12 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcSubscriptions;
use Psr\Log\LoggerInterface;
use WC_Order;
use WC_Subscription;
use WC_Payment_Tokens;
use WC_Subscription;
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;
@ -25,8 +27,8 @@ use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenApplePay;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenPayPal;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenVenmo;
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
@ -132,6 +134,20 @@ class RenewalHandler {
*/
private $subscription_helper;
/**
* Payment tokens endpoint
*
* @var PaymentTokensEndpoint
*/
private $payment_tokens_endpoint;
/**
* WooCommerce payments tokens factory.
*
* @var WooCommercePaymentTokens
*/
private $wc_payment_tokens;
/**
* RenewalHandler constructor.
*
@ -147,6 +163,8 @@ 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.
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payments tokens factory.
*/
public function __construct(
LoggerInterface $logger,
@ -160,7 +178,9 @@ 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,
WooCommercePaymentTokens $wc_payment_tokens
) {
$this->logger = $logger;
@ -175,6 +195,8 @@ 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;
$this->wc_payment_tokens = $wc_payment_tokens;
}
/**
@ -236,8 +258,26 @@ 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_tokens = $this->wc_payment_tokens->customer_tokens( $user_id );
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, PayPalGateway::ID );
if ( $customer_tokens && empty( $wc_tokens ) ) {
$this->wc_payment_tokens->create_wc_tokens( $customer_tokens, $user_id );
}
$customer_token_ids = array();
foreach ( $customer_tokens as $customer_token ) {
$customer_token_ids[] = $customer_token['id'];
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, PayPalGateway::ID );
foreach ( $wc_tokens as $token ) {
if ( ! in_array( $token->get_token(), $customer_token_ids, true ) ) {
$token->delete();
continue;
}
$name = 'paypal';
$properties = array(
'vault_id' => $token->get_token(),
@ -270,7 +310,27 @@ class RenewalHandler {
}
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), CreditCardGateway::ID );
$customer_tokens = $this->wc_payment_tokens->customer_tokens( $user_id );
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, CreditCardGateway::ID );
if ( $customer_tokens && empty( $wc_tokens ) ) {
$this->wc_payment_tokens->create_wc_tokens( $customer_tokens, $user_id );
}
$customer_token_ids = array();
foreach ( $customer_tokens as $customer_token ) {
$customer_token_ids[] = $customer_token['id'];
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, CreditCardGateway::ID );
foreach ( $wc_tokens as $token ) {
if ( ! in_array( $token->get_token(), $customer_token_ids, true ) ) {
$token->delete();
}
}
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, CreditCardGateway::ID );
$last_token = end( $wc_tokens );
if ( $last_token ) {
$payment_source = $this->card_payment_source( $last_token->get_token(), $wc_order );
@ -295,7 +355,7 @@ class RenewalHandler {
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {
$card_payment_source = $order->payment_source();
if ( $card_payment_source ) {
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), CreditCardGateway::ID );
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, CreditCardGateway::ID );
$last_token = end( $wc_tokens );
$expiry = $card_payment_source->properties()->expiry ?? '';
$last_digits = $card_payment_source->properties()->last_digits ?? '';

View file

@ -4,21 +4,23 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use Mockery;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use WC_Order;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
use WooCommerce\PayPalCommerce\TestCase;
use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler;
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
use function Brain\Monkey\Functions\when;
class CreditCardGatewayTest extends TestCase
@ -34,6 +36,8 @@ class CreditCardGatewayTest extends TestCase
private $subscriptionHelper;
private $captureCardPayment;
private $prefix;
private $paymentTokensEndpoint;
private $wcPaymentTokens;
private $logger;
private $paymentsEndpoint;
private $vaultedCreditCardHandler;
@ -56,6 +60,8 @@ class CreditCardGatewayTest extends TestCase
$this->subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$this->captureCardPayment = Mockery::mock(CaptureCardPayment::class);
$this->prefix = 'some-prefix';
$this->paymentTokensEndpoint = Mockery::mock(PaymentTokensEndpoint::class);
$this->wcPaymentTokens = Mockery::mock(WooCommercePaymentTokens::class);
$this->logger = Mockery::mock(LoggerInterface::class);
$this->paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$this->vaultedCreditCardHandler = Mockery::mock(VaultedCreditCardHandler::class);
@ -84,6 +90,8 @@ class CreditCardGatewayTest extends TestCase
$this->orderEndpoint,
$this->captureCardPayment,
$this->prefix,
$this->paymentTokensEndpoint,
$this->wcPaymentTokens,
$this->logger
);
}