<commit_before><?php

/**
 * Adyen Payment Module
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to <EMAIL> so we can send you a copy immediately.
 *
 * @category	Adyen
 * @package	Adyen_Payment
 * @copyright	Copyright (c) 2011 Adyen (http://www.adyen.com)
 * @license	http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
/**
 * @category   Payment Gateway
 * @package    Adyen_Payment
 * @author     Adyen
 * @property   Adyen B.V
 * @copyright  Copyright (c) 2014 Adyen BV (http://www.adyen.com)
 */
class Adyen_Payment_Model_ProcessNotification extends Mage_Core_Model_Abstract {


    /**
     * Collected debug information
     *
     * @var array
     */
    protected $_debugData = array();

    /**
     * Process the notification that is received by the Adyen platform
     * @param $response
     * @return string
     */
    public function processResponse($response)
    {
        // SOAP, JSON, HTTP POST
        $storeId = null;

        $this->_debugData['processResponse begin'] = 'Begin to process Notification';

        if (empty($response)) {
            $this->_debugData['error'] = 'Response is empty, please check your webserver that the result url accepts parameters';
            $this->_debug($storeId);
            return "401";
        }

        // Log the results in log file and adyen_debug table
        $this->_debugData['response'] = $response;
        Mage::getResourceModel('adyen/adyen_debug')->assignData($response);

//      $params = new Varien_Object($response);
        // Create Varien_Object from response (soap compatible)
        $params = new Varien_Object();
        foreach ($response as $code => $value) {
            $params->setData($code, $value);
        }
        $actionName = $this->_getRequest()->getActionName();

        // authenticate result url
        $authStatus = Mage::getModel('adyen/authenticate')->authenticate($actionName, $params);
        if (!$authStatus) {
            $this->_debugData['error'] = 'Autentication failure please check your notification username and password. This must be the same in Magento as in the Adyen platform';
            $this->_debug($storeId);
            return "401";
        }

        // skip notification if notification is REPORT_AVAILABLE
        $eventCode = trim($params->getData('eventCode'));
        if($eventCode == Adyen_Payment_Model_Event::ADYEN_EVENT_REPORT_AVAILABLE) {
            $this->_debugData['processResponse info'] = 'Skip notification REPORT_AVAILABLE';
            $this->_debug($storeId);
            return;
        }

        // check if notification is not duplicate
        if(!$this->_isDuplicate($params)) {

            $incrementId = $params->getData('merchantReference');

            if($incrementId) {
                $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
                if ($order->getId()) {
                    // set StoreId for retrieving debug log setting
                    $storeId = $order->getStoreId();

                    $this->_updateOrder($order, $params);
                } else {
                    $this->_debugData['error'] = 'Order does not exists with increment_id: ' . $incrementId;
                    $this->_addNotificationToQueue($params);
                }
            } else {
                $this->_debugData['error'] = 'Empty merchantReference';
            }
        } else {
            $this->_debugData['processResponse info'] = 'Skipping duplicate notification';
        }

        // update the queue if it is not processed by cronjob
        if(!$this->_getConfigData('update_notification_cronjob')) {
            $this->_updateNotProcessedNotifications();
        }

        $this->_debug($storeId);
    }

    /**
     * Check if notification is already received
     * If this is the case ignore the notification
     * @param $params
     * @return bool
     */
    protected function _isDuplicate($params)
    {
        $pspReference = trim($params->getData('pspReference'));
        $success = trim($params->getData('success'));
        $eventCode = trim($params->getData('eventCode'));

        // if notification is already processed ignore it
        $isDuplicate = Mage::getModel('adyen/event')
            ->isDuplicate($pspReference, $eventCode, $success);
        if ($isDuplicate && $eventCode != Adyen_Payment_Model_Event::ADYEN_EVENT_RECURRING_CONTRACT) {
            return true;
        }
        return false;
    }

    // notification attributes
    protected $_pspReference;
    protected $_merchantReference;
    protected $_eventCode;
    protected $_success;
    protected $_paymentMethod;
    protected $_reason;
    protected $_value;
    protected $_boletoOriginalAmount;
    protected $_boletoPaidAmount;
    protected $_modificationResult;
    protected $_klarnaReservationNumber;
    protected $_fraudManualReview;


    /**
     * @desc a public function for updateOrder to update a specific from the QueueController
     * @param $order
     * @param $params
     */
    public function updateOrder($order, $params) {
        $this->_updateOrder($order, $params);
    }
    /**
     * @param $order
     * @param $params
     */
    protected function _updateOrder($order, $params)
    {
        if (!($order->getPayment()->getMethodInstance() instanceof Adyen_Payment_Model_Adyen_Abstract)) {
            // This method only applies to Adyen orders
            return;
        }

        $this->_debugData['_updateOrder'] = 'Updating the order';

        Mage::dispatchEvent('adyen_payment_process_notifications_before', array('order' => $order, 'adyen_response' => $params));
        if ($params->getData('handled')) {
            $this->_debug($order->getStoreId());
            return;
        }

        $this->_declareVariables($order, $params);

        $previousAdyenEventCode = $order->getAdyenEventCode();

        // add notification to comment history status is current status
        $this->_addStatusHistoryComment($order);

        // update order details
        $this->_updateAdyenAttributes($order, $params);

        // 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($order->getState() === Mage_Sales_Model_Order::STATE_PENDING_PAYMENT || $order->getState() === Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW || $this->_eventCode == Adyen_Payment_Model_Event::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($order) == 'api') {
                    if($this->_pspReference == $order->getPayment()->getAdyenPspReference()) {
                        // don't cancel the order if previous state is authorisation with success=true
                        if($previousAdyenEventCode != "AUTHORISATION : TRUE") {
                            // This has been disabled because in the case of Magento, no order
                            // exists at the time an API (like CC) notification occurs. It is
                            // however relevant for HPP methods
                            //$this->_holdCancelOrder($order, false);
                        } else {
                            $order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode
                            $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($order, false);
                    } else {
                        $order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode<commit_msg>Fixes #426 with wrong "success" flag validation.<commit_after><?php

/**
 * Adyen Payment Module
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to <EMAIL> so we can send you a copy immediately.
 *
 * @category	Adyen
 * @package	Adyen_Payment
 * @copyright	Copyright (c) 2011 Adyen (http://www.adyen.com)
 * @license	http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
/**
 * @category   Payment Gateway
 * @package    Adyen_Payment
 * @author     Adyen
 * @property   Adyen B.V
 * @copyright  Copyright (c) 2014 Adyen BV (http://www.adyen.com)
 */
class Adyen_Payment_Model_ProcessNotification extends Mage_Core_Model_Abstract {


    /**
     * Collected debug information
     *
     * @var array
     */
    protected $_debugData = array();

    /**
     * Process the notification that is received by the Adyen platform
     * @param $response
     * @return string
     */
    public function processResponse($response)
    {
        // SOAP, JSON, HTTP POST
        $storeId = null;

        $this->_debugData['processResponse begin'] = 'Begin to process Notification';

        if (empty($response)) {
            $this->_debugData['error'] = 'Response is empty, please check your webserver that the result url accepts parameters';
            $this->_debug($storeId);
            return "401";
        }

        // Log the results in log file and adyen_debug table
        $this->_debugData['response'] = $response;
        Mage::getResourceModel('adyen/adyen_debug')->assignData($response);

//      $params = new Varien_Object($response);
        // Create Varien_Object from response (soap compatible)
        $params = new Varien_Object();
        foreach ($response as $code => $value) {
            $params->setData($code, $value);
        }
        $actionName = $this->_getRequest()->getActionName();

        // authenticate result url
        $authStatus = Mage::getModel('adyen/authenticate')->authenticate($actionName, $params);
        if (!$authStatus) {
            $this->_debugData['error'] = 'Autentication failure please check your notification username and password. This must be the same in Magento as in the Adyen platform';
            $this->_debug($storeId);
            return "401";
        }

        // skip notification if notification is REPORT_AVAILABLE
        $eventCode = trim($params->getData('eventCode'));
        if($eventCode == Adyen_Payment_Model_Event::ADYEN_EVENT_REPORT_AVAILABLE) {
            $this->_debugData['processResponse info'] = 'Skip notification REPORT_AVAILABLE';
            $this->_debug($storeId);
            return;
        }

        // check if notification is not duplicate
        if(!$this->_isDuplicate($params)) {

            $incrementId = $params->getData('merchantReference');

            if($incrementId) {
                $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
                if ($order->getId()) {
                    // set StoreId for retrieving debug log setting
                    $storeId = $order->getStoreId();

                    $this->_updateOrder($order, $params);
                } else {
                    $this->_debugData['error'] = 'Order does not exists with increment_id: ' . $incrementId;
                    $this->_addNotificationToQueue($params);
                }
            } else {
                $this->_debugData['error'] = 'Empty merchantReference';
            }
        } else {
            $this->_debugData['processResponse info'] = 'Skipping duplicate notification';
        }

        // update the queue if it is not processed by cronjob
        if(!$this->_getConfigData('update_notification_cronjob')) {
            $this->_updateNotProcessedNotifications();
        }

        $this->_debug($storeId);
    }

    /**
     * Check if notification is already received
     * If this is the case ignore the notification
     * @param $params
     * @return bool
     */
    protected function _isDuplicate($params)
    {
        $pspReference = trim($params->getData('pspReference'));
        $success = trim($params->getData('success'));
        $eventCode = trim($params->getData('eventCode'));

        // if notification is already processed ignore it
        $isDuplicate = Mage::getModel('adyen/event')
            ->isDuplicate($pspReference, $eventCode, $success);
        if ($isDuplicate && $eventCode != Adyen_Payment_Model_Event::ADYEN_EVENT_RECURRING_CONTRACT) {
            return true;
        }
        return false;
    }

    // notification attributes
    protected $_pspReference;
    protected $_merchantReference;
    protected $_eventCode;
    protected $_success;
    protected $_paymentMethod;
    protected $_reason;
    protected $_value;
    protected $_boletoOriginalAmount;
    protected $_boletoPaidAmount;
    protected $_modificationResult;
    protected $_klarnaReservationNumber;
    protected $_fraudManualReview;


    /**
     * @desc a public function for updateOrder to update a specific from the QueueController
     * @param $order
     * @param $params
     */
    public function updateOrder($order, $params) {
        $this->_updateOrder($order, $params);
    }
    /**
     * @param $order
     * @param $params
     */
    protected function _updateOrder($order, $params)
    {
        if (!($order->getPayment()->getMethodInstance() instanceof Adyen_Payment_Model_Adyen_Abstract)) {
            // This method only applies to Adyen orders
            return;
        }

        $this->_debugData['_updateOrder'] = 'Updating the order';

        Mage::dispatchEvent('adyen_payment_process_notifications_before', array('order' => $order, 'adyen_response' => $params));
        if ($params->getData('handled')) {
            $this->_debug($order->getStoreId());
            return;
        }

        $this->_declareVariables($order, $params);

        $previousAdyenEventCode = $order->getAdyenEventCode();

        // add notification to comment history status is current status
        $this->_addStatusHistoryComment($order);

        // update order details
        $this->_updateAdyenAttributes($order, $params);

        // check if success is true of false
        if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0 || strcmp($this->_success, '') == 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($order->getState() === Mage_Sales_Model_Order::STATE_PENDING_PAYMENT || $order->getState() === Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW || $this->_eventCode == Adyen_Payment_Model_Event::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($order) == 'api') {
                    if($this->_pspReference == $order->getPayment()->getAdyenPspReference()) {
                        // don't cancel the order if previous state is authorisation with success=true
                        if($previousAdyenEventCode != "AUTHORISATION : TRUE") {
                            // This has been disabled because in the case of Magento, no order
                            // exists at the time an API (like CC) notification occurs. It is
                            // however relevant for HPP methods
                            //$this->_holdCancelOrder($order, false);
                        } else {
                            $order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode
                            $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($order, false);
                    } else {
                        $order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode
{'fraction_non_alphanumeric': 0.11078062742016948, 'fraction_numerical': 0.0030304730905213535, 'mean_word_length': 2.335829277424186, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 130, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5935107', 'n_tokens_mistral': 4771, 'n_tokens_neox': 4601, 'n_words': 1275}