Commit 96f82040 authored by attilak's avatar attilak

Finalise card payments with generic component

Remove buildThreeDS2ProcessResponseJson(), not used anymore
Use onAdditionalDetails instead of onComplete in the checkout components
Update bundle with the fixes
Remove unnecessary mapping on the backend regarding the action fields
Remove unnecessary additionalInformation settings in payment object
parent 577bf82c
......@@ -69,15 +69,9 @@ class CheckoutResponseValidator extends AbstractValidator
// validate result
if (!empty($response['resultCode'])) {
switch ($response['resultCode']) {
case "IdentifyShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation('threeDS2Token', $response['authentication']['threeds2.fingerprintToken']);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
break;
case "ChallengeShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation('threeDS2Token', $response['authentication']['threeds2.challengeToken']);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
case "IdentifyShopper":
$payment->setAdditionalInformation('action', $response['action']);
break;
case "Authorised":
case "Received":
......
......@@ -1792,27 +1792,6 @@ class Data extends AbstractHelper
return $timeStamp->format($format);
}
/**
* @param string|null $type
* @param string|null $token
* @return string
*/
public function buildThreeDS2ProcessResponseJson($type = null, $token = null)
{
$response = ['threeDS2' => false];
if (!empty($type)) {
$response['type'] = $type;
}
if ($type && $token) {
$response['threeDS2'] = true;
$response['token'] = $token;
}
return json_encode($response);
}
/**
* @param int $storeId
* @return mixed|string
......
......@@ -75,18 +75,11 @@ class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentSta
) {
$additionalInformation = $payment->getAdditionalInformation();
$type = null;
if (!empty($additionalInformation['threeDSType'])) {
$type = $additionalInformation['threeDSType'];
if (!empty($additionalInformation['action'])) {
return json_encode($additionalInformation['action']);
}
$token = null;
if (!empty($additionalInformation['threeDS2Token'])) {
$token = $additionalInformation['threeDS2Token'];
}
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($type, $token);
}
return true;
}
}
......@@ -76,6 +76,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
public function initiate($payload)
{
// Decode payload from frontend
// TODO implement interface to handle the request the correct way
$payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format
......@@ -83,6 +84,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because the request was not a valid JSON'));
}
// Validate if order id is present
if (empty($payload['orderId'])) {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because of a missing order id'));
}
......@@ -91,28 +93,16 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$order = $this->orderFactory->create()->load($payload['orderId']);
$payment = $order->getPayment();
// Init payments/details request
$result = [];
if ($paymentData = $payment->getAdditionalInformation("threeDS2PaymentData")) {
// Add payment data into the request object
$request = [
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
];
// unset payment data from additional information
$payment->unsAdditionalInformation("threeDS2PaymentData");
} else {
$this->adyenLogger->error("3D secure 2.0 failed, payment data not found");
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed, payment data not found'));
}
// Depends on the component's response we send a fingerprint or the challenge result
if (!empty($payload['details']['threeds2.fingerprint'])) {
$request['details']['threeds2.fingerprint'] = $payload['details']['threeds2.fingerprint'];
} elseif (!empty($payload['details']['threeds2.challengeResult'])) {
$request['details']['threeds2.challengeResult'] = $payload['details']['threeds2.challengeResult'];
}
// Unset action from additional info since it is not needed anymore
$payment->unsAdditionalInformation("action");
// TODO validate and format the request root level keys
$request = $payload;
// Init payments/details request
$result = [];
// Send the request
try {
......@@ -128,9 +118,9 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
// Check if result is challenge shopper, if yes return the token
if (!empty($result['resultCode']) &&
$result['resultCode'] === 'ChallengeShopper' &&
!empty($result['authentication']['threeds2.challengeToken'])
!empty($result['action'])
) {
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($result['resultCode'], $result['authentication']['threeds2.challengeToken']);
return json_encode($result['action']);
}
// Save the payments response because we are going to need it during the place order flow
......
This diff is collapsed.
......@@ -124,12 +124,11 @@ define(
// TODO get config from admin configuration
installmentsConfiguration = '[[0,2,3],[2,3,3]]'; // DUmmy data for testing
var placeOrderAllowed = self.placeOrderAllowed.bind(this);
var placeOrderAllowed = self.placeOrderAllowed.bind(self);
function handleOnChange(state, component) {
if (!!state.isValid) {
console.log(state.data);
this.stateData = state.data;
self.stateData = state.data;
placeOrderAllowed(true);
} else {
placeOrderAllowed(false);
......@@ -164,10 +163,9 @@ define(
var self = this;
// Handle identify shopper action
if (action.type == 'IdentifyShopper') {
if (action.type == 'threeDS2Fingerprint') {
var configuration = {
onComplete: function (result) {
self.threeDS2IdentifyComponent.unmount();
onAdditionalDetails: function (result) {
var request = result.data;
request.orderId = orderId;
adyenPaymentService.processThreeDS2(request).done(function (responseJSON) {
......@@ -182,7 +180,7 @@ define(
}
// Handle challenge shopper action
if (action.type == "ChallengeShopper") {
if (action.type == "threeDS2Challenge") {
fullScreenLoader.stopLoader();
var popupModal = $('#threeDS2Modal').modal({
......@@ -199,8 +197,7 @@ define(
var configuration = {
size: '05',
onComplete: function (result) {
self.threeDS2ChallengeComponent.unmount();
onAdditionalDetails: function (result) {
self.closeModal(popupModal);
fullScreenLoader.startLoader();
var request = result.data;
......@@ -217,7 +214,6 @@ define(
}
self.checkoutComponent.createFromAction(action, configuration).mount('#threeDS2Container');
},
/**
* This method is a workaround to close the modal in the right way and reconstruct the threeDS2Modal.
......@@ -243,7 +239,8 @@ define(
'method': this.item.method,
additional_data: {
'state_data': JSON.stringify(this.stateData),
'combo_card_type': this.comboCardOption()
'combo_card_type': this.comboCardOption(),
'channel': 'Web' //TODO pass channel from frontend
}
};
this.vaultEnabler.visitAdditionalData(data);
......@@ -302,9 +299,12 @@ define(
var self = this;
var response = JSON.parse(responseJSON);
if (!!response.threeDS2) {
if (!!response.type && (
response.type == "threeDS2Fingerprint" ||
response.type == "threeDS2Challenge"
)) {
// render component
self.renderThreeDS2Component(response.type, response.token, orderId);
self.renderThreeDS2Component(response, orderId);
} else {
window.location.replace(url.build(
window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl)
......@@ -329,19 +329,6 @@ define(
return true;
},
/**
* Validates if the typed in card holder is valid
* - length validation, can not be empty
*
* @returns {boolean}
*/
isCardOwnerValid: function () {
if (this.creditCardOwner().length == 0) {
return false;
}
return true;
},
/**
* Translates the card type alt code (used in Adyen) to card type code (used in Magento) if it's available
*
......
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