<?php
/* Оплата через Platron */
class system_of_pay_handler
{
// Идентифкатор магазина, с которым будет работать обработчик
var $merchant_id = 12345;
// Секретный ключ (заполняется вручную пользователем на странице настроек магазина)
var $merchant_secret_key = "qwertyuiop";
// Валюта платежа RUR для работы или TST для тестирования системы
var $currencyName = "RUR";
// Код рублей
var $platron_currency = 1;
// Запускаем обработчик платежной системы
function Execute()
{
// Пришло подтверждение оплаты, обработаем его
if (isset($_REQUEST['pg_order_id']))
{
$this->ProcessResult();
return true;
}
// Иначе оформляем заказ и отображаем стартовую страницу для оплаты через Platron
$this->ShowPurseRequest();
}
// Обработка ответа платежной системы
function ProcessResult()
{
// Информация о заказе
$order_id = to_int($_REQUEST['pg_order_id']);
if (!$order_id)
{
return false;
}
$shop = & singleton('shop');
$order_row = $shop->GetOrder($order_id);
// Заказ не найден или уже оплачен
if (!$order_row || $order_row['shop_order_status_of_pay'])
{
return false;
}
$shop_row = $shop->GetShop($order_row['shop_shops_id']);
// Устанавливаем параметры, которые не зависят от совпадения хешей
$param['id'] = $order_row['shop_order_id'];
$param['shop_shops_id'] = $order_row['shop_shops_id'];
$order_sum = $shop->GetOrderSum($order_id);
// Делаем перерасчет суммы в валюту Platron
$shop_currency_id = $shop_row['shop_currency_id'];
$coefficient = $shop->GetCurrencyCoefficientToShopCurrency($shop_currency_id, $this->platron_currency);
$im_sum = round($order_sum * $coefficient, 2);
// Сравниваем хэши
if (self::check(to_str($_POST['pg_sig']), "", $_POST, $this->merchant_secret_key))
{
if (to_int($_POST['pg_result']) == 1
&& round(to_float($_POST['pg_net_amount']), 2) == $im_sum)
{
$id_plat = to_str($_POST['pg_payment_id']);
$param['system_information'] = "Товар оплачен через Platron.\n\n"
. "Информация:\n\n"
. "Идентификатор платежа в системе Platron: {$id_plat}\n"
. "\n";
// Обновляем информацию о заказе
$shop->InsertOrder($param);
// Изменяем статус оплаты ПОСЛЕ ОБНОВЛЕНИЯ ИНФОРМАЦИ, генерируем ссылки для эл.товаров, списываем товары
$shop->SetOrderPaymentStatus($order_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']));
$order_row = $shop->GetOrder($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'], $order_id, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
'user-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_confirm_user_subject'], $order_id, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
'email_from_admin' => $order_row['shop_order_users_email']));
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><response/>');
$xml->addChild('pg_salt', $_POST['pg_salt']);
$xml->addChild('pg_status', 'ok');
$xml->addChild('pg_description', "Оплата принята");
$xml->addChild('pg_sig', self::makeXML("", $xml, $this->merchant_secret_key));
header('Content-type: text/xml');
print $xml->asXML();
}
}
else
{
$param['system_information'] = 'Хэш не совпал!';
// Обновляем информацию о заказе
$shop->InsertOrder($param);
}
}
/**
* Отображает стартовую страницу для оплаты через Platron.
*
*/
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;
}
}
}
}
/**
* Метод для отображения формы заказа для печати.
*
* @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']);
$order_id = $order_row['shop_order_id'];
$order_sum = $shop->GetOrderSum($order_id);
// Делаем перерасчет суммы в валюту Platron
$shop_currency_id = $shop_row['shop_currency_id'];
// Получаем название валюты
$currency_row = $shop->GetCurrency($shop_currency_id);
$currency_name = $currency_row['shop_currency_name'];
$coefficient = $shop->GetCurrencyCoefficientToShopCurrency($shop_currency_id, $this->platron_currency);
$im_sum = round($order_sum * $coefficient, 2);
// Получаем имя/фамилию/отчество заказчика
$fio = implode(" ", array($order_row['shop_order_users_surname'], $order_row['shop_order_users_name'], $order_row['shop_order_users_patronymic']));
// Получаем email заказчика
$email = $order_row['shop_order_users_email'];
// Информация об алиасе сайта
$site = & singleton ('site');
$site_alias = $site->GetCurrentAlias($shop_row['site_id']);
/* Получаем путь к магазину */
$Structure = & singleton('Structure');
$kernel = & singleton('kernel');
$shop_path = "/".$Structure->GetStructurePath($shop_row['structure_id'], 0);
$handler_url = 'http://'.$site_alias.$shop_path.'cart/';
$array_of_params = array(
'pg_merchant_id' => $this->merchant_id,
'pg_order_id' => $order_id,
'pg_amount' => $im_sum,
'pg_lifetime' => 86400,
'pg_description' => "Оплата заказа №$order_id",
'pg_salt' => rand(21,43433),
'zzz' => "Перейти к оплате"
);
$sig = self::make('payment.php', $array_of_params, $this->merchant_secret_key);
?>
<h1>Оплата через систему Platron</h1>
<!-- Форма для оплаты через Platron -->
<p>К оплате <strong><?php echo $im_sum . " " . $currency_name?></strong></p>
<form method="post" action="https://www.platron.ru/payment.php">
<input type="hidden" name="pg_merchant_id" value="<?php echo $array_of_params['pg_merchant_id']?>">
<input type="hidden" name="pg_order_id" value="<?php echo $array_of_params['pg_order_id']?>">
<input type="hidden" name="pg_amount" value="<?php echo $array_of_params['pg_amount']?>">
<input type="hidden" name="pg_lifetime" value="<?php echo $array_of_params['pg_lifetime']?>">
<input type="hidden" name="pg_description" value="<?php echo $array_of_params['pg_description']?>">
<input type="hidden" name="pg_salt" value="<?php echo $array_of_params['pg_salt']?>">
<input type="hidden" name="pg_sig" value="<?php echo $sig?>">
<input name="submit" value="Перейти к оплате" type="submit"/>
</form>
<?php
}
}
// *****************************
// Далее идут методы Platron'а
// *****************************
public static function getScriptNameFromUrl ( $url )
{
$path = parse_url($url, PHP_URL_PATH);
$len = strlen($path);
if ( $len == 0 || '/' == $path{$len-1} ) {
return "";
}
return basename($path);
}
/**
* Get name of currently executed script (need to check signature of incoming message using self::check)
*
* @return string
*/
public static function getOurScriptName ()
{
return self::getScriptNameFromUrl( $_SERVER['PHP_SELF'] );
}
/**
* Creates a signature
*
* @param array $arrParams associative array of parameters for the signature
* @param string $strSecretKey
* @return string
*/
public static function make ( $strScriptName, $arrParams, $strSecretKey )
{
return md5( self::makeSigStr($strScriptName, $arrParams, $strSecretKey) );
}
/**
* Verifies the signature
*
* @param string $signature
* @param array $arrParams associative array of parameters for the signature
* @param string $strSecretKey
* @return bool
*/
public static function check ( $signature, $strScriptName, $arrParams, $strSecretKey )
{
return (string)$signature === self::make($strScriptName, $arrParams, $strSecretKey);
}
private static function makeSigStr ( $strScriptName, $arrParams, $strSecretKey )
{
if(isset($arrParams['pg_sig']))
{
unset($arrParams['pg_sig']);
}
ksort($arrParams);
array_unshift($arrParams, $strScriptName);
array_push ($arrParams, $strSecretKey);
return join(';', $arrParams);
}
/**
* make the signature for XML
*
* @param string|SimpleXMLElement $xml
* @param string $strSecretKey
* @return string
*/
public static function makeXML ( $strScriptName, $xml, $strSecretKey )
{
$arrFlatParams = self::makeFlatParamsXML($xml);
return self::make($strScriptName, $arrFlatParams, $strSecretKey);
}
/**
* Returns flat array of XML params
*
* @param (string|SimpleXMLElement) $xml
* @return array
*/
private static function makeFlatParamsXML ( $xml, $parent_name = '' )
{
if (!$xml instanceof SimpleXMLElement)
{
$xml = new SimpleXMLElement($xml);
}
$arrParams = array();
$i = 0;
foreach ($xml->children() as $tag)
{
$i++;
if ('pg_sig' == $tag->getName())
continue;
/**
* Имя делаем вида tag001subtag001
* Чтобы можно было потом нормально отсортировать и вложенные узлы не запутались при сортировке
*/
$name = $parent_name . $tag->getName().sprintf('%03d', $i);
if ($tag->children())
{
$arrParams = array_merge($arrParams, self::makeFlatParamsXML($tag, $name));
continue;
}
$arrParams += array($name => (string)$tag);
}
return $arrParams;
}
}
?>
В блок
// Идентифкатор магазина, с которым будет работать обработчик
var $merchant_id = 12345;
// Секретный ключ (заполняется вручную пользователем на странице настроек магазина)
var $merchant_secret_key = "qwertyuiop";
добавьте свои данные.
В ТДС корзины традиционно встречаем запрос Platron'а:
// ------------------------------------------------
// Подготовка редиректа для Platron
// ------------------------------------------------
if (isset($_POST['pg_order_id']))
{
// Получаем ID заказа
$order_id = to_int($_POST['pg_order_id']);
$order_row = $shop->GetOrder($order_id);
if ($order_row)
{
// Вызов обработчика платежной системы
$shop->ExecSystemsOfPayHandler($order_row['shop_system_of_pay_id']);
}
}