We will be off from 27/1 (Monday) to 31/1 (Friday) (GMT +7) for our Tet Holiday (Lunar New Year) in our country

Commit 842509ae authored by Rik ter Beek's avatar Rik ter Beek Committed by GitHub

Merge pull request #773 from Adyen/develop

Release 6.3.0
parents 6a7bb718 2a5c3deb
......@@ -68,6 +68,7 @@ class CheckoutResponseValidator extends AbstractValidator
$errorMessages = [];
// validate result
if (!empty($response['resultCode'])) {
$payment->setAdditionalInformation('resultCode', $response['resultCode']);
switch ($response['resultCode']) {
case "IdentifyShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
......@@ -75,7 +76,7 @@ class CheckoutResponseValidator extends AbstractValidator
'threeDS2Token',
$response['authentication']['threeds2.fingerprintToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
$payment->setAdditionalInformation('adyenPaymentData', $response['paymentData']);
break;
case "ChallengeShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
......@@ -83,7 +84,7 @@ class CheckoutResponseValidator extends AbstractValidator
'threeDS2Token',
$response['authentication']['threeds2.challengeToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
$payment->setAdditionalInformation('adyenPaymentData', $response['paymentData']);
break;
case "Authorised":
case "Received":
......@@ -122,6 +123,12 @@ class CheckoutResponseValidator extends AbstractValidator
$payment->setAdditionalInformation('pspReference', $response['pspReference']);
}
break;
case 'Pending':
$payment->setAdditionalInformation('adyenPaymentData', $response['paymentData']);
if (!empty($response['action'])) {
$payment->setAdditionalInformation('action', $response['action']);
}
break;
case "RedirectShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2019 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
// phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod
namespace Adyen\Payment\Gateway\Validator;
use Magento\Payment\Gateway\Validator\AbstractValidator;
class ThreeDS2ResponseValidator extends AbstractValidator
{
/**
* GeneralResponseValidator constructor.
*
* @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
*/
public function __construct(
\Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
) {
parent::__construct($resultFactory);
}
/**
* @param array $validationSubject
* @return \Magento\Payment\Gateway\Validator\ResultInterface
*/
public function validate(array $validationSubject)
{
$response = \Magento\Payment\Gateway\Helper\SubjectReader::readResponse($validationSubject);
if (!empty($validationSubject['payment'])) {
$payment = $validationSubject['payment'];
} else {
$errorMsg = __('Error with payment method during validation please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
$isValid = true;
$errorMessages = [];
// validate result
if (!empty($response['resultCode'])) {
// 3DS2.0 should have IdentifyShopper or ChallengeShopper as a resultCode
if ($response['resultCode'] == "IdentifyShopper" &&
!empty($response['authentication']['threeds2.fingerprintToken'])
) {
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation(
'threeDS2Token',
$response['authentication']['threeds2.fingerprintToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
} elseif ($response['resultCode'] == "ChallengeShopper" &&
!empty($response['authentication']['threeds2.challengeToken'])
) {
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation(
'threeDS2Token',
$response['authentication']['threeds2.challengeToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
return $this->createResult($isValid, $errorMessages);
}
}
This diff is collapsed.
......@@ -385,7 +385,7 @@ class PaymentMethods extends AbstractHelper
*/
public function getConnectedTerminals()
{
$storeId = $this->getQuote()->getStoreId();
$storeId = $this->session->getQuote()->getStoreId();
// initialize the adyen client
$client = $this->adyenHelper->initializeAdyenClient($storeId, $this->adyenHelper->getPosApiKey($storeId));
......
......@@ -25,6 +25,7 @@
namespace Adyen\Payment\Model;
use Adyen\Payment\Model\Ui\AdyenCcConfigProvider;
use Adyen\Payment\Model\Ui\AdyenHppConfigProvider;
use Adyen\Payment\Model\Ui\AdyenOneclickConfigProvider;
class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentStatusInterface
......@@ -87,6 +88,21 @@ class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentSta
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($type, $token);
}
/**
* If payment method result is Pending and action is provided provide component action back to checkout
*/
if ($payment->getMethod() === AdyenHppConfigProvider::CODE) {
$additionalInformation = $payment->getAdditionalInformation();
if (
!empty($additionalInformation['action']) &&
$additionalInformation['resultCode'] == 'Pending'
) {
return json_encode(['action' => $additionalInformation['action']]);
}
}
return true;
}
}
......@@ -23,7 +23,7 @@
namespace Adyen\Payment\Model;
use \Adyen\Payment\Api\AdyenThreeDS2ProcessInterface;
use Adyen\Payment\Api\AdyenThreeDS2ProcessInterface;
class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
{
......@@ -92,6 +92,8 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
} else {
// Create order by order id
$order = $this->orderFactory->create()->load($payload['orderId']);
// don't send orderId to adyen. Improve that orderId and state.data are separated in payload
unset($payload['orderId']);
}
$payment = $order->getPayment();
......@@ -99,14 +101,14 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
// Init payments/details request
$result = [];
if ($paymentData = $payment->getAdditionalInformation("threeDS2PaymentData")) {
if ($paymentData = $payment->getAdditionalInformation("adyenPaymentData")) {
// Add payment data into the request object
$request = [
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
"paymentData" => $paymentData
];
// unset payment data from additional information
$payment->unsAdditionalInformation("threeDS2PaymentData");
$payment->unsAdditionalInformation("adyenPaymentData");
} else {
$this->adyenLogger->error("3D secure 2.0 failed, payment data not found");
throw new \Magento\Framework\Exception\LocalizedException(
......@@ -119,8 +121,11 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$request['details']['threeds2.fingerprint'] = $payload['details']['threeds2.fingerprint'];
} elseif (!empty($payload['details']['threeds2.challengeResult'])) {
$request['details']['threeds2.challengeResult'] = $payload['details']['threeds2.challengeResult'];
} elseif (!empty($payload)) {
$request = $payload;
}
// Send the request
try {
$client = $this->adyenHelper->initializeAdyenClient($order->getStoreId());
......@@ -161,6 +166,12 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$order->cancel()->save();
$this->adyenLogger->error(
sprintf("Payment details call failed for action or 3ds2 payment method, resultcode is %s Raw API responds: %s",
$result['resultCode'],
print_r($result, true)
));
throw new \Magento\Framework\Exception\LocalizedException(__('The payment is REFUSED.'));
}
......
......@@ -157,10 +157,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
$config['payment']['adyenCc']['icons'] = $this->getIcons();
$config['payment']['adyenCc']['originKey'] = $this->_adyenHelper->getOriginKeyForBaseUrl();
$config['payment']['adyenCc']['checkoutEnvironment'] = $this->_adyenHelper->getCheckoutEnvironment(
$this->storeManager->getStore()->getId()
);
// has installments by default false
$config['payment']['adyenCc']['hasInstallments'] = false;
......
......@@ -32,7 +32,7 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
protected $adyenHelper;
/**
* @var \Magento\Store\Model\StoreManagerInterface
......@@ -48,7 +48,7 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->_adyenHelper = $adyenHelper;
$this->adyenHelper = $adyenHelper;
$this->storeManager = $storeManager;
}
......@@ -63,36 +63,26 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
'payment' => []
];
// show logos turned on by default
if ($this->_showLogos()) {
if ($this->showLogos()) {
$config['payment']['adyen']['showLogo'] = true;
} else {
$config['payment']['adyen']['showLogo'] = false;
}
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs(
$config['payment']['adyen']['originKey'] = $this->adyenHelper->getOriginKeyForBaseUrl();
$config['payment']['adyen']['checkoutEnvironment'] = $this->adyenHelper->getCheckoutEnvironment(
$this->storeManager->getStore()->getId()
);
return $config;
}
/**
* Return redirect URL for method
*
* @param string $code
* @return mixed
*/
protected function getMethodRedirectUrl($code)
{
return $this->_methods[$code]->getCheckoutRedirectUrl();
}
/**
* @return bool
*/
protected function _showLogos()
protected function showLogos()
{
$showLogos = $this->_adyenHelper->getAdyenAbstractConfigData('title_renderer');
$showLogos = $this->adyenHelper->getAdyenAbstractConfigData('title_renderer');
if ($showLogos == \Adyen\Payment\Model\Config\Source\RenderMode::MODE_TITLE_IMAGE) {
return true;
}
......
......@@ -144,10 +144,6 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
);
$config['payment']['adyenOneclick']['methodCode'] = self::CODE;
$config['payment']['adyenOneclick']['originKey'] = $this->_adyenHelper->getOriginKeyForBaseUrl();
$config['payment']['adyenOneclick']['checkoutEnvironment'] = $this->_adyenHelper->getCheckoutEnvironment(
$this->_storeManager->getStore()->getId()
);
$config['payment']['adyenOneclick']['locale'] = $this->_adyenHelper->getStoreLocale(
$this->_storeManager->getStore()->getId()
);
......
......@@ -2,7 +2,7 @@
"name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module",
"version": "6.2.1",
"version": "6.3.0",
"license": [
"OSL-3.0",
"AFL-3.0"
......
......@@ -11,5 +11,10 @@ var config = {
'Magento_CheckoutAgreements/js/model/place-order-mixin': true
}
}
},
map: {
'*': {
'adyenCheckout': 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/3.4.0/adyen.js'
}
}
};
......@@ -64,16 +64,8 @@ define(
/** Add view logic here if needed */
return Component.extend({
initialize: function () {
var self = this;
this._super();
// include checkout card component javascript
var checkoutCardComponentScriptTag = document.createElement('script');
checkoutCardComponentScriptTag.id = "AdyenCheckoutCardComponentScript";
checkoutCardComponentScriptTag.src = self.getCheckoutCardComponentSource();
checkoutCardComponentScriptTag.type = "text/javascript";
document.head.appendChild(checkoutCardComponentScriptTag);
if (this.isGooglePayEnabled()) {
var googlepayscript = document.createElement('script');
googlepayscript.src = "https://pay.google.com/gp/p/js/pay.js";
......@@ -81,12 +73,9 @@ define(
document.head.appendChild(googlepayscript);
}
},
getCheckoutCardComponentSource: function () {
return window.checkoutConfig.payment.checkoutCardComponentSource;
},
isGooglePayEnabled: function () {
return window.checkoutConfig.payment.adyenGooglePay.active;
}
});
}
);
\ No newline at end of file
);
......@@ -39,7 +39,8 @@ define(
'Adyen_Payment/js/threeds2-js-utils',
'Adyen_Payment/js/model/threeds2',
'Magento_Checkout/js/model/error-processor',
'Adyen_Payment/js/model/adyen-payment-service'
'Adyen_Payment/js/model/adyen-payment-service',
'adyenCheckout'
],
function (
$,
......@@ -60,7 +61,8 @@ define(
threeDS2Utils,
threeds2,
errorProcessor,
adyenPaymentService
adyenPaymentService,
AdyenCheckout
) {
'use strict';
......@@ -88,7 +90,9 @@ define(
// initialize adyen component for general use
this.checkout = new AdyenCheckout({
locale: this.getLocale()
locale: this.getLocale(),
originKey: this.getOriginKey(),
environment: this.getCheckoutEnvironment()
});
return this;
......@@ -136,6 +140,7 @@ define(
var allInstallments = self.getAllInstallments();
var cardNode = document.getElementById('cardContainer');
self.cardComponent = self.checkout.create('card', {
originKey: self.getOriginKey(),
environment: self.getCheckoutEnvironment(),
......@@ -230,9 +235,9 @@ define(
fullScreenLoader.stopLoader();
});
},
onError: function (error) {
console.log(JSON.stringify(error));
}
onError: function (error) {
console.log(JSON.stringify(error));
}
});
self.threeDS2IdentifyComponent.mount(threeDS2Node);
......@@ -269,9 +274,9 @@ define(
fullScreenLoader.stopLoader();
});
},
onError: function (error) {
console.log(JSON.stringify(error));
}
onError: function (error) {
console.log(JSON.stringify(error));
}
});
self.threeDS2ChallengeComponent.mount(threeDS2Node);
}
......@@ -296,7 +301,7 @@ define(
* @returns {{method: *}}
*/
getData: function () {
const browserInfo = threeDS2Utils.getBrowserInfo();
var browserInfo = threeDS2Utils.getBrowserInfo();
var data = {
'method': this.item.method,
......@@ -356,14 +361,14 @@ define(
self.isPlaceOrderActionAllowed(true);
}
).done(
function (orderId) {
self.afterPlaceOrder();
adyenPaymentService.getOrderPaymentStatus(orderId)
function (orderId) {
self.afterPlaceOrder();
adyenPaymentService.getOrderPaymentStatus(orderId)
.done(function (responseJSON) {
self.validateThreeDS2OrPlaceOrder(responseJSON, orderId)
});
}
);
}
);
}
return false;
},
......@@ -457,10 +462,10 @@ define(
return window.checkoutConfig.payment.adyenCc.methodCode;
},
getOriginKey: function () {
return window.checkoutConfig.payment.adyenCc.originKey;
return window.checkoutConfig.payment.adyen.originKey;
},
getCheckoutEnvironment: function () {
return window.checkoutConfig.payment.adyenCc.checkoutEnvironment;
return window.checkoutConfig.payment.adyen.checkoutEnvironment;
},
getLocale: function () {
return window.checkoutConfig.payment.adyenCc.locale;
......
......@@ -32,9 +32,10 @@ define(
'Magento_Checkout/js/model/url-builder',
'Magento_Checkout/js/model/full-screen-loader',
'mage/url',
'Magento_Vault/js/view/payment/vault-enabler'
'Magento_Vault/js/view/payment/vault-enabler',
'adyenCheckout'
],
function (ko, $, Component, placeOrderAction, quote, urlBuilder, fullScreenLoader, url, VaultEnabler) {
function (ko, $, Component, placeOrderAction, quote, urlBuilder, fullScreenLoader, url, VaultEnabler, AdyenCheckout) {
'use strict';
/**
......@@ -89,6 +90,8 @@ define(
var googlePayNode = document.getElementById('googlePay');
self.checkoutComponent = new AdyenCheckout({
locale: self.getLocale(),
originKey: self.getOriginKey(),
environment: self.getCheckoutEnvironment(),
risk: {
enabled: false
}
......@@ -111,9 +114,11 @@ define(
currency: quote.totals().quote_currency_code,
totalPriceStatus: 'FINAL',
// empty onSubmit to resolve javascript issues.
onSubmit: function() {},
onChange: function (state) {
if (!!state.isValid) {
self.googlePayToken(state.data.paymentMethod["paywithgoogle.token"]);
self.googlePayToken(state.data.paymentMethod.googlePayToken);
self.getPlaceOrderDeferredObject()
.fail(
function () {
......@@ -143,9 +148,6 @@ define(
self.googlePayAllowed(false);
});
},
getCheckoutEnvironment: function () {
return window.checkoutConfig.payment.adyenGooglePay.checkoutEnvironment;
},
isGooglePayAllowed: function () {
if (this.googlePayAllowed()) {
return true;
......@@ -206,6 +208,12 @@ define(
},
getVaultCode: function () {
return "adyen_google_pay_vault";
},
getOriginKey: function () {
return window.checkoutConfig.payment.adyen.originKey;
},
getCheckoutEnvironment: function () {
return window.checkoutConfig.payment.adyen.checkoutEnvironment;
}
});
}
......
......@@ -41,7 +41,8 @@ define(
'Magento_Checkout/js/action/place-order',
'Adyen_Payment/js/model/threeds2',
'Magento_Checkout/js/model/error-processor',
'Adyen_Payment/js/model/adyen-payment-service'
'Adyen_Payment/js/model/adyen-payment-service',
'adyenCheckout'
],
function (
ko,
......@@ -64,7 +65,8 @@ define(
placeOrderAction,
threeds2,
errorProcessor,
adyenPaymentService
adyenPaymentService,
AdyenCheckout
) {
'use strict';
......@@ -257,30 +259,20 @@ define(
}
var oneClickCardNode = document.getElementById('cvcContainer-' + self.value);
// this should be fixed in new version of checkout card component
var hideCVC = false;
if (this.hasVerification()) {
if (self.agreement_data.variant == "maestro") {
// for maestro cvc is optional
self.placeOrderAllowed(true);
}
} else {
// hide cvc if contract has been stored as recurring
if (!this.hasVerification()) {
hideCVC = true;
}
var oneClickCard = checkout
.create('card', {
type: self.agreement_data.variant,
hideCVC: hideCVC,
details: self.getOneclickDetails(),
storedDetails: {
"card": {
"expiryMonth": self.agreement_data.card.expiryMonth,
"expiryYear": self.agreement_data.card.expiryYear,
"holderName": self.agreement_data.card.holderName,
"number": self.agreement_data.card.number
}
},
brand: self.agreement_data.variant,
storedPaymentMethodId: this.value,
expiryMonth: self.agreement_data.card.expiryMonth,
expiryYear: self.agreement_data.card.expiryYear,
holderName: self.agreement_data.card.holderName,
onChange: function (state, component) {
if (state.isValid) {
self.placeOrderAllowed(true);
......@@ -303,8 +295,6 @@ define(
}
})
.mount(oneClickCardNode);
window.adyencheckout = oneClickCard;
},
/**
......@@ -396,27 +386,6 @@ define(
self.threeDS2Component.mount(threeDS2Node);
},
/**
* We use the billingAgreements to save the oneClick stored payments but we don't store the
* details object that we get from the paymentMethods call. This function is a fix for BCMC.
* When we render the stored payments dynamically from the paymentMethods call response it
* should be removed
* @returns {*}
*/
getOneclickDetails: function () {
var self = this;
if (self.agreement_data.variant === 'bcmc') {
return [];
} else {
return [
{
"key": "cardDetails.cvc",
"type": "cvc"
}
];
}
},
/**
* Builds the payment details part of the payment information reqeust
*
......@@ -485,7 +454,7 @@ define(
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer())
);
},
}
}
});
......@@ -567,10 +536,10 @@ define(
return window.checkoutConfig.payment.adyenOneclick.locale;
},
getOriginKey: function () {
return window.checkoutConfig.payment.adyenOneclick.originKey;
return window.checkoutConfig.payment.adyen.originKey;
},
getCheckoutEnvironment: function () {
return window.checkoutConfig.payment.adyenOneclick.checkoutEnvironment;
return window.checkoutConfig.payment.adyen.checkoutEnvironment;
}
});
}
......
......@@ -22,6 +22,12 @@
*/
-->
<div id="ActionWrapper">
<div id="ActionModal">
<div id="ActionContainer"></div>
</div>
</div>
<!-- ko foreach: getAdyenHppPaymentMethods() -->
<div class="payment-method" data-bind="css: {'_active': (value == $parent.isBrandCodeChecked())}">
<div class="payment-method-title field choice">
......@@ -45,6 +51,14 @@
</div>
<div class="payment-method-content">
<!-- ko foreach: $parent.getRegion(getMessageName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<div>
<span class="message message-error error hpp-message" data-bind="attr: {id: 'messages-' + value}"></span>
</div>
<div class="payment-method-billing-address">
<!-- ko foreach: $parents[1].getRegion($parent.getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
......@@ -295,16 +309,14 @@
<!--/ko-->
</div>
<div>
<span class="message message-error error hpp-message" data-bind="attr: {id: 'messages-' + value}"></span>
</div>
<div class="actions-toolbar">
<div class="primary">
<button class="action primary checkout"
type="submit"
data-bind="
click: $parent.continueToAdyenBrandCode,
click: continueToAdyenBrandCode,
enable: placeOrderAllowed() && (value == $parent.isBrandCodeChecked()),
css: {disabled: !$parent.isPlaceOrderActionAllowed()}"
disabled>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment