From 658bfd70056896f2ac597625e6ffafbe9137b8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ke=CC=81vin=20Allard?= Date: Fri, 25 Mar 2022 13:28:32 +0100 Subject: [PATCH 1/5] CHECMAG2003-50: fix issue if keys are stored in website or store scope --- Setup/Patch/Data/EncryptOldApiKeys.php | 28 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Setup/Patch/Data/EncryptOldApiKeys.php b/Setup/Patch/Data/EncryptOldApiKeys.php index 33b1165e..8818898e 100644 --- a/Setup/Patch/Data/EncryptOldApiKeys.php +++ b/Setup/Patch/Data/EncryptOldApiKeys.php @@ -116,17 +116,29 @@ public function apply() /** @var string $coreConfigDataTable */ $coreConfigDataTable = $setup->getTableName('core_config_data'); /** @var Select $query */ - $query = $setup->select()->from($coreConfigDataTable, ['value'])->where('path = ?', $configPath); - /** @var mixed $oldKey */ - $oldKey = $setup->fetchRow($query); + $query = $setup->select()->from($coreConfigDataTable, ['scope', 'scope_id', 'value'])->where('path = ?', $configPath); + /** @var mixed[] $oldKeys */ + $oldKeys = $setup->fetchAll($query); - if ($oldKey) { - $oldKey = $oldKey['value']; - /** @var string $encryptedKey */ - $encryptedKey = $this->encryptor->encrypt($oldKey); - $this->writer->save($configPath, $encryptedKey); + /** @var mixed[] $oldKey */ + foreach ($oldKeys as $oldKey) { + $this->encryptKey($oldKey, $configPath); } } $this->moduleDataSetup->getConnection()->endSetup(); } + + /** + * @param mixed[] $oldKey + * @param string $configPath + * + * @return void + */ + public function encryptKey(array $oldKey, string $configPath): void { + if ($oldKey) { + /** @var string $encryptedKey */ + $encryptedKey = $this->encryptor->encrypt($oldKey['value']); + $this->writer->save($configPath, $encryptedKey, $oldKey['scope'], (int)$oldKey['scope_id']); + } + } } From 29387c3988f15745c0a6e908244c6096955500d0 Mon Sep 17 00:00:00 2001 From: Paul Negrerie Date: Mon, 28 Mar 2022 14:49:47 +0200 Subject: [PATCH 2/5] CHECMAG2003-43: Add 3ds config on Google Pay method --- Model/Methods/GooglePayMethod.php | 75 +++++---- etc/adminhtml/system.xml | 9 +- .../method-renderer/checkoutcom_google_pay.js | 157 ++++++++++-------- 3 files changed, 133 insertions(+), 108 deletions(-) diff --git a/Model/Methods/GooglePayMethod.php b/Model/Methods/GooglePayMethod.php index 99a72405..dfd4958a 100755 --- a/Model/Methods/GooglePayMethod.php +++ b/Model/Methods/GooglePayMethod.php @@ -22,6 +22,7 @@ use Checkout\Library\Exceptions\CheckoutHttpException; use Checkout\Models\Payments\BillingDescriptor; use Checkout\Models\Payments\Payment; +use Checkout\Models\Payments\ThreeDs; use Checkout\Models\Payments\TokenSource; use Checkout\Models\Tokens\GooglePay; use CheckoutCom\Magento2\Gateway\Config\Config; @@ -39,7 +40,6 @@ use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Message\ManagerInterface; use Magento\Framework\Model\Context; use Magento\Framework\Model\ResourceModel\AbstractResource; use Magento\Framework\Registry; @@ -160,25 +160,25 @@ class GooglePayMethod extends AbstractMethod /** * GooglePayMethod constructor * - * @param Context $context - * @param Registry $registry + * @param Context $context + * @param Registry $registry * @param ExtensionAttributesFactory $extensionFactory - * @param AttributeValueFactory $customAttributeFactory - * @param Data $paymentData - * @param ScopeConfigInterface $scopeConfig - * @param Logger $logger - * @param Config $config - * @param ApiHandlerService $apiHandler - * @param Utilities $utilities - * @param StoreManagerInterface $storeManager - * @param QuoteHandlerService $quoteHandler - * @param LoggerHelper $ckoLogger - * @param Session $backendAuthSession - * @param DirectoryHelper $directoryHelper - * @param DataObjectFactory $dataObjectFactory - * @param AbstractResource|null $resource - * @param AbstractDb|null $resourceCollection - * @param array $data + * @param AttributeValueFactory $customAttributeFactory + * @param Data $paymentData + * @param ScopeConfigInterface $scopeConfig + * @param Logger $logger + * @param Config $config + * @param ApiHandlerService $apiHandler + * @param Utilities $utilities + * @param StoreManagerInterface $storeManager + * @param QuoteHandlerService $quoteHandler + * @param LoggerHelper $ckoLogger + * @param Session $backendAuthSession + * @param DirectoryHelper $directoryHelper + * @param DataObjectFactory $dataObjectFactory + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data */ public function __construct( Context $context, @@ -217,12 +217,12 @@ public function __construct( $data ); - $this->config = $config; - $this->apiHandler = $apiHandler; - $this->utilities = $utilities; - $this->storeManager = $storeManager; - $this->quoteHandler = $quoteHandler; - $this->ckoLogger = $ckoLogger; + $this->config = $config; + $this->apiHandler = $apiHandler; + $this->utilities = $utilities; + $this->storeManager = $storeManager; + $this->quoteHandler = $quoteHandler; + $this->ckoLogger = $ckoLogger; $this->backendAuthSession = $backendAuthSession; } @@ -230,9 +230,9 @@ public function __construct( * Send a charge request * * @param string[] $data - * @param float $amount - * @param string $currency - * @param string $reference + * @param float $amount + * @param string $currency + * @param string $reference * * @return mixed|void * @throws FileSystemException @@ -263,6 +263,7 @@ public function sendPaymentRequest(array $data, float $amount, string $currency, $tokenSource = new TokenSource($tokenData->getId()); // Set the payment + /** @var Payment $request */ $request = new Payment( $tokenSource, $currency ); @@ -278,15 +279,19 @@ public function sendPaymentRequest(array $data, float $amount, string $currency, } // Set the request parameters - $request->amount = $this->quoteHandler->amountToGateway( + $request->amount = $this->quoteHandler->amountToGateway( $this->utilities->formatDecimals($amount), $quote ); - $request->reference = $reference; - $request->description = __('Payment request from %1', $this->config->getStoreName())->render(); - $request->customer = $api->createCustomer($quote); + + $request->reference = $reference; + $request->success_url = $this->config->getStoreUrl() . 'checkout_com/payment/verify'; + $request->failure_url = $this->config->getStoreUrl() . 'checkout_com/payment/fail'; + $request->threeDs = new ThreeDs($this->config->needs3ds($this->_code)); + $request->description = __('Payment request from %1', $this->config->getStoreName())->render(); + $request->customer = $api->createCustomer($quote); $request->payment_type = 'Regular'; - $request->shipping = $api->createShippingAddress($quote); + $request->shipping = $api->createShippingAddress($quote); // Billing descriptor if ($this->config->needsDynamicDescriptor()) { @@ -318,7 +323,7 @@ public function sendPaymentRequest(array $data, float $amount, string $currency, * Perform a capture request * * @param InfoInterface $payment - * @param float $amount + * @param float $amount * * @return $this|GooglePayMethod * @throws LocalizedException @@ -442,7 +447,7 @@ public function cancel(InfoInterface $payment): AbstractMethod * Perform a refund request * * @param InfoInterface $payment - * @param float $amount + * @param float $amount * * @return $this|GooglePayMethod * @throws LocalizedException diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 7c2d5616..764b720d 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -94,7 +94,7 @@ Magento\Config\Model\Config\Source\Yesno settings/checkoutcom_configuration/webhooks_table_enabled - This enables webhooks to be logged to a dedicated table to improve traceability for when webhook events are received. + This enables webhooks to be logged to a dedicated table to improve traceability for when webhook events are received. @@ -420,7 +420,6 @@ The Apple Pay merchant id (e.g. merchant.example.com.sandbox). Make sure you validated this domain in the mercahnt id settings. - payment/checkoutcom_apple_pay/merchant_id_certificate @@ -477,6 +476,12 @@ + + + Magento\Config\Model\Config\Source\Yesno + payment/checkoutcom_google_pay/three_ds + + validate-number diff --git a/view/frontend/web/js/view/payment/method-renderer/checkoutcom_google_pay.js b/view/frontend/web/js/view/payment/method-renderer/checkoutcom_google_pay.js index 72a88bc1..ca4ef1b5 100755 --- a/view/frontend/web/js/view/payment/method-renderer/checkoutcom_google_pay.js +++ b/view/frontend/web/js/view/payment/method-renderer/checkoutcom_google_pay.js @@ -22,9 +22,11 @@ define( 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Checkout/js/action/redirect-on-success', 'mage/translate', - 'googlepayjs' + 'googlepayjs', ], - function ($, Component, Utilities, FullScreenLoader, AdditionalValidators, RedirectOnSuccessAction, __) { + function( + $, Component, Utilities, FullScreenLoader, AdditionalValidators, + RedirectOnSuccessAction, __) { 'use strict'; window.checkoutConfig.reloadOnBillingAddress = true; const METHOD_ID = 'checkoutcom_google_pay'; @@ -32,15 +34,16 @@ define( return Component.extend( { defaults: { - template: 'CheckoutCom_Magento2/payment/' + METHOD_ID + '.html', + template: 'CheckoutCom_Magento2/payment/' + METHOD_ID + + '.html', button_target: '#ckoGooglePayButton', - redirectAfterPlaceOrder: false + redirectAfterPlaceOrder: false, }, /** * @return {exports} */ - initialize: function () { + initialize: function() { this._super(); Utilities.setEmail(); Utilities.loadCss('google-pay', 'google-pay'); @@ -55,14 +58,14 @@ define( /** * @return {string} */ - getCode: function () { + getCode: function() { return METHOD_ID; }, /** * @return {string} */ - getValue: function (field) { + getValue: function(field) { return Utilities.getValue(METHOD_ID, field); }, @@ -72,23 +75,25 @@ define( /** * @return {array} */ - getAllowedNetworks: function () { + getAllowedNetworks: function() { return this.getValue('allowed_card_networks').split(','); }, /** * @return {bool} */ - launchGooglePay: function () { + launchGooglePay: function() { // Prepare the parameters var self = this; // Apply the button style - $(self.button_target).addClass('google-pay-button-' + self.getValue('button_style')); + $(self.button_target). + addClass('google-pay-button-' + + self.getValue('button_style')); // Button click event $(self.button_target).click( - function (evt) { + function(evt) { if (Utilities.methodIsSelected(METHOD_ID)) { // Validate T&C submission if (!AdditionalValidators.validate()) { @@ -96,16 +101,20 @@ define( } // Prepare the payment parameters - var allowedPaymentMethods = ['CARD', 'TOKENIZED_CARD']; + var allowedPaymentMethods = [ + 'CARD', + 'TOKENIZED_CARD']; var allowedCardNetworks = self.getAllowedNetworks(); var tokenizationParameters = { tokenizationType: 'PAYMENT_GATEWAY', parameters: { - 'gateway': self.getValue('gateway_name'), - 'gatewayMerchantId': self.getValue('public_key') - } - } + 'gateway': self.getValue( + 'gateway_name'), + 'gatewayMerchantId': self.getValue( + 'public_key'), + }, + }; // Prepare the Google Pay client onGooglePayLoaded(); @@ -117,17 +126,16 @@ define( paymentDataRequest.transactionInfo = getGoogleTransactionInfo(); var paymentsClient = getGooglePaymentsClient(); - paymentsClient.loadPaymentData(paymentDataRequest) - .then( - function (paymentData) { + paymentsClient.loadPaymentData( + paymentDataRequest).then( + function(paymentData) { // handle the response processPayment(paymentData); - } - ) - .catch( - function (error) { + }, + ).catch( + function(error) { Utilities.log(error); - } + }, ); /** @@ -135,34 +143,34 @@ define( * * @return {google.payments.api.PaymentsClient} Google Pay API client */ - function getGooglePaymentsClient() - { + function getGooglePaymentsClient() { return (new google.payments.api.PaymentsClient( { - environment: self.getValue('environment') - } + environment: self.getValue( + 'environment'), + }, )); } /** * Initialize Google PaymentsClient after Google-hosted JavaScript has loaded */ - function onGooglePayLoaded() - { + function onGooglePayLoaded() { var paymentsClient = getGooglePaymentsClient(); - paymentsClient.isReadyToPay({ allowedPaymentMethods: allowedPaymentMethods }) - .then( - function (response) { - if (response.result) { - prefetchGooglePaymentData(); - } - } - ) - .catch( - function (err) { - Utilities.log(err); - } - ); + paymentsClient.isReadyToPay( + {allowedPaymentMethods: allowedPaymentMethods}). + then( + function(response) { + if (response.result) { + prefetchGooglePaymentData(); + } + }, + ). + catch( + function(err) { + Utilities.log(err); + }, + ); } /** @@ -171,15 +179,15 @@ define( * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentDataRequest|PaymentDataRequest} * @return {object} PaymentDataRequest fields */ - function getGooglePaymentDataConfiguration() - { + function getGooglePaymentDataConfiguration() { return { - merchantId: self.getValue('merchant_id'), + merchantId: self.getValue( + 'merchant_id'), paymentMethodTokenizationParameters: tokenizationParameters, allowedPaymentMethods: allowedPaymentMethods, cardRequirements: { - allowedCardNetworks: allowedCardNetworks - } + allowedCardNetworks: allowedCardNetworks, + }, }; } @@ -189,30 +197,29 @@ define( * @see {@link https://developers.google.com/pay/api/web/reference/object#TransactionInfo|TransactionInfo} * @return {object} transaction info, suitable for use as transactionInfo property of PaymentDataRequest */ - function getGoogleTransactionInfo() - { + function getGoogleTransactionInfo() { return { currencyCode: Utilities.getQuoteCurrency(), totalPriceStatus: 'FINAL', - totalPrice: Utilities.getQuoteValue() + totalPrice: Utilities.getQuoteValue(), }; } /** * Prefetch payment data to improve performance */ - function prefetchGooglePaymentData() - { + function prefetchGooglePaymentData() { var paymentDataRequest = getGooglePaymentDataConfiguration(); // TransactionInfo must be set but does not affect cache paymentDataRequest.transactionInfo = { totalPriceStatus: 'NOT_CURRENTLY_KNOWN', - currencyCode: Utilities.getQuoteCurrency() + currencyCode: Utilities.getQuoteCurrency(), }; var paymentsClient = getGooglePaymentsClient(); - paymentsClient.prefetchPaymentData(paymentDataRequest); + paymentsClient.prefetchPaymentData( + paymentDataRequest); } /** @@ -221,8 +228,7 @@ define( * @param {object} paymentData response from Google Pay API after shopper approves payment * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentData|PaymentData object reference} */ - function processPayment(paymentData) - { + function processPayment(paymentData) { // Start the loader FullScreenLoader.startLoader(); @@ -230,30 +236,39 @@ define( var payload = { methodId: METHOD_ID, cardToken: { - signature: JSON.parse(paymentData.paymentMethodToken.token).signature, - protocolVersion: JSON.parse(paymentData.paymentMethodToken.token).protocolVersion, - signedMessage: JSON.parse(paymentData.paymentMethodToken.token).signedMessage, + signature: JSON.parse( + paymentData.paymentMethodToken.token).signature, + protocolVersion: JSON.parse( + paymentData.paymentMethodToken.token).protocolVersion, + signedMessage: JSON.parse( + paymentData.paymentMethodToken.token).signedMessage, }, - source: METHOD_ID + source: METHOD_ID, }; // Send the request $.post( Utilities.getUrl('payment/placeorder'), payload, - function (data, status) { + function(data, status) { if (data.success === true) { - // Redirect to success page - RedirectOnSuccessAction.execute(); + // Redirect to 3Ds page + if (data.url) { + window.location.href = data.url; + } else { + // Redirect to success page + RedirectOnSuccessAction.execute(); + } } else { FullScreenLoader.stopLoader(); - alert(__('An error has occurred. Please try again.')); + alert( + __('An error has occurred. Please try again.')); } - } + }, ); } } - } + }, ); }, @@ -264,7 +279,7 @@ define( /** * @return {string} */ - beforePlaceOrder: function () { + beforePlaceOrder: function() { // Start the loader FullScreenLoader.startLoader(); @@ -274,8 +289,8 @@ define( } else { FullScreenLoader.stopLoader(); } - } - } + }, + }, ); - } + }, ); From 182d3fc543b0c27be9c2e86f278151aba60a8bf6 Mon Sep 17 00:00:00 2001 From: Paul Negrerie Date: Mon, 28 Mar 2022 16:55:29 +0200 Subject: [PATCH 3/5] CHECMAG2003-43: Reformat code , change label configuration --- Model/Methods/GooglePayMethod.php | 2 +- etc/adminhtml/system.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Model/Methods/GooglePayMethod.php b/Model/Methods/GooglePayMethod.php index dfd4958a..598a7ad2 100755 --- a/Model/Methods/GooglePayMethod.php +++ b/Model/Methods/GooglePayMethod.php @@ -291,7 +291,7 @@ public function sendPaymentRequest(array $data, float $amount, string $currency, $request->description = __('Payment request from %1', $this->config->getStoreName())->render(); $request->customer = $api->createCustomer($quote); $request->payment_type = 'Regular'; - $request->shipping = $api->createShippingAddress($quote); + $request->shipping = $api->createShippingAddress($quote); // Billing descriptor if ($this->config->needsDynamicDescriptor()) { diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 764b720d..0ac24988 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -477,7 +477,7 @@ - + Magento\Config\Model\Config\Source\Yesno payment/checkoutcom_google_pay/three_ds From a171829c5e71f162082b9fc68e6d9a8feb2e26ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ke=CC=81vin=20Allard?= Date: Wed, 30 Mar 2022 08:47:13 +0200 Subject: [PATCH 4/5] CHECMAG2003-50: reformat code --- Setup/Patch/Data/EncryptOldApiKeys.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Setup/Patch/Data/EncryptOldApiKeys.php b/Setup/Patch/Data/EncryptOldApiKeys.php index 8818898e..8bebd56d 100644 --- a/Setup/Patch/Data/EncryptOldApiKeys.php +++ b/Setup/Patch/Data/EncryptOldApiKeys.php @@ -67,8 +67,8 @@ class EncryptOldApiKeys implements DataPatchInterface * EncryptOldApiKeys constructor * * @param ModuleDataSetupInterface $moduleDataSetup - * @param EncryptorInterface $encryptor - * @param WriterInterface $writer + * @param EncryptorInterface $encryptor + * @param WriterInterface $writer */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, @@ -76,8 +76,8 @@ public function __construct( WriterInterface $writer ) { $this->moduleDataSetup = $moduleDataSetup; - $this->encryptor = $encryptor; - $this->writer = $writer; + $this->encryptor = $encryptor; + $this->writer = $writer; } /** @@ -129,12 +129,13 @@ public function apply() } /** - * @param mixed[] $oldKey + * @param mixed[] $oldKey * @param string $configPath * * @return void */ - public function encryptKey(array $oldKey, string $configPath): void { + public function encryptKey(array $oldKey, string $configPath): void + { if ($oldKey) { /** @var string $encryptedKey */ $encryptedKey = $this->encryptor->encrypt($oldKey['value']); From 5a5fb3a0c2295d24b5dd9ff2a9eb9f5b21857d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verri=C3=A8re?= Date: Thu, 31 Mar 2022 11:37:01 +0200 Subject: [PATCH 5/5] v3.1.0: Bump composer.json version to 3.1.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 295e7a77..82b70759 100755 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "magento/framework": ">=100.0.1" }, "type": "magento2-module", - "version": "3.0.1", + "version": "3.1.0", "autoload": { "files": [ "registration.php"