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
$componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA);
$requestBody = array_merge($requestBody, $componentStateData);
if (empty($requestBody['paymentMethod']['type']) && !empty(
$payment->getAdditionalInformation(
AdyenHppDataAssignObserver::BRAND_CODE
......@@ -200,7 +199,6 @@ class CheckoutDataBuilder implements BuilderInterface
}
unset($requestBody['installments']);
}
$request['body'] = $requestBody;
return $request;
......
......@@ -33,20 +33,36 @@ use Magento\Quote\Api\Data\PaymentInterface;
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
*/
private $adyenHelper;
/**
* @var \Magento\Customer\Api\CustomerRepositoryInterface
*/
private $customerRepository;
/**
* Requests constructor.
*
* @param Data $adyenHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
) {
$this->adyenHelper = $adyenHelper;
$this->customerRepository = $customerRepository;
}
/**
......@@ -72,8 +88,8 @@ class Requests extends AbstractHelper
* @param $storeId
* @param null $payment
* @param null $additionalData
* @return array
* @param array $request
* @return array
*/
public function buildCustomerData(
$billingAddress,
......@@ -85,6 +101,14 @@ class Requests extends AbstractHelper
) {
if ($customerId > 0) {
$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 = '';
......@@ -92,62 +116,38 @@ class Requests extends AbstractHelper
$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($additionalData['guestEmail'])) {
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethod) &&
!$this->adyenHelper->isPaymentMethodAfterpayTouchMethod($paymentMethod)
) {
$request['paymentMethod']['personalDetails']['shopperEmail'] = $additionalData['guestEmail'];
} else {
$request['shopperEmail'] = $additionalData['guestEmail'];
if (!empty($billingAddress)) {
if (empty($request[self::SHOPPER_EMAIL]) && $customerEmail = $billingAddress->getEmail()) {
$request[self::SHOPPER_EMAIL] = $customerEmail;
}
}
if (!empty($billingAddress)) {
// Openinvoice (klarna and afterpay BUT not afterpay touch) methods requires different request format
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethod) &&
!$this->adyenHelper->isPaymentMethodAfterpayTouchMethod($paymentMethod)
if (empty($request[self::TELEPHONE_NUMBER]) &&
$customerTelephone = trim($billingAddress->getTelephone())
) {
if ($customerEmail = $billingAddress->getEmail()) {
$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;
}
$request[self::TELEPHONE_NUMBER] = $customerTelephone;
}
if ($firstName = $billingAddress->getFirstname()) {
$request['shopperName']['firstName'] = $firstName;
}
if (empty($request[self::SHOPPER_NAME][self::FIRST_NAME]) &&
$firstName = $billingAddress->getFirstname()
) {
$request[self::SHOPPER_NAME][self::FIRST_NAME] = $firstName;
}
if ($lastName = $billingAddress->getLastname()) {
$request['shopperName']['lastName'] = $lastName;
}
if (empty($request[self::SHOPPER_NAME][self::LAST_NAME]) &&
$firstName = $billingAddress->getLastname()
) {
$request[self::SHOPPER_NAME][self::LAST_NAME] = $firstName;
}
if ($countryId = $billingAddress->getCountryId()) {
$request['countryCode'] = $countryId;
if (empty($request[self::COUNTRY_CODE]) && $countryId = $billingAddress->getCountryId()) {
$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;
}
......@@ -261,7 +261,6 @@ class Requests extends AbstractHelper
$request['deliveryAddress'] = $requestDelivery;
}
}
return $request;
}
......@@ -375,42 +374,54 @@ class Requests extends AbstractHelper
$request['paymentMethod']['type'] = 'scheme';
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]) &&
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]
) &&
$cardNumber = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER]) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]) &&
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]
) &&
$expiryMonth = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH]) {
$request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]) &&
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]
) &&
$expiryYear = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR]) {
$request['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::HOLDER_NAME]) && $holderName =
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::HOLDER_NAME]
) && $holderName =
$payload[PaymentInterface::KEY_ADDITIONAL_DATA][AdyenCcDataAssignObserver::HOLDER_NAME]) {
$request['paymentMethod']['holderName'] = $holderName;
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]) &&
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]
) &&
$securityCode = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE]) {
$request['paymentMethod']['encryptedSecurityCode'] = $securityCode;
}
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]) &&
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]
) &&
$recurringDetailReference = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE]
) {
......@@ -437,8 +448,10 @@ class Requests extends AbstractHelper
}
// if installments is set add it into the request
if (!empty($payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS])) {
if (!empty(
$payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS]
)) {
if (($numberOfInstallment = $payload[PaymentInterface::KEY_ADDITIONAL_DATA]
[AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS]) > 0) {
$request['installments']['value'] = $numberOfInstallment;
......
......@@ -59,11 +59,6 @@ abstract class AdyenAbstractDataAssignObserver extends AbstractDataAssignObserve
$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
$additionalData[self::STATE_DATA] = $stateData;
......
......@@ -51,6 +51,16 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver
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
* @return void
......@@ -61,7 +71,11 @@ class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver
$data = $this->readDataArgument($observer);
$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
$paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) {
......
......@@ -23,16 +23,23 @@
namespace Adyen\Payment\Observer;
use Adyen\Payment\Observer\Adminhtml\AdyenSateDataValidator;
use Magento\Framework\Event\Observer;
use Magento\Quote\Api\Data\PaymentInterface;
class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver
{
/**
* Approved root level keys from additional data array
*
* @var array
* @var \Adyen\Service\Validator\CheckoutStateDataValidator
*/
public $checkoutStateDataValidator;
public function __construct(
\Adyen\Service\Validator\CheckoutStateDataValidator $checkoutStateDataValidator
) {
$this->checkoutStateDataValidator = $checkoutStateDataValidator;
}
protected $approvedAdditionalDataKeys = [
self::STATE_DATA,
self::BRAND_CODE
......@@ -57,9 +64,12 @@ class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver
{
// Get request fields
$data = $this->readDataArgument($observer);
$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
$paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) {
......
......@@ -14,7 +14,7 @@
}
],
"require": {
"adyen/php-api-library": "^6.3",
"adyen/php-api-library": "^7",
"magento/framework": ">=101.0.8 <102 || >=102.0.1",
"magento/module-vault": "101.*",
"magento/module-paypal": ">=100.2.6"
......
This diff is collapsed.
This diff is collapsed.
......@@ -122,7 +122,7 @@ define(
// installments configuration
var installmentsConfiguration = this.getAllInstallments();
// 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);
......@@ -141,7 +141,7 @@ define(
holderNameRequired: true,
enableStoreDetails: self.getEnableStoreDetails(),
groupTypes: self.getAvailableCardTypeAltCodes(),
installments: installmentsConfiguration,
installmentOptions: installmentsConfiguration,
onChange: handleOnChange
};
......
......@@ -212,18 +212,55 @@ define(
var country = '';
var postalCode = '';
var street = '';
var firstName = '';
var lastName = '';
var telephone = '';
var email = '';
var shopperGender = '';
var shopperDateOfBirth = '';
if (!!quote && !!quote.shippingAddress()) {
city = quote.shippingAddress().city;
country = quote.shippingAddress().countryId;
postalCode = quote.shippingAddress().postcode;
street = quote.shippingAddress().street.join(" ");
city = quote.shippingAddress().city;
country = quote.shippingAddress().countryId;
postalCode = quote.shippingAddress().postcode;
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*/
var configuration = {
showPayButton: showPayButton,
/*data: {
countryCode: country,
data: {
personalDetails: {
firstName: firstName,
lastName: lastName,
telephoneNumber: telephone,
shopperEmail: email,
gender: getAdyenGender(shopperGender),
dateOfBirth:shopperDateOfBirth
},
billingAddress: {
city: city,
country: country,
......@@ -231,7 +268,7 @@ define(
postalCode: postalCode,
street: street
}
},*/
},
onChange: function (state) {
if (!!state.isValid) {
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