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 6bdeaaa5 authored by Attila Kiss's avatar Attila Kiss Committed by GitHub

Merge pull request #730 from Adyen/develop

Release 6.1.1
parents 21350d08 c3a7e85c
* @msilvagarcia @cyattilakiss @Aleffio @AlexandrosMor @rikterbeek @acampos1916 * @cyattilakiss @AlexandrosMor @msilvagarcia @acampos1916 @Aleffio @rikterbeek
**Magento version**: x.y.z
**Plugin version**: x.y.z
**Description**
<!--
- Please provide a description of the issue. In case of bug report, please provide the necessary steps to reproduce.
- For merchant specific requests, please use https://support.adyen.com
-->
\ No newline at end of file
...@@ -29,4 +29,18 @@ class Boleto extends AbstractInfo ...@@ -29,4 +29,18 @@ class Boleto extends AbstractInfo
* @var string * @var string
*/ */
protected $_template = 'Adyen_Payment::info/adyen_boleto.phtml'; protected $_template = 'Adyen_Payment::info/adyen_boleto.phtml';
/**
* @param $data string
* @return string
*/
public function getPaymentActionData($data)
{
$paymentAction = $this->getMethod()->getInfoInstance()->getAdditionalInformation('action');
if (empty($paymentAction[$data])) {
return '';
}
return $paymentAction[$data];
}
} }
...@@ -107,7 +107,14 @@ class Result extends \Magento\Framework\App\Action\Action ...@@ -107,7 +107,14 @@ class Result extends \Magento\Framework\App\Action\Action
$session->getQuote()->setIsActive(false)->save(); $session->getQuote()->setIsActive(false)->save();
$this->_redirect('checkout/onepage/success', ['_query' => ['utm_nooverride' => '1']]); $this->_redirect('checkout/onepage/success', ['_query' => ['utm_nooverride' => '1']]);
} else { } else {
$this->_cancel($response); $this->_adyenLogger->addAdyenResult(
sprintf(
'Payment for order %s was unsuccessful, ' .
'it will be cancelled when the OFFER_CLOSED notification has been processed.',
$this->_order->getIncrementId()
)
);
$this->restoreCart($response);
$failReturnPath = $this->_adyenHelper->getAdyenAbstractConfigData('return_path'); $failReturnPath = $this->_adyenHelper->getAdyenAbstractConfigData('return_path');
$this->_redirect($failReturnPath); $this->_redirect($failReturnPath);
} }
...@@ -121,17 +128,13 @@ class Result extends \Magento\Framework\App\Action\Action ...@@ -121,17 +128,13 @@ class Result extends \Magento\Framework\App\Action\Action
/** /**
* @param $response * @param $response
*/ */
protected function _cancel($response) protected function restoreCart($response)
{ {
$session = $this->_session; $session = $this->_session;
// restore the quote // restore the quote
$session->restoreQuote(); $session->restoreQuote();
$order = $this->_order;
$this->_adyenHelper->cancelOrder($order);
if (isset($response['authResult']) && $response['authResult'] == \Adyen\Payment\Model\Notification::CANCELLED) { if (isset($response['authResult']) && $response['authResult'] == \Adyen\Payment\Model\Notification::CANCELLED) {
$this->messageManager->addError(__('You have cancelled the order. Please try again')); $this->messageManager->addError(__('You have cancelled the order. Please try again'));
} else { } else {
...@@ -270,17 +273,13 @@ class Result extends \Magento\Framework\App\Action\Action ...@@ -270,17 +273,13 @@ class Result extends \Magento\Framework\App\Action\Action
$this->_adyenLogger->addAdyenResult('Do nothing wait for the notification'); $this->_adyenLogger->addAdyenResult('Do nothing wait for the notification');
break; break;
case Notification::CANCELLED: case Notification::CANCELLED:
$this->_adyenLogger->addAdyenResult('Cancel or Hold the order'); case Notification::ERROR:
$this->_adyenLogger->addAdyenResult('Cancel or Hold the order on OFFER_CLOSED notification');
$result = false; $result = false;
break; break;
case Notification::REFUSED: case Notification::REFUSED:
// if refused there will be a AUTHORIZATION : FALSE notification send only exception is idea // if refused there will be a AUTHORIZATION : FALSE notification send only exception is idea
$this->_adyenLogger->addAdyenResult('Cancel or Hold the order'); $this->_adyenLogger->addAdyenResult('Cancel or Hold the order on AUTHORISATION success = false notification');
$result = false;
break;
case Notification::ERROR:
//attempt to hold/cancel
$this->_adyenLogger->addAdyenResult('Cancel or Hold the order');
$result = false; $result = false;
break; break;
default: default:
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2020 Adyen NV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Data\Order;
use Magento\Sales\Api\Data\OrderAddressInterface;
class AddressAdapter extends \Magento\Payment\Gateway\Data\Order\AddressAdapter
{
/**
* @var OrderAddressInterface
*/
private $address;
public function __construct(OrderAddressInterface $address)
{
$this->address = $address;
parent::__construct($address);
}
/**
* Get street line 3
*
* @return string
*/
public function getStreetLine3()
{
$street = $this->address->getStreet();
return isset($street[2]) ? $street[2] : '';
}
/**
* Get street line 4
*
* @return string
*/
public function getStreetLine4()
{
$street = $this->address->getStreet();
return isset($street[3]) ? $street[3] : '';
}
}
...@@ -64,14 +64,8 @@ class TransactionAuthorization implements ClientInterface ...@@ -64,14 +64,8 @@ class TransactionAuthorization implements ClientInterface
public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject) public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject)
{ {
$request = $transferObject->getBody(); $request = $transferObject->getBody();
$headers = $transferObject->getHeaders();
$requestOptions = []; $requestOptions = [];
if (!empty($headers['idempotencyKey'])) {
$requestOptions['idempotencyKey'] = $headers['idempotencyKey'];
}
// call lib // call lib
$service = new \Adyen\Service\Payment($this->client); $service = new \Adyen\Service\Payment($this->client);
......
...@@ -63,7 +63,6 @@ class TransactionPayment implements ClientInterface ...@@ -63,7 +63,6 @@ class TransactionPayment implements ClientInterface
public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject) public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject)
{ {
$request = $transferObject->getBody(); $request = $transferObject->getBody();
$headers = $transferObject->getHeaders();
// If the payments call is already done return the request // If the payments call is already done return the request
if (!empty($request['resultCode'])) { if (!empty($request['resultCode'])) {
...@@ -77,10 +76,6 @@ class TransactionPayment implements ClientInterface ...@@ -77,10 +76,6 @@ class TransactionPayment implements ClientInterface
$requestOptions = []; $requestOptions = [];
if (!empty($headers['idempotencyKey'])) {
$requestOptions['idempotencyKey'] = $headers['idempotencyKey'];
}
$request = $this->applicationInfo->addMerchantApplicationIntoRequest($request); $request = $this->applicationInfo->addMerchantApplicationIntoRequest($request);
try { try {
......
...@@ -156,8 +156,8 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -156,8 +156,8 @@ class CheckoutDataBuilder implements BuilderInterface
$requestBody['shopperName']['firstName'] = $payment->getAdditionalInformation("firstname"); $requestBody['shopperName']['firstName'] = $payment->getAdditionalInformation("firstname");
} }
if ($payment->getAdditionalInformation("lastName")) { if ($payment->getAdditionalInformation("lastname")) {
$requestBody['shopperName']['lastName'] = $payment->getAdditionalInformation("lastName"); $requestBody['shopperName']['lastName'] = $payment->getAdditionalInformation("lastname");
} }
if ($payment->getMethod() == \Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider::CODE) { if ($payment->getMethod() == \Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider::CODE) {
......
...@@ -64,8 +64,6 @@ class PaymentDataBuilder implements BuilderInterface ...@@ -64,8 +64,6 @@ class PaymentDataBuilder implements BuilderInterface
$request['body'] = $this->adyenRequestsHelper->buildPaymentData([], $amount, $currencyCode, $reference, $paymentMethod); $request['body'] = $this->adyenRequestsHelper->buildPaymentData([], $amount, $currencyCode, $reference, $paymentMethod);
$request['headers'] = $this->adyenRequestsHelper->addIdempotencyKey([], $paymentMethod, $reference);
return $request; return $request;
} }
} }
...@@ -23,43 +23,79 @@ ...@@ -23,43 +23,79 @@
namespace Adyen\Payment\Gateway\Response; namespace Adyen\Payment\Gateway\Response;
use Adyen\Payment\Helper\Data;
use Adyen\Payment\Logger\AdyenLogger;
use Magento\Vault\Api\Data\PaymentTokenFactoryInterface; use Magento\Vault\Api\Data\PaymentTokenFactoryInterface;
use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Payment\Gateway\Response\HandlerInterface;
use Magento\Payment\Model\InfoInterface; use Magento\Payment\Model\InfoInterface;
use Magento\Vault\Model\PaymentTokenManagement;
use Magento\Payment\Gateway\Data\PaymentDataObject;
use Magento\Vault\Api\PaymentTokenRepositoryInterface;
class VaultDetailsHandler implements HandlerInterface class VaultDetailsHandler implements HandlerInterface
{ {
const RECURRING_DETAIL_REFERENCE = 'recurring.recurringDetailReference';
const CARD_SUMMARY = 'cardSummary';
const EXPIRY_DATE = 'expiryDate';
const PAYMENT_METHOD = 'paymentMethod';
const ADDITIONAL_DATA_ERRORS = array(
self::RECURRING_DETAIL_REFERENCE => 'Missing Token in Result please enable in ' .
'Settings -> API URLs and Response menu in the Adyen Customer Area Recurring details setting',
self::CARD_SUMMARY => 'Missing cardSummary in Result please login to the adyen portal ' .
'and go to Settings -> API URLs and Response and enable the Card summary property',
self::EXPIRY_DATE => 'Missing expiryDate in Result please login to the adyen portal and go to ' .
'Settings -> API URLs and Response and enable the Expiry date property',
self::PAYMENT_METHOD => 'Missing paymentMethod in Result please login to the adyen portal and go to ' .
'Settings -> API URLs and Response and enable the Variant property'
);
/** /**
* @var PaymentTokenInterfaceFactory * @var PaymentTokenFactoryInterface
*/ */
protected $paymentTokenFactory; protected $paymentTokenFactory;
/** /**
* @var \Adyen\Payment\Logger\AdyenLogger * @var AdyenLogger
*/ */
private $adyenLogger; private $adyenLogger;
/** /**
* @var \Adyen\Payment\Helper\Data * @var Data
*/ */
private $adyenHelper; private $adyenHelper;
/**
* @var PaymentTokenManagement
*/
private $paymentTokenManagement;
/**
* @var
*/
private $paymentTokenRepository;
/** /**
* VaultDetailsHandler constructor. * VaultDetailsHandler constructor.
* *
* @param PaymentTokenFactoryInterface $paymentTokenFactory * @param PaymentTokenFactoryInterface $paymentTokenFactory
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger * @param AdyenLogger $adyenLogger
* @param \Adyen\Payment\Helper\Data $adyenHelper * @param Data $adyenHelper
* @param PaymentTokenManagement $paymentTokenManagement
* @param PaymentTokenRepositoryInterface $paymentTokenRepository
*/ */
public function __construct( public function __construct(
PaymentTokenFactoryInterface $paymentTokenFactory, PaymentTokenFactoryInterface $paymentTokenFactory,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger, AdyenLogger $adyenLogger,
\Adyen\Payment\Helper\Data $adyenHelper Data $adyenHelper,
PaymentTokenManagement $paymentTokenManagement,
PaymentTokenRepositoryInterface $paymentTokenRepository
) { ) {
$this->adyenLogger = $adyenLogger; $this->adyenLogger = $adyenLogger;
$this->adyenHelper = $adyenHelper; $this->adyenHelper = $adyenHelper;
$this->paymentTokenFactory = $paymentTokenFactory; $this->paymentTokenFactory = $paymentTokenFactory;
$this->paymentTokenManagement = $paymentTokenManagement;
$this->paymentTokenRepository = $paymentTokenRepository;
} }
/** /**
...@@ -67,18 +103,23 @@ class VaultDetailsHandler implements HandlerInterface ...@@ -67,18 +103,23 @@ class VaultDetailsHandler implements HandlerInterface
*/ */
public function handle(array $handlingSubject, array $response) public function handle(array $handlingSubject, array $response)
{ {
$payment = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($handlingSubject); /** @var PaymentDataObject $orderPayment */
$orderPayment = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($handlingSubject);
/** @var \Adyen\Payment\Api\Data\OrderPaymentInterface $payment */ $payment = $orderPayment->getPayment();
$payment = $payment->getPayment();
if ($this->adyenHelper->isCreditCardVaultEnabled($payment->getOrder()->getStoreId())) { if ($this->adyenHelper->isCreditCardVaultEnabled($payment->getOrder()->getStoreId())) {
// add vault payment token entity to extension attributes // add vault payment token entity to extension attributes
$paymentToken = $this->getVaultPaymentToken($response); $paymentToken = $this->getVaultPaymentToken($response, $payment);
if (null !== $paymentToken) { if (null !== $paymentToken) {
$extensionAttributes = $this->getExtensionAttributes($payment); $extensionAttributes = $this->getExtensionAttributes($payment);
$extensionAttributes->setVaultPaymentToken($paymentToken); $extensionAttributes->setVaultPaymentToken($paymentToken);
} else {
$this->adyenLogger->error(
sprintf('Failure trying to save credit card token in vault for order %s',
$payment->getOrder()->getIncrementId())
);
} }
} }
} }
...@@ -87,78 +128,70 @@ class VaultDetailsHandler implements HandlerInterface ...@@ -87,78 +128,70 @@ class VaultDetailsHandler implements HandlerInterface
* Get vault payment token entity * Get vault payment token entity
* *
* @param array $response * @param array $response
* @param $payment
* @return PaymentTokenInterface|null * @return PaymentTokenInterface|null
*/ */
private function getVaultPaymentToken(array $response) private function getVaultPaymentToken(array $response, $payment)
{ {
$paymentToken = null;
if (!empty($response['additionalData'])) {
$additionalData = $response['additionalData'];
if (empty($additionalData['recurring.recurringDetailReference'])) { if (empty($response['additionalData'])) {
$this->adyenLogger->error(
'Missing Token in Result please enable in ' .
'Settings -> API URLs and Response menu in the Adyen Customer Area Recurring details setting'
);
return null; return null;
} }
$token = $additionalData['recurring.recurringDetailReference'];
$additionalData = $response['additionalData'];
if (empty($additionalData['cardSummary'])) { $paymentToken = null;
$this->adyenLogger->error(
'Missing cardSummary in Result please login to the adyen portal ' .
'and go to Settings -> API URLs and Response and enable the Card summary property'
);
return null;
}
$cardSummary = $additionalData['cardSummary'];
if (empty($additionalData['expiryDate'])) { foreach (self::ADDITIONAL_DATA_ERRORS as $key => $errorMsg) {
$this->adyenLogger->error( if (empty($additionalData[$key])) {
'Missing expiryDate in Result please login to the adyen portal and go to ' . $this->adyenLogger->error($errorMsg);
'Settings -> API URLs and Response and enable the Expiry date property'
);
return null; return null;
} }
$expirationDate = $additionalData['expiryDate'];
if (empty($additionalData['paymentMethod'])) {
$this->adyenLogger->error(
'Missing paymentMethod in Result please login to the adyen portal and go to ' .
'Settings -> API URLs and Response and enable the Variant property'
);
return null;
} }
$cardType = $additionalData['paymentMethod'];
try { try {
// Check if paymentToken exists already
$paymentToken = $this->paymentTokenManagement->getByGatewayToken($additionalData[self::RECURRING_DETAIL_REFERENCE],
$payment->getMethodInstance()->getCode(), $payment->getOrder()->getCustomerId());
$paymentTokenSaveRequired = false;
// In case the payment token does not exist, create it based on the additionalData
if (is_null($paymentToken)) {
/** @var PaymentTokenInterface $paymentToken */ /** @var PaymentTokenInterface $paymentToken */
$paymentToken = $this->paymentTokenFactory->create( $paymentToken = $this->paymentTokenFactory->create(
PaymentTokenFactoryInterface::TOKEN_TYPE_CREDIT_CARD PaymentTokenFactoryInterface::TOKEN_TYPE_CREDIT_CARD
); );
if (strpos($cardType, "paywithgoogle") !== false && !empty($additionalData['paymentMethodVariant'])) { $paymentToken->setGatewayToken($additionalData[self::RECURRING_DETAIL_REFERENCE]);
$cardType = $additionalData['paymentMethodVariant'];
if (strpos($additionalData[self::PAYMENT_METHOD], "paywithgoogle") !== false
&& !empty($additionalData['paymentMethodVariant'])) {
$additionalData[self::PAYMENT_METHOD] = $additionalData['paymentMethodVariant'];
$paymentToken->setIsVisible(false); $paymentToken->setIsVisible(false);
} }
$paymentToken->setGatewayToken($token); } else {
$paymentToken->setExpiresAt($this->getExpirationDate($expirationDate)); $paymentTokenSaveRequired = true;
}
$paymentToken->setExpiresAt($this->getExpirationDate($additionalData[self::EXPIRY_DATE]));
$details = [ $details = [
'type' => $cardType, 'type' => $additionalData[self::PAYMENT_METHOD],
'maskedCC' => $cardSummary, 'maskedCC' => $additionalData[self::CARD_SUMMARY],
'expirationDate' => $expirationDate 'expirationDate' => $additionalData[self::EXPIRY_DATE]
]; ];
$paymentToken->setTokenDetails(json_encode($details)); $paymentToken->setTokenDetails(json_encode($details));
// If the token is updated, it needs to be saved to keep the changes
if ($paymentTokenSaveRequired) {
$this->paymentTokenRepository->save($paymentToken);
}
} catch (\Exception $e) { } catch (\Exception $e) {
$this->adyenLogger->error(print_r($e, true)); $this->adyenLogger->error(print_r($e, true));
} }
}
return $paymentToken; return $paymentToken;
} }
......
...@@ -487,26 +487,15 @@ class Requests extends AbstractHelper ...@@ -487,26 +487,15 @@ class Requests extends AbstractHelper
// Parse address into street and house number where possible // Parse address into street and house number where possible
$address = $this->adyenHelper->getStreetFromString($address->getStreetFull()); $address = $this->adyenHelper->getStreetFromString($address->getStreetFull());
} else { } else {
$address = $this->adyenHelper->getStreetFromString(implode(' ', [$address->getStreetLine1(), $address->getStreetLine2()])); $address = $this->adyenHelper->getStreetFromString(
implode(' ', [
$address->getStreetLine1(),
$address->getStreetLine2(),
$address->getStreetLine3(),
$address->getStreetLine4()
]));
} }
return $address; return $address;
} }
/**
* Only adds idempotency key if payment method is adyen_hpp for now
*
* @param array $request
* @param $paymentMethod
* @param $idempotencyKey
* @return array
*/
public function addIdempotencyKey($request = [], $paymentMethod, $idempotencyKey)
{
if (!empty($paymentMethod) && $paymentMethod == 'adyen_hpp') {
$request['idempotencyKey'] = $idempotencyKey;
}
return $request;
}
} }
...@@ -331,6 +331,34 @@ class Cron ...@@ -331,6 +331,34 @@ class Cron
} }
} }
/**
* @param $notification
* @return bool
*/
private function shouldSkipProcessingNotification($notification)
{
// OFFER_CLOSED notifications needs to be at least 10 minutes old to be processed
$offerClosedMinDate = new \DateTime();
$offerClosedMinDate->modify('-10 minutes');
// Remove OFFER_CLOSED notifications arrived in the last 10 minutes from the list to process to ensure it
// won't close any order which has an AUTHORISED notification arrived a bit later than the OFFER_CLOSED one.
$createdAt = \DateTime::createFromFormat('Y-m-d H:i:s', $notification['created_at']);
// To get the difference between $offerClosedMinDate and $createdAt, $offerClosedMinDate time in seconds is
// deducted from $createdAt time in seconds, divided by 60 and rounded down to integer
$minutesUntilProcessing = floor(($createdAt->getTimestamp() - $offerClosedMinDate->getTimestamp()) / 60);
if ($notification['event_code'] == Notification::OFFER_CLOSED && $minutesUntilProcessing > 0) {
$this->_adyenLogger->addAdyenNotificationCronjob(
sprintf('OFFER_CLOSED notification %s skipped! Wait %s minute(s) before processing.',
$notification->getEntityId(), $minutesUntilProcessing)
);
return true;
}
return false;
}
public function execute() public function execute()
{ {
// needed for Magento < 2.2.0 https://github.com/magento/magento2/pull/8413 // needed for Magento < 2.2.0 https://github.com/magento/magento2/pull/8413
...@@ -341,22 +369,19 @@ class Cron ...@@ -341,22 +369,19 @@ class Cron
$this->_order = null; $this->_order = null;
// execute notifications from 2 minute or earlier because order could not yet been created by magento
$dateStart = new \DateTime();
$dateStart->modify('-5 day');
$dateEnd = new \DateTime();
$dateEnd->modify('-1 minute');
$dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true];
// create collection
$notifications = $this->_notificationFactory->create(); $notifications = $this->_notificationFactory->create();
$notifications->addFieldToFilter('done', 0); $notifications->notificationsToProcessFilter();
$notifications->addFieldToFilter('processing', 0);
$notifications->addFieldToFilter('created_at', $dateRange);
$notifications->addFieldToFilter('error_count', ['lt' => Notification::MAX_ERROR_COUNT]);
// Loop thorugh notifications to set processing to true if notifiaction should not be skipped
foreach ($notifications as $notification) { foreach ($notifications as $notification) {
// set Cron processing to true // Check if notification should be processed or not
if ($this->shouldSkipProcessingNotification($notification)) {
// Remove notification from collection which will be processed
$notifications->removeItemByKey($notification->getId());
continue;
}
// set notification processing to true
$this->_updateNotification($notification, true, false); $this->_updateNotification($notification, true, false);
} }
...@@ -459,7 +484,7 @@ class Cron ...@@ -459,7 +484,7 @@ class Cron
); );
} }
//Trigger admin notice for unsuccessful REFUND notifications //Trigger admin notice for unsuccessful REFUND notifications
if ($this->_eventCode == Notification::REFUND){ if ($this->_eventCode == Notification::REFUND) {
$this->addRefundFailedNotice(); $this->addRefundFailedNotice();
} }
} else { } else {
...@@ -882,7 +907,6 @@ class Cron ...@@ -882,7 +907,6 @@ class Cron
*/ */
protected function _processNotification() protected function _processNotification()
{ {
$this->_adyenLogger->addAdyenNotificationCronjob('Processing the notification'); $this->_adyenLogger->addAdyenNotificationCronjob('Processing the notification');
$_paymentCode = $this->_paymentMethodCode(); $_paymentCode = $this->_paymentMethodCode();
...@@ -1143,10 +1167,8 @@ class Cron ...@@ -1143,10 +1167,8 @@ class Cron
// Populate billing agreement data // Populate billing agreement data
$billingAgreement->parseRecurringContractData($contractDetail); $billingAgreement->parseRecurringContractData($contractDetail);
if ($billingAgreement->isValid()) { if ($billingAgreement->isValid()) {
if (!$this->agreementResourceModel->getOrderRelation($billingAgreement->getAgreementId(), if (!$this->agreementResourceModel->getOrderRelation($billingAgreement->getAgreementId(),
$this->_order->getId())) { $this->_order->getId())) {
// save into sales_billing_agreement_order // save into sales_billing_agreement_order
$billingAgreement->addOrderRelation($this->_order); $billingAgreement->addOrderRelation($this->_order);
......
...@@ -46,4 +46,30 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab ...@@ -46,4 +46,30 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
$this->addFieldToFilter('created_at', $dateRange); $this->addFieldToFilter('created_at', $dateRange);
return $this; return $this;
} }
/**
* Filter the notifications table to get non processed or done notifications without 5 or more errors older than
* 2 minutes but not older than 5 days, ordered by created_at and event_code columns
*
* @return $this
*/
public function notificationsToProcessFilter()
{
// execute notifications from 2 minute or earlier because order could not yet been created by magento
$dateStart = new \DateTime();
$dateStart->modify('-5 day');
$dateEnd = new \DateTime();
$dateEnd->modify('-1 minute');
$dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true];
$this->addFieldToFilter('done', 0);
$this->addFieldToFilter('processing', 0);
$this->addFieldToFilter('created_at', $dateRange);
$this->addFieldToFilter('error_count', ['lt' => \Adyen\Payment\Model\Notification::MAX_ERROR_COUNT]);
// Process the notifications in ascending order by creation date and event_code
$this->getSelect()->order('created_at ASC')->order('event_code ASC');
return $this;
}
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "adyen/module-payment", "name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.", "description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module", "type": "magento2-module",
"version": "6.1.0", "version": "6.1.1",
"license": [ "license": [
"OSL-3.0", "OSL-3.0",
"AFL-3.0" "AFL-3.0"
......
...@@ -914,6 +914,7 @@ ...@@ -914,6 +914,7 @@
</virtualType> </virtualType>
<preference for="Magento\Paypal\Model\Billing\Agreement" type="Adyen\Payment\Model\Billing\Agreement" /> <preference for="Magento\Paypal\Model\Billing\Agreement" type="Adyen\Payment\Model\Billing\Agreement" />
<preference for="Magento\Payment\Gateway\Data\Order\AddressAdapter" type="Adyen\Payment\Gateway\Data\Order\AddressAdapter"/>
<type name="Adyen\Payment\Logger\Handler\AdyenDebug"> <type name="Adyen\Payment\Logger\Handler\AdyenDebug">
<arguments> <arguments>
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument> <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
......
...@@ -73,9 +73,9 @@ $_isDemoMode = $block->isDemoMode(); ...@@ -73,9 +73,9 @@ $_isDemoMode = $block->isDemoMode();
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if($_info->getAdditionalInformation('expirationDate') != ""): ?> <?php if(!empty($block->getPaymentActionData('expiresAt'))): ?>
<div> <div>
<?php echo __('Expiration Date: %1', $_info->getAdditionalInformation('expirationDate')) ?> <?php echo __('Expiration Date: %1', $block->getPaymentActionData('expiresAt')) ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
...@@ -85,9 +85,9 @@ $_isDemoMode = $block->isDemoMode(); ...@@ -85,9 +85,9 @@ $_isDemoMode = $block->isDemoMode();
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if($_info->getAdditionalInformation('url') != ""): ?> <?php if(!empty($block->getPaymentActionData('downloadUrl'))): ?>
<div> <div>
<a target="_blank" href="<?php echo $_info->getAdditionalInformation('url'); ?>"><?php echo __('PDF Url'); ?></a> <a target="_blank" href="<?php echo $block->getPaymentActionData('downloadUrl'); ?>"><?php echo __('PDF Url'); ?></a>
</div> </div>
<?php endif; ?> <?php endif; ?>
......
...@@ -33,5 +33,5 @@ $_info = $this->getInfo(); ...@@ -33,5 +33,5 @@ $_info = $this->getInfo();
<dt class="title"><?php echo $_info->getAdditionalInformation('boleto_type'); ?></dt> <dt class="title"><?php echo $_info->getAdditionalInformation('boleto_type'); ?></dt>
<dt class="title"><?php echo $_info->getAdditionalInformation('firstname'); ?></dt> <dt class="title"><?php echo $_info->getAdditionalInformation('firstname'); ?></dt>
<dt class="title"><?php echo $_info->getAdditionalInformation('lastname'); ?></dt> <dt class="title"><?php echo $_info->getAdditionalInformation('lastname'); ?></dt>
<dt class="title"><a target="_blank" href="<?php echo $this->getMethod()->getInfoInstance()->getAdditionalInformation('url'); ?>"><?php echo __("Click here to download Boleto PDF."); ?></a></dt> <dt class="title"><a target="_blank" href="<?php echo $this->getPaymentActionData('downloadUrl'); ?>"><?php echo __("Click here to download Boleto PDF."); ?></a></dt>
</dl> </dl>
...@@ -78,6 +78,7 @@ define( ...@@ -78,6 +78,7 @@ define(
var isValid = ko.observable(false); var isValid = ko.observable(false);
return Component.extend({ return Component.extend({
isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null),
defaults: { defaults: {
template: 'Adyen_Payment/payment/oneclick-form', template: 'Adyen_Payment/payment/oneclick-form',
recurringDetailReference: '', recurringDetailReference: '',
...@@ -195,7 +196,7 @@ define( ...@@ -195,7 +196,7 @@ define(
isButtonActive: function () { isButtonActive: function () {
return self.isActive() && this.getCode() == self.isChecked() && self.isBillingAgreementChecked() && this.placeOrderAllowed(); return self.isActive() && this.getCode() == self.isChecked() && self.isBillingAgreementChecked() && this.placeOrderAllowed() && self.isPlaceOrderActionAllowed();
}, },
/** /**
* Custom place order function * Custom place order function
...@@ -528,7 +529,6 @@ define( ...@@ -528,7 +529,6 @@ define(
if (quote.paymentMethod().method == paymentMethod()) { if (quote.paymentMethod().method == paymentMethod()) {
return recurringDetailReference(); return recurringDetailReference();
} }
return null; return null;
}), }),
placeOrderHandler: null, placeOrderHandler: null,
......
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