Commit 1d4b096b authored by Alexandros Moraitis's avatar Alexandros Moraitis Committed by GitHub

[PW-2489] Fix afterpay component (#760)

* Work in progress

* Add after pay fields to payment request

* remove extra loggers

* Fix code smells

* Fix code smells adding in more places the consts

* Integrate the checks in the request class

* Update Gateway/Request/CheckoutDataBuilder.php
Co-authored-by: default avatarAlessio Zampatti <alessio.zampatti@adyen.com>

* Update Observer/AdyenHppDataAssignObserver.php
Co-authored-by: default avatarAlessio Zampatti <alessio.zampatti@adyen.com>

* remove unused field

* Update request structure for customerData

* Fix instalments error on frontend and update generic component

* [WIP] Fix missing getDateOfBirth

* Fix date of birth retrieval from customer

* Fix guest email address
Co-authored-by: default avatarAlessio Zampatti <alessio.zampatti@adyen.com>
Co-authored-by: default avatarattilak <attila.kiss@adyen.com>
parent b22eb220
...@@ -86,7 +86,6 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -86,7 +86,6 @@ class CheckoutDataBuilder implements BuilderInterface
$componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA); $componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA);
$requestBody = array_merge($requestBody, $componentStateData); $requestBody = array_merge($requestBody, $componentStateData);
if (empty($requestBody['paymentMethod']['type']) && !empty( if (empty($requestBody['paymentMethod']['type']) && !empty(
$payment->getAdditionalInformation( $payment->getAdditionalInformation(
AdyenHppDataAssignObserver::BRAND_CODE AdyenHppDataAssignObserver::BRAND_CODE
...@@ -200,7 +199,6 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -200,7 +199,6 @@ class CheckoutDataBuilder implements BuilderInterface
} }
unset($requestBody['installments']); unset($requestBody['installments']);
} }
$request['body'] = $requestBody; $request['body'] = $requestBody;
return $request; return $request;
......
...@@ -33,20 +33,36 @@ use Magento\Quote\Api\Data\PaymentInterface; ...@@ -33,20 +33,36 @@ use Magento\Quote\Api\Data\PaymentInterface;
class Requests extends AbstractHelper class Requests extends AbstractHelper
{ {
const TELEPHONE_NUMBER = 'telephoneNumber';
const FIRST_NAME = 'firstName';
const LAST_NAME = 'lastName';
const SHOPPER_NAME = 'shopperName';
const DATE_OF_BIRTH = 'dateOfBirth';
const SHOPPER_EMAIL = 'shopperEmail';
const COUNTRY_CODE = 'countryCode';
const SHOPPER_LOCALE = 'shopperLocale';
/** /**
* @var \Adyen\Payment\Helper\Data * @var \Adyen\Payment\Helper\Data
*/ */
private $adyenHelper; private $adyenHelper;
/**
* @var \Magento\Customer\Api\CustomerRepositoryInterface
*/
private $customerRepository;
/** /**
* Requests constructor. * Requests constructor.
* *
* @param Data $adyenHelper * @param Data $adyenHelper
*/ */
public function __construct( public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper \Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
) { ) {
$this->adyenHelper = $adyenHelper; $this->adyenHelper = $adyenHelper;
$this->customerRepository = $customerRepository;
} }
/** /**
...@@ -72,8 +88,8 @@ class Requests extends AbstractHelper ...@@ -72,8 +88,8 @@ class Requests extends AbstractHelper
* @param $storeId * @param $storeId
* @param null $payment * @param null $payment
* @param null $additionalData * @param null $additionalData
* @return array
* @param array $request * @param array $request
* @return array
*/ */
public function buildCustomerData( public function buildCustomerData(
$billingAddress, $billingAddress,
...@@ -85,6 +101,14 @@ class Requests extends AbstractHelper ...@@ -85,6 +101,14 @@ class Requests extends AbstractHelper
) { ) {
if ($customerId > 0) { if ($customerId > 0) {
$request['shopperReference'] = $customerId; $request['shopperReference'] = $customerId;
$customer = $this->customerRepository->getById($customerId);
if (empty($request[self::DATE_OF_BIRTH]) && $dateOfBirth = $customer->getDob()) {
$request[self::DATE_OF_BIRTH] = $dateOfBirth;
}
//TODO check if Gender can be retrieved
} }
$paymentMethod = ''; $paymentMethod = '';
...@@ -92,62 +116,38 @@ class Requests extends AbstractHelper ...@@ -92,62 +116,38 @@ class Requests extends AbstractHelper
$paymentMethod = $payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE); $paymentMethod = $payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE);
} }
// In case of virtual product and guest checkout there is a workaround to get the guest's email address if (!empty($billingAddress)) {
if (!empty($additionalData['guestEmail'])) { if (empty($request[self::SHOPPER_EMAIL]) && $customerEmail = $billingAddress->getEmail()) {
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethod) && $request[self::SHOPPER_EMAIL] = $customerEmail;
!$this->adyenHelper->isPaymentMethodAfterpayTouchMethod($paymentMethod)
) {
$request['paymentMethod']['personalDetails']['shopperEmail'] = $additionalData['guestEmail'];
} else {
$request['shopperEmail'] = $additionalData['guestEmail'];
} }
}
if (!empty($billingAddress)) { if (empty($request[self::TELEPHONE_NUMBER]) &&
// Openinvoice (klarna and afterpay BUT not afterpay touch) methods requires different request format $customerTelephone = trim($billingAddress->getTelephone())
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethod) &&
!$this->adyenHelper->isPaymentMethodAfterpayTouchMethod($paymentMethod)
) { ) {
if ($customerEmail = $billingAddress->getEmail()) { $request[self::TELEPHONE_NUMBER] = $customerTelephone;
$request['paymentMethod']['personalDetails']['shopperEmail'] = $customerEmail; }
}
if ($customerTelephone = trim($billingAddress->getTelephone())) {
$request['paymentMethod']['personalDetails']['telephoneNumber'] = $customerTelephone;
}
if ($firstName = $billingAddress->getFirstname()) {
$request['paymentMethod']['personalDetails']['firstName'] = $firstName;
}
if ($lastName = $billingAddress->getLastname()) {
$request['paymentMethod']['personalDetails']['lastName'] = $lastName;
}
} else {
if ($customerEmail = $billingAddress->getEmail()) {
$request['shopperEmail'] = $customerEmail;
}
if ($customerTelephone = trim($billingAddress->getTelephone())) {
$request['telephoneNumber'] = $customerTelephone;
}
if ($firstName = $billingAddress->getFirstname()) { if (empty($request[self::SHOPPER_NAME][self::FIRST_NAME]) &&
$request['shopperName']['firstName'] = $firstName; $firstName = $billingAddress->getFirstname()
} ) {
$request[self::SHOPPER_NAME][self::FIRST_NAME] = $firstName;
}
if ($lastName = $billingAddress->getLastname()) { if (empty($request[self::SHOPPER_NAME][self::LAST_NAME]) &&
$request['shopperName']['lastName'] = $lastName; $firstName = $billingAddress->getLastname()
} ) {
$request[self::SHOPPER_NAME][self::LAST_NAME] = $firstName;
} }
if ($countryId = $billingAddress->getCountryId()) { if (empty($request[self::COUNTRY_CODE]) && $countryId = $billingAddress->getCountryId()) {
$request['countryCode'] = $countryId; $request[self::COUNTRY_CODE] = $countryId;
} }
$request['shopperLocale'] = $this->adyenHelper->getCurrentLocaleCode($storeId); if (empty($request[self::SHOPPER_LOCALE])) {
$request[self::SHOPPER_LOCALE] = $this->adyenHelper->getCurrentLocaleCode($storeId);
}
} }
return $request; return $request;
} }
...@@ -261,7 +261,6 @@ class Requests extends AbstractHelper ...@@ -261,7 +261,6 @@ class Requests extends AbstractHelper
$request['deliveryAddress'] = $requestDelivery; $request['deliveryAddress'] = $requestDelivery;
} }
} }
return $request; return $request;
} }
...@@ -375,42 +374,54 @@ class Requests extends AbstractHelper ...@@ -375,42 +374,54 @@ class Requests extends AbstractHelper
$request['paymentMethod']['type'] = 'scheme'; $request['paymentMethod']['type'] = 'scheme';
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]) && $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]
) &&
$cardNumber = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] $cardNumber = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]) { [AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber; $request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]) && $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]
) &&
$expiryMonth = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] $expiryMonth = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]) { [AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]) {
$request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth; $request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]) && $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]
) &&
$expiryYear = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] $expiryYear = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]) { [AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]) {
$request['paymentMethod']['encryptedExpiryYear'] = $expiryYear; $request['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::HOLDER_NAME]) && $holderName = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::HOLDER_NAME]
) && $holderName =
$payload[PaymentInterface::KEY_ADDITIONAL_DATA][AdyenCcDataAssignObserver::HOLDER_NAME]) { $payload[PaymentInterface::KEY_ADDITIONAL_DATA][AdyenCcDataAssignObserver::HOLDER_NAME]) {
$request['paymentMethod']['holderName'] = $holderName; $request['paymentMethod']['holderName'] = $holderName;
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]) && $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]
) &&
$securityCode = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] $securityCode = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]) { [AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]) {
$request['paymentMethod']['encryptedSecurityCode'] = $securityCode; $request['paymentMethod']['encryptedSecurityCode'] = $securityCode;
} }
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]) && $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]
) &&
$recurringDetailReference = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] $recurringDetailReference = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE] [AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]
) { ) {
...@@ -437,8 +448,10 @@ class Requests extends AbstractHelper ...@@ -437,8 +448,10 @@ class Requests extends AbstractHelper
} }
// if installments is set add it into the request // if installments is set add it into the request
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (!empty(
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS])) { $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS]
)) {
if (($numberOfInstallment = $payload[PaymentInterface::KEY_ADDITIONAL_DATA] if (($numberOfInstallment = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS]) > 0) { [AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS]) > 0) {
$request['installments']['value'] = $numberOfInstallment; $request['installments']['value'] = $numberOfInstallment;
......
...@@ -59,11 +59,6 @@ abstract class AdyenAbstractDataAssignObserver extends AbstractDataAssignObserve ...@@ -59,11 +59,6 @@ abstract class AdyenAbstractDataAssignObserver extends AbstractDataAssignObserve
$stateData = json_decode($additionalData[self::STATE_DATA], true); $stateData = json_decode($additionalData[self::STATE_DATA], true);
} }
// Get validated state data array
if (!empty($stateData)) {
$stateData = $this->getArrayOnlyWithApprovedKeys($stateData, $this->approvedStateDataKeys);
}
// Replace state data with the decoded and validated state data // Replace state data with the decoded and validated state data
$additionalData[self::STATE_DATA] = $stateData; $additionalData[self::STATE_DATA] = $stateData;
......
...@@ -51,6 +51,16 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver ...@@ -51,6 +51,16 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver
self::STORE_PAYMENT_METHOD self::STORE_PAYMENT_METHOD
]; ];
/**
* @var \Adyen\Service\Validator\CheckoutStateDataValidator
*/
public $checkoutStateDataValidator;
public function __construct(
\Adyen\Service\Validator\CheckoutStateDataValidator $checkoutStateDataValidator
) {
$this->checkoutStateDataValidator = $checkoutStateDataValidator;
}
/** /**
* @param Observer $observer * @param Observer $observer
* @return void * @return void
...@@ -61,7 +71,11 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver ...@@ -61,7 +71,11 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver
$data = $this->readDataArgument($observer); $data = $this->readDataArgument($observer);
$additionalData = $this->getValidatedAdditionalData($data); $additionalData = $this->getValidatedAdditionalData($data);
if (!empty($additionalData[self::STATE_DATA])) {
$additionalData[self::STATE_DATA] = $this->checkoutStateDataValidator->getValidatedAdditionalData(
$additionalData[self::STATE_DATA]
);
}
// Set additional data in the payment // Set additional data in the payment
$paymentInfo = $this->readPaymentModelArgument($observer); $paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) { foreach ($additionalData as $key => $data) {
......
...@@ -23,16 +23,23 @@ ...@@ -23,16 +23,23 @@
namespace Adyen\Payment\Observer; namespace Adyen\Payment\Observer;
use Adyen\Payment\Observer\Adminhtml\AdyenSateDataValidator;
use Magento\Framework\Event\Observer; use Magento\Framework\Event\Observer;
use Magento\Quote\Api\Data\PaymentInterface;
class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver
{ {
/** /**
* Approved root level keys from additional data array * @var \Adyen\Service\Validator\CheckoutStateDataValidator
*
* @var array
*/ */
public $checkoutStateDataValidator;
public function __construct(
\Adyen\Service\Validator\CheckoutStateDataValidator $checkoutStateDataValidator
) {
$this->checkoutStateDataValidator = $checkoutStateDataValidator;
}
protected $approvedAdditionalDataKeys = [ protected $approvedAdditionalDataKeys = [
self::STATE_DATA, self::STATE_DATA,
self::BRAND_CODE self::BRAND_CODE
...@@ -57,9 +64,12 @@ class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver ...@@ -57,9 +64,12 @@ class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver
{ {
// Get request fields // Get request fields
$data = $this->readDataArgument($observer); $data = $this->readDataArgument($observer);
$additionalData = $this->getValidatedAdditionalData($data); $additionalData = $this->getValidatedAdditionalData($data);
if (!empty($additionalData[self::STATE_DATA])) {
$additionalData[self::STATE_DATA] = $this->checkoutStateDataValidator->getValidatedAdditionalData(
$additionalData[self::STATE_DATA]
);
}
// Set additional data in the payment // Set additional data in the payment
$paymentInfo = $this->readPaymentModelArgument($observer); $paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) { foreach ($additionalData as $key => $data) {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
} }
], ],
"require": { "require": {
"adyen/php-api-library": "^6.3", "adyen/php-api-library": "^7",
"magento/framework": ">=101.0.8 <102 || >=102.0.1", "magento/framework": ">=101.0.8 <102 || >=102.0.1",
"magento/module-vault": "101.*", "magento/module-vault": "101.*",
"magento/module-paypal": ">=100.2.6" "magento/module-paypal": ">=100.2.6"
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -122,7 +122,7 @@ define( ...@@ -122,7 +122,7 @@ define(
// installments configuration // installments configuration
var installmentsConfiguration = this.getAllInstallments(); var installmentsConfiguration = this.getAllInstallments();
// TODO get config from admin configuration // TODO get config from admin configuration
installmentsConfiguration = '[[0,2,3],[2,3,3]]'; // DUmmy data for testing installmentsConfiguration = []; // DUmmy data for testing
var placeOrderAllowed = self.placeOrderAllowed.bind(self); var placeOrderAllowed = self.placeOrderAllowed.bind(self);
...@@ -141,7 +141,7 @@ define( ...@@ -141,7 +141,7 @@ define(
holderNameRequired: true, holderNameRequired: true,
enableStoreDetails: self.getEnableStoreDetails(), enableStoreDetails: self.getEnableStoreDetails(),
groupTypes: self.getAvailableCardTypeAltCodes(), groupTypes: self.getAvailableCardTypeAltCodes(),
installments: installmentsConfiguration, installmentOptions: installmentsConfiguration,
onChange: handleOnChange onChange: handleOnChange
}; };
......
...@@ -212,18 +212,55 @@ define( ...@@ -212,18 +212,55 @@ define(
var country = ''; var country = '';
var postalCode = ''; var postalCode = '';
var street = ''; var street = '';
var firstName = '';
var lastName = '';
var telephone = '';
var email = '';
var shopperGender = '';
var shopperDateOfBirth = '';
if (!!quote && !!quote.shippingAddress()) { if (!!quote && !!quote.shippingAddress()) {
city = quote.shippingAddress().city; city = quote.shippingAddress().city;
country = quote.shippingAddress().countryId; country = quote.shippingAddress().countryId;
postalCode = quote.shippingAddress().postcode; postalCode = quote.shippingAddress().postcode;
street = quote.shippingAddress().street.join(" "); street = quote.shippingAddress().street.join(" ");
firstName = quote.shippingAddress().firstname;
lastName = quote.shippingAddress().lastname;
telephone = quote.shippingAddress().telephone;
if (!!customerData.email) {
email = customerData.email;
} else if (!!quote.guestEmail) {
email = quote.guestEmail;
}
shopperGender = customerData.gender;
shopperDateOfBirth = customerData.dob;
}
function getAdyenGender(gender) {
if (gender == 1) {
return 'MALE';
} else if (gender == 2) {
return 'FEMALE';
}
return 'UNKNOWN';
} }
/*Use the storedPaymentMethod object and the custom onChange function as the configuration object together*/ /*Use the storedPaymentMethod object and the custom onChange function as the configuration object together*/
var configuration = { var configuration = {
showPayButton: showPayButton, showPayButton: showPayButton,
/*data: { countryCode: country,
data: {
personalDetails: {
firstName: firstName,
lastName: lastName,
telephoneNumber: telephone,
shopperEmail: email,
gender: getAdyenGender(shopperGender),
dateOfBirth:shopperDateOfBirth
},
billingAddress: { billingAddress: {
city: city, city: city,
country: country, country: country,
...@@ -231,7 +268,7 @@ define( ...@@ -231,7 +268,7 @@ define(
postalCode: postalCode, postalCode: postalCode,
street: street street: street
} }
},*/ },
onChange: function (state) { onChange: function (state) {
if (!!state.isValid) { if (!!state.isValid) {
result.stateData = state.data; result.stateData = state.data;
......
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