From 0d4fbc4c0b3d1212139dbf43ca82441daeff85aa Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Fri, 26 Jan 2024 14:22:20 +0000
Subject: [PATCH] Refactor Venmo and ApplePay payment tokens.
---
.../src/SavePaymentMethodsModule.php | 29 ++++--
.../src/WooCommercePaymentTokens.php | 90 +++++++++++++++++--
.../src/PaymentTokenApplePay.php | 31 +++++++
.../ppcp-vaulting/src/PaymentTokenFactory.php | 6 +-
.../ppcp-vaulting/src/PaymentTokenHelper.php | 11 ++-
.../ppcp-vaulting/src/PaymentTokenPayPal.php | 21 +----
.../ppcp-vaulting/src/PaymentTokenVenmo.php | 51 +++++++++++
.../src/PaymentTokensMigration.php | 2 +-
modules/ppcp-vaulting/src/VaultingModule.php | 37 ++++----
.../src/RenewalHandler.php | 26 +++---
10 files changed, 234 insertions(+), 70 deletions(-)
create mode 100644 modules/ppcp-vaulting/src/PaymentTokenApplePay.php
create mode 100644 modules/ppcp-vaulting/src/PaymentTokenVenmo.php
diff --git a/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php
index e79ec11f6..5ea2a78dd 100644
--- a/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php
+++ b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php
@@ -188,12 +188,29 @@ class SavePaymentMethodsModule implements ModuleInterface {
}
if ( $wc_order->get_payment_method() === PayPalGateway::ID ) {
- $wc_payment_tokens->create_payment_token_paypal(
- $wc_order->get_customer_id(),
- $token_id,
- $payment_source->properties()->email_address ?? '',
- $payment_source->name()
- );
+ switch ( $payment_source->name() ) {
+ case 'venmo':
+ $wc_payment_tokens->create_payment_token_venmo(
+ $wc_order->get_customer_id(),
+ $token_id,
+ $payment_source->properties()->email_address ?? ''
+ );
+ break;
+ case 'apple_pay':
+ $wc_payment_tokens->create_payment_token_applepay(
+ $wc_order->get_customer_id(),
+ $token_id
+ );
+ break;
+ case 'paypal':
+ default:
+ $wc_payment_tokens->create_payment_token_paypal(
+ $wc_order->get_customer_id(),
+ $token_id,
+ $payment_source->properties()->email_address ?? ''
+ );
+ break;
+ }
}
}
},
diff --git a/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php b/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php
index e57198a0d..c878f10d1 100644
--- a/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php
+++ b/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php
@@ -14,9 +14,11 @@ 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\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
@@ -69,19 +71,17 @@ class WooCommercePaymentTokens {
* @param int $customer_id The WC customer ID.
* @param string $token The PayPal payment token.
* @param string $email The PayPal customer email.
- * @param string $payment_source The funding source.
*
* @return int
*/
public function create_payment_token_paypal(
int $customer_id,
string $token,
- string $email,
- string $payment_source = ''
+ string $email
): int {
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
- if ( $this->payment_token_helper->token_exist( $wc_tokens, $token ) ) {
+ if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenPayPal::class ) ) {
return 0;
}
@@ -96,10 +96,6 @@ class WooCommercePaymentTokens {
$payment_token_paypal->set_email( $email );
}
- if ( $payment_source ) {
- $payment_token_paypal->set_payment_source( $payment_source );
- }
-
try {
$payment_token_paypal->save();
} catch ( Exception $exception ) {
@@ -111,6 +107,84 @@ class WooCommercePaymentTokens {
return $payment_token_paypal->get_id();
}
+ /**
+ * Creates a WC Payment Token for Venmo payment.
+ *
+ * @param int $customer_id The WC customer ID.
+ * @param string $token The Venmo payment token.
+ * @param string $email The Venmo customer email.
+ *
+ * @return int
+ */
+ public function create_payment_token_venmo(
+ int $customer_id,
+ string $token,
+ string $email
+ ): int {
+
+ $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;
+ }
+
+ $payment_token_venmo = $this->payment_token_factory->create( 'venmo' );
+ assert( $payment_token_venmo instanceof PaymentTokenVenmo );
+
+ $payment_token_venmo->set_token( $token );
+ $payment_token_venmo->set_user_id( $customer_id );
+ $payment_token_venmo->set_gateway_id( PayPalGateway::ID );
+
+ if ( $email && is_email( $email ) ) {
+ $payment_token_venmo->set_email( $email );
+ }
+
+ try {
+ $payment_token_venmo->save();
+ } catch ( Exception $exception ) {
+ $this->logger->error(
+ "Could not create WC payment token Venmo for customer {$customer_id}. " . $exception->getMessage()
+ );
+ }
+
+ return $payment_token_venmo->get_id();
+ }
+
+ /**
+ * Creates a WC Payment Token for ApplePay payment.
+ *
+ * @param int $customer_id The WC customer ID.
+ * @param string $token The ApplePay payment token.
+ *
+ * @return int
+ */
+ public function create_payment_token_applepay(
+ int $customer_id,
+ string $token
+ ): int {
+
+ $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;
+ }
+
+ $payment_token_applepay = $this->payment_token_factory->create( 'apple_pay' );
+ assert( $payment_token_applepay instanceof PaymentTokenApplePay );
+
+ $payment_token_applepay->set_token( $token );
+ $payment_token_applepay->set_user_id( $customer_id );
+ $payment_token_applepay->set_gateway_id( PayPalGateway::ID );
+
+ try {
+ $payment_token_applepay->save();
+ } catch ( Exception $exception ) {
+ $this->logger->error(
+ "Could not create WC payment token ApplePay for customer {$customer_id}. " . $exception->getMessage()
+ );
+ }
+
+ return $payment_token_applepay->get_id();
+ }
+
/**
* Creates a WC Payment Token for Credit Card payment.
*
diff --git a/modules/ppcp-vaulting/src/PaymentTokenApplePay.php b/modules/ppcp-vaulting/src/PaymentTokenApplePay.php
new file mode 100644
index 000000000..a53aa254a
--- /dev/null
+++ b/modules/ppcp-vaulting/src/PaymentTokenApplePay.php
@@ -0,0 +1,31 @@
+get_token() === $token_id ) {
- return true;
+ if ( null !== $class_name ) {
+ if ( $wc_token instanceof $class_name ) {
+ return true;
+ }
+ } else {
+ return true;
+ }
}
}
diff --git a/modules/ppcp-vaulting/src/PaymentTokenPayPal.php b/modules/ppcp-vaulting/src/PaymentTokenPayPal.php
index 3b8eac849..1a5858118 100644
--- a/modules/ppcp-vaulting/src/PaymentTokenPayPal.php
+++ b/modules/ppcp-vaulting/src/PaymentTokenPayPal.php
@@ -28,8 +28,7 @@ class PaymentTokenPayPal extends WC_Payment_Token {
* @var string[]
*/
protected $extra_data = array(
- 'email' => '',
- 'payment_source' => '',
+ 'email' => '',
);
/**
@@ -49,22 +48,4 @@ class PaymentTokenPayPal extends WC_Payment_Token {
public function set_email( $email ) {
$this->add_meta_data( 'email', $email, true );
}
-
- /**
- * Get the payment source.
- *
- * @return string The payment source.
- */
- public function get_payment_source() {
- return $this->get_meta( 'payment_source' );
- }
-
- /**
- * Set the payment source.
- *
- * @param string $payment_source The payment source.
- */
- public function set_payment_source( string $payment_source ) {
- $this->add_meta_data( 'payment_source', $payment_source, true );
- }
}
diff --git a/modules/ppcp-vaulting/src/PaymentTokenVenmo.php b/modules/ppcp-vaulting/src/PaymentTokenVenmo.php
new file mode 100644
index 000000000..d53a4b4fb
--- /dev/null
+++ b/modules/ppcp-vaulting/src/PaymentTokenVenmo.php
@@ -0,0 +1,51 @@
+ '',
+ );
+
+ /**
+ * Get PayPal account email.
+ *
+ * @return string PayPal account email.
+ */
+ public function get_email() {
+ return $this->get_meta( 'email' );
+ }
+
+ /**
+ * Set PayPal account email.
+ *
+ * @param string $email PayPal account email.
+ */
+ public function set_email( $email ) {
+ $this->add_meta_data( 'email', $email, true );
+ }
+}
diff --git a/modules/ppcp-vaulting/src/PaymentTokensMigration.php b/modules/ppcp-vaulting/src/PaymentTokensMigration.php
index a7d3511cc..1ef41df4a 100644
--- a/modules/ppcp-vaulting/src/PaymentTokensMigration.php
+++ b/modules/ppcp-vaulting/src/PaymentTokensMigration.php
@@ -107,7 +107,7 @@ class PaymentTokensMigration {
}
} elseif ( $token->source()->paypal ) {
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $id, PayPalGateway::ID );
- if ( $this->payment_token_helper->token_exist( $wc_tokens, $token->id() ) ) {
+ if ( $this->payment_token_helper->token_exist( $wc_tokens, $token->id(), PaymentTokenPayPal::class ) ) {
$this->logger->info( 'Token already exist for user ' . (string) $id );
continue;
}
diff --git a/modules/ppcp-vaulting/src/VaultingModule.php b/modules/ppcp-vaulting/src/VaultingModule.php
index 1860a889d..ff8acdf3b 100644
--- a/modules/ppcp-vaulting/src/VaultingModule.php
+++ b/modules/ppcp-vaulting/src/VaultingModule.php
@@ -81,6 +81,12 @@ class VaultingModule implements ModuleInterface {
if ( $type === 'WC_Payment_Token_PayPal' ) {
return PaymentTokenPayPal::class;
}
+ if ( $type === 'WC_Payment_Token_Venmo' ) {
+ return PaymentTokenVenmo::class;
+ }
+ if ( $type === 'WC_Payment_Token_ApplePay' ) {
+ return PaymentTokenApplePay::class;
+ }
return $type;
}
@@ -102,10 +108,7 @@ class VaultingModule implements ModuleInterface {
// Exclude ApplePay tokens from payment pages.
if ( is_checkout() || is_cart() || is_product() ) {
foreach ( $tokens as $index => $token ) {
- if (
- $token instanceof PaymentTokenPayPal
- && $token->get_payment_source() === 'apple_pay'
- ) {
+ if ( $token instanceof PaymentTokenApplePay ) {
unset( $tokens[ $index ] );
}
}
@@ -129,24 +132,18 @@ class VaultingModule implements ModuleInterface {
return $item;
}
- if ( strtolower( $payment_token->get_type() ) === 'paypal' ) {
- assert( $payment_token instanceof PaymentTokenPayPal );
+ if ( $payment_token instanceof PaymentTokenPayPal ) {
+ $item['method']['brand'] = 'PayPal / ' . $payment_token->get_email();
+ return $item;
+ }
- $email = $payment_token->get_email();
- $payment_source = $payment_token->get_payment_source();
- $brand_parts = array();
+ if ( $payment_token instanceof PaymentTokenVenmo ) {
+ $item['method']['brand'] = 'Venmo / ' . $payment_token->get_email();
+ return $item;
+ }
- if ( $payment_source !== 'paypal' ) {
- $brand_parts[] = ucwords( $payment_source );
- }
-
- if ( $email ) {
- $brand_parts[] = $email;
- } else {
- $brand_parts[] = '#' . ( (string) $payment_token->get_id() );
- }
-
- $item['method']['brand'] = implode( ' / ', array_filter( $brand_parts ) );
+ if ( $payment_token instanceof PaymentTokenApplePay ) {
+ $item['method']['brand'] = 'ApplePay #' . ( (string) $payment_token->get_id() );
return $item;
}
diff --git a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php
index e3ce5bbfd..a4ce028ee 100644
--- a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php
+++ b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php
@@ -22,9 +22,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
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\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
@@ -209,20 +211,20 @@ class RenewalHandler {
);
if ( $token instanceof PaymentTokenPayPal ) {
- $payment_source_name = $token->get_payment_source();
+ $name = 'paypal';
+ }
- if ( $payment_source_name ) {
- $name = $payment_source_name;
- }
+ if ( $token instanceof PaymentTokenVenmo ) {
+ $name = 'venmo';
+ }
- // Add required stored_credentials for apple_pay.
- if ( $payment_source_name === 'apple_pay' ) {
- $properties['stored_credential'] = array(
- 'payment_initiator' => 'MERCHANT',
- 'payment_type' => 'RECURRING',
- 'usage' => 'SUBSEQUENT',
- );
- }
+ if ( $token instanceof PaymentTokenApplePay ) {
+ $name = 'apple_pay';
+ $properties['stored_credential'] = array(
+ 'payment_initiator' => 'MERCHANT',
+ 'payment_type' => 'RECURRING',
+ 'usage' => 'SUBSEQUENT',
+ );
}
$payment_source = new PaymentSource(