Файл: monst/ok.php
Строк: 184
<?php
//error_reporting(-1);
//ini_set('display_errors', 1);
$HOME = $_SERVER['DOCUMENT_ROOT'];
include $HOME . '/core/in/fnct.php';
include $HOME . '/core/in/db.php';
/*
* Класс отвечает за следующие операции:
* проверка корректности платежа, сохранение информации о платеже,
* ответ на запрос сервера одноклассников.
*/
class Payment {
const ERROR_TYPE_UNKNOWN = 1;
const ERROR_TYPE_SERVISE = 2;
const ERROR_TYPE_CALLBACK_INVALID_PYMENT = 3;
const ERROR_TYPE_SYSTEM = 9999;
const ERROR_TYPE_PARAM_SIGNATURE = 104;
// в эти переменные следует записать открытый и секретный ключи приложения
const APP_PUBLIC_KEY = "CBAJCCAMEBABABABA";
const APP_SECRET_KEY = "D13B0D81BD6FC99F9DD7E02C";
// массив пар код продукта => цена
private static $catalog = array(
"1" => 1,
"10" => 10,
"100" => 100,
"200" => 200,
"500" => 500,
"1000" => 1000,
);
// массив пар код ошибки => описание
private static $errors = array(
1 => "UNKNOWN: please, try again later. If error repeats, contact application support team.",
2 => "SERVICE: service temporary unavailible. Please try again later",
3 => "CALLBACK_INVALID_PAYMENT: invalid payment data. Please try again later. If error repeats, contact application support team. ",
9999 => "SYSTEM: critical system error. Please contact application support team.",
104 => "PARAM_SIGNATURE: invalid signature. Please contact application support team."
);
// функция рассчитывает подпись для пришедшего запроса
// подробнее про алгоритм расчета подписи можно посмотреть в документации (http://apiok.ru/wiki/pages/viewpage.action?pageId=42476522)
public static function calcSignature($request){
$tmp = $request;
unset($tmp["sig"]);
ksort($tmp);
$resstr = "";
foreach($tmp as $key=>$value){
$resstr = $resstr.$key."=".$value;
}
$resstr = $resstr.self::APP_SECRET_KEY;
return md5($resstr);
}
// функция провкерки корректности платежа
public static function checkPayment($productCode, $price){
if (array_key_exists($productCode, self::$catalog) && (self::$catalog[$productCode] == $price)) {
return true;
} else {
return false;
}
}
// функция возвращает ответ на сервер одноклассников
// о корректном платеже
public static function returnPaymentOK(){
$rootElement = 'callbacks_payment_response';
$dom = self::createXMLWithRoot($rootElement);
$root = $dom->getElementsByTagName($rootElement)->item(0);
// добавление текста "true" в тег <callbacks_payment_response>
$root->appendChild($dom->createTextNode('true'));
// генерация xml
$dom->formatOutput = true;
$rezString = $dom->saveXML();
// установка заголовка
header('Content-Type: application/xml');
// вывод xml
print $rezString;
}
// функция возвращает ответ на сервер одноклассников
// об ошибочном платеже и информацию лб ошибке
public static function returnPaymentError($errorCode){
$rootElement = 'ns2:error_response';
$dom = self::createXMLWithRoot($rootElement);
$root = $dom->getElementsByTagName($rootElement)->item(0);
// добавление кода ошибки и описания ошибки
$el = $dom->createElement('error_code');
$el->appendChild($dom->createTextNode($errorCode));
$root->appendChild($el);
if (array_key_exists($errorCode, self::$errors)){
$el = $dom->createElement('error_msg');
$el->appendChild($dom->createTextNode(self::$errors[$errorCode]));
$root->appendChild($el);
}
// генерация xml
$dom->formatOutput = true;
$rezString = $dom->saveXML();
// добавление необходимых заголовков
header('Content-Type: application/xml');
// ВАЖНО: если не добавить этот заголовок, система может некорректно обработать ответ
header('invocation-error:'.$errorCode);
// вывод xml
print $rezString;
}
// Рекомендуется хранить информацию обо всех транзакциях
public static function saveTransaction(/* any params you need*/){
// тут может быть код для сохранения информации о транзакции
// 2:/ok.php?transaction_id=482672427776&sig=39b420f85bbd401a6725c7a5c6fbfea3&uid=576028221573&amount=1&method=callbacks.payment&transaction_time=2017-11-17+16%3A23%3A21&product_code=170&product_option=&application_key=CBAJCCAMEBABABABA&call_id=1510925002015
global $HOME, $_users, $_payment, $_not;
$uid = $_GET['uid'];
$amount = $_GET['amount'];
$product_code = $_GET['product_code'];
$transaction_id = $_GET['transaction_id'];
$codes = [1, 10, 100, 200, 500, 1000];
if ( !in_array($product_code, $codes) ) {
exit;
}
$find = $_users -> findOne(
[
'ok_id' => $uid
]
);
if ( !$find ) {
exit;
}
if ( $find ) {
$gold = $amount * 10;
$gold = $gold * 2;
$_users -> update(
[
'id' => $find['id']
],
[
'$set' => [
'gold' => $find['gold'] + $gold
]
]
);
$payment_id = new_id('_payment');
$_payment -> insert(
[
'id'=> $payment_id,
'time' => time(),
'user_id' => $find['id'],
'ok_payment' => 1,
'transaction_id' => $transaction_id,
'gold' => $gold,
'ok' => $product_code,
]
);
// not
$not_text = '+' . $gold . ' золота.<br/>Одноклассники';
$not_id = new_id('_not');
$_not -> insert(
[
'id' => $not_id,
'user_id' => $find['id'],
'time' => time(),
'text' => $not_text
]
);
// quest
include $HOME . '/core/content/daily.php';
$daily_db = $find['daily'];
$daily = $DAILY;
foreach ( $daily as $q ) {
$daily[$q['id']]['count'] = $daily_db[$q['id']]['count'];
$daily[$q['id']]['end'] = $daily_db[$q['id']]['end'];
}
foreach ( $daily as $q ) {
if ( $q['type'] == 'buy_gold' ) {
$daily_db[$q['id']]['count'] += $gold;
$_users -> update(
[
'id' => $find['id']
],
[
'$set' => [
'daily' => $daily_db
]
]
);
}
}
}
}
// функция создает объект DomDocument и добавляет в него в качестве корневого тега $root
private static function createXMLWithRoot($root){
// создание xml документа
$dom = new DomDocument('1.0');
// добавление корневого тега
$root = $dom->appendChild($dom->createElement($root));
$attr = $dom->createAttribute("xmlns:ns2");
$attr->value = "http://api.forticom.com/1.0/";
$root->appendChild($attr);
return $dom;
}
}
/*
* Обработка платежа начинается отсюда
*/
if (array_key_exists("product_code", $_GET) && array_key_exists("amount", $_GET) && array_key_exists("sig", $_GET)){
if (Payment::checkPayment($_GET["product_code"], $_GET["amount"])){
if ($_GET["sig"] == Payment::calcSignature($_GET)){
Payment::saveTransaction();
Payment::returnPaymentOK();
} else {
// здесь можно что-нибудь сделать, если подпись неверная
Payment::returnPaymentError(Payment::ERROR_TYPE_PARAM_SIGNATURE);
}
} else {
// здесь можно что-нибудь сделать, если информация о покупке некорректна
Payment::returnPaymentError(Payment::ERROR_TYPE_CALLBACK_INVALID_PYMENT);
}
} else {
// здесь можно что-нибудь сделать, если информация о покупке или подпись отсутствуют в запросе
Payment::returnPaymentError(Payment::ERROR_TYPE_CALLBACK_INVALID_PYMENT);
}
?>