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 6ecfbe45 authored by Alessio Zampatti's avatar Alessio Zampatti Committed by GitHub

PW-329: Include cron health checks (#222)

* PW-329: Include cron health checks

* An admin message will show up if there is a notification which has not been processed for more than 10 minutes
* Trigger the same check on a notification coming from the Adyen Backoffice

* PW-329: Moved the croncheck into the try/catch clause, minor issues fix.

* PW-329: Moved the cronchecktest so that it is initiated only after the Authentication is done.
parent dd4a3a43
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\AdminMessage;
class CronMessage implements \Magento\Framework\Notification\MessageInterface
{
protected $_authSession;
protected $_cronCheck;
protected $_dateChecked;
protected $_adyenHelper;
protected $_timezoneInterface;
public function __construct(
\Magento\Backend\Model\Auth\Session $authSession,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezoneInterface
) {
$this->_authSession = $authSession;
$this->_cronCheck = $this->getSessionData("cronCheck");
$this->_dateChecked = $this->getSessionData("dateChecked");
$this->_adyenHelper = $adyenHelper;
$this->_timezoneInterface = $timezoneInterface;
}
/**
* Message identity
*/
const MESSAGE_IDENTITY = 'Adyen Cronjob system message';
/**
* Retrieve unique system message identity
*
* @return string
*/
public function getIdentity()
{
return self::MESSAGE_IDENTITY;
}
/**
* Check whether the system message should be shown
*
* @return bool
*/
public function isDisplayed()
{
// Only execute the query the first time you access the Admin page
if ($this->_authSession->isFirstPageAfterLogin()) {
$this->_dateChecked = $this->_timezoneInterface->date();
$this->_cronCheck = $this->_adyenHelper->getUnprocessedNotifications();
$this->setSessionData("cronCheck", $this->_cronCheck);
$this->setSessionData("dateChecked", $this->_dateChecked);
}
// Do not show any message if there are no unprocessed notifications
if ($this->_cronCheck > 0) {
return true;
} else {
return false;
}
}
/**
* Retrieve system message text
*
* @return \Magento\Framework\Phrase
*/
public function getText()
{
$message = __('You have ' . $this->_cronCheck . ' unprocessed notification(s). Please check your Cron');
$urlMagento = "http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-cron.html";
$urlAdyen = "https://docs.adyen.com/developers/plug-ins-and-partners/magento/magento-2/configuring-the-adyen-plug-in";
$message .= __(' and visit <a href="%1">Magento DevDocs</a> and <a href="%2">Adyen Docs</a> on how to configure Cron.',
$urlMagento, $urlAdyen);
$message .= __('<i> Last cron check was: %1</i> ', $this->_dateChecked->format('d/m/Y H:i:s'));
return __($message);
}
/**
* Retrieve system message severity
*
* @return int
*/
public function getSeverity()
{
return self::SEVERITY_CRITICAL;
}
/**
* Set the current value for the backend session
*/
public function setSessionData($key, $value)
{
return $this->_authSession->setData($key, $value);
}
/**
* Retrieve the session value
*/
public function getSessionData($key, $remove = false)
{
return $this->_authSession->getData($key, $remove);
}
}
......@@ -110,12 +110,23 @@ class Json extends \Magento\Framework\App\Action\Action
}
}
$acceptedMessage = "[accepted]";
$cronCheckTest = $notificationItems['notificationItems'][0]['NotificationRequestItem']['pspReference'];
// Run the query for checking unprocessed notifications, do this only for test notifications coming from the Adyen Customer Area
if ($this->_isTestNotification($cronCheckTest)) {
$unprocessedNotifications = $this->_adyenHelper->getUnprocessedNotifications();
if ($unprocessedNotifications > 0) {
$acceptedMessage .= "\nYou have " . $unprocessedNotifications . " unprocessed notifications.";
}
}
$this->_adyenLogger->addAdyenNotification("The result is accepted");
$this->getResponse()
->clearHeader('Content-Type')
->setHeader('Content-Type', 'text/html')
->setBody("[accepted]");
->setBody($acceptedMessage);
return;
} else {
if ($notificationMode == "") {
......@@ -139,11 +150,12 @@ class Json extends \Magento\Framework\App\Action\Action
{
$mode = $this->_adyenHelper->getAdyenAbstractConfigData('demo_mode');
if (($mode=='1' && $notificationMode == "false") || ($mode=='0' && $notificationMode == 'true')) {
if (($mode == '1' && $notificationMode == "false") || ($mode == '0' && $notificationMode == 'true')) {
return true;
}
return false;
}
/**
* save notification into the database for cronjob to execute notification
*
......@@ -157,7 +169,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate the notification
if ($this->authorised($response)) {
// check if notificaiton already exists
// check if notification already exists
if (!$this->_isDuplicate($response)) {
try {
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
......@@ -234,8 +246,7 @@ class Json extends \Magento\Framework\App\Action\Action
$submitedMerchantAccount = $response['merchantAccountCode'];
if (empty($submitedMerchantAccount) && empty($internalMerchantAccount)) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
echo 'merchantAccountCode is empty in magento settings';
exit();
}
......@@ -244,8 +255,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate username and password
if ((!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']))) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
echo 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode';
exit();
}
......@@ -263,8 +273,7 @@ class Json extends \Magento\Framework\App\Action\Action
}
// If notification is test check if fields are correct if not return error
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
if ($accountCmp != 0) {
echo 'MerchantAccount in notification is not the same as in Magento settings';
exit();
......@@ -288,7 +297,7 @@ class Json extends \Magento\Framework\App\Action\Action
$eventCode = trim($response['eventCode']);
$success = trim($response['success']);
$originalReference = null;
if(isset($response['originalReference'])) {
if (isset($response['originalReference'])) {
$originalReference = trim($response['originalReference']);
}
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
......@@ -301,24 +310,25 @@ class Json extends \Magento\Framework\App\Action\Action
protected function _fixCgiHttpAuthentication()
{
// do nothing if values are already there
if(!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
return;
} elseif (isset($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']) &&
$_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != '') {
$_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != ''
) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']),2);
explode(':', base64_decode($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']), 2);
} elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)),2);
explode(':', base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)), 2);
} elseif (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)),2);
explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)), 2);
} elseif (!empty($_SERVER['REMOTE_USER'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REMOTE_USER'], 6)),2);
explode(':', base64_decode(substr($_SERVER['REMOTE_USER'], 6)), 2);
} elseif (!empty($_SERVER['REDIRECT_REMOTE_USER'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)),2);
explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)), 2);
}
}
......@@ -329,4 +339,21 @@ class Json extends \Magento\Framework\App\Action\Action
{
$this->getResponse()->setHttpResponseCode(401);
}
/**
* If notification is a test notification from Adyen Customer Area
*
* @param $pspReference
* @return bool
*/
protected function _isTestNotification($pspReference)
{
if (strpos(strtolower($pspReference), "test_") !== false
|| strpos(strtolower($pspReference), "testnotification_") !== false
) {
return true;
} else {
return false;
}
}
}
\ No newline at end of file
......@@ -86,7 +86,8 @@ class Data extends AbstractHelper
\Magento\Framework\Module\ModuleListInterface $moduleList,
\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory,
\Magento\Framework\View\Asset\Repository $assetRepo,
\Magento\Framework\View\Asset\Source $assetSource
\Magento\Framework\View\Asset\Source $assetSource,
\Adyen\Payment\Model\Resource\Notification\CollectionFactory $notificationFactory
) {
parent::__construct($context);
$this->_encryptor = $encryptor;
......@@ -96,6 +97,7 @@ class Data extends AbstractHelper
$this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory;
$this->_assetRepo = $assetRepo;
$this->_assetSource = $assetSource;
$this->_notificationFactory = $notificationFactory;
}
/**
......@@ -127,7 +129,8 @@ class Data extends AbstractHelper
* @desc return recurring types for configuration setting
* @return array
*/
public function getCaptureModes() {
public function getCaptureModes()
{
return [
'auto' => 'immediate',
'manual' => 'manual'
......@@ -138,7 +141,8 @@ class Data extends AbstractHelper
* @desc return recurring types for configuration setting
* @return array
*/
public function getPaymentRoutines() {
public function getPaymentRoutines()
{
return [
'single' => 'Single Page Payment Routine',
'multi' => 'Multi-page Payment Routine'
......@@ -154,7 +158,7 @@ class Data extends AbstractHelper
*/
public function formatAmount($amount, $currency)
{
switch($currency) {
switch ($currency) {
case "JPY":
case "IDR":
case "KRW":
......@@ -213,7 +217,7 @@ class Data extends AbstractHelper
public function originalAmount($amount, $currency)
{
// check the format
switch($currency) {
switch ($currency) {
case "JPY":
case "IDR":
case "KRW":
......@@ -515,9 +519,11 @@ class Data extends AbstractHelper
public function getWsPassword($storeId = null)
{
if ($this->isDemoMode($storeId)) {
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_test', $storeId)));
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_test',
$storeId)));
} else {
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_live', $storeId)));
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_live',
$storeId)));
}
return $wsPassword;
}
......@@ -596,7 +602,7 @@ class Data extends AbstractHelper
{
$path = 'payment/' . $paymentMethodCode . '/' . $field;
if(!$flag) {
if (!$flag) {
return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
} else {
return $this->scopeConfig->isSetFlag($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
......@@ -610,9 +616,44 @@ class Data extends AbstractHelper
public function getSepaCountries()
{
$sepaCountriesAllowed = [
"AT", "BE", "BG", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR", "GB", "GF", "GI", "GP", "GR", "HR",
"HU", "IE", "IS", "IT", "LI", "LT", "LU", "LV", "MC", "MQ", "MT", "NL", "NO", "PL", "PT", "RE", "RO", "SE",
"SI", "SK"
"AT",
"BE",
"BG",
"CH",
"CY",
"CZ",
"DE",
"DK",
"EE",
"ES",
"FI",
"FR",
"GB",
"GF",
"GI",
"GP",
"GR",
"HR",
"HU",
"IE",
"IS",
"IT",
"LI",
"LT",
"LU",
"LV",
"MC",
"MQ",
"MT",
"NL",
"NO",
"PL",
"PT",
"RE",
"RO",
"SE",
"SI",
"SK"
];
$countryList = $this->_country->toOptionArray();
......@@ -629,7 +670,7 @@ class Data extends AbstractHelper
public function getModuleVersion()
{
return (string) $this->_moduleList->getOne("Adyen_Payment")['setup_version'];
return (string)$this->_moduleList->getOne("Adyen_Payment")['setup_version'];
}
public function getBoletoTypes()
......@@ -695,7 +736,8 @@ class Data extends AbstractHelper
$agreementData['variant'] = 'sepadirectdebit';
}
$data = ['reference_id' => $billingAgreement->getReferenceId(),
$data = [
'reference_id' => $billingAgreement->getReferenceId(),
'agreement_label' => $billingAgreement->getAgreementLabel(),
'agreement_data' => $agreementData
];
......@@ -763,12 +805,14 @@ class Data extends AbstractHelper
{
if (strlen($paymentMethod) >= 9 && substr($paymentMethod, 0, 9) == 'afterpay_') {
return true;
} else if($paymentMethod == 'klarna' || $paymentMethod == 'ratepay') {
} else {
if ($paymentMethod == 'klarna' || $paymentMethod == 'ratepay') {
return true;
} else {
return false;
}
}
}
public function getRatePayId()
{
......@@ -816,9 +860,17 @@ class Data extends AbstractHelper
return $this->_assetRepo->createAsset($fileId, $params);
}
public function getStoreLocale($storeId) {
public function getStoreLocale($storeId)
{
$path = \Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE;
return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
}
public function getUnprocessedNotifications()
{
$notifications = $this->_notificationFactory->create();
$notifications->unprocessedNotificationsFilter();
return count($notifications);
}
}
\ No newline at end of file
......@@ -32,4 +32,18 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
{
$this->_init('Adyen\Payment\Model\Notification', 'Adyen\Payment\Model\Resource\Notification');
}
/**
* Filter the notifications table to see if there are any unprocessed ones that have been created more than 10 minutes ago
*/
public function unprocessedNotificationsFilter()
{
$dateEnd = new \DateTime();
$dateEnd->modify('-10 minute');
$dateRange = ['to' => $dateEnd, 'datetime' => true];
$this->addFieldToFilter('done', 0);
$this->addFieldToFilter('processing', 0);
$this->addFieldToFilter('created_at', $dateRange);
return $this;
}
}
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Notification\MessageList">
<arguments>
<argument name="messages" xsi:type="array">
<item name="cronMessage" xsi:type="string">Adyen\Payment\AdminMessage\CronMessage</item>
</argument>
</arguments>
</type>
</config>
......@@ -30,6 +30,7 @@
<module name="Magento_Quote"/>
<module name="Magento_Checkout"/>
<module name="Magento_Paypal"/>
<module name="Magento_AdminNotification"/>
</sequence>
</module>
</config>
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