/** * Process the notification * @return void */ public function processNotification() { $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->addFieldToFilter('done', 0); $notifications->addFieldToFilter('created_at', $dateRange); // loop over the notifications $count = 0; foreach ($notifications as $notification) { $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Processing notification %s", $notification->getEntityId())); // log the executed notification $this->_adyenLogger->addAdyenNotificationCronjob(print_r($notification->debug(), 1)); // get order $incrementId = $notification->getMerchantReference(); $this->_order = $this->_orderFactory->create()->loadByIncrementId($incrementId); if (!$this->_order->getId()) { // order does not exists remove from queue $notification->delete(); continue; } // declare all variables that are needed $this->_declareVariables($notification); // add notification to comment history status is current status $this->_addStatusHistoryComment(); $previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code'); // update order details $this->_updateAdyenAttributes($notification); // check if success is true of false if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0) { /* * Only cancel the order when it is in state pending, payment review or * if the ORDER_CLOSED is failed (means split payment has not be successful) */ if ($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == Notification::ORDER_CLOSED) { $this->_adyenLogger->addAdyenNotificationCronjob('Going to cancel the order'); // if payment is API check, check if API result pspreference is the same as reference if ($this->_eventCode == NOTIFICATION::AUTHORISATION && $this->_getPaymentMethodType() == 'api') { // don't cancel the order becasue order was successfull through api $this->_adyenLogger->addAdyenNotificationCronjob('order is not cancelled because api result was succesfull'); } else { /* * don't cancel the order if previous state is authorisation with success=true * Split payments can fail if the second payment has failed the first payment is * refund/cancelled as well so if it is a split payment that failed cancel the order as well */ if ($previousAdyenEventCode != "AUTHORISATION : TRUE" || $this->_eventCode == Notification::ORDER_CLOSED) { $this->_holdCancelOrder(false); } else { $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_adyenLogger->addAdyenNotificationCronjob('order is not cancelled because previous notification was an authorisation that succeeded'); } } } else { $this->_adyenLogger->addAdyenNotificationCronjob('Order is already processed so ignore this notification state is:' . $this->_order->getState()); } } else { // Notification is successful $this->_processNotification(); } $this->_order->save(); // set done to true $dateEnd = new \DateTime(); $notification->setDone(true); $notification->setUpdatedAt($dateEnd); $notification->save(); $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Notification %s is processed", $notification->getEntityId())); ++$count; } if ($count > 0) { $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Cronjob updated %s notification(s)", $count)); } }
public function processNotification() { $this->_order = null; $this->_logger->info("START OF THE CRONJOB"); //fixme somehow the created_at is saved in my timzone $dateStart = new \DateTime(); // loop over notifications that are not processed and from 1 minute ago $dateStart = new \DateTime(); $dateStart->modify('-1 day'); // excecute notifications from 2 minute or earlier because order could not yet been created by mangento $dateEnd = new \DateTime(); $dateEnd->modify('-2 minute'); $dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true]; $notifications = $this->_notificationFactory->create(); $notifications->addFieldToFilter('done', 0); $notifications->addFieldToFilter('created_at', $dateRange); foreach ($notifications as $notification) { // get order $incrementId = $notification->getMerchantReference(); $this->_order = $this->_orderFactory->create()->loadByIncrementId($incrementId); if (!$this->_order->getId()) { throw new Exception(sprintf('Wrong order ID: "%1".', $incrementId)); } // declare all variables that are needed $this->_declareVariables($notification); // add notification to comment history status is current status $this->_addStatusHistoryComment(); // $previousAdyenEventCode = $this->order->getAdyenNotificationEventCode(); $previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code'); // set pspReference on payment object $this->_order->getPayment()->setAdditionalInformation('pspReference', $this->_pspReference); // check if success is true of false if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0) { // Only cancel the order when it is in state pending, payment review or if the ORDER_CLOSED is failed (means split payment has not be successful) if ($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == \Magento\Sales\Model\Order::ADYEN_EVENT_ORDER_CLOSED) { $this->_debugData['_updateOrder info'] = 'Going to cancel the order'; // if payment is API check, check if API result pspreference is the same as reference if ($this->_eventCode == Adyen_Payment_Model_Event::ADYEN_EVENT_AUTHORISATION && $this->_getPaymentMethodType() == 'api') { if ($this->_pspReference == $this->_order->getPayment()->getAdditionalInformation('pspReference')) { // don't cancel the order if previous state is authorisation with success=true if ($previousAdyenEventCode != "AUTHORISATION : TRUE") { $this->_holdCancelOrder(false); } else { //$this->_order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_debugData['_updateOrder warning'] = 'order is not cancelled because previous notification was a authorisation that succeeded'; } } else { $this->_debugData['_updateOrder warning'] = 'order is not cancelled because pspReference does not match with the order'; } } else { // don't cancel the order if previous state is authorisation with success=true if ($previousAdyenEventCode != "AUTHORISATION : TRUE") { $this->_holdCancelOrder(false); } else { // $this->_order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_debugData['_updateOrder warning'] = 'order is not cancelled because previous notification was a authorisation that succeeded'; } } } else { $this->_debugData['_updateOrder info'] = 'Order is already processed so ignore this notification state is:' . $this->_order->getState(); } } else { // Notification is successful $this->_processNotification(); } $this->_order->save(); foreach ($this->_debugData as $debug) { $this->_logger->info($debug); } // set done to true $dateEnd = new \DateTime(); $notification->setDone(true); $notification->setUpdatedAt($dateEnd); $notification->save(); } $this->_logger->info("END OF THE CRONJOB"); }