Skip to content

Commit

Permalink
[PW-7179] - Adjust vault tokenization functionality (#1709)
Browse files Browse the repository at this point in the history
* PW-7179 - Re-add parent AdyenUiComponentProvider

* PW-7179 - Check if property exists before checking type

* PW-7179 - Fix issue created in merge commit and update PaymentVaultDeleteToken

* PW-7179 - Do not show ApplePay and AmazonPay for now. Also add to do annotations for them

* [PW-7157]Add India live prefix for frontend (#1708)

* Add India live prefix for frontend

* revert adyen-methods.js

Co-authored-by: Jeantwan Teuma <Morerice@users.noreply.github.com>

* PW-7179 - Move tooltip to comment

* PW-7129: Remove full request/response logging (#1712)

* PW-7129: Remove full request/response logging

Add new log processors to help with troubleshooting.

* PW-7129: Use context placeholders

* Adding number format to getAmountIncludingTax in test (#1715)

* Adding number format to getAmountIncludingTax in test

* Apply number format on getTaxAmount

Co-authored-by: Alexandros Moraitis <alexandros.moraitis@adyen.com>
Co-authored-by: Michael Paul <michael.paul@adyen.com>
Co-authored-by: Ángel Campos <angel.campos@adyen.com>
  • Loading branch information
4 people committed Sep 20, 2022
1 parent 1794741 commit 9ec4f80
Show file tree
Hide file tree
Showing 16 changed files with 118 additions and 66 deletions.
8 changes: 5 additions & 3 deletions Helper/Data.php
Expand Up @@ -55,6 +55,7 @@ class Data extends AbstractHelper
const LIVE = 'live';
const LIVE_AU = 'live-au';
const LIVE_US = 'live-us';
const LIVE_IN = 'live-in';
const PSP_REFERENCE_REGEX = '/(?P<pspReference>[0-9.A-Z]{16})(?P<suffix>[a-z\-]*)/';
const AFTERPAY = 'afterpay';
const AFTERPAY_TOUCH = 'afterpaytouch';
Expand Down Expand Up @@ -286,7 +287,8 @@ public function getCheckoutFrontendRegions()
return [
'eu' => 'Default (EU - Europe)',
'au' => 'AU - Australasia',
'us' => 'US - United States'
'us' => 'US - United States',
'in' => 'IN - India'
];
}

Expand Down Expand Up @@ -1494,8 +1496,6 @@ public function initializeAdyenClient($storeId = null, $apiKey = null, $motoMerc
$client->setEnvironment(\Adyen\Environment::LIVE, $this->getLiveEndpointPrefix($storeId));
}

$client->setLogger($this->adyenLogger);

return $client;
}

Expand Down Expand Up @@ -1613,6 +1613,8 @@ public function getCheckoutEnvironment($storeId = null)
return self::LIVE_AU;
case "us":
return self::LIVE_US;
case "in":
return self::LIVE_IN;
default:
return self::LIVE;
}
Expand Down
8 changes: 4 additions & 4 deletions Helper/PaymentMethods/AmazonPayPaymentMethod.php
Expand Up @@ -12,7 +12,7 @@

namespace Adyen\Payment\Helper\PaymentMethods;


/** TODO: This PM can be enabled for recurring purposes once tested */
class AmazonPayPaymentMethod extends AbstractWalletPaymentMethod
{
const TX_VARIANT = 'amazonpay';
Expand Down Expand Up @@ -40,16 +40,16 @@ public function supportsAutoCapture(): bool

public function supportsCardOnFile(): bool
{
return true;
return false;
}

public function supportsSubscription(): bool
{
return true;
return false;
}

public function supportsUnscheduledCardOnFile(): bool
{
return true;
return false;
}
}
7 changes: 4 additions & 3 deletions Helper/PaymentMethods/ApplePayPaymentMethod.php
Expand Up @@ -11,6 +11,7 @@
*/
namespace Adyen\Payment\Helper\PaymentMethods;

/** TODO: This PM can be enabled for recurring purposes once tested */
class ApplePayPaymentMethod extends AbstractWalletPaymentMethod
{
const TX_VARIANT = 'applepay';
Expand Down Expand Up @@ -38,16 +39,16 @@ public function supportsAutoCapture(): bool

public function supportsCardOnFile(): bool
{
return true;
return false;
}

public function supportsSubscription(): bool
{
return true;
return false;
}

public function supportsUnscheduledCardOnFile(): bool
{
return true;
return false;
}
}
2 changes: 1 addition & 1 deletion Helper/Webhook.php
Expand Up @@ -162,7 +162,7 @@ public function processNotification(Notification $notification): bool
$currentState = $this->getCurrentState($this->order->getState());
if (!$currentState) {
$this->logger->addAdyenNotification(
sprintf("ERROR: Unhandled order state '%s'.", $this->order->getState()),
"ERROR: Unhandled order state '{orderState}'",
$this->logger->getOrderContext($this->order)
);
return false;
Expand Down
2 changes: 1 addition & 1 deletion Helper/Webhook/CaptureWebhookHandler.php
Expand Up @@ -105,7 +105,7 @@ public function handleWebhook(MagentoOrder $order, Notification $notification, s

$magentoInvoice = $this->magentoInvoiceFactory->create()->load($adyenInvoice->getInvoiceId(), MagentoInvoice::ENTITY_ID);
$this->adyenLogger->addAdyenNotification(
sprintf('Notification %s updated invoice %s.', $notification->getEntityId(), $magentoInvoice->getEntityid()),
sprintf('Notification %s updated invoice {invoiceId}', $notification->getEntityId()),
$this->adyenLogger->getInvoiceContext($magentoInvoice)
);

Expand Down
2 changes: 1 addition & 1 deletion Model/Comment/TokenizedPaymentMethods.php
Expand Up @@ -22,6 +22,6 @@ class TokenizedPaymentMethods implements CommentInterface
*/
public function getCommentText($elementValue): string
{
return 'Selected payment methods will automatically be tokenized on every transaction. At the moment, CardOnFile tokens can only be created using Wallet payment methods (Google Pay, Amazon Pay etc.).';
return 'Selected payment methods will automatically be tokenized on every transaction. At the moment, CardOnFile tokens can only be created using Wallet payment methods (Google Pay).';
}
}
5 changes: 3 additions & 2 deletions Model/Config/Source/TokenizedPaymentMethods.php
Expand Up @@ -13,14 +13,15 @@ class TokenizedPaymentMethods implements OptionSourceInterface
public function toOptionArray()
{
return [
/** TODO: These PMs can be enabled for recurring purposes once tested */
/*[
'value' => PaymentMethods\ApplePayPaymentMethod::TX_VARIANT,
'label' => PaymentMethods\ApplePayPaymentMethod::NAME
],*/
],
[
'value' => PaymentMethods\AmazonPayPaymentMethod::TX_VARIANT,
'label' => PaymentMethods\AmazonPayPaymentMethod::NAME
],
],*/
[
'value' => PaymentMethods\GooglePayPaymentMethod::TX_VARIANT,
'label' => PaymentMethods\GooglePayPaymentMethod::NAME
Expand Down
60 changes: 60 additions & 0 deletions Model/Ui/AdyenUiComponentProvider.php
@@ -0,0 +1,60 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2022 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Model\Ui;

use Adyen\Payment\Helper\Data;
use Magento\Vault\Api\Data\PaymentTokenInterface;
use Magento\Vault\Model\Ui\TokenUiComponentInterface;
use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface;
use Magento\Vault\Model\Ui\TokenUiComponentInterfaceFactory;

class AdyenUiComponentProvider
{

protected $componentFactory;
protected $dataHelper;

/**
* @param TokenUiComponentInterfaceFactory $componentFactory
* @param Data $dataHelper
*/
public function __construct(
TokenUiComponentInterfaceFactory $componentFactory,
Data $dataHelper
) {
$this->componentFactory = $componentFactory;
$this->dataHelper = $dataHelper;
}

/**
* Get UI component for token
*
* @param PaymentTokenInterface $paymentToken
* @return TokenUiComponentInterface
*/
public function getCardComponentForToken(PaymentTokenInterface $paymentToken): TokenUiComponentInterface
{
$details = json_decode($paymentToken->getTokenDetails() ?: '{}', true);
$details['icon'] = $this->dataHelper->getVariantIcon($details['type']);

return $this->componentFactory->create(
[
'config' => [
'code' => AdyenCcConfigProvider::CC_VAULT_CODE,
TokenUiComponentProviderInterface::COMPONENT_DETAILS => $details,
TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash()
],
'name' => 'Adyen_Payment/js/view/payment/method-renderer/vault'
]
);
}
}
5 changes: 2 additions & 3 deletions Model/Ui/PaymentMethodUiComponentProvider.php
Expand Up @@ -22,12 +22,11 @@
use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface;
use Magento\Vault\Model\Ui\TokenUiComponentInterfaceFactory;

class PaymentMethodUiComponentProvider implements TokenUiComponentProviderInterface
class PaymentMethodUiComponentProvider extends AdyenUiComponentProvider implements TokenUiComponentProviderInterface
{

private $vaultHelper;
private $paymentMethodFactory;
private $dataHelper;

/**
* @param TokenUiComponentInterfaceFactory $componentFactory
Expand All @@ -41,7 +40,7 @@ public function __construct(
Vault $vaultHelper,
PaymentMethodFactory $paymentMethodFactory
) {
$this->dataHelper = $dataHelper;
parent::__construct($componentFactory, $dataHelper);
$this->vaultHelper = $vaultHelper;
$this->paymentMethodFactory = $paymentMethodFactory;
}
Expand Down
34 changes: 2 additions & 32 deletions Model/Ui/TokenUiComponentProvider.php
Expand Up @@ -19,22 +19,8 @@
use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface;
use Magento\Vault\Model\Ui\TokenUiComponentInterfaceFactory;

class TokenUiComponentProvider implements TokenUiComponentProviderInterface
class TokenUiComponentProvider extends AdyenUiComponentProvider implements TokenUiComponentProviderInterface
{
/**
* @param TokenUiComponentInterfaceFactory $componentFactory
* @param Data $dataHelper
*/
public function __construct(
TokenUiComponentInterfaceFactory $componentFactory,
Data $dataHelper,
Vault $vaultHelper
) {
$this->componentFactory = $componentFactory;
$this->dataHelper = $dataHelper;
$this->vaultHelper = $vaultHelper;
}

/**
* Get UI component for token
*
Expand All @@ -43,22 +29,6 @@ public function __construct(
*/
public function getComponentForToken(PaymentTokenInterface $paymentToken): TokenUiComponentInterface
{
$tokenType = $this->vaultHelper->getAdyenTokenType($paymentToken);
$details = json_decode($paymentToken->getTokenDetails() ?: '{}', true);
$details['icon'] = $this->dataHelper->getVariantIcon($details['type']);
$createdAt = new \DateTime($paymentToken->getCreatedAt());
$details['created'] = $createdAt->format('Y-m-d');
$details['displayToken'] = $tokenType === Recurring::CARD_ON_FILE || is_null($tokenType);

return $this->componentFactory->create(
[
'config' => [
'code' => AdyenCcConfigProvider::CC_VAULT_CODE,
TokenUiComponentProviderInterface::COMPONENT_DETAILS => $details,
TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash()
],
'name' => 'Adyen_Payment/js/view/payment/method-renderer/adyen-vault-method'
]
);
return $this->getCardComponentForToken($paymentToken);
}
}
4 changes: 2 additions & 2 deletions Observer/InvoiceObserver.php
Expand Up @@ -104,7 +104,7 @@ public function execute(Observer $observer)


$this->logger->addAdyenDebug(
sprintf('Event sales_order_invoice_save_after for invoice %s will be handled', $invoice->getEntityId()),
'Event sales_order_invoice_save_after for invoice {invoiceId} will be handled',
array_merge($this->logger->getInvoiceContext($invoice), $this->logger->getOrderContext($order))
);

Expand Down Expand Up @@ -134,7 +134,7 @@ public function execute(Observer $observer)
$order->setStatus($status);

$this->logger->addAdyenDebug(
sprintf('Event sales_order_invoice_save_after for invoice %s was handled', $invoice->getEntityId()),
'Event sales_order_invoice_save_after for invoice {invoiceId} was handled',
array_merge($this->logger->getInvoiceContext($invoice), $this->logger->getOrderContext($order))
);
}
Expand Down
5 changes: 4 additions & 1 deletion Plugin/CustomerFilterVaultTokens.php
Expand Up @@ -11,13 +11,16 @@

namespace Adyen\Payment\Plugin;

use Adyen\Payment\Helper\Vault;
use Magento\Vault\Model\CustomerTokenManagement;
use Adyen\Payment\Helper\Recurring;

class CustomerFilterVaultTokens
{
/**
* Returns filtered list of payment tokens for current customer session
* Hide token if it is specifically set to SUBSCRIPTION or UNSCHEDULED_CARD_ON_FILE
*
* @param CustomerTokenManagement $customerTokenManagement
* @param array $customerSessionTokens
* @return array
Expand All @@ -27,7 +30,7 @@ public function afterGetCustomerSessionTokens(CustomerTokenManagement $customerT
foreach($customerSessionTokens as $key => $token) {
if (strpos($token->getPaymentMethodCode(), 'adyen_') === 0) {
$tokenDetails = json_decode($token->getTokenDetails());
if ($tokenDetails->tokenType === Recurring::UNSCHEDULED_CARD_ON_FILE || $tokenDetails->tokenType === Recurring::SUBSCRIPTION) {
if (property_exists($tokenDetails, Vault::TOKEN_TYPE) && in_array($tokenDetails->tokenType, [Recurring::SUBSCRIPTION, Recurring::UNSCHEDULED_CARD_ON_FILE])) {
unset($customerSessionTokens[$key]);
}
}
Expand Down
30 changes: 21 additions & 9 deletions Plugin/PaymentVaultDeleteToken.php
Expand Up @@ -3,58 +3,70 @@
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2019 Adyen BV (https://www.adyen.com/)
* Copyright (c) 2022 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Plugin;

use Adyen\Payment\Model\Api\PaymentRequest;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Vault\Api\Data\PaymentTokenInterface;
use Magento\Vault\Api\PaymentTokenRepositoryInterface;

class PaymentVaultDeleteToken
{
/**
* @var \Adyen\Payment\Model\Api\PaymentRequest
* @var PaymentRequest
*/
protected $paymentRequest;

/**
* @var \Magento\Store\Model\StoreManagerInterface
* @var StoreManagerInterface
*/
protected $storeManager;

/**
* PaymentVaultDeleteToken constructor.
*
* @param \Adyen\Payment\Model\Api\PaymentRequest $paymentRequest
* @param PaymentRequest $paymentRequest
* @param StoreManagerInterface $storeManager
*/
public function __construct(
\Adyen\Payment\Model\Api\PaymentRequest $paymentRequest,
\Magento\Store\Model\StoreManagerInterface $storeManager
PaymentRequest $paymentRequest,
StoreManagerInterface $storeManager
) {
$this->paymentRequest = $paymentRequest;
$this->storeManager = $storeManager;
}

/**
* @throws NoSuchEntityException
* @throws LocalizedException
*/
public function beforeDelete(
\Magento\Vault\Api\PaymentTokenRepositoryInterface $subject,
PaymentTokenRepositoryInterface $subject,
PaymentTokenInterface $paymentToken
) {
$paymentMethodCode = $paymentToken->getPaymentMethodCode();
$storeId = $this->storeManager->getStore()->getStoreId();

if (is_null($paymentMethodCode) || strpos($paymentMethodCode, 'adyen_') !== 0) {
return [$paymentToken];
}

try {
$this->paymentRequest->disableRecurringContract(
$paymentToken->getGatewayToken(),
$paymentToken->getCustomerId(),
$this->storeManager->getStore()->getStoreId()
$storeId
);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(__('Failed to disable this contract'));
throw new LocalizedException(__('Failed to disable this contract'));
}
}
}

0 comments on commit 9ec4f80

Please sign in to comment.