mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
load data-client-id via endpoint when needed
This commit is contained in:
parent
4f72597a9a
commit
56b510e8fc
6 changed files with 138 additions and 17 deletions
|
@ -5,6 +5,7 @@ import CheckoutBootstap from './modules/ContextBootstrap/CheckoutBootstap';
|
|||
import Renderer from './modules/Renderer/Renderer';
|
||||
import ErrorHandler from './modules/ErrorHandler';
|
||||
import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
|
||||
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
||||
|
||||
const bootstrap = () => {
|
||||
const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
|
||||
|
@ -57,15 +58,20 @@ document.addEventListener(
|
|||
}
|
||||
const script = document.createElement('script');
|
||||
|
||||
script.addEventListener('load', (event) => {
|
||||
bootstrap();
|
||||
});
|
||||
script.setAttribute('src', PayPalCommerceGateway.button.url);
|
||||
Object.entries(PayPalCommerceGateway.script_attributes).forEach(
|
||||
(keyValue) => {
|
||||
script.setAttribute(keyValue[0], keyValue[1]);
|
||||
}
|
||||
);
|
||||
script.addEventListener('load', (event) => {
|
||||
bootstrap();
|
||||
});
|
||||
|
||||
if (PayPalCommerceGateway.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.append(script);
|
||||
},
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
const storageKey = 'ppcp-data-client-id';
|
||||
|
||||
const validateToken = (token, user) => {
|
||||
if (! token) {
|
||||
return false;
|
||||
}
|
||||
if (token.user !== user) {
|
||||
return false;
|
||||
}
|
||||
const currentTime = new Date().getTime();
|
||||
const isExpired = currentTime >= token.expiration * 1000;
|
||||
return ! isExpired;
|
||||
}
|
||||
|
||||
const storedTokenForUser = (user) => {
|
||||
const token = JSON.parse(sessionStorage.getItem(storageKey));
|
||||
if (validateToken(token, user)) {
|
||||
return token.token;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const storeToken = (token) => {
|
||||
sessionStorage.setItem(storageKey, JSON.stringify(token));
|
||||
}
|
||||
|
||||
const dataClientIdAttributeHandler = (script, config) => {
|
||||
const token = storedTokenForUser(config.user);
|
||||
if (token) {
|
||||
script.setAttribute('data-client-token', token);
|
||||
document.body.append(script);
|
||||
return;
|
||||
}
|
||||
fetch(config.endpoint, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
nonce: config.nonce
|
||||
})
|
||||
}).then((res)=>{
|
||||
return res.json();
|
||||
}).then((data)=>{
|
||||
const isValid = validateToken(data, config.user);
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
storeToken(data);
|
||||
script.setAttribute('data-client-token', data.token);
|
||||
document.body.append(script);
|
||||
});
|
||||
}
|
||||
|
||||
export default dataClientIdAttributeHandler;
|
|
@ -11,6 +11,7 @@ use Inpsyde\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
|||
use Inpsyde\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\RequestData;
|
||||
use Inpsyde\PayPalCommerce\Button\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\Button\Helper\ThreeDSecure;
|
||||
|
@ -106,6 +107,14 @@ return [
|
|||
$threeDSecure = $container->get('button.helper.three-d-secure');
|
||||
return new ApproveOrderEndpoint($requestData, $apiClient, $sessionHandler, $threeDSecure);
|
||||
},
|
||||
'button.endpoint.data-client-id' => static function(ContainerInterface $container) : DataClientIdEndpoint {
|
||||
$requestData = $container->get('button.request-data');
|
||||
$tokenEndpoint = $container->get('api.endpoint.identity-token');
|
||||
return new DataClientIdEndpoint(
|
||||
$requestData,
|
||||
$tokenEndpoint
|
||||
);
|
||||
},
|
||||
'button.helper.three-d-secure' => static function (ContainerInterface $container): ThreeDSecure {
|
||||
return new ThreeDSecure();
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ use Inpsyde\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
|||
use Inpsyde\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\RequestData;
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
|
@ -305,6 +306,12 @@ class SmartButton implements SmartButtonInterface
|
|||
$this->requestData->enqueueNonceFix();
|
||||
$localize = [
|
||||
'script_attributes' => $this->attributes(),
|
||||
'data_client_id' => [
|
||||
'set_attribute' => $this->dccIsEnabled() || $this->canSaveVaultToken(),
|
||||
'endpoint' => home_url(\WC_AJAX::get_endpoint(DataClientIdEndpoint::ENDPOINT)),
|
||||
'nonce' => wp_create_nonce(DataClientIdEndpoint::nonce()),
|
||||
'user' => get_current_user_id(),
|
||||
],
|
||||
'redirect' => wc_get_checkout_url(),
|
||||
'context' => $this->context(),
|
||||
'ajax' => [
|
||||
|
@ -408,22 +415,9 @@ class SmartButton implements SmartButtonInterface
|
|||
|
||||
private function attributes(): array
|
||||
{
|
||||
$attributes = [
|
||||
return [
|
||||
'data-partner-attribution-id' => $this->bnCodeForContext($this->context()),
|
||||
];
|
||||
try {
|
||||
if (!is_user_logged_in()) {
|
||||
return $attributes;
|
||||
}
|
||||
if (! $this->dccIsEnabled() && ! $this->canSaveVaultToken()) {
|
||||
return $attributes;
|
||||
}
|
||||
$clientToken = $this->identityToken->generateForCustomer((int) get_current_user_id());
|
||||
$attributes['data-client-token'] = $clientToken->token();
|
||||
return $attributes;
|
||||
} catch (RuntimeException $exception) {
|
||||
return $attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@ use Inpsyde\PayPalCommerce\Button\Assets\SmartButton;
|
|||
use Inpsyde\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Button\Endpoint\RequestData;
|
||||
use Interop\Container\ServiceProviderInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
@ -49,6 +50,17 @@ class ButtonModule implements ModuleInterface
|
|||
$smartButton->enqueue();
|
||||
});
|
||||
|
||||
add_action(
|
||||
'wc_ajax_' . DataClientIdEndpoint::ENDPOINT,
|
||||
static function () use ($container) {
|
||||
$endpoint = $container->get('button.endpoint.data-client-id');
|
||||
/**
|
||||
* @var DataClientIdEndpoint $endpoint
|
||||
*/
|
||||
$endpoint->handleRequest();
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wc_ajax_' . ChangeCartEndpoint::ENDPOINT,
|
||||
static function () use ($container) {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\Button\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class DataClientIdEndpoint implements EndpointInterface
|
||||
{
|
||||
|
||||
public const ENDPOINT = 'data-client-id';
|
||||
|
||||
private $requestData;
|
||||
private $identityToken;
|
||||
public function __construct(
|
||||
RequestData $requestData,
|
||||
IdentityToken $identityToken
|
||||
) {
|
||||
|
||||
$this->requestData = $requestData;
|
||||
$this->identityToken = $identityToken;
|
||||
}
|
||||
|
||||
public static function nonce(): string
|
||||
{
|
||||
return self::ENDPOINT;
|
||||
}
|
||||
|
||||
public function handleRequest(): bool
|
||||
{
|
||||
try {
|
||||
$this->requestData->readRequest($this->nonce());
|
||||
$userId = get_current_user_id();
|
||||
$token = $this->identityToken->generateForCustomer($userId);
|
||||
wp_send_json([
|
||||
'token' => $token->token(),
|
||||
'expiration' => $token->expirationTimestamp(),
|
||||
'user' => get_current_user_id(),
|
||||
]);
|
||||
return true;
|
||||
} catch (RuntimeException $error) {
|
||||
wp_send_json_error($error->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue