Выдано 109994 лицензии

Обработчики платежных систем

Обработчики платежной системы реализуют логику оплаты и принятия информации о завершении оплаты от платежной системы. Код обработчика вносится при редактировании платежной системы через центр администрирования, файлы размещаются в директории /hostcmsfiles/shop/pay/handler{ID}.php.

Обработчик платежной системы представляет собой класс, унаследованный от Shop_Payment_System_Handler, имя класса зависит от идентификатора платежной системы по схеме Shop_Payment_System_Handler{ID}

В левом меню выберите раздел КонтентИнтернет-магазины. Перейдите в магазин и выберите в меню Справочники пункт Платежные системы.

Пример минимального кода обработчика для платежной системы с кодом 9:

<?php

class Shop_Payment_System_Handler9 extends Shop_Payment_System_Handler
{
}

Пример типового обработчика платежной системы с кодом 9:

<?php

class Shop_Payment_System_Handler9 extends Shop_Payment_System_Handler
{
    /**
     * Идентификатор валюты, в которой передается сумма в платежную систему
     */
    protected $_currency = 1;

    /**
     * Метод, вызываемый в коде настроек ТДС через Shop_Payment_System_Handler::checkBeforeContent($oShop); Может быть использован для получения данных от платежной системе о статусе платежа.
     */
    public function checkPaymentBeforeContent()
    {
        if (isset($_REQUEST['SignatureValue']))
        {
            // Получаем ID заказа
            $order_id = intval(Core_Array::getRequest('InvId'));

            $oShop_Order = Core_Entity::factory('Shop_Order')->find($order_id);

            if (!is_null($oShop_Order->id))
            {
                // Вызов обработчика платежной системы
                Shop_Payment_System_Handler::factory($oShop_Order->Shop_Payment_System)
                    ->shopOrder($oShop_Order)
                    ->paymentProcessing();
            }
            exit();
        }
    }

    /**
     * Метод, вызываемый в коде ТДС через Shop_Payment_System_Handler::checkAfterContent($oShop); Может быть использован как для получения информации от платежной системы о статусе платежа, так и о выводе информации о результатах оплаты после перенаправления пользователя платежной системой на корзину магазина.
     */
    public function checkPaymentAfterContent()
    {
        if (isset($_REQUEST['SignatureValue']))
        {
            // Получаем ID заказа
            $order_id = intval(Core_Array::getRequest('InvId'));

            $oShop_Order = Core_Entity::factory('Shop_Order')->find($order_id);

            if (!is_null($oShop_Order->id))
            {
                // Вызов обработчика платежной системы
                Shop_Payment_System_Handler::factory($oShop_Order->Shop_Payment_System)
                    ->shopOrder($oShop_Order)
                    ->paymentProcessing();
            }
        }
    }



    /*
     * Метод, запускающий выполнение обработчика
     */
    public function execute()
    {
        parent::execute();

        // Показ формы оплаты (перехода на оплату), сама форма генерируется в getNotification()
        $this->printNotification();

        return $this;
    }

    /**
     * Оформление нового заказа
     */
    protected function _processOrder()
    {
        // Вызываем стандартное оформление заказа из родительского класса Shop_Payment_System_Handler
        parent::_processOrder();

        // Установка XSL-шаблонов в соответствии с настройками в узле структуры
        $this->setXSLs();

        // Отправка писем клиенту и пользователю
        $this->send();

        return $this;
    }

    /**
     * Обработка уведомлений об оплате заказа или возврате пользователя из магазина.
     * Используются уникальные параметры, передаваемые платежной системой и позволяющие
     * определить, идет уведомление об платежной системы об оплате или возврат пользователя
     * из платежной системы на сайт после успешной/неуспешной оплаты.
     */
    public function paymentProcessing()
    {
        // Пользователь перешел на страницу с уведомлением о статусе заказа
        if (isset($_REQUEST['InvId']) && isset($_REQUEST['некийПараметр']))
        {
            $this->showResultMessage();
            return TRUE;
        }

        // Пришло подтверждение оплаты, обработаем его
        if (isset($_REQUEST['InvId']))
        {
            $this->ProcessResult();
            return TRUE;
        }
    }

    /**
     * Сумма заказа в валюте платежной системы ($this->_currency)
     */
    public function getSumWithCoeff()
    {
        return Shop_Controller::instance()->round(($this->_currency > 0
                && $this->_shopOrder->shop_currency_id > 0
            ? Shop_Controller::instance()->getCurrencyCoefficientInShopCurrency(
                $this->_shopOrder->Shop_Currency,
                Core_Entity::factory('Shop_Currency', $this->_currency)
            )
            : 0) * $this->_shopOrder->getAmount() * $this->_coefficient);
    }

    /**
     * Возвращает строку с формой перехода к оплате
     */
    public function getNotification()
    {
        $sSum = $this->getSumWithCoeff();

        ob_start();
        ?>
        <h1>Оплата через платежную систему XYZ</h1>

        <p>Сумма к оплате составляет <strong><?php echo $sSum?> <?php echo Core_Entity::factory('Shop_Currency', $this->_currency)->name?></strong></p>

        <p>Для оплаты нажмите кнопку "Оплатить".</p>

        <form action="http://xxxyyyzzz.com/pay.php" method="POST">
            <input type="hidden" name="Sum" value="<?php echo $sSum?>">
            <input type="hidden" name="InvId" value="<?php echo $this->_shopOrder->id?>">
            <input type="hidden" name="Desc" value="<?php echo "Оплата счета N {$this->_shopOrder->invoice}"?>">
            <input type="submit" value="Оплатить">
        </form>
        <?php

        return ob_get_clean();
    }

    /**
     * Получить код счета (в данном случае равен коду перехода на оплату).
     * Используется, например, в центре администрирования при печати заказа
     */
    public function getInvoice()
    {
        return $this->getNotification();
    }

    // Вывод сообщения об успешности/неуспешности оплаты
    function showResultMessage()
    {
        $iShop_Order_Id = Core_Array::getRequest('InvId', 0);
        $oShop_Order = Core_Entity::factory('Shop_Order')->find($iShop_Order_Id);

        if(is_null($oShop_Order->id))
        {
            // Заказ не найден
            return FALSE;
        }

        $sHash = Core_Array::getRequest('Signature', '');
        $sSum = Core_Array::getRequest('Sum', '');

        // В данном примере сумма обязательно должна быть с двумя десятичными нулями
        $sHostcmsSum = sprintf("%.2f", $this->getSumWithCoeff());

        // Суммы совпали?
        $sHostcmsHash = $sSum == $sHostcmsSum
            ? md5("параметры_используемые_при_контроле_хэша")
            : '';

        // Сравниваем хэши
        if (mb_strtoupper($sHostcmsHash) == mb_strtoupper($sHash))
        {
            $sStatus = $oShop_Order->paid == 1 ? "оплачен" : "не оплачен";

            ?><h1>Заказ <?php echo $sStatus?></h1>
            <p>Заказ <strong>№ <?php echo $oShop_Order->invoice?></strong> <?php echo $sStatus?>.</p>
            <?php
        }
        else
        {
            ?><p>Хэш не совпал!</p><?php
        }
    }

    /*
     * Обработка статуса оплаты
    */
    function ProcessResult()
    {
        $iShop_Order_Id = Core_Array::getRequest('InvId', 0);
        $oShop_Order = Core_Entity::factory('Shop_Order')->find($iShop_Order_Id);

        if(is_null($oShop_Order->id) || $oShop_Order->paid)
        {
            // Заказ не найден
            return FALSE;
        }

        $sHash = Core_Array::getRequest('Signature', '');
        $sSum = Core_Array::getRequest('Sum', '');

        // В данном примере сумма обязательно должна быть с двумя десятичными нулями
        $sHostcmsSum = sprintf("%.2f", $this->getSumWithCoeff());

        if ($sSum == $sHostcmsSum)
        {
            $sHostcmsHash = md5("параметры_используемые_при_контроле_хэша");

            // Сравниваем хэши
            if (mb_strtoupper($sHostcmsHash) == mb_strtoupper($sHash))
            {
                $this->shopOrder($oShop_Order)->shopOrderBeforeAction(clone $oShop_Order);

                $oShop_Order->system_information = "Товар оплачен через платежную систему XYZ.\n";
                $oShop_Order->paid();
                $this->setXSLs();
                $this->send();

                // Ответ платежной системе на уведомление об оплате, см. API платежной системы
                echo "OK{$oShop_Order->id}\n";

                ob_start();
                $this->changedOrder('changeStatusPaid');
                ob_get_clean();
            }
            else
            {
                $oShop_Order->system_information = 'XYZ хэш не совпал!';
                $oShop_Order->save();

                // Ответ платежной системе на уведомление об оплате, см. API платежной системы
                echo "bad sign\n";
            }
        }
        else
        {
            $oShop_Order->system_information = 'XYZ сумма не совпала!';
            $oShop_Order->save();

            // Ответ платежной системе на уведомление об оплате, см. API платежной системы
            echo "bad sign\n";
        }
    }
}

В коде настроек ТДС корзины вызов обработчиков платежных систем осуществлется следующим образом:

Shop_Payment_System_Handler::checkBeforeContent($oShop);

в коде ТДС:

Shop_Payment_System_Handler::checkAfterContent($oShop);