Merge pull request #1986 from woocommerce/PCP-2521-apple-pay-recurring-payments

Apple Pay recurring payments (2521)
This commit is contained in:
Emili Castells 2024-02-07 10:47:08 +01:00 committed by GitHub
commit 037f650288
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 437 additions and 37 deletions

View file

@ -148,6 +148,21 @@ class SavePaymentMethodsModule implements ModuleInterface {
'vault' => array(
'store_in_vault' => 'ON_SUCCESS',
'usage_type' => 'MERCHANT',
'permit_multiple_payment_tokens' => true,
),
),
),
);
} elseif ( $funding_source && $funding_source === 'apple_pay' ) {
$data['payment_source'] = array(
'apple_pay' => array(
'stored_credential' => array(
'payment_initiator' => 'CUSTOMER',
'payment_type' => 'RECURRING',
),
'attributes' => array(
'vault' => array(
'store_in_vault' => 'ON_SUCCESS',
),
),
),
@ -159,6 +174,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
'vault' => array(
'store_in_vault' => 'ON_SUCCESS',
'usage_type' => 'MERCHANT',
'permit_multiple_payment_tokens' => true,
),
),
),
@ -207,11 +223,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 ?? ''
);
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;
}
}
}
},

View file

@ -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;
@ -66,9 +68,9 @@ class WooCommercePaymentTokens {
/**
* Creates a WC Payment Token for PayPal payment.
*
* @param int $customer_id The WC customer ID.
* @param string $token The PayPal payment token.
* @param string $email The PayPal customer email.
* @param int $customer_id The WC customer ID.
* @param string $token The PayPal payment token.
* @param string $email The PayPal customer email.
*
* @return int
*/
@ -79,11 +81,17 @@ class WooCommercePaymentTokens {
): 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;
}
$payment_token_paypal = $this->payment_token_factory->create( 'paypal' );
// Try to update existing token of type before creating a new one.
$payment_token_paypal = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenPayPal::class );
if ( ! $payment_token_paypal ) {
$payment_token_paypal = $this->payment_token_factory->create( 'paypal' );
}
assert( $payment_token_paypal instanceof PaymentTokenPayPal );
$payment_token_paypal->set_token( $token );
@ -105,6 +113,96 @@ 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;
}
// Try to update existing token of type before creating a new one.
$payment_token_venmo = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenVenmo::class );
if ( ! $payment_token_venmo ) {
$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;
}
// Try to update existing token of type before creating a new one.
$payment_token_applepay = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenApplePay::class );
if ( ! $payment_token_applepay ) {
$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.
*