HostCMS
Выдано 65 987 лицензий.
На главную страницу Карта сайта

Обработчик платежной системы Робокасса для тестирования

Список форумовПолезные решения на базе HostCMS

Обработчик платежной системы Робокасса для тестирования
HostCMS
Модератор

Регистрация: 02.04.2007
Инструкции — http://www.robokassa.ru/Doc/Ru/Interface.aspx

1. В код настроек типовой дин. страницы корзины добавляем
// ------------------------------------------------
// Обработка уведомления об оплате от ROBOKASSA
// должно быть только в настройках типовой дин. страницы
// ------------------------------------------------
if (isset($_REQUEST['SignatureValue'])
// для отличия от SuccessURL/FailURL
&& !isset($_REQUEST['Culture']))
{
   // Получаем ID заказа
   $order_id = to_int($_REQUEST['InvId']);

   $order_row = $shop->GetOrder($order_id);

   if ($order_row)
   {
      // Вызов обработчика платежной системы
      $shop->ExecSystemsOfPayHandler($order_row['shop_system_of_pay_id']);
   }
   
   exit();
}
// ------------------------------------------------

2. В код типовой дин. страницы корзины добавляем
// ------------------------------------------------
// Обработка уведомления об оплате от ROBOKASSA
// ------------------------------------------------
if (isset($_REQUEST['SignatureValue']) && isset($_REQUEST['Culture']))
{
   // Получаем ID заказа
   $order_id = to_int($_REQUEST['InvId']);

   $order_row = $shop->GetOrder($order_id);

   if ($order_row)
   {
      // Вызов обработчика платежной системы
      $shop->ExecSystemsOfPayHandler($order_row['shop_system_of_pay_id']);
   }
}
// ------------------------------------------------

3. Обновляем обработчик платежной системы:
<?php
/* Оплата через ROBOKASSA  */
class system_of_pay_handler
{
   /* Логин в системе ROBOKASSA */
   var $mrh_login = "mylogin";

   /* Пароль #1 - Используется интерфейсом инициализации оплаты */
   var $mrh_pass1 = "1234567a";

   // регистрационная информация (пароль #2)
   // registration info (password #2)
   var $mrh_pass2 = "98765432a";

   /* язык */
   var $culture = "ru";

   /* предлагаемая валюта платежа
   default payment e-currency
   Доступные валюты: http://merchant.roboxchange.com/Handler/Xml/CurrList.ashx
   */
   var $in_curr = "YandexMerchantOceanR";

   /* Код валюты в магазине HostCMS, которая была указана при регистрации магазина*/
   var $robokassa_currency = 1;

   /* Определяем коэффициент перерасчета при оплате ROBOKASSA */
   var $coefficient = 1;
   
   /**
    * Обработка статуса оплаты
    *
    */
   function ProcessResult()
   {
      /* Информация о заказе */
      $order_id = to_int($_REQUEST['InvId']);

      if (!$order_id)
      {
         return false;
      }

      $shop = & singleton('shop');

      $order_row = $shop->GetOrder($order_id);

      if (!$order_row)
      {
         return false;
      }

      $shop_row = $shop->GetShop($order_row['shop_shops_id']);

      // Сумма от Robokassa
      $out_summ = to_str($_REQUEST["OutSum"]);
      
      // Хэш от Robokassa
      $crc = to_str($_REQUEST["SignatureValue"]);

      /* Сумма заказа в валюте магазина HostCMS */
      $order_sum = sprintf("%.6f", $shop->GetOrderSum($order_id) * $this->coefficient);
      
      if ($out_summ == $order_sum)
      {
         // Для ResultURL используется mrh_pass2!
         $my_crc = md5("$out_summ:$order_id:{$this->mrh_pass2}");

         /* Устанавливаем параметры */
         $param['id'] = $order_row['shop_order_id'];
         $param['shop_shops_id'] = $order_row['shop_shops_id'];
      }
      else
      {
         // Суммы не совпали
         $my_crc = '';
      }

      /* Сравниваем хэши */
      if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
      {
         /* Проверка прошла успешно!
         Добавляем комментарий */
         $param['system_information'] = "Товар оплачен через ROBOKASSA.\n";

         // Обновляем информацию о заказе
         $shop->InsertOrder($param);

         // Изменяем статус оплаты ПОСЛЕ ОБНОВЛЕНИЯ ИНФОРМАЦИ, генерируем ссылки для эл.товаров, списываем товары
         $shop->SetOrderPaymentStatus($order_id);
         
         // Проводки по партнерской программе
         $affiliate = & singleton('affiliate');
         $affiliate->AcceptAffiliatePlanForSiteUsers($order_row['site_users_id'], $order_id);
      }
      else
      {
         $param['system_information'] = 'ROBOKASSA хэш не совпал!';
         
         // Обновляем информацию о заказе
         $shop->InsertOrder($param);
      }

      // Отправку письма об оплате делаем только после вставки информации об оплате
      if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
      {
         $structure = & singleton('Structure');
         $structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

         $lib = new lib();
         $LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

         $order_row = $shop->GetOrder($order_id);

         if (trim(to_str($order_row['shop_order_account_number'])) != '')
         {
            $shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
         }
         else
         {
            $shop_order_account_number = $order_id;
         }
         
         // Отправляем письмо администратору о подтверждении платежа
         $shop->SendMailAboutOrder($order_row['shop_shops_id'], $order_id, $order_row['site_users_id'],
         to_str($LA['xsl_letter_to_admin']),
         to_str($LA['xsl_letter_to_user']),
         $order_row['shop_order_users_email'],
         array(
         'admin-content-type' => 'html',
         'user-content-type' => 'html',
         'admin-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_confirm_admin_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
         'user-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_confirm_user_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
         'email_from_admin' => $order_row['shop_order_users_email']));
         
         // http://www.robokassa.ru/Doc/Ru/Interface.aspx#223
         // 3. Оповещение об оплате (ResultURL)
         // Факт успешности сообщения магазину об исполнении операции определяется по результату, возвращаемому обменному пункту. Результат должен содержать "OKnMerchantInvId", т.е. для счета #5 должен быть возвращен текст "OK5".
         echo "OK{$order_id}\n";
      }
      else
      {
          echo "bad sign\n";
      }
   }

   /* Вывод сообщения об успешности/неуспешности оплаты */
   function ShowResultMessage()
   {
      /* Информация о заказе */
      $order_id = to_int($_REQUEST['InvId']);

      if (!$order_id)
      {
         return false;
      }

      $shop = & singleton('shop');

      $order_row = $shop->GetOrder($order_id);

      if (!$order_row)
      {
         return false;
      }

      $shop_row = $shop->GetShop($order_row['shop_shops_id']);

      // Хэш1 от Robokassa
      $crc = to_str($_REQUEST["SignatureValue"]);
      
      // Сумма от Robokassa
      $out_summ = to_str($_REQUEST["OutSum"]);
      
      /* Сумма заказа в валюте магазина HostCMS */
      $order_sum = $shop->GetOrderSum($order_id) * $this->coefficient;
      $order_sum = sprintf("%.6f", $order_sum);
      
      if ($out_summ == $order_sum)
      {
         // Для SuccessURL и FailURL используется mrh_pass1!
         $my_crc = md5("$out_summ:$order_id:{$this->mrh_pass1}");
      }
      else
      {
         $my_crc = '';
      }

      /* Сравниваем хэши */
      if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
      {
         if ($order_row['shop_order_status_of_pay'] == 1)
         {
            $status = "оплачен";
         }
         else
         {
            $status = "не оплачен";
         }
         ?><h1>Заказ <?php echo $status?></h1>
         <p>Заказ <strong>№ <?php echo $order_row['shop_order_account_number']?></strong> <?php echo $status?>.</p>
         <?php
      }
      else
      {
         ?><p>Хэш не совпал!</p><?php
      }
   }

   /**
    * Отображает стартовую страницу для оплаты через ROBOKASSA.
    *
    */
   function ShowPurseRequest()
   {
      $shop = & singleton('shop');
      
      /* ID платежной системы берем из сессии */
      $system_of_pay_id = to_int($_SESSION['system_of_pay_id']);
      $row_system_of_pay = $shop->GetSystemOfPay($system_of_pay_id);
      
      if ($row_system_of_pay)
      {
         $shop_id = $row_system_of_pay['shop_shops_id'];
      }
      else
      {
         return false;
      }

      /* Получаем id текущего пользователя сайта */
      if (class_exists('SiteUsers'))
      {
         /* Получаем id текущего пользователя сайта */
         $SiteUsers = & singleton('SiteUsers');
         $site_users_id = $SiteUsers->GetCurrentSiteUser();
      }
      else
      {
         $site_users_id = false;
      }

      // статус платежа, по умолчанию 0
      $order_row['status_of_pay'] = 0 ;

      // дата платежа, по умолчанию пустая строка
      $order_row['date_of_pay'] = '';

      $order_row['description'] = to_str($_SESSION['description']);

      // описание и системная информация, по умолчанию пустая строка
      if (to_str($_SESSION['shop_coupon_text']) != '')
      {
         $order_row['description'] .= "Купон на скидку: ".to_str($_SESSION['shop_coupon_text'])."\n";
      }

      if (!isset($_SESSION['last_order_id']))
      {
         $_SESSION['last_order_id'] = 0;
      }

      // Если заказ еще не был оформлен
      if ($_SESSION['last_order_id'] == 0)
      {
         /* Оформляем заказ */
         $order_id = $shop->ProcessOrder($shop_id, $site_users_id, $system_of_pay_id, $order_row);
      }
      else
      {
         $order_id = $_SESSION['last_order_id'];
      }

      if ($order_id > 0)
      {
         if (!class_exists('SiteUsers'))
         {
            /* Класс пользователей сайта не существует, дописываем информацию о заказчике
            в поле shop_order_description из текущей сессии */
            if ($order_row)
            {
               /* Описание заказчика */
               $order_row['description'] .= "Информация о заказчике:\n"
               ."Имя: ".to_str($_SESSION['site_users_name'])."\n"
               ."Фамилия: ".to_str($_SESSION['site_users_surname'])."\n"
               ."Отчество: ".to_str($_SESSION['site_users_patronymic'])."\n"
               ."E-Mail: ".to_str($_SESSION['site_users_email'])."\n"
               ."Телефон: ".to_str($_SESSION['site_users_phone'])."\n"
               ."Факс: ".to_str($_SESSION['site_users_fax'])."\n"
               ."Адрес: ".to_str($_SESSION['full_address'])."\n";

               /* Дополнительная информация о заказе */
               $order_row['system_information'] = to_str($_SESSION['system_information']);

               /* Обязательно добавляем идентификатор! */
               $order_row['id'] = $order_id;

               $shop->InsertOrder($order_row);
            }
         }

         $order_row = $shop->GetOrder($order_id);

         if ($order_row)
         {
            $this->PrintOrder($order_id);
         }

         $shop_row = $shop->GetShop($shop_id);

         if ($_SESSION['last_order_id'] == 0)
         {
            $structure = & singleton('Structure');
            $structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

            $lib = new lib();
            $LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

            $date_str = date("d.m.Y H:i:s");

            if (trim(to_str($order_row['shop_order_account_number'])) != '')
            {
               $shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
            }
            else
            {
               $shop_order_account_number = $order_id;
            }

            /* Отправляем письмо заказчику */
            $shop->SendMailAboutOrder($shop_id,
            $order_id,
            $site_users_id,
            to_str($LA['xsl_letter_to_admin']),
            to_str($LA['xsl_letter_to_user']),
            $order_row['shop_order_users_email'],
            array('admin-content-type' => 'html',
            'user-content-type' => 'html',
            'admin-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_admin_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
            'user-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_user_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
            'email_from_admin' => $order_row['shop_order_users_email']));
         }

         // Сохраняем ID последнего оформленного заказа ТОЛЬКО ПОСЛЕ ОТПРАВКИ ПИСЬМА
         $_SESSION['last_order_id'] = $order_id;
      }
      else
      {
         switch ($order_id)
         {
            case -1:
               {
                  ?><div id="error">Ошибка вставки заказа в базу данных. Обратитесь к администратору.</div><?php
                  break;
               }
            case -2:
               {
                  ?><div id="error">Ошибка - не найден магазин. Обратитесь к администратору.</div><?php
                  break;
               }
            case -3:
               {
                  ?><div id="error">Ошибка - корзина пуста. Добавьте товар в корзину и оформите заказ.</div><?php
                  break;
               }
         }
      }
   }

   /**
    * Метод, запускающий выполнение обработчика
    */
   function Execute()
   {
      /* Пользователь перешел на страницу с уведомлением о статусе заказа */
      if (isset($_REQUEST['InvId']) && isset($_REQUEST['Culture']))
      {
         $this->ShowResultMessage();
         return true;
      }
      
      /* Пришло подтверждение оплаты, обработаем его */
      if (isset($_REQUEST['InvId']))
      {
         $this->ProcessResult();
         return true;
      }

      /* Иначе оформляем заказ и отображаем стартовую страницу для оплаты через WebMoney */
      $this->ShowPurseRequest();
   }

   /**
    * Метод для отображения формы заказа для печати.
    *
    * @param int $order_id идентификатор заказа
    */
   function PrintOrder($order_id)
   {
      $shop = & singleton('shop');

      $order_row = $shop->GetOrder($order_id);
      if (!$order_row)
      {
         return false;
      }

      if ($order_row)
      {
         $shop_row = $shop->GetShop($order_row['shop_shops_id']);

         /* Сумма заказа в валюте магазина HostCMS (далее пересчитывается в валюту) */
         $order_sum = $shop->GetOrderSum($order_id) * $this->coefficient;

         /* Валюта магазина HostCMS */
         $shop_currency_id = $shop_row['shop_currency_id'];

         $currency_row = $shop->GetCurrency($shop_currency_id);
         
         /* Получаем коэффициент пересчета в валюту ROBOKASSA */
         $currency_coefficient = $shop->GetCurrencyCoefficientToShopCurrency($shop_currency_id, $this->robokassa_currency);
         $robokassa_sum = round($order_sum * $currency_coefficient, 2);

         // Описание заказа
         $inv_desc = "Оплата счета N {$order_row['shop_order_account_number']}";

         // build CRC value
         $crc = md5("{$this->mrh_login}:$order_sum:$order_id:{$this->mrh_pass1}");

         // Тестовый - http://test.robokassa.ru/Index.aspx
         // Рабочий - https://merchant.roboxchange.com/Index.aspx

         ?>
         <h1>Оплата через систему ROBOKASSA</h1>
         
         <p>
         <a href="http://www.robokassa.ru/" target="_blank">
         <img src="http://www.robokassa.ru/Images/logo.gif" border="0" alt="Система электронных платежей">
         </a>
         </p>
         
         <p>Сумма к оплате составляет <strong><?php echo $order_sum?> <?php echo $currency_row['shop_currency_name']?></strong></p>
         
         <p>Для оплаты нажмите кнопку "Оплатить".</p>
         
         <p style="color: rgb(112, 112, 112);">
         Внимание! Нажимая &laquo;Оплатить&raquo; Вы подтверждаете передачу контактных данных на сервер ROBOKASSA для оплаты.
         </p>

         <form action="http://test.robokassa.ru/Index.aspx" method="POST">
            <input type="hidden" name="MrchLogin" value="<?php echo $this->mrh_login?>">
            <input type="hidden" name="OutSum" value="<?php echo $robokassa_sum?>">
            <input type="hidden" name="InvId" value="<?php echo $order_id?>">
            <input type="hidden" name="Desc" value="<?php echo $inv_desc?>">
            <input type="hidden" name="SignatureValue" value="<?php echo $crc?>">
            <input type="hidden" name="IncCurrLabel" value="<?php echo $this->in_curr?>">
            <input type="hidden" name="Culture" value="<?php echo $this->culture?>">
            <input type="submit" value="Оплатить">
         </form>
         <?php
      }
   }

   /**
    * Изменение статуса заказа. Позволяет пользователю внедрять собственные
    * обработчики при изменении статуса.
    *
    * @param array $param массив атрибутов
    * - $param['shop_order_id'] идентификатор заказа
    * - $param['prev_order_row'] информация о предыдущем состоянии заказа (доступно не всегда)
    * - $param['action'] выполняемое действие над заказом, может принимать значения:
    * edit (редактирование заказа), cancel (отмена заказа),
    * status (изменение статуса заказа), delete (удаление заказа),
    * edit_item (редактирование товара в заказе), delete_item (удаление товара в заказе)
    */
   function ChangeStatus($param = array())
   {
      // Если произошло изменение статуса
      if (isset($param['action']) && in_array($param['action'], array('status', 'edit')))
      {
         $shop_order_id = to_int($param['shop_order_id']);

         $shop = & singleton('shop');

         $order_row = $shop->GetOrder($shop_order_id);

         // Получаем информацию о магазине
         $shop_id = to_int($order_row['shop_shops_id']);

         $shop_row = $shop->GetShop($shop_id);

         $structure = & singleton('Structure');
         $structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

         $lib = new lib();
         $LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

         if ($order_row)
         {
            $DateClass = new DateClass();
            $date_str = $DateClass->datetime_format($order_row['shop_order_date_time']);
         }
         else
         {
            $date_str = '';
         }

         // Если предыдущий статус заказа был 1, то меняем тему на подтверждение
         if (to_int($order_row['shop_order_status_of_pay']) == 1)
         {
            $admin_subject = $GLOBALS['MSG_shops']['shop_order_confirm_admin_subject'];
            $user_subject = $GLOBALS['MSG_shops']['shop_order_confirm_user_subject'];
         }
         else
         {
            $admin_subject = $GLOBALS['MSG_shops']['shop_order_admin_subject'];
            $user_subject = $GLOBALS['MSG_shops']['shop_order_user_subject'];
         }

         $not_paid = isset($param['prev_order_row']) && $param['prev_order_row']['shop_order_status_of_pay'] == 0;
         
         // Письмо отправляем только при установке статуса активности для заказа
         if (to_int($order_row['shop_order_status_of_pay']) == 1 && $not_paid)
         {
            if (trim(to_str($order_row['shop_order_account_number'])) != '')
            {
               $shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
            }
            else
            {
               $shop_order_account_number = $shop_order_id;
            }

            /* Отправляем письмо заказчику */
            $shop->SendMailAboutOrder($shop_id,
            $shop_order_id,
            $order_row['site_users_id'],
            to_str($LA['xsl_letter_to_admin']),
            to_str($LA['xsl_letter_to_user']),
            $order_row['shop_order_users_email'],
            array('admin-content-type' => 'html',
            'user-content-type' => 'html',
            'admin-subject' => sprintf($admin_subject, $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
            'user-subject' => sprintf($user_subject, $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
            'email_from_admin' => $order_row['shop_order_users_email']));
         }
      }
   }
}
?>
Профиль | Сообщений: 10759 | Дата создания: 27.10.2009 12:17:55
Re: Обработчик платежной системы Робокасса для тестирования
MaksRF

Регистрация: 25.10.2007
О, я попробую, скоро отпишусь.
Профиль | Сообщений: 33 | Дата создания: 10.02.2010 13:00:48
Re: Обработчик платежной системы Робокасса для тестирования
Sizam4ik

Регистрация: 26.07.2008
Ткните носом — куда добавлять обработчик платежной системы?

hostcmsfiles\shop\pay\
а через веб-интерфейс…

Интернет-магазин — Список интернет-магазинов — Платежные системы
но тут только список вариантов оплаты…
Профиль | Сообщений: 1 | Дата создания: 09.06.2010 21:45:36
Re: Обработчик платежной системы Робокасса для тестирования
natalya

Регистрация: 30.11.1999
Sizam4ik писал(а):
но тут только список вариантов оплаты…
 — создайте новый обработчик через меню «Платежная система» -> „Добавить“. И сделайте его активным.
Профиль | Сообщений: 2634 | Дата создания: 10.06.2010 08:45:35
Re: Обработчик платежной системы Робокасса для тестирования
hell0men

Регистрация: 04.01.2009
«Не удалось установить связь с магазином для передачи ему информации об оплате. Через минуту будет произведена повторная попытка.»
— после оплаты.
Какие должны быть параметры
Result URL:
[используется для оповещения о платеже, если метод отсылки - email, то email-адрес]    
Метод отсылки данных по Result URL:


И прочие?

http://www.aiventa.ru
Профиль | Сообщений: 251 | Дата создания: 15.06.2010 22:00:36
Re: Обработчик платежной системы Робокасса для тестирования
HostCMS
Модератор

Регистрация: 02.04.2007
hell0men,
Адрес корзины на Вашем сайте, например, http://www.site.ru/shop/cart/
Профиль | Сообщений: 10759 | Дата создания: 16.06.2010 13:56:49
Re: Обработчик платежной системы Робокасса для тестирования
hell0men

Регистрация: 04.01.2009
Именно так и стоит. А GET|POST?

http://www.aiventa.ru
Профиль | Сообщений: 251 | Дата создания: 16.06.2010 21:27:41
Re: Обработчик платежной системы Робокасса для тестирования
HostCMS
Модератор

Регистрация: 02.04.2007
hell0men,
Там из $_REQUEST берется, можно POST поставить. Если не получится, уточните проблему у Робокассы.
Профиль | Сообщений: 10759 | Дата создания: 17.06.2010 09:09:08
Re: Обработчик платежной системы Робокасса для тестирования
hell0men

Регистрация: 04.01.2009
Я и GET и POST попробовал, проблема в следующем:
   
«Не удалось установить связь с магазином для передачи ему информации об оплате. Через минуту будет произведена повторная попытка.» — после оплаты.
Адреса такие же как в системе WebMoney.

http://www.aiventa.ru
Профиль | Сообщений: 251 | Дата создания: 18.06.2010 10:25:40
Re: Обработчик платежной системы Робокасса для тестирования
HostCMS
Модератор

Регистрация: 02.04.2007
HostCMS писал(а):
Если не получится, уточните проблему у Робокассы.
Профиль | Сообщений: 10759 | Дата создания: 18.06.2010 14:18:34

12345

Авторизация
Логин: Пароль:  

Список форумовПолезные решения на базе HostCMS

О нас говорят!

Нужно было создать интернет-магазин и HostCMS идеально подошла под эти цели! Техническая поддержка реагирует быстро и отвечает подробно.

Фаизова Юлия Рафаиловна
Руководитель проекта
Студия современной вышивки «JFStudio»

Акции партнеров

Хостинг от SPRINTHOST.RU

При покупке лицензии HostCMS в компании SPRINTHOST.RU в зависимости от выбранной редакции SPRINTHOST.RU дарит вам бесплатный хостинг по подходящему тарифному плану на период от 3 до 12 месяцев!

Рекомендуем хостинг

SPRINTHOST.RU

Тариф «HostCMS.Mini» за 70 руб./мес., Тариф «HostCMS» за 250 руб./мес.

Создаете сайты?

У нас есть партнерское предложение по поставке системы управления сайтом:

О HostCMS
Редакции HostCMS
Возможности
Поддержка
Области применения
Партнерская программа
Заказать сайт