Добавление обработчика оплаты через СМС сервиса AvisoSMS
1. Добавьте обработчик платежной системы AvisoSMS
Идем в:
Интернет магазин ->
Выбираем магазин (по умолчанию Демо магазин) ->
Вверху Справочники, в нем Платежные системы, там добавляем новую систему.
Вставляем в поле "Обработчик" (приведен ниже)
После добавления, в этом модуле из закладки Идентификатор,
в коде заменяем идентификатор Shop_Payment_System_Handler<ID>
Указываем в коде данные для доступа к Aviso:
Код обработчика:
2. Идем в:
Типовые динамические страницы ->
Интернет-магазин ->
Редактировать (иконка карандаша) "Интернет-магазин корзина"
Здесь выбираем вкладку "Настройки страницы" и добавляем в начало
(после $oShop = Core_Entity::factory('Shop', Core_Array::get(Core_Page::instance()->libParams, 'shopId'
)
код:
3. Обработчик платежей, указывается в Панели AvisoSMS
Идем в:
Интернет магазин ->
Выбираем магазин (по умолчанию Демо магазин) ->
Вверху Справочники, в нем Платежные системы, там добавляем новую систему.
Вставляем в поле "Обработчик" (приведен ниже)
После добавления, в этом модуле из закладки Идентификатор,
в коде заменяем идентификатор Shop_Payment_System_Handler<ID>
Указываем в коде данные для доступа к Aviso:
// логин в системе AvisoSMS
private $_username = '';
// SECURE_HASH (хэш код)
private $_secure_hash = '';
// ID сервиса
private $_service_id = '';
// текст в SMS после успешной оплаты
private $_success_message = 'Заказ оплачен';
// false - для боевых платежей
private $_test = true;
private $_username = '';
// SECURE_HASH (хэш код)
private $_secure_hash = '';
// ID сервиса
private $_service_id = '';
// текст в SMS после успешной оплаты
private $_success_message = 'Заказ оплачен';
// false - для боевых платежей
private $_test = true;
Код обработчика:
<?php
/* Оплата через AvisoSMS */
class Shop_Payment_System_Handler19 extends Shop_Payment_System_Handler
{
// логин в системе AvisoSMS
private $_username = '';
// SECURE_HASH (хэш код)
private $_secure_hash = '';
// ID сервиса
private $_service_id = '';
// текст в SMS после успешной оплаты
private $_success_message = 'Заказ оплачен';
// false - для боевых платежей
private $_test = true;
private $_currency_id = 1;
/* Вызывается на 4-ом шаге оформления заказа*/
public function execute()
{
parent::execute();
$this->printNotification();
return $this;
}
protected function _processOrder()
{
parent::_processOrder();
// Установка XSL-шаблонов в соответствии с настройками в узле структуры
$this->setXSLs();
// Отправка писем клиенту и пользователю
$this->send();
return $this;
}
/* вычисление суммы товаров заказа */
public function getSumWithCoeff()
{
return Shop_Controller::instance()->round(($this->_currency_id > 0
&& $this->_shopOrder->shop_currency_id > 0
? Shop_Controller::instance()->getCurrencyCoefficientInShopCurrency(
$this->_shopOrder->Shop_Currency,
Core_Entity::factory('Shop_Currency', $this->_currency_id)
)
: 0) * $this->_shopOrder->getAmount());
}
/* проверка оплаты платежа, оплачивает заказ */
public function paymentProcessing()
{
$oShop_Order = Core_Entity::factory('Shop_Order')->find($_POST['merchant_order_id']);
if(is_null($oShop_Order->id) || $oShop_Order->paid)
{
return FALSE;
}
$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
$result = array(
'error' => 1,
'text' => '',
);
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
if (isset($_POST['avisosms']))
{
ob_clean();
die('checkout');
}
elseif (isset($_POST['avisosms_to']))
{
$phone = preg_replace('|[^0-9]+|si', '', $_POST['avisosms_to']);
if (strlen($phone) == 11)
{
$description = 'Оплата заказа #' . $this->_shopOrder->id;
$m_commerce = new AvisosmsMCommerce($this->_username, $this->_secure_hash, $this->_service_id);
$m_commerce->test = $this->_test;
$sum = $this->getSumWithCoeff();
if ($m_commerce->createOrder($description, $sum, $this->_success_message, $phone, $this->_shopOrder->id)) {
$result['text'] = 'На номер: ' . htmlspecialchars($_POST['avisosms_to']) . ' выслано смс с подтверждением платежа. Подтвердите платеж ответив на это смс. Ответ бесплатный. Не закрывайте окно браузера до завершения операции.';
$result['error'] = 0;
}
else
{
$result['text'] = 'Ошибка! ';
$result['text'] .= $m_commerce->error_message();
}
}
else
{
$result['text'] = 'Ошибка! Некорректный номер (' . $_POST['avisosms_to'] . ') телефона.';
}
if ($ajax)
{
ob_clean();
die(json_encode($result));
}
}
else
{
$m_commerce = new AvisosmsMCommerce($this->_username, $this->_secure_hash, $this->_service_id);
if ($m_commerce->updateOrderStatus()) {
$oShop_Order->system_information = "Товар оплачен через AvisoSMS.\n";
$oShop_Order->paid();
$this->setXSLs();
$this->send();
}
}
}
}
/* печатает форму отправки запроса на сайт платёжной системы */
public function getNotification()
{
$sum = $this->getSumWithCoeff();
$oShop_Currency = Core_Entity::factory('Shop_Currency')->find($this->_currency_id);
if(!is_null($oShop_Currency->id))
{
$phone = preg_replace('|[^0-9+-]+|si', '', $this->_shopOrder->phone);
$form = '
<script>
$(function() {
$("form.avisosms").live("submit", function() {
$.post(location.href, $(this).serialize(), function (data) {
var d = $.parseJSON(data);
if (d["error"] == 0) {
$("div.avisosms").html( d["text"] + "<p></p>" );
$("img.avisosms").show();
$("form.avisosms").hide();
aviso_check();
} else {
$("p.avisosms").html( d["text"] );
}
});
return false;
});
});
function aviso_check() {
$.post(location.href, {avisosms: 0, merchant_order_id: ' . $this->_shopOrder->id . '}, function(data) {
if (data == "checkout") { } else {
$("img.avisosms").hide();
$("div.avisosms").html("Ваш платеж успешно подтвержден. Спасибо за покупку!");
location.href = "?payment=success&order_id=' . $this->_shopOrder->id . '";
}
});
if ($("img.avisosms").is(":visible"))
setTimeout("aviso_check()", 5000);
}
</script>
<h1>Оплата со счета мобильного телефона</h1>
<p>Номер вашего заказа: <strong>№ ' . $this->_shopOrder->id . '</strong></p>
<p>Сумма к оплате составляет <strong>' . $sum . ' ' . $oShop_Currency->name . '</strong></p>
' . ($this->_shopOrder->paid ? '
<p>Ваш заказ уже оплачен.</p>
' : '
<form method="POST" class="avisosms">
<p>
Проверьте номер телефона и нажмите кнопку "Оплатить".
</p>
<p>
На этот номер телефона придет SMS для подтверждения платежа
</p>
<p class="avisosms"></p>
<p>
<input type="text" name="avisosms_to" value="' . $phone . '">
</p>
<p>
<input type="submit" value="Оплатить">
</p>
<input type="hidden" name="merchant_order_id" value="' . $this->_shopOrder->id . '">
</form>
<div class="avisosms"></div>
<img class="avisosms" style="display:none" alt="Ждем ответ от сервера..." title="Ждем ответ от сервера..." width="124" height="124"
src="data:image/gif;base64,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" />
');
echo $form;
}
}
public function getInvoice()
{
return $this->getNotification();
}
}
/**
* Класс для работы с сервисом AvisoSMS Мобильная коммерция
*
* Документация:
*
* @author
* @copyright
* @license
*/
class AvisosmsMCommerce {
/**
* @var Ссылка до API
*/
public $url = 'https://api.avisosms.ru/mc/';
/**
* @var Имя пользователя в системе AvisoSMS
*/
public $username = NULL;
/**
* @var Ключ доступа. Указывается в настройках аккаунта (Настройки удалённого доступа)
*/
public $secure_hash = NULL;
/**
* @var ID сервиса
*/
public $service_id = NULL;
/**
* @var Время ожидания ответа от сервера в секундах
*/
public $timeout = 10;
/**
* @var Кодировка приложения
*/
public $out_charset = 'UTF-8';
/**
* @var Расшифровка статусов заказов.
*/
public $order_status = array(
'success' => 'Заказ успешно оплачен',
'failure' => 'Заказ не был оплачен',
'cancel' => 'Заказ был отменён пользователем со стороны сотового оператора',
'pending' => 'Заказ обрабатывается',
);
/**
* @var Расшифровка статусов.
*/
private $_status = array(
'0' => 'Нет ошибок. Операция произведена успешно',
'1' => 'Неожиданная ошибка. Этой ошибки быть не должно',
'2' => 'Эта ошибка может возникнуть, если для данного номера не доступна услуга мобильной коммерции',
'3' => 'Некоторые параметры переданы неверно или не переданы',
'4' => 'Ошибка авторизации',
'5' => 'Ошибка проверки цифровой подписи',
'255' => 'Ошибка соединения с сервером',
);
private $_response = NULL;
private $_error_message = NULL;
/**
* @var Режим тестирования
*/
public $test = FALSE;
public $debug_text = '';
/**
* @var Кодировка скрипта
*/
const CHARSET = 'UTF-8';
/**
* Конструктор
*
* // Создаем новый объект для работы с avisosms m_commerce
* $m_commerce = new avisosms_m_commerce($username, $secure_hash, $service_id);
* // Включаем тестовый режим
* $m_commerce->test = TRUE;
* $m_commerce->debug = TRUE;
*
* @param string Имя пользователя в системе AvisoSMS.
* @param string Ключ доступа. Указывается в настройках платформы.
* @param string ID сервиса. Указывается в личном кабинете.
*
* @return boolean TRUE
*/
function AvisosmsMCommerce($username, $secure_hash, $service_id)
{
$this->username = $username;
$this->secure_hash = $secure_hash;
$this->service_id = $service_id;
return TRUE;
}
/**
* Создание заказа
*
* if ($m_commerce->createOrder($description, $price, $success_message, $phone, ''))
* {
* // Заказ создан успешно (status = 0)
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Ошибка создания заказа (status > 0)
* echo 'Ошибка: '.$m_commerce->error_message();
* var_dump($m_commerce->response());
* }
*
* @param string Описание заказа. Максимальная длина 100 символов, минимальная - 10.
* @param string Сумма заказа. Дробные числа указываются через точку. Максимум до сотых долей.
* @param string Сообщение, отправляемое пользователю, в случае успешного завершения оплаты.
* @param string Телефон абонента.
* @param string Необязательный параметр. ID платежа в системе магазина. До 100 знаков.
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function createOrder($description, $price, $success_message, $phone, $merchant_order_id = '')
{
$data = array(
'description' => $description,
'price' => (float)number_format($price, 2, '.', ''),
'success_message' => $success_message,
'phone' => $phone,
'merchant_order_id' => $merchant_order_id,
);
return $this->send($data, 'create_order');
}
/**
* Запрос статуса заказа
*
* if ($m_commerce->getOrderStatus('4d2c8957f612fc6f3c0003e4'))
* {
* // Данные получены успешно (status = 0)
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Ошибка получение данных (status > 0)
* echo 'Ошибка: '.$m_commerce->error_message();
* var_dump($m_commerce->response());
* }
*
* @param string ID заказа
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function getOrderStatus($phone, $order_id)
{
$data = array(
'phone' => $phone,
'order_id' => $order_id,
);
return $this->send($data, 'get_order_info');
}
/**
* Уведомление о статусе
*
* if ($m_commerce->updateOrderStatus())
* {
* // Данные получены, проверка secure_hash пройдена
* // Можно обрабатывать полученные данные
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Переданные данные не верны.
* die('Ошибка: '.$m_commerce->error_message());
* }
*
* @param array Массив с переданными данными (если получаются самостоятельно)
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function updateOrderStatus($data = NULL)
{
$options = array(
'order_id' => '',
'order_status' => '',
'phone' => '',
'sign' => '',
'merchant_order_id' => '',
);
if (is_null($data))
{
$data = file_get_contents("php://input");
$data = json_decode($data);
}
//phone, order_status, service_id, username и SECURE_HASH
$this->_response = array_merge($options, (array) $data);
//phone, order_status, service_id, username и SECURE_HASH
$signatureString = $this->_response['phone'] . $this->_response['order_status'] . $this->service_id . $this->username . $this->secure_hash;
$signature = md5 ( $signatureString );
$this->debug_text .= 'Полученные данные: <pre>' . print_r($data, true). '</pre><br />';
$this->debug_text .= 'Ожидаемая цифровая подпись: ' . $signature . '<br />';
$this->debug_text .= 'Полученная цифровая подпись: ' . $this->_response['sign'] . '<br />';
$this->debug_text .= 'Цифровая подпись генерирутся из строки: ' . $signatureString . '<br />';
if (empty($this->_response['sign']) || $this->_response['sign'] != $signature) {
$this->_error_message = 'Неверный ключ доступа.';
return FALSE;
}
return TRUE;
}
/**
* Обращение к API
*
* @param array Массив с данными
* @param string Название функции
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function send($data, $postfix)
{
if ($this->test) {
$data['test'] = true;
}
if ($this->out_charset <> self::CHARSET) {
foreach($data as $k => $v) {
$data[$k] = iconv($this->out_charset, self::CHARSET, $v);
}
}
$data['username'] = $this->username;
$data['service_id'] = $this->service_id;
$data['access_key'] = '';
$data['sign'] = md5($data['phone'] . $data['service_id'] . $data['username'] . $this->secure_hash);
$url = $this->url.$postfix.'/';
$json_data = json_encode($data);
$this->debug_text .= 'Запрос: <b>' . $postfix . '</b><br />';
//$this->debug_text .= '<pre>' . print_r($data, true) . '</pre>';
$this->debug_text .= 'Цифровая подпись: '. $data['sign'] . '<br />';
$this->debug_text .= 'Строка для подписи: '. ($data['phone'] . $data['service_id'] . $data['username'] . $this->secure_hash). '<br />';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_COOKIE, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
$result = curl_exec($ch);
$this->debug_text .= 'Передаем запрос '.$url.': <br><pre>'.print_r($data, true).'</pre>';
$this->debug_text .= 'Получаем ответ: <br><pre>'.print_r(json_decode($result), true).'</pre>';
$this->_response = array('status' => 255);
//echo $this->debug_text;
if (curl_errno($ch))
{
$this->_error_message = curl_error($ch);
}
else
{
$this->_response = array_merge($this->_response, (array)json_decode($result, TRUE));
$this->_error_message = $this->_status[$this->_response['status']];
}
curl_close($ch);
return !$this->_response['status'];
1
}
/**
* Возвращает ответ от сервера
*
* @return array Ответ от сервера
*/
public function response()
{
$data = $this->_response;
if ($this->out_charset <> self::CHARSET) foreach($data as $k => $v) {
$data[$k] = iconv(self::CHARSET, $this->out_charset, $v);
}
return $data;
}
/**
* Возвращает текст ошибки
*
* @return string Текст ошибки
*/
public function error_message()
{
return ($this->out_charset == self::CHARSET) ? $this->_error_message : iconv(self::CHARSET, $this->out_charset, $this->_error_message);
}
/**
* Возвращает текстовый статус заказа
*
* @param string Статус
* @return string
*/
public function order_status($status)
{
if (!isset($this->order_status[$status])) {
return NULL;
}
return ($this->out_charset == self::CHARSET) ? $this->order_status[$status] : iconv(self::CHARSET, $this->out_charset, $this->order_status[$status]);
}
}
//PHP 4.2.x Compatibility function
if (!function_exists('file_get_contents')) {
function file_get_contents($filename, $incpath = false, $resource_context = null)
{
if (false === $fh = fopen($filename, 'rb', $incpath)) {
trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
return false;
}
clearstatcache();
if ($fsize = @filesize($filename)) {
$data = fread($fh, $fsize);
} else {
$data = '';
while (!feof($fh)) {
$data .= fread($fh, 8192);
}
}
fclose($fh);
return $data;
}
}
if (!function_exists('json_encode')) {
function json_encode( $array ){
if( !is_array( $array ) ){
return false;
}
$associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) ));
if( $associative ){
$construct = array();
foreach( $array as $key => $value ){
// We first copy each key/value pair into a staging array,
// formatting each key and value properly as we go.
// Format the key:
if( is_numeric($key) ){
$key = "key_$key";
}
$key = "'".addslashes($key)."'";
// Format the value:
if( is_array( $value )){
$value = array_to_json( $value );
} else if( !is_numeric( $value ) || is_string( $value ) ){
$value = "'".addslashes($value)."'";
}
// Add to staging array:
$construct[] = "$key: $value";
}
// Then we collapse the staging array into the JSON form:
$result = "{ " . implode( ", ", $construct ) . " }";
} else { // If the array is a vector (not associative):
$construct = array();
foreach( $array as $value ){
// Format the value:
if( is_array( $value )){
$value = array_to_json( $value );
} else if( !is_numeric( $value ) || is_string( $value ) ){
$value = "'".addslashes($value)."'";
}
// Add to staging array:
$construct[] = $value;
}
// Then we collapse the staging array into the JSON form:
$result = "[ " . implode( ", ", $construct ) . " ]";
}
return $result;
}
}
if ( !function_exists('json_decode') ){
function json_decode($json)
{
$comment = false;
$out = '$x=';
for ($i=0; $i<strlen($json); $i++)
{
if (!$comment)
{
if (($json[$i] == '{') || ($json[$i] == '[')) $out .= ' array(';
else if (($json[$i] == '}') || ($json[$i] == ']')) $out .= ')';
else if ($json[$i] == ':') $out .= '=>';
else $out .= $json[$i];
}
else $out .= $json[$i];
if ($json[$i] == '"' && $json[($i-1)]!="\\") $comment = !$comment;
}
eval($out . ';');
return $x;
}
}
/* Оплата через AvisoSMS */
class Shop_Payment_System_Handler19 extends Shop_Payment_System_Handler
{
// логин в системе AvisoSMS
private $_username = '';
// SECURE_HASH (хэш код)
private $_secure_hash = '';
// ID сервиса
private $_service_id = '';
// текст в SMS после успешной оплаты
private $_success_message = 'Заказ оплачен';
// false - для боевых платежей
private $_test = true;
private $_currency_id = 1;
/* Вызывается на 4-ом шаге оформления заказа*/
public function execute()
{
parent::execute();
$this->printNotification();
return $this;
}
protected function _processOrder()
{
parent::_processOrder();
// Установка XSL-шаблонов в соответствии с настройками в узле структуры
$this->setXSLs();
// Отправка писем клиенту и пользователю
$this->send();
return $this;
}
/* вычисление суммы товаров заказа */
public function getSumWithCoeff()
{
return Shop_Controller::instance()->round(($this->_currency_id > 0
&& $this->_shopOrder->shop_currency_id > 0
? Shop_Controller::instance()->getCurrencyCoefficientInShopCurrency(
$this->_shopOrder->Shop_Currency,
Core_Entity::factory('Shop_Currency', $this->_currency_id)
)
: 0) * $this->_shopOrder->getAmount());
}
/* проверка оплаты платежа, оплачивает заказ */
public function paymentProcessing()
{
$oShop_Order = Core_Entity::factory('Shop_Order')->find($_POST['merchant_order_id']);
if(is_null($oShop_Order->id) || $oShop_Order->paid)
{
return FALSE;
}
$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
$result = array(
'error' => 1,
'text' => '',
);
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
if (isset($_POST['avisosms']))
{
ob_clean();
die('checkout');
}
elseif (isset($_POST['avisosms_to']))
{
$phone = preg_replace('|[^0-9]+|si', '', $_POST['avisosms_to']);
if (strlen($phone) == 11)
{
$description = 'Оплата заказа #' . $this->_shopOrder->id;
$m_commerce = new AvisosmsMCommerce($this->_username, $this->_secure_hash, $this->_service_id);
$m_commerce->test = $this->_test;
$sum = $this->getSumWithCoeff();
if ($m_commerce->createOrder($description, $sum, $this->_success_message, $phone, $this->_shopOrder->id)) {
$result['text'] = 'На номер: ' . htmlspecialchars($_POST['avisosms_to']) . ' выслано смс с подтверждением платежа. Подтвердите платеж ответив на это смс. Ответ бесплатный. Не закрывайте окно браузера до завершения операции.';
$result['error'] = 0;
}
else
{
$result['text'] = 'Ошибка! ';
$result['text'] .= $m_commerce->error_message();
}
}
else
{
$result['text'] = 'Ошибка! Некорректный номер (' . $_POST['avisosms_to'] . ') телефона.';
}
if ($ajax)
{
ob_clean();
die(json_encode($result));
}
}
else
{
$m_commerce = new AvisosmsMCommerce($this->_username, $this->_secure_hash, $this->_service_id);
if ($m_commerce->updateOrderStatus()) {
$oShop_Order->system_information = "Товар оплачен через AvisoSMS.\n";
$oShop_Order->paid();
$this->setXSLs();
$this->send();
}
}
}
}
/* печатает форму отправки запроса на сайт платёжной системы */
public function getNotification()
{
$sum = $this->getSumWithCoeff();
$oShop_Currency = Core_Entity::factory('Shop_Currency')->find($this->_currency_id);
if(!is_null($oShop_Currency->id))
{
$phone = preg_replace('|[^0-9+-]+|si', '', $this->_shopOrder->phone);
$form = '
<script>
$(function() {
$("form.avisosms").live("submit", function() {
$.post(location.href, $(this).serialize(), function (data) {
var d = $.parseJSON(data);
if (d["error"] == 0) {
$("div.avisosms").html( d["text"] + "<p></p>" );
$("img.avisosms").show();
$("form.avisosms").hide();
aviso_check();
} else {
$("p.avisosms").html( d["text"] );
}
});
return false;
});
});
function aviso_check() {
$.post(location.href, {avisosms: 0, merchant_order_id: ' . $this->_shopOrder->id . '}, function(data) {
if (data == "checkout") { } else {
$("img.avisosms").hide();
$("div.avisosms").html("Ваш платеж успешно подтвержден. Спасибо за покупку!");
location.href = "?payment=success&order_id=' . $this->_shopOrder->id . '";
}
});
if ($("img.avisosms").is(":visible"))
setTimeout("aviso_check()", 5000);
}
</script>
<h1>Оплата со счета мобильного телефона</h1>
<p>Номер вашего заказа: <strong>№ ' . $this->_shopOrder->id . '</strong></p>
<p>Сумма к оплате составляет <strong>' . $sum . ' ' . $oShop_Currency->name . '</strong></p>
' . ($this->_shopOrder->paid ? '
<p>Ваш заказ уже оплачен.</p>
' : '
<form method="POST" class="avisosms">
<p>
Проверьте номер телефона и нажмите кнопку "Оплатить".
</p>
<p>
На этот номер телефона придет SMS для подтверждения платежа
</p>
<p class="avisosms"></p>
<p>
<input type="text" name="avisosms_to" value="' . $phone . '">
</p>
<p>
<input type="submit" value="Оплатить">
</p>
<input type="hidden" name="merchant_order_id" value="' . $this->_shopOrder->id . '">
</form>
<div class="avisosms"></div>
<img class="avisosms" style="display:none" alt="Ждем ответ от сервера..." title="Ждем ответ от сервера..." width="124" height="124"
src="data:image/gif;base64,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" />
');
echo $form;
}
}
public function getInvoice()
{
return $this->getNotification();
}
}
/**
* Класс для работы с сервисом AvisoSMS Мобильная коммерция
*
* Документация:
*
* @author
* @copyright
* @license
*/
class AvisosmsMCommerce {
/**
* @var Ссылка до API
*/
public $url = 'https://api.avisosms.ru/mc/';
/**
* @var Имя пользователя в системе AvisoSMS
*/
public $username = NULL;
/**
* @var Ключ доступа. Указывается в настройках аккаунта (Настройки удалённого доступа)
*/
public $secure_hash = NULL;
/**
* @var ID сервиса
*/
public $service_id = NULL;
/**
* @var Время ожидания ответа от сервера в секундах
*/
public $timeout = 10;
/**
* @var Кодировка приложения
*/
public $out_charset = 'UTF-8';
/**
* @var Расшифровка статусов заказов.
*/
public $order_status = array(
'success' => 'Заказ успешно оплачен',
'failure' => 'Заказ не был оплачен',
'cancel' => 'Заказ был отменён пользователем со стороны сотового оператора',
'pending' => 'Заказ обрабатывается',
);
/**
* @var Расшифровка статусов.
*/
private $_status = array(
'0' => 'Нет ошибок. Операция произведена успешно',
'1' => 'Неожиданная ошибка. Этой ошибки быть не должно',
'2' => 'Эта ошибка может возникнуть, если для данного номера не доступна услуга мобильной коммерции',
'3' => 'Некоторые параметры переданы неверно или не переданы',
'4' => 'Ошибка авторизации',
'5' => 'Ошибка проверки цифровой подписи',
'255' => 'Ошибка соединения с сервером',
);
private $_response = NULL;
private $_error_message = NULL;
/**
* @var Режим тестирования
*/
public $test = FALSE;
public $debug_text = '';
/**
* @var Кодировка скрипта
*/
const CHARSET = 'UTF-8';
/**
* Конструктор
*
* // Создаем новый объект для работы с avisosms m_commerce
* $m_commerce = new avisosms_m_commerce($username, $secure_hash, $service_id);
* // Включаем тестовый режим
* $m_commerce->test = TRUE;
* $m_commerce->debug = TRUE;
*
* @param string Имя пользователя в системе AvisoSMS.
* @param string Ключ доступа. Указывается в настройках платформы.
* @param string ID сервиса. Указывается в личном кабинете.
*
* @return boolean TRUE
*/
function AvisosmsMCommerce($username, $secure_hash, $service_id)
{
$this->username = $username;
$this->secure_hash = $secure_hash;
$this->service_id = $service_id;
return TRUE;
}
/**
* Создание заказа
*
* if ($m_commerce->createOrder($description, $price, $success_message, $phone, ''))
* {
* // Заказ создан успешно (status = 0)
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Ошибка создания заказа (status > 0)
* echo 'Ошибка: '.$m_commerce->error_message();
* var_dump($m_commerce->response());
* }
*
* @param string Описание заказа. Максимальная длина 100 символов, минимальная - 10.
* @param string Сумма заказа. Дробные числа указываются через точку. Максимум до сотых долей.
* @param string Сообщение, отправляемое пользователю, в случае успешного завершения оплаты.
* @param string Телефон абонента.
* @param string Необязательный параметр. ID платежа в системе магазина. До 100 знаков.
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function createOrder($description, $price, $success_message, $phone, $merchant_order_id = '')
{
$data = array(
'description' => $description,
'price' => (float)number_format($price, 2, '.', ''),
'success_message' => $success_message,
'phone' => $phone,
'merchant_order_id' => $merchant_order_id,
);
return $this->send($data, 'create_order');
}
/**
* Запрос статуса заказа
*
* if ($m_commerce->getOrderStatus('4d2c8957f612fc6f3c0003e4'))
* {
* // Данные получены успешно (status = 0)
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Ошибка получение данных (status > 0)
* echo 'Ошибка: '.$m_commerce->error_message();
* var_dump($m_commerce->response());
* }
*
* @param string ID заказа
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function getOrderStatus($phone, $order_id)
{
$data = array(
'phone' => $phone,
'order_id' => $order_id,
);
return $this->send($data, 'get_order_info');
}
/**
* Уведомление о статусе
*
* if ($m_commerce->updateOrderStatus())
* {
* // Данные получены, проверка secure_hash пройдена
* // Можно обрабатывать полученные данные
* $response = $m_commerce->response();
* var_dump($response);
* }
* else
* {
* // Переданные данные не верны.
* die('Ошибка: '.$m_commerce->error_message());
* }
*
* @param array Массив с переданными данными (если получаются самостоятельно)
*
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function updateOrderStatus($data = NULL)
{
$options = array(
'order_id' => '',
'order_status' => '',
'phone' => '',
'sign' => '',
'merchant_order_id' => '',
);
if (is_null($data))
{
$data = file_get_contents("php://input");
$data = json_decode($data);
}
//phone, order_status, service_id, username и SECURE_HASH
$this->_response = array_merge($options, (array) $data);
//phone, order_status, service_id, username и SECURE_HASH
$signatureString = $this->_response['phone'] . $this->_response['order_status'] . $this->service_id . $this->username . $this->secure_hash;
$signature = md5 ( $signatureString );
$this->debug_text .= 'Полученные данные: <pre>' . print_r($data, true). '</pre><br />';
$this->debug_text .= 'Ожидаемая цифровая подпись: ' . $signature . '<br />';
$this->debug_text .= 'Полученная цифровая подпись: ' . $this->_response['sign'] . '<br />';
$this->debug_text .= 'Цифровая подпись генерирутся из строки: ' . $signatureString . '<br />';
if (empty($this->_response['sign']) || $this->_response['sign'] != $signature) {
$this->_error_message = 'Неверный ключ доступа.';
return FALSE;
}
return TRUE;
}
/**
* Обращение к API
*
* @param array Массив с данными
* @param string Название функции
* @return boolean Возвращает TRUE, если status = 0, иначе FALSE
*/
function send($data, $postfix)
{
if ($this->test) {
$data['test'] = true;
}
if ($this->out_charset <> self::CHARSET) {
foreach($data as $k => $v) {
$data[$k] = iconv($this->out_charset, self::CHARSET, $v);
}
}
$data['username'] = $this->username;
$data['service_id'] = $this->service_id;
$data['access_key'] = '';
$data['sign'] = md5($data['phone'] . $data['service_id'] . $data['username'] . $this->secure_hash);
$url = $this->url.$postfix.'/';
$json_data = json_encode($data);
$this->debug_text .= 'Запрос: <b>' . $postfix . '</b><br />';
//$this->debug_text .= '<pre>' . print_r($data, true) . '</pre>';
$this->debug_text .= 'Цифровая подпись: '. $data['sign'] . '<br />';
$this->debug_text .= 'Строка для подписи: '. ($data['phone'] . $data['service_id'] . $data['username'] . $this->secure_hash). '<br />';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_COOKIE, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
$result = curl_exec($ch);
$this->debug_text .= 'Передаем запрос '.$url.': <br><pre>'.print_r($data, true).'</pre>';
$this->debug_text .= 'Получаем ответ: <br><pre>'.print_r(json_decode($result), true).'</pre>';
$this->_response = array('status' => 255);
//echo $this->debug_text;
if (curl_errno($ch))
{
$this->_error_message = curl_error($ch);
}
else
{
$this->_response = array_merge($this->_response, (array)json_decode($result, TRUE));
$this->_error_message = $this->_status[$this->_response['status']];
}
curl_close($ch);
return !$this->_response['status'];
1
}
/**
* Возвращает ответ от сервера
*
* @return array Ответ от сервера
*/
public function response()
{
$data = $this->_response;
if ($this->out_charset <> self::CHARSET) foreach($data as $k => $v) {
$data[$k] = iconv(self::CHARSET, $this->out_charset, $v);
}
return $data;
}
/**
* Возвращает текст ошибки
*
* @return string Текст ошибки
*/
public function error_message()
{
return ($this->out_charset == self::CHARSET) ? $this->_error_message : iconv(self::CHARSET, $this->out_charset, $this->_error_message);
}
/**
* Возвращает текстовый статус заказа
*
* @param string Статус
* @return string
*/
public function order_status($status)
{
if (!isset($this->order_status[$status])) {
return NULL;
}
return ($this->out_charset == self::CHARSET) ? $this->order_status[$status] : iconv(self::CHARSET, $this->out_charset, $this->order_status[$status]);
}
}
//PHP 4.2.x Compatibility function
if (!function_exists('file_get_contents')) {
function file_get_contents($filename, $incpath = false, $resource_context = null)
{
if (false === $fh = fopen($filename, 'rb', $incpath)) {
trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
return false;
}
clearstatcache();
if ($fsize = @filesize($filename)) {
$data = fread($fh, $fsize);
} else {
$data = '';
while (!feof($fh)) {
$data .= fread($fh, 8192);
}
}
fclose($fh);
return $data;
}
}
if (!function_exists('json_encode')) {
function json_encode( $array ){
if( !is_array( $array ) ){
return false;
}
$associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) ));
if( $associative ){
$construct = array();
foreach( $array as $key => $value ){
// We first copy each key/value pair into a staging array,
// formatting each key and value properly as we go.
// Format the key:
if( is_numeric($key) ){
$key = "key_$key";
}
$key = "'".addslashes($key)."'";
// Format the value:
if( is_array( $value )){
$value = array_to_json( $value );
} else if( !is_numeric( $value ) || is_string( $value ) ){
$value = "'".addslashes($value)."'";
}
// Add to staging array:
$construct[] = "$key: $value";
}
// Then we collapse the staging array into the JSON form:
$result = "{ " . implode( ", ", $construct ) . " }";
} else { // If the array is a vector (not associative):
$construct = array();
foreach( $array as $value ){
// Format the value:
if( is_array( $value )){
$value = array_to_json( $value );
} else if( !is_numeric( $value ) || is_string( $value ) ){
$value = "'".addslashes($value)."'";
}
// Add to staging array:
$construct[] = $value;
}
// Then we collapse the staging array into the JSON form:
$result = "[ " . implode( ", ", $construct ) . " ]";
}
return $result;
}
}
if ( !function_exists('json_decode') ){
function json_decode($json)
{
$comment = false;
$out = '$x=';
for ($i=0; $i<strlen($json); $i++)
{
if (!$comment)
{
if (($json[$i] == '{') || ($json[$i] == '[')) $out .= ' array(';
else if (($json[$i] == '}') || ($json[$i] == ']')) $out .= ')';
else if ($json[$i] == ':') $out .= '=>';
else $out .= $json[$i];
}
else $out .= $json[$i];
if ($json[$i] == '"' && $json[($i-1)]!="\\") $comment = !$comment;
}
eval($out . ';');
return $x;
}
}
2. Идем в:
Типовые динамические страницы ->
Интернет-магазин ->
Редактировать (иконка карандаша) "Интернет-магазин корзина"
Здесь выбираем вкладку "Настройки страницы" и добавляем в начало
(после $oShop = Core_Entity::factory('Shop', Core_Array::get(Core_Page::instance()->libParams, 'shopId'
)
код:
// ------------------------------------------------
// Обработка запросов от AvisoSMS
// ------------------------------------------------
$order_id = 0;
if (isset($_POST['merchant_order_id']))
{
$order_id = (int)$_POST['merchant_order_id'];
}
elseif (isset($_GET['aviso']))
{
$aviso = file_get_contents("php://input");
if ($aviso != '')
{
$aviso = @json_decode($aviso, true);
if (isset($aviso['merchant_order_id']))
{
$order_id = intval($aviso['merchant_order_id']);
}
}
}
if ($order_id > 0)
{
$oShop_Order = Core_Entity::factory('Shop_Order')->find($order_id);
if (!is_null($oShop_Order->id))
{
$_POST['merchant_order_id'] = $order_id;
// Вызов обработчика платежной системы
Shop_Payment_System_Handler::factory($oShop_Order->Shop_Payment_System)
->shopOrder($oShop_Order)
->paymentProcessing();
}
}
// Обработка запросов от AvisoSMS
// ------------------------------------------------
$order_id = 0;
if (isset($_POST['merchant_order_id']))
{
$order_id = (int)$_POST['merchant_order_id'];
}
elseif (isset($_GET['aviso']))
{
$aviso = file_get_contents("php://input");
if ($aviso != '')
{
$aviso = @json_decode($aviso, true);
if (isset($aviso['merchant_order_id']))
{
$order_id = intval($aviso['merchant_order_id']);
}
}
}
if ($order_id > 0)
{
$oShop_Order = Core_Entity::factory('Shop_Order')->find($order_id);
if (!is_null($oShop_Order->id))
{
$_POST['merchant_order_id'] = $order_id;
// Вызов обработчика платежной системы
Shop_Payment_System_Handler::factory($oShop_Order->Shop_Payment_System)
->shopOrder($oShop_Order)
->paymentProcessing();
}
}
3. Обработчик платежей, указывается в Панели AvisoSMS
http://<ваш_сайт>/shop/cart/?aviso=1
Авторизация