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 6eeed37f authored by alessio's avatar alessio Committed by attilak

PW-1103: Added Oneclick support for 3ds2, added temporary TODOs for challengeshopper

parent 44574199
......@@ -23,12 +23,13 @@
namespace Adyen\Payment\Helper;
use Adyen\Payment\Observer\AdyenOneclickDataAssignObserver;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Vault\Model\Ui\VaultConfigProvider;
use Adyen\Payment\Observer\AdyenHppDataAssignObserver;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
//TODO: enable stateOrProvince field if no issues with empty values
class Requests extends AbstractHelper
{
/**
......@@ -148,14 +149,14 @@ class Requests extends AbstractHelper
"postalCode" => '',
"city" => "N/A",
"houseNumberOrName" => '',
"stateOrProvince" => '',
// "stateOrProvince" => '',
"country" => "ZZ"
];
// Save the defaults for later to compare if anything has changed
$requestBilling = $requestBillingDefaults;
$address = $this->getStreetStringFromBillingAddress($billingAddress);
$address = $this->getStreetStringFromAddress($billingAddress);
if (!empty($address["name"])) {
$requestBilling["street"] = $address["name"];
......@@ -173,9 +174,9 @@ class Requests extends AbstractHelper
$requestBilling["city"] = $billingAddress->getCity();
}
if (!empty($billingAddress->getRegionCode())) {
$requestBilling["stateOrProvince"] = $billingAddress->getRegionCode();
}
// if (!empty($billingAddress->getRegionCode())) {
// $requestBilling["stateOrProvince"] = $billingAddress->getRegionCode();
// }
if (!empty($billingAddress->getCountryId())) {
$requestBilling["country"] = $billingAddress->getCountryId();
......@@ -195,7 +196,7 @@ class Requests extends AbstractHelper
"postalCode" => '',
"city" => "N/A",
"houseNumberOrName" => '',
"stateOrProvince" => '',
// "stateOrProvince" => '',
"country" => "ZZ"
];
......@@ -203,7 +204,7 @@ class Requests extends AbstractHelper
$requestDelivery = $requestDeliveryDefaults;
// Parse address into street and house number where possible
$address = $this->adyenHelper->getStreetFromString($shippingAddress->getStreetFull());
$address = $this->getStreetStringFromAddress($shippingAddress);
if (!empty($address['name'])) {
$requestDelivery["street"] = $address["name"];
......@@ -221,9 +222,9 @@ class Requests extends AbstractHelper
$requestDelivery["city"] = $shippingAddress->getCity();
}
if (!empty($shippingAddress->getRegionCode())) {
$requestDelivery["stateOrProvince"] = $shippingAddress->getRegionCode();
}
// if (!empty($shippingAddress->getRegionCode())) {
// $requestDelivery["stateOrProvince"] = $shippingAddress->getRegionCode();
// }
if (!empty($shippingAddress->getCountryId())) {
$requestDelivery["country"] = $shippingAddress->getCountryId();
......@@ -288,8 +289,8 @@ class Requests extends AbstractHelper
$request['browserInfo']['screenHeight'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_HEIGHT);
$request['browserInfo']['colorDepth'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_COLOR_DEPTH);
$request['browserInfo']['timeZoneOffset'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::TIMEZONE_OFFSET);
$request['browserInfo']['language'] = $this->adyenHelper->getCurrentLocaleCode($store);
$request['browserInfo']['javaEnabled'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::JAVA_ENABLED);
$request['browserInfo']['language'] = "nl-NL";//$this->adyenHelper->getCurrentLocaleCode($store); TODO change format to nl-NL instead of nl_NL
$request['browserInfo']['javaEnabled'] = false; //$payment->getAdditionalInformation(AdyenCcDataAssignObserver::JAVA_ENABLED);TODO make sure it is not passed as null
// uset browser related data from additional information
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_WIDTH);
......@@ -370,6 +371,10 @@ class Requests extends AbstractHelper
$request['paymentMethod']['encryptedSecurityCode'] = $securityCode;
}
if ($recurringDetailReference = $payment->getAdditionalInformation(AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE)) {
$request['paymentMethod']['recurringDetailReference'] = $recurringDetailReference;
}
// Remove from additional information
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER);
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH);
......@@ -424,13 +429,13 @@ class Requests extends AbstractHelper
* @param $billingAddress
* @return array
*/
private function getStreetStringFromBillingAddress($billingAddress)
private function getStreetStringFromAddress($address)
{
if (method_exists($billingAddress, 'getStreetFull')) {
if (method_exists($address, 'getStreetFull')) {
// Parse address into street and house number where possible
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetFull());
$address = $this->adyenHelper->getStreetFromString($address->getStreetFull());
} else {
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetLine1());
$address = $this->adyenHelper->getStreetFromString($address->getStreetLine1());
}
return $address;
......
......@@ -35,6 +35,11 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
const ENCRYPTED_SECURITY_CODE = 'cvc';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
const VARIANT = 'variant';
const JAVA_ENABLED = 'java_enabled';
const SCREEN_COLOR_DEPTH = 'screen_color_depth';
const SCREEN_WIDTH = 'screen_width';
const SCREEN_HEIGHT = 'screen_height';
const TIMEZONE_OFFSET = 'timezone_offset';
/**
* @var array
......@@ -43,7 +48,12 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
self::RECURRING_DETAIL_REFERENCE,
self::ENCRYPTED_SECURITY_CODE,
self::NUMBER_OF_INSTALLMENTS,
self::VARIANT
self::VARIANT,
self::JAVA_ENABLED,
self::SCREEN_COLOR_DEPTH,
self::SCREEN_WIDTH,
self::SCREEN_HEIGHT,
self::TIMEZONE_OFFSET
];
/**
......
......@@ -528,15 +528,7 @@
<virtualType name="AdyenPaymentOneclickAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="customer" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="address" xsi:type="string">Adyen\Payment\Gateway\Request\AddressDataBuilder</item>
<item name="payment" xsi:type="string">Adyen\Payment\Gateway\Request\PaymentDataBuilder</item>
<item name="browserinfo" xsi:type="string">Adyen\Payment\Gateway\Request\BrowserInfoDataBuilder</item>
<item name="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CcAuthorizationDataBuilder</item>
<item name="oneclick" xsi:type="string">Adyen\Payment\Gateway\Request\OneclickAuthorizationDataBuilder</item>
</argument>
</arguments>
</virtualType>
......
......@@ -32,10 +32,15 @@ define(
'Magento_Checkout/js/action/redirect-on-success',
'uiLayout',
'Magento_Ui/js/model/messages',
'Magento_Checkout/js/action/place-order',
'mage/url'
'mage/url',
'Adyen_Payment/js/threeds2-js-utils',
'Magento_Checkout/js/model/full-screen-loader',
'Magento_Paypal/js/action/set-payment-method',
'Magento_Checkout/js/model/url-builder',
'mage/storage',
'Magento_Checkout/js/action/place-order'
],
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) {
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, url, threeDS2Utils, fullScreenLoader, setPaymentMethodAction, urlBuilder, storage, placeOrderAction) {
'use strict';
......@@ -59,7 +64,7 @@ define(
.observe([
'recurringDetailReference',
'creditCardType',
'creditCardVerificationNumber',
'encryptedCreditCardVerificationNumber',
'variant',
'numberOfInstallments'
]);
......@@ -165,46 +170,50 @@ define(
return self.isActive() && this.getCode() == self.isChecked() && self.isBillingAgreementChecked() && this.placeOrderAllowed();
},
/**
* Custom place order function
*
* @override
*
* @param data
* @param event
* @returns {boolean}
*/
placeOrder: function (data, event) {
var self = this;
console.log("placeorder");
if (event) {
event.preventDefault();
}
// only use installments for cards
if (self.agreement_data.card) {
if (self.hasVerification()) {
var options = {enableValidations: false};
}
if (self.agreement_data.card) {
if (self.hasVerification()) {
var options = {enableValidations: false};
}
// set payment method to adyen_hpp
// TODO can observer in front-end this not needed
numberOfInstallments(self.installment);
}
// set payment method to adyen_hpp
// TODO can observer in front-end this not needed
numberOfInstallments(self.installment);
}
// in different context so need custom place order logic
if (this.validate() && additionalValidators.validate()) {
fullScreenLoader.startLoader();
self.isPlaceOrderActionAllowed(false);
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
// use custom redirect Link for supporting 3D secure
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
}
);
return true;
//update payment method information if additional data was changed
selectPaymentMethodAction(this.getCcData());
setPaymentMethodAction(this.messageContainer).done(
function (responseJSON) {
fullScreenLoader.stopLoader();
self.isPlaceOrderActionAllowed(true);
self.validateThreeDS2OrPlaceOrder(responseJSON);
});
return false;
}
return false;
},
/**
* Renders the secure CVC field,
* creates the card component,
......@@ -275,6 +284,131 @@ define(
window.adyencheckout = oneClickCard;
},
/**
* Builds the payment details part of the payment information reqeust
*
* @returns {{method: *, additional_data: {card_brand: *, cc_type: *, number: *, cvc: *, expiryMonth: *, expiryYear: *, holderName: *, store_cc: (boolean|*), number_of_installments: *, java_enabled: boolean, screen_color_depth: number, screen_width, screen_height, timezone_offset: *}}}
*/
getCcData: function () {
var self = this;
var browserInfo = threeDS2Utils.getBrowserInfo();
var data = {
'method': self.method,
additional_data: {
'variant': variant(),
'recurring_detail_reference': recurringDetailReference(),
'number_of_installments': numberOfInstallments(),
'cvc': self.encryptedCreditCardVerificationNumber,
'expiryMonth': self.creditCardExpMonth(),
'expiryYear': self.creditCardExpYear(),
'java_enabled': browserInfo.javaEnabled,
'screen_color_depth': browserInfo.colorDepth,
'screen_width': browserInfo.screenWidth,
'screen_height': browserInfo.screenHeight,
'timezone_offset': browserInfo.timeZoneOffset
}
};
return data;
},
/**
* Based on the response we can start a 3DS2 validation or place the order
* @param responseJSON
*/
validateThreeDS2OrPlaceOrder: function(responseJSON) {
var self = this;
var response = JSON.parse(responseJSON);
if (!!response.threeDS2) {
// render component
self.renderThreeDS2Component(response.type, response.token);
} else {
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
}
);
}
},
/**
* The results that the 3DS2 components returns in the onComplete callback needs to be sent to the
* backend to the /adyen/threeDS2Process endpoint and based on the response render a new threeDS2
* component or place the order (validateThreeDS2OrPlaceOrder)
* @param response
*/
processThreeDS2: function(data) {
var self = this;
fullScreenLoader.startLoader();
var payload = {
"payload": JSON.stringify(data)
};
var serviceUrl = urlBuilder.createUrl('/adyen/threeDS2Process', {});
storage.post(
serviceUrl,
JSON.stringify(payload),
true
).done(function(responseJSON) {
fullScreenLoader.stopLoader();
self.validateThreeDS2OrPlaceOrder(responseJSON)
});
},
/**
* Rendering the 3DS2.0 components
* To do the device fingerprint at the response of IdentifyShopper render the threeDS2DeviceFingerprint
* component
* To render the challenge for the customer at the response of ChallengeShopper render the
* threeDS2Challenge component
* Both of them is going to be rendered in a Magento dialog popup
*
* @param type
* @param token
*/
renderThreeDS2Component: function(type, token) {
var self = this;
var threeDS2Node = document.getElementById('threeDS2ContainerOneClick');
if (type == "IdentifyShopper") {
fullScreenLoader.startLoader();
self.threeDS2Component = checkout.create('threeDS2DeviceFingerprint', {
fingerprintToken: token,
onComplete: function(result) {
fullScreenLoader.stopLoader();
self.processThreeDS2(result.data);
}
});
} else if (type == "ChallengeShopper") {
$('#threeDS2ModalOneClick').modal({
// disable user to hide popup
clickableOverlay: false,
// empty buttons, we don't need that
buttons: []
});
$('#threeDS2ModalOneClick').modal("openModal");
self.threeDS2Component = checkout
.create('threeDS2Challenge', {
challengeToken: token,
onComplete: function(result) {
self.processThreeDS2(result.data);
$('#threeDS2ModalOneClick').modal("closeModal");
}
});
}
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.
......
......@@ -134,6 +134,11 @@
</div>
</div>
<!-- /ko -->
<div id="threeDS2ModalOneClick">
<div id="threeDS2ContainerOneClick"></div>
</div>
</fieldset>
</form>
<div class="checkout-agreements-block">
......
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