mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 13:44:42 +08:00
Add my account payment method for PayPal payment
This commit is contained in:
parent
34cc1bffe4
commit
48c5773ecd
7 changed files with 298 additions and 91 deletions
|
@ -16,25 +16,61 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class PaymentMethodTokensEndpoint
|
||||
*/
|
||||
class PaymentMethodTokensEndpoint {
|
||||
|
||||
use RequestTrait;
|
||||
|
||||
private string $host;
|
||||
private Bearer $bearer;
|
||||
private LoggerInterface $logger;
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
public function __construct(string $host, Bearer $bearer, LoggerInterface $logger)
|
||||
{
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* PaymentMethodTokensEndpoint constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct( string $host, Bearer $bearer, LoggerInterface $logger ) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function setup_tokens(PaymentSource $payment_source): stdClass {
|
||||
/**
|
||||
* Creates a setup token.
|
||||
*
|
||||
* @param PaymentSource $payment_source The payment source.
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
* @throws RuntimeException When something when wrong with the request.
|
||||
* @throws PayPalApiException When something when wrong setting up the token.
|
||||
*/
|
||||
public function setup_tokens( PaymentSource $payment_source ): stdClass {
|
||||
$data = array(
|
||||
'payment_source' => array(
|
||||
$payment_source->name() => $payment_source->properties()
|
||||
$payment_source->name() => $payment_source->properties(),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -69,10 +105,20 @@ class PaymentMethodTokensEndpoint {
|
|||
return $json;
|
||||
}
|
||||
|
||||
public function payment_tokens(PaymentSource $payment_source) {
|
||||
/**
|
||||
* Creates a payment token for the given payment source.
|
||||
*
|
||||
* @param PaymentSource $payment_source The payment source.
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
* @throws RuntimeException When something when wrong with the request.
|
||||
* @throws PayPalApiException When something when wrong setting up the token.
|
||||
*/
|
||||
public function payment_tokens( PaymentSource $payment_source ): stdClass {
|
||||
$data = array(
|
||||
'payment_source' => array(
|
||||
$payment_source->name() => $payment_source->properties()
|
||||
$payment_source->name() => $payment_source->properties(),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -54,16 +54,24 @@ return array(
|
|||
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
|
||||
);
|
||||
},
|
||||
'save-payment-methods.endpoint.create-setup-token' => static function (ContainerInterface $container): CreateSetupToken {
|
||||
'save-payment-methods.endpoint.create-setup-token' => static function ( ContainerInterface $container ): CreateSetupToken {
|
||||
return new CreateSetupToken(
|
||||
$container->get( 'button.request-data' ),
|
||||
$container->get('api.endpoint.payment-method-tokens')
|
||||
$container->get( 'api.endpoint.payment-method-tokens' )
|
||||
);
|
||||
},
|
||||
'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')
|
||||
'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' )
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
<?php
|
||||
/**
|
||||
* The Create Payment Token endpoint.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
|
||||
|
||||
|
@ -7,20 +14,51 @@ 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;
|
||||
|
||||
/**
|
||||
* Class CreatePaymentToken
|
||||
*/
|
||||
class CreatePaymentToken implements EndpointInterface {
|
||||
|
||||
const ENDPOINT = 'ppc-create-payment-token';
|
||||
|
||||
private RequestData $request_data;
|
||||
private PaymentMethodTokensEndpoint $payment_method_tokens_endpoint;
|
||||
/**
|
||||
* The request data.
|
||||
*
|
||||
* @var RequestData
|
||||
*/
|
||||
private $request_data;
|
||||
|
||||
/**
|
||||
* The payment method tokens endpoint.
|
||||
*
|
||||
* @var PaymentMethodTokensEndpoint
|
||||
*/
|
||||
private $payment_method_tokens_endpoint;
|
||||
|
||||
/**
|
||||
* The WC payment tokens.
|
||||
*
|
||||
* @var WooCommercePaymentTokens
|
||||
*/
|
||||
private $wc_payment_tokens;
|
||||
|
||||
/**
|
||||
* CreatePaymentToken constructor.
|
||||
*
|
||||
* @param RequestData $request_data The request data.
|
||||
* @param PaymentMethodTokensEndpoint $payment_method_tokens_endpoint The payment method tokens endpoint.
|
||||
* @param WooCommercePaymentTokens $wc_payment_tokens The WC payment tokens.
|
||||
*/
|
||||
public function __construct(
|
||||
RequestData $request_data,
|
||||
PaymentMethodTokensEndpoint $payment_method_tokens_endpoint
|
||||
PaymentMethodTokensEndpoint $payment_method_tokens_endpoint,
|
||||
WooCommercePaymentTokens $wc_payment_tokens
|
||||
) {
|
||||
$this->request_data = $request_data;
|
||||
$this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint;
|
||||
$this->wc_payment_tokens = $wc_payment_tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,11 +84,27 @@ class CreatePaymentToken implements EndpointInterface {
|
|||
'token',
|
||||
(object) array(
|
||||
'id' => $data['vault_setup_token'],
|
||||
'type' => 'SETUP-TOKEN',
|
||||
'type' => 'SETUP_TOKEN',
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->payment_method_tokens_endpoint->payment_tokens( $payment_source );
|
||||
|
||||
if ( is_user_logged_in() && isset( $result->customer->id ) ) {
|
||||
update_user_meta( get_current_user_id(), '_ppcp_target_customer_id', $result->customer->id );
|
||||
|
||||
$email = '';
|
||||
if ( isset( $result->payment_source->paypal->email_address ) ) {
|
||||
$email = $result->payment_source->paypal->email_address;
|
||||
}
|
||||
|
||||
$this->wc_payment_tokens->create_payment_token_paypal(
|
||||
get_current_user_id(),
|
||||
$result->id,
|
||||
$email
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success( $result );
|
||||
return true;
|
||||
} catch ( Exception $exception ) {
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
<?php
|
||||
/**
|
||||
* The Create Setup Token endpoint.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
|
||||
|
||||
|
@ -8,29 +15,37 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
|||
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||
|
||||
class CreateSetupToken implements EndpointInterface
|
||||
{
|
||||
/**
|
||||
* Class CreateSetupToken
|
||||
*/
|
||||
class CreateSetupToken implements EndpointInterface {
|
||||
|
||||
const ENDPOINT = 'ppc-create-setup-token';
|
||||
|
||||
/**
|
||||
* * The request data helper.
|
||||
* The request data helper.
|
||||
*
|
||||
* @var RequestData
|
||||
*/
|
||||
private RequestData $request_data;
|
||||
private $request_data;
|
||||
|
||||
/**
|
||||
* Payment Method Tokens endpoint.
|
||||
*
|
||||
* @var PaymentMethodTokensEndpoint
|
||||
*/
|
||||
private PaymentMethodTokensEndpoint $payment_method_tokens_endpoint;
|
||||
private $payment_method_tokens_endpoint;
|
||||
|
||||
/**
|
||||
* CreateSetupToken constructor.
|
||||
*
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param PaymentMethodTokensEndpoint $payment_method_tokens_endpoint Payment Method Tokens endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
RequestData $request_data,
|
||||
PaymentMethodTokensEndpoint $payment_method_tokens_endpoint
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->request_data = $request_data;
|
||||
$this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint;
|
||||
}
|
||||
|
@ -40,8 +55,7 @@ class CreateSetupToken implements EndpointInterface
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function nonce(): string
|
||||
{
|
||||
public static function nonce(): string {
|
||||
return self::ENDPOINT;
|
||||
}
|
||||
|
||||
|
@ -51,8 +65,7 @@ class CreateSetupToken implements EndpointInterface
|
|||
* @return bool
|
||||
* @throws Exception On Error.
|
||||
*/
|
||||
public function handle_request(): bool
|
||||
{
|
||||
public function handle_request(): bool {
|
||||
try {
|
||||
$this->request_data->read_request( $this->nonce() );
|
||||
|
||||
|
@ -63,15 +76,15 @@ class CreateSetupToken implements EndpointInterface
|
|||
'experience_context' => (object) array(
|
||||
'return_url' => esc_url( wc_get_account_endpoint_url( 'payment-methods' ) ),
|
||||
'cancel_url' => esc_url( wc_get_account_endpoint_url( 'add-payment-method' ) ),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->payment_method_tokens_endpoint->setup_tokens($payment_source);
|
||||
$result = $this->payment_method_tokens_endpoint->setup_tokens( $payment_source );
|
||||
|
||||
wp_send_json_success($result);
|
||||
wp_send_json_success( $result );
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
} catch ( Exception $exception ) {
|
||||
wp_send_json_error();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
|||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use stdClass;
|
||||
use WC_Order;
|
||||
use WC_Payment_Tokens;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
|
@ -116,37 +117,21 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
$payment_token_helper = $c->get( 'vaulting.payment-token-helper' );
|
||||
assert( $payment_token_helper instanceof PaymentTokenHelper );
|
||||
|
||||
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $wc_order->get_customer_id(), PayPalGateway::ID );
|
||||
if ( $payment_token_helper->token_exist( $wc_tokens, $payment_vault_attributes->id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_token_factory = $c->get( 'vaulting.payment-token-factory' );
|
||||
assert( $payment_token_factory instanceof PaymentTokenFactory );
|
||||
|
||||
$payment_token_paypal = $payment_token_factory->create( 'paypal' );
|
||||
assert( $payment_token_paypal instanceof PaymentTokenPayPal );
|
||||
|
||||
$payment_token_paypal->set_token( $payment_vault_attributes->id );
|
||||
$payment_token_paypal->set_user_id( $wc_order->get_customer_id() );
|
||||
$payment_token_paypal->set_gateway_id( PayPalGateway::ID );
|
||||
|
||||
$email = $order->payment_source()->properties()->email_address ?? '';
|
||||
if ( $email && is_email( $email ) ) {
|
||||
$payment_token_paypal->set_email( $email );
|
||||
}
|
||||
|
||||
try {
|
||||
$payment_token_paypal->save();
|
||||
} catch ( Exception $exception ) {
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
|
||||
$logger->error(
|
||||
"Could not save WC payment token PayPal for order #{$wc_order->get_id()}. " . $exception->getMessage()
|
||||
$wc_payment_tokens = $c->get( 'save-payment-methods.wc-payment-tokens' );
|
||||
assert( $wc_payment_tokens instanceof WooCommercePaymentTokens );
|
||||
|
||||
$wc_payment_tokens->create_payment_token_paypal(
|
||||
$wc_order->get_customer_id(),
|
||||
$payment_vault_attributes->id,
|
||||
$order->payment_source()->properties()->email_address ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
10,
|
||||
2
|
||||
|
@ -170,16 +155,16 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
true
|
||||
);
|
||||
|
||||
$api = $c->get('api.user-id-token');
|
||||
assert($api instanceof UserIdToken);
|
||||
$api = $c->get( 'api.user-id-token' );
|
||||
assert( $api instanceof UserIdToken );
|
||||
|
||||
try {
|
||||
$target_customer_id = '';
|
||||
if (is_user_logged_in()) {
|
||||
$target_customer_id = get_user_meta(get_current_user_id(), '_ppcp_target_customer_id', true);
|
||||
if ( is_user_logged_in() ) {
|
||||
$target_customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true );
|
||||
}
|
||||
|
||||
$id_token = $api->id_token($target_customer_id);
|
||||
$id_token = $api->id_token( $target_customer_id );
|
||||
|
||||
wp_localize_script(
|
||||
'ppcp-add-payment-method',
|
||||
|
@ -200,16 +185,16 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
),
|
||||
)
|
||||
);
|
||||
} catch (RuntimeException $exception) {
|
||||
$logger = $c->get('woocommerce.logger.woocommerce');
|
||||
assert($logger instanceof LoggerInterface);
|
||||
} catch ( RuntimeException $exception ) {
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
|
||||
$error = $exception->getMessage();
|
||||
if (is_a($exception, PayPalApiException::class)) {
|
||||
$error = $exception->get_details($error);
|
||||
if ( is_a( $exception, PayPalApiException::class ) ) {
|
||||
$error = $exception->get_details( $error );
|
||||
}
|
||||
|
||||
$logger->error($error);
|
||||
$logger->error( $error );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -221,7 +206,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
echo '<div id="ppc-button-' . PayPalGateway::ID . '-save-payment-method"></div>';
|
||||
echo '<div id="ppc-button-' . esc_attr( PayPalGateway::ID ) . '-save-payment-method"></div>';
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -229,7 +214,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
'wc_ajax_' . CreateSetupToken::ENDPOINT,
|
||||
static function () use ( $c ) {
|
||||
$endpoint = $c->get( 'save-payment-methods.endpoint.create-setup-token' );
|
||||
assert($endpoint instanceof CreateSetupToken);
|
||||
assert( $endpoint instanceof CreateSetupToken );
|
||||
|
||||
$endpoint->handle_request();
|
||||
}
|
||||
|
@ -239,7 +224,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
'wc_ajax_' . CreatePaymentToken::ENDPOINT,
|
||||
static function () use ( $c ) {
|
||||
$endpoint = $c->get( 'save-payment-methods.endpoint.create-payment-token' );
|
||||
assert($endpoint instanceof CreatePaymentToken);
|
||||
assert( $endpoint instanceof CreatePaymentToken );
|
||||
|
||||
$endpoint->handle_request();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
/**
|
||||
* Service to create WC Payment Tokens.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Applepay
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Payment_Tokens;
|
||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenFactory;
|
||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenHelper;
|
||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenPayPal;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class WooCommercePaymentTokens
|
||||
*/
|
||||
class WooCommercePaymentTokens {
|
||||
|
||||
/**
|
||||
* The payment token helper.
|
||||
*
|
||||
* @var PaymentTokenHelper
|
||||
*/
|
||||
private $payment_token_helper;
|
||||
|
||||
/**
|
||||
* The payment token factory.
|
||||
*
|
||||
* @var PaymentTokenFactory
|
||||
*/
|
||||
private $payment_token_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function __construct(
|
||||
PaymentTokenHelper $payment_token_helper,
|
||||
PaymentTokenFactory $payment_token_factory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->payment_token_helper = $payment_token_helper;
|
||||
$this->payment_token_factory = $payment_token_factory;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function create_payment_token_paypal(
|
||||
int $customer_id,
|
||||
string $token,
|
||||
string $email
|
||||
): void {
|
||||
|
||||
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
|
||||
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_token_paypal = $this->payment_token_factory->create( 'paypal' );
|
||||
assert( $payment_token_paypal instanceof PaymentTokenPayPal );
|
||||
|
||||
$payment_token_paypal->set_token( $token );
|
||||
$payment_token_paypal->set_user_id( $customer_id );
|
||||
$payment_token_paypal->set_gateway_id( PayPalGateway::ID );
|
||||
|
||||
if ( $email && is_email( $email ) ) {
|
||||
$payment_token_paypal->set_email( $email );
|
||||
}
|
||||
|
||||
try {
|
||||
$payment_token_paypal->save();
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error(
|
||||
"Could not create WC payment token PayPal for customer {$customer_id}. " . $exception->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,7 +60,6 @@ return array(
|
|||
$source
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array {
|
||||
$path_to_settings_fields = __DIR__ . '/src/Settings/Fields';
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue