Пример автоматической организации платного доступа к закрытым разделам сайта

!!! версия под API 2.0 (последняя) доступна здесь:
https://onpaysolutions.ru/pages/onpay_class.html
Под закрытым разделом сайта подразумевается часть страницы, доступная только после ввода специального пароля. На ней можно размещать любую информацию, включая html и php скрипты, видео, секретные ссылки на файлы с паролем в своем названиии (например, book34dFs.zip).
Для того, чтобы закрыть доступ к директории /dir/, достаточно разместить в ней индексный файл (index.php), тогда все переходы по адресу http://domen.ru/dir/ будут вызывать скрипт index.php. В котором размещается скрипт проверки пароля, не показывающий информаци до ввода пароля доступа.
/dir/index.php

PHP-код скрипта, генерирующего секретный код и проверящего его оплату через систему Onpay

<?php
/* В настройках кабинета необходимо указать "Проверять md5 на ссылках",
чтобы нельзя было заплатить сумму отличную от заданной в переменной $summa */
$summa=50; //Стоимость доступа к платному разделу, в рублях
$period=60*60*24*2; //Время доступа, в секундах (60 секунд * 60 минут * 24 часа * 2 суток = 172800 секунд). Исчисляется от времени поступления оплаты за код доступа.
$login='demo1'; //Ваше "Имя пользователя" (логин) в системе Onpay.ru
$key='a2su3ig8y'; //Ваш "Секретный пароль для API IN" в системе Onpay.ru
/* Для того, чтобы закрыть доступ к папке, данный код необходимо размещать в индексном файле (index.php) */
$path='http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; //Путь к файлу с этим кодом (определяется автоматически), например: http://onpay.ru/dir/index.php
$access=0; //Запрещаем доступ, по умолчанию (0 = доступ закрыт, 1 = доступ открыт)
$code='';
$error='';
//Функция округления для md5
function to_float($sum) {
if (strpos($sum, ".")) {$sum=round($sum,2);}
else {$sum=$sum.".0";}
return $sum;
}
/* Подключаемся к базе данных, если нажали на кнопку оплатить или ввели код доступа */
if(isset($_POST['pay']) || isset($_POST['code'])) {
$db_host='localhost'; //Хост сервера базы данных (домен или IP-адрес)
$db_user='root'; //Имя пользователя БД
$db_pass=''; //Пароль БД
$db_name='pays'; //Название базы данных
$db_tabl='payments'; //Название таблицы в которой будут храниться платежи
if(!mysql_connect($db_host, $db_user, $db_pass)) {echo 'Невозможно подключиться к серверу баз данных';exit;} //Подключение к серверу баз данных
if(!mysql_select_db($db_name)) {echo 'Не получилось выбрать базу данных '.$db_name;exit;} //Выбор базы данных
}
/* Разбираем данные, отправленные через форму*/
if(isset($_POST['pay'])) { //Если нажали на кнопку покупки кода, то генерируем код, сохраняем его в базу данных и выводим форму оплаты:
if(is_numeric($summa)) { //Если сумма введена корректно
$sql = "INSERT INTO $db_tabl SET ".
"path='$path',".
"sum='$summa',".
"payed=0,".
"date=".time().",".
"ip='".$_SERVER['REMOTE_ADDR']."';"; //Запрос в базу данных на создание новой записи
$result=mysql_query($sql); //Добавляем новую строку в базу данных
if($result) { //Если сохранено в базу данных без ошибок
$id=mysql_insert_id(); //Получаем id записи
$code=$id.substr(time(),-7); //Создаем секретный код - соединяем уникальный номер строки в базе данных (id) и последние 7 знаков текущего времени в секундах (коды доступа не должны повторяться)
$sql = "UPDATE $db_tabl SET code='$code' WHERE id='$id';"; //Запрос в базу данных, для добавления кода доступа
$result=mysql_query($sql); //Сохраняем код в базу данных
if($result) { //Если сохранено в базу данных без ошибок
$sum_for_md5=to_float($summa);
$md5check=md5("fix;$sum_for_md5;RUR;$code;yes;$key"); //Создаем проверочную строку, которая защищает платежную ссылку от изменений
$url="http://secure.onpay.ru/pay/$login?pay_mode=fix&pay_for=$code&price=$summa&currency=RUR&convert=yes&md5=$md5check&url_success=".$path; //Формируем платежную ссылку
/*Выводим код*/
?><p style="font-size:14pt;color:blue;">Ваш код доступа: <b><?=$code; //Выводим код ?></b> (сохраните его в надежном месте)<?php
/*Выводим форму оплаты*/
?><h1><a target="_blank" href="<?=$url; //Выводим платежную ссылку ?>">Оплатить код доступа:</a></h1>
<iframe src="<?=$url; //Выводим платежную ссылку ?>" width="195" height="600" frameborder=no scrolling=no></iframe><?php
} else unset($_POST['pay']); //Удаляем элемент массива (чтобы выводилась кнопка покупки кода)
} else unset($_POST['pay']);
} else unset($_POST['pay']); //Конец условия if(is_numeric($summa)) { //Если сумма введена корректно
} elseif(isset($_POST['code'])) { //Если ввели код, то проверяем его в базе данных и если верный, то сохраняем в COOKIE
$code=intval($_POST['code']); //Код должен быть целым числом
$sql = "SELECT * FROM $db_tabl WHERE code='$code' AND path='$path' AND payed>=sum AND date>=".time().";"; //Проверка кода
$result=mysql_query($sql); //Сохраняем код в базу данных
if($result) { //Если сохранено в базу данных без ошибок
if($row=mysql_fetch_assoc($result)) { //Если в базе данных найдена строка с введенным кодом для данной директории и он не просрочен, то сохраняем код
$access=1; //Разрешаем доступ
} else $error='Введен неправильный код доступа.';
}
} //
if($access == 0) { //Если доступ запрещен, то выводим форму для покупки или ввода оплаченного кода
?><p style="font-size:14pt;font-weight:bold;">Доступ закрыт.<?php
?><p style="font-size:14pt;font-weight:bold;color:red;"><?=$error; //Выводим ошибки?><?php
if(!isset($_POST['pay'])) { //Если не выведена форма оплаты
?><form method="POST" action="<?=$path; //Выводим путь на который будет отправлена форма (на текущую страницу) ?>">
<input style="font-size:16pt;font-weight:bold;color:red;" type="submit" name="pay" value="Купить доступ до <?=date('H:i:s d.m.Y',time()+$period); //Выводим дату ?> всего за <?=$summa; //Выводим сумму ?>&nbsp;руб.">
</form><?php
}
?><p><form method="POST" action="<?=$path; //Выводим путь на который будет отправлена форма (на текущую страницу) ?>">
<input style="font-size:14pt;" type="text" name="code" value="<?=$code; //Выводим текущий код доступа, при его наличии ?>">
<input style="font-size:14pt;" type="submit" value="Ввести оплаченный код доступа">
</form><?php
exit; //Прекращаем выполнение скрипта и выходим
/*Все, что расположено ниже этой строки - не выводится без верного кода доступа. */
} //Конец условия if($access == 0) { if(isset($_POST['pay'])) {
?>
<h1>Доступ по коду <u><?=$row['code'];?></u> разрешен до <?=date('H:i:s d.m.Y',$row['date']);?></h1>
<p>Получено: <?=$row['payed'];?>&nbsp;руб.
<p>Цена продления: <?=$row['sum'];?>&nbsp;руб.
<p>onpay_id: <?=$row['onpay_id'];?>
<p><a href=" <?=$row['path'];?>">Секретная ссылка</a>

Условия доступа:
Если код доступа совпадает, текущий адрес странцы совпадает с указанным в базе данных, сумма платежа больше или равна минимальной и текущее время меньше или равно сроку годности, то доступ будет разрешен.
Во всех остальных случаях - запрещен.

SQL-код

Для создания таблицы в базе данных:

create table payments
(
id int(11) unsigned auto_increment not null,
code bigint(16) unsigned,
path char(255),
sum float(7,2),
payed float(7,2),
onpay_id int(8) unsigned,
date int(8) unsigned,
ip char(255),
primary key (id)
);

Описание полей таблицы:
id - уникальный номер строки, создается базой данных автоматически
code - секретный код доступа, составляется из уникального номера строки (id) и 7 последних цифр текущего времени в секундах
path - полный путь до страницы, к которой предоставляется доступ
sum - минимальная сумма платежа за доступ к странице
payed - сумма платежа (равна или больше sum)
onpay_id - номер платежа в системе Onpay.ru
date - срок годности кода (до какой даты), в секундах (Unix Time Format)
ip - IP-адрес пользователя, создавшего код платежа
/api.php

URL API IN для оповещений от Onpay о пришедших платежах

<?php
$period=60*60*24*2; //Время доступа, в секундах (60 секунд * 60 минут * 24 часа * 2 суток = 172800 секунд). Исчисляется от времени поступления оплаты за код доступа.
$login='demo1'; //Ваше "Имя пользователя" (логин) в системе Onpay.ru
$key='a2su3ig8y'; //Ваш "Секретный пароль для API IN" в системе Onpay.ru
$db_host='localhost'; //Хост сервера базы данных (домен или IP-адрес)
$db_user='root'; //Имя пользователя БД
$db_pass=''; //Пароль БД
$db_name='pays'; //Название базы данных
$db_tabl='payments'; //Название таблицы в которой будут храниться платежи
if(!mysql_connect($db_host, $db_user, $db_pass)) {echo 'Невозможно подключиться к серверу баз данных';exit;} //Подключение к серверу баз данных
if(!mysql_select_db($db_name)) {echo 'Не получилось выбрать базу данных '.$db_name;exit;} //Выбор базы данных
if($_REQUEST['type']=='check') { //Ответ на запрос check от Onpay (проверка наличия кода в базе данных)
$error=0;
$order_amount=$_REQUEST['order_amount'];
$order_currency=$_REQUEST['order_currency'];
$code=$pay_for=$_REQUEST['pay_for'];
$md5=$_REQUEST['md5'];
$sum=floatval($order_amount);
$code=intval($code); //Код должен быть целым числом
$sql = "SELECT * FROM $db_tabl WHERE code='$code';"; //Проверка кода и переводимой за него суммы
$result=mysql_query($sql); //Сохраняем код в базу данных
if($result) { //Если сохранено в базу данных без ошибок
if(mysql_num_rows($result)) { //Если в базе данных найдена строка с введенным кодом для данной директории и он не просрочен, то отвечаем ОК
$rezult=answer($_REQUEST['type'],0,$pay_for,$order_amount,$order_currency,'OK'); //Отвечаем серверу Onpay, что все хорошо, можно принимать деньги
} else $error=1;
} else $error=1;
if($error==1)
$rezult=answer($_REQUEST['type'],2,$pay_for,$order_amount,$order_currency,'Error code pay_for: '.$code); //Сообщаем ошибку
}
if($_REQUEST['type']=="pay") { //Ответ на запрос pay от Onpay (прием оплаты за код)
$onpay_id=$_REQUEST['onpay_id'];
$code=$pay_for=$_REQUEST['pay_for'];
$order_amount=$_REQUEST['order_amount'];
$order_currency=$_REQUEST['order_currency'];
$balance_amount=$_REQUEST['balance_amount'];
$balance_currency=$_REQUEST['balance_currency'];
$exchange_rate=$_REQUEST['exchange_rate'];
$paymentDateTime=$_REQUEST['paymentDateTime'];
$md5=$_REQUEST['md5'];
$error='';
//Проверка входных данных
if (empty($onpay_id)) {$error .="Не указан id<br>";}
else {if (!is_numeric(intval($onpay_id))) {$error .="Параметр не является числом<br>";}}
if (empty($order_amount)) {$error .="Не указана сумма<br>";}
else {if (!is_numeric($order_amount)) {$error .="Параметр не является числом<br>";}}
if (empty($balance_amount)) {$error .="Не указана сумма<br>";}
else {if (!is_numeric(intval($balance_amount))) {$error .="Параметр не является числом<br>";}}
if (empty($balance_currency)) {$error .="Не указана валюта<br>";}
else {if (strlen($balance_currency)>4) {$error .="Параметр слишком длинный<br>";}}
if (empty($order_currency)) {$error .="Не указана валюта<br>";}
else {if (strlen($order_currency)>4) {$error .="Параметр слишком длинный<br>";}}
if (empty($exchange_rate)) {$error .="Не указана сумма<br>";}
else {if (!is_numeric($exchange_rate)) {$error .="Параметр не является числом<br>";}}
if (!$error) { //Если нет ошибок
if(is_numeric($code)) {//Если pay_for - число
$code=intval($code); //Код должен быть целым числом
$sum=floatval($order_amount);
$rezult=mysql_query("SELECT * FROM $db_tabl WHERE code='$code'"); //Проверяем, что код есть в базе данных, и оплачиваема сумма не меньше допустимой
if(mysql_num_rows($rezult) == 1) {
//Создаем строку хэша с присланных данных
$md5fb=strtoupper(md5($_REQUEST['type'].";".$pay_for.";".$onpay_id.";".$order_amount.";".$order_currency.";".$key.""));
//Сверяем строчки хеша (присланную и созданную нами)
if ($md5fb != $md5) {$rezult=answerpay($_REQUEST['type'],7,$pay_for,$order_amount,$order_currency,'Md5 signature is wrong',$onpay_id);}
else {
$time=time();
$rezult1=mysql_query("UPDATE $db_tabl SET date='".(time()+$period)."',payed=payed+'$sum',onpay_id='$onpay_id' WHERE code='$code';"); //Добавляем сумму оплаты и устанавливаем срок действия кода доступа
if ($rezult1) {$rezult=answerpay($_REQUEST['type'],0,$pay_for,$order_amount,$order_currency,'OK',$onpay_id);} //Если занесение информации в базу данных прошло без ошибок,
else {$rezult=answerpay($_REQUEST['type'],3,$pay_for,$order_amount,$order_currency,'Error in mechant database queries: operation or balance tables error',$onpay_id);}
}
} else {$rezult=answerpay($_REQUEST['type'],3,$pay_for,$order_amount,$order_currency,'Cannot find any pay rows acording to this parameters: wrong payment',$onpay_id);}
} else {//Если pay_for - не правильный формат
$rezult=answerpay($_REQUEST['type'],3,$pay_for,$order_amount,$order_currency,'Error in parameters data',$onpay_id);
}
} else {//Если есть ошибки
$rezult=answerpay($_REQUEST['type'],3,$pay_for,$order_amount,$order_currency,'Error in parameters data',$onpay_id);
}
}
echo $rezult;
//Функция выдает ответ для сервиса Onpay в формате XML на чек запрос
function answer($type,$code,$pay_for,$order_amount,$order_currency,$text) {
global $key;
$md5=strtoupper(md5("$type;$pay_for;$order_amount;$order_currency;$code;$key"));
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<result>\n<code>$code</code>\n<pay_for>$pay_for</pay_for>\n<comment>$text</comment>\n<md5>$md5</md5>\n</result>";
}
//Функция выдает ответ для сервиса Onpay в формате XML на pay запрос
function answerpay($type,$code,$pay_for,$order_amount,$order_currency,$text,$onpay_id) {
global $key;
$md5=strtoupper(md5("$type;$pay_for;$onpay_id;$pay_for;$order_amount;$order_currency;$code;$key"));
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<result>\n<code>$code</code>\n <comment>$text</comment>\n<onpay_id>$onpay_id</onpay_id>\n <pay_for>$pay_for</pay_for>\n<order_id>$pay_for</order_id>\n<md5>$md5</md5>\n</result>";
}
?>