skew_death Posted September 23, 2020 Posted September 23, 2020 Всем привет, собственно кто может подсказать как на php допилить скрипт от bisys, а именно разделение строки в методом POST? Изначально в скрипте от bisys идет такой код(прием xml и дальнейшее разделение), а в сбере идет изначально формат script.php?ACTION=check&ACCOUNT=000. function get_tag_content($string, $tagname) { $pattern = "|<".$tagname.">(.+)</".$tagname."|si"; preg_match($pattern, $string, $matches); return $matches[1]; } Вставить ник Quote
Кошачии ловец Posted September 23, 2020 Posted September 23, 2020 Можете выложить полностью скрипт. И объяснить: какой биллинг; вы принимаете платежи через сбербанк или бисус? Вставить ник Quote
skew_death Posted September 23, 2020 Author Posted September 23, 2020 Биллинг самописный. Принимаем в данным момент через бисис, надо сделать через сбер, в бисис формируется xml запрос, в сбере через GET(POST) и с этим небольшая проблема. <?php /* Скрипт для обработки запросов Протокола оператора Версии 3.5. Редакции 5. 19.01.2012 Версия скрипта 11 ООО "Биллинговые системы" http://bisys.ru/ */ $agent_id = 1; // Идентификатор агента в базе платежей $password = "test1234"; // Пароль для генерации подписи запросов $allowed_ips = "127.0.0.1"; // Список разрешенных адресов для запросов, перечисляются через запятую $check_sign = TRUE; // Проверять ли подпись // Параметры подключения к БД $db_host = "localhost"; $db_user = "test"; $db_password = "test"; $db_name = "bd"; $in_data = ""; // Входные данные запроса $out_data = ""; // Выходные данные запроса $err_code_g = ""; // Код ошибки $err_text_g = ""; // Текст ошибки $query_sign = ""; // Подпись запроса // Извлечение тега из строки function get_tag_content($string, $tagname) { $pattern = "|<".$tagname.">(.+)</".$tagname."|si"; preg_match($pattern, $string, $matches); return $matches[1]; } // Формирование тега вида <tagname>value</tagname> // Если $newline истинно, то в начало добавляется переход на новую строку function tag_format($tagname, $value, $newline = TRUE) { if ($newline) return "\n<".$tagname.">".$value."</".$tagname.">"; else return "<".$tagname.">".$value."</".$tagname.">"; } // Генерация ответа сервера на запрос function response( $err_code, // Код ошибки $err_text, // Текст ошибки $params = "", // Параметры $signed = TRUE // Подписывать ли ответ ) { // Записывам выходные данные в глобальные переменные, для дальнейшего сохранения их в логах global $out_data; global $err_code_g; global $err_text_g; global $password; $err_code_g = $err_code; $err_text_g = $err_text; global $query_sign; if ($params == "") $params = tag_format("err_code", $err_code, FALSE).tag_format("err_text", $err_text); else $params = tag_format("err_code", $err_code, FALSE).tag_format("err_text", $err_text).$params; if ($signed == TRUE) $sign = tag_format("sign", strtoupper(md5($params.$query_sign.$password))); else $sign = ""; $out_data = "<?xml version=\"1.0\" encoding=\"utf8\"?><response><params>".$params."</params>".$sign."</response>"; echo $out_data; // Выводим ответ } // Проверка параметров платежа function check_payment( $account, // Счет $pay_amount, // Сумма $params, // Параметры &$balance, // Баланс &$login ) { // Проверить существование указанного номера $sql_result = mysql_query("SELECT * FROM accounts WHERE `account` = '".$account."' AND status = 1"); if (!$sql_result) return 90; $row = mysql_fetch_assoc($sql_result); $account_id = (int)$row['uid']; if ($account_id == 0) return 20; // Проверить $pay_amount и другие параметры при необоходимости if ($pay_amount == 0) $pay_amount = 10000; if (!(($pay_amount >= 100) and ($pay_amount <= 1500000))) return 29; // Вернуть баланс, если возможно $balance = $row['balance']; $login = $row['login']; return 0; } // Проведение платежа function do_payment( $account, // Счет $pay_amount, // Сумма $pay_id, // Уникальный номер платежа $pay_date, // Дата платежа $params, // Параметры &$account_id // ID счета в базе ) { // Проверить существование указанного номера $sql_result = mysql_query("SELECT * FROM users WHERE id = ".$account." "); if (!$sql_result) return 90; $row = mysql_fetch_assoc($sql_result); $account_id = (int)$row['id']; if ($account_id == 0) return 20; if (!(($pay_amount >= 100) and ($pay_amount <= 1500000))) return 29; $client_id = $row['id']; // Провести платеж, вернуть 0 в случае успеха, 90 в случае ошибки // [!] Здесь необходимо вставить свой код пополнения баланса указанного счета //add to users.deposit $ndeposit = $row['balance'] + ($pay_amount * 10000 ); mysql_query('UPDATE `users` SET `balance` = '.(int)$ndeposit.' WHERE `id` = '.(int)$account); $source = 'Sberbank Billing System'; $source_id = 2; $serv_code = (int)get_tag_content($params, "serv_code"); if ($serv_code == 2){ $source = 'Sberbank Billing System'; $source_id = 2; } elseif ($serv_code == 3){ $source = 'Site Billing System'; $source_id = 3; } mysql_query("INSERT INTO `log` (`date`, `payer`, `type`, `user`, `before`, `payment`) VALUES ('".date("Y-m-d H:i:s")."', '".$source."', ".$source_id.", '".$row['login']."', ".$row['balance'].", ".($pay_amount/100).")"); return 0; } // Проверка разрешенных IP для доступа $ips = explode(",",$allowed_ips); if (array_search($_SERVER["REMOTE_ADDR"],$ips) === FALSE) { response(10, "Запрос выполнен с неразрешенного адреса", "", FALSE); exit; }; if (!isset($_POST['params'])) { response(11, "Указаны не все необходимые параметры", "", FALSE); exit; } $query = $_POST['params']; $in_data = $query; $params = get_tag_content($query, "params"); $query_sign = get_tag_content($query, "sign"); $sign = md5($params.$password); // Проверка подписи if ($check_sign and (($query_sign == "") or (strtoupper($sign) <> strtoupper($query_sign)))) { response(13, "Неверная цифровая подпись", "", FALSE); exit; } $act = (int)get_tag_content($params, "act"); if (($act == "") or ($act == 0)) { response(11, "Указаны не все необходимые параметры", ""); exit; } // Проверка доступа к базе $link = mysql_connect($db_host,$db_user,$db_password); if (!$link) { response(90, "Временная техническая ошибка [1]"); exit; } $db_selected = mysql_select_db($db_name); if (!$db_selected) { response(90, "Временная техническая ошибка [2]"); exit; } mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET 'utf8'"); switch ($act) { // Проверка параметров платежа case 1: $account = mysql_escape_string(get_tag_content($params, "account")); if ($account <> "") { $pay_amount = (int)get_tag_content($params, "pay_amount"); $result = check_payment($account, $pay_amount, $params, $balance, $login); switch ($result) { case 0: $params = tag_format("account",$account, FALSE); if ($balance <> "") $params = $params.tag_format("balance", number_format($balance/100, 2, '.', '')); $params .= $params.tag_format("client_name", $login); response(0, "OK", $params); break; case 20: response(20, "Указанный номер счета отсутствует"); break; case 21: response(21, "Запрещены платежи на указанный номер счета"); break; case 22: response(22, "Запрещены платежи для указанной услуги"); break; case 23: response(23, "Запрещены платежи для указанного агента"); break; case 29: response(29, "Неверная сумма платежа"); break; case 90: response(90, "Временная техническая ошибка"); break; default: response(99, "Неизвестный ответ функции проверки параметров платежа"); } } else response(11, "Указаны не все необходимые параметры"); break; // Проведение платежа case 2: $account = mysql_escape_string(get_tag_content($params, "account")); if ($account <> "") { $pay_amount = (int)get_tag_content($params, "pay_amount"); $pay_id = mysql_escape_string(get_tag_content($params, "pay_id")); $pay_date = get_tag_content($params, "pay_date"); $agent_date = get_tag_content($params, "agent_date"); if ($pay_id == "") { response(11, "Указаны не все необходимые параметры"); exit; } $sql_result = mysql_query(" SELECT a_payments.*, users.id FROM a_payments, users WHERE a_payments.account_id = users.id AND agent_id = ".$agent_id." AND pay_num = '".$pay_id."'"); if (!$sql_result) { response(90, "Временная техническая ошибка"); exit; } $row = mysql_fetch_assoc($sql_result); $reg_id = (int)$row['payment_id']; // Проверка на дублирование if ($reg_id <> 0) { $pay_amount_db = $row['amount']; $account_db = $row['account_id']; $reg_id = $row['payment_id']; $reg_date = $row['reg_date']; $params = tag_format("account",$account, FALSE); if ($account == $account_db) { if ($pay_amount != $pay_amount_db) { //$params = $params.tag_format("reg_id",$reg_id).tag_format("reg_date", date("Y-m-d H:i:s",strtotime($reg_date))); response(30, "Был другой платеж другой суммы с указанным номером", $params); } else { //$params = $params.tag_format("reg_id",$reg_id).tag_format("reg_date", date("Y-m-d H:i:s",strtotime($reg_date))); $params .= tag_format("reg_date",$reg_date, FALSE); $params .= tag_format("reg_id",$reg_id, FALSE); response(1, "Платеж уже был проведен", $params); } } else { $params .= tag_format("reg_date",$reg_date, FALSE); $params .= tag_format("reg_id",$reg_id, FALSE); response(1, "Был другой платеж с указанным номером", $params); } } else { $result = do_payment($account, $pay_amount, $pay_id, $pay_date, $params, $account_id); switch ($result) { case 0: $params = tag_format("account",$account, FALSE); mysql_query("INSERT INTO S_payments (agent_id, pay_num, account_id, amount, pay_date, reg_date, agent_date) VALUES ('".$agent_id."', '".$pay_id."', '".$account_id."', ".$pay_amount.", '".$pay_date."', NOW(), '".$agent_date."' ) "); $reg_id = mysql_insert_id(); $sql_result = mysql_query("SELECT * FROM s_payments WHERE payment_id = ".$reg_id); if ((!$sql_result) or ($reg_id == 0)) { // Ошибка при добавлении платежа в базу // Возвращать техническую ошибку только в случе, если пополнение происходит вне функции do_payment // response(90, "Временная техническая ошибка [3]"); } else { $row = mysql_fetch_assoc($sql_result); $reg_date = $row['reg_date']; $params = $params.tag_format("reg_id",$reg_id).tag_format("reg_date", date("Y-m-d H:i:s",strtotime($reg_date))); } response(0, "OK", $params); break; case 20: response(20, "Указанный номер счета отсутствует"); break; case 21: response(21, "Запрещены платежи на указанный номер счета"); break; case 22: response(22, "Запрещены платежи для указанной услуги"); break; case 23: response(23, "Запрещены платежи для указанного агента"); break; case 29: response(29, "Неверная сумма платежа"); break; case 90: response(90, "Временная техническая ошибка"); break; default: response(99, "Неизвестный ответ функции отправки платежа"); } } } else response(11, "Указаны не все необходимые параметры"); break; default: response(12, "Неверный формат параметров"); } ?> @ixi Гуглил $_POST, вешается с ошибкой 500, или выдает пустой массив данных. К примеру: $query = $_POST; $in_data = $query; if ($act == $_POST['check']) { $act = 1; }; if ($act == $_POST['payment']) { $act = 2; }; switch ($act) { // Проверка параметров платежа case 1: $account = mysql_escape_string($_POST['ACCOUNT']); if ($account <> "") { $pay_amount = $_POST['amount']); $result = check_payment($account, $pay_amount, $balance, $login); switch ($result) { case 0: $params = tag_format("account",$account, FALSE); if ($balance <> "") $params = $params.tag_format("balance", number_format($balance/100, 2, '.', '')); $params .= $params.tag_format("client_name", $login); response(0, "OK", $params); break; case 20: response(20, "Указанный номер счета отсутствует"); break; case 21: response(21, "Запрещены платежи на указанный номер счета"); break; case 22: response(22, "Запрещены платежи для указанной услуги"); break; case 23: response(23, "Запрещены платежи для указанного агента"); break; case 29: response(29, "Неверная сумма платежа"); break; case 90: response(90, "Временная техническая ошибка"); break; default: response(99, "Неизвестный ответ функции проверки параметров платежа"); } } else response(11, "Указаны не все необходимые параметры"); break; Вставить ник Quote
alibek Posted September 23, 2020 Posted September 23, 2020 Фрагменты из обработчика протокола Сбербанка. Обработка входящего запроса (в функцию передается $_GET): public function parse($request, $options=null) { if (!isset($request)) return false; $params = array(); foreach ($request as $index=>$node) { if (in_array($index, array('command', 'account', 'txn_id', 'txn_date', 'sum'))) { $params[$index] = $node; } } if (empty($params)) { $this->response(300, 'Некорректный запрос.'); return; } $this->params = $params; $cfg = _cfg('agents', true); $min = _get($cfg['_system_'], 'min'); $max = _get($cfg['_system_'], 'max'); $type = _get($cfg['_system_'], 'types'); $cfg = _get($cfg, $this->class); if (isset($cfg) && is_array($cfg)) { $cfg['type'] = _nvl(_get($cfg, 'types'), $type); $cfg['min'] = _nvl(_get($cfg, 'min'), $min); $cfg['max'] = _nvl(_get($cfg, 'max'), $max); $ips = _get($cfg, 'ip'); } if (isset($min)) settype($min, 'int'); if (isset($max)) settype($max, 'int'); $this->config = $cfg; $ip = _get($_SERVER, 'REMOTE_ADDR'); if (empty($ip) || (ip_check($ip, $ips)===false)) { $this->response(300, 'Доступ с неразрешенного IP-адреса'); return; } if ($this->disabled == true) { $this->response(300, 'Платежный агент отключен, запрос отклонен.'); return; } if ($this->process()===true) return true; } Обработка запроса: public function process() { $config = $this->config; $params = $this->params; if (!array_key_exists('command', $params)) { $this->response(300, 'Не указан тип запроса'); return; } $types = array('check'=>'verify', 'pay'=>'payment'); $type = null; if (isset($params) && $params['command'] && in_array($params['command'], array_keys($types))) $type = $types[$params['command']]; if (!isset($type)) { $this->response(300, 'Неизвестный тип запроса'); return; } if (!array_key_exists('account', $params)) { $this->response(4, 'Не указан лицевой счет'); return; } $account = $params['account']; $amount = _get($params, 'sum'); if (isset($amount)) $amount = 0+$amount; list($pay_id, $pay_date) = array(_get($params,'txn_id'), _get($params,'txn_date')); // далее частная реализация Формирование ответа: private function response($code, $text=null, $payment=null, $idRemote=null, $idLocal=null) { if (isset($filter) && !is_array($filter)) $filter = array($filter); $div = "\n"; $xml = ""; if (isset($idRemote)) $xml .= $div . "<osmp_txn_id>" . htmlentities($idRemote, ENT_COMPAT|ENT_XML1) . "</osmp_txn_id>"; if (isset($idLocal)) $xml .= $div . "<prv_txn>" . htmlentities($idLocal, ENT_COMPAT|ENT_XML1) . "</prv_txn>"; if (isset($payment) && is_a($payment, 'Payment')) { if (isset($payment->reqAmount)) $xml .= $div . "<sum>" . htmlentities(number_format($payment->reqAmount, 2, '.', ''), ENT_COMPAT|ENT_XML1) . "</sum>"; } if (isset($code)) $xml .= $div . "<result>" . htmlentities($code, ENT_COMPAT|ENT_XML1) . "</result>"; if (isset($text)) $xml .= $div . "<comment>" . htmlentities($text, ENT_COMPAT|ENT_XML1) . "</comment>"; $xml = '<?xml version="1.0" encoding="UTF-8"?>' . $div . "<response>{$xml}{$div}</response>{$div}"; header('Content-Type: text/xml; charset=utf-8'); print $xml; if (isset($payment) && is_a($payment, 'Payment')) { $payment->retClock = $this->dateString(); $payment->retSuccess = (isset($code) && $code == 0 ? 1 : null); $payment->retCode = $code; $payment->retText = $text; $payment->save(); } } Вставить ник Quote
skew_death Posted September 23, 2020 Author Posted September 23, 2020 @alibek Спасибо. Вставить ник Quote
Кошачии ловец Posted September 23, 2020 Posted September 23, 2020 (edited) С кусками твоего кода, на ошибки не проверял. Должно работать сходу. if ($_GET['action']=='check') { echo '<?xml version="1.0" encoding="UTF-8"?>'; echo '<response>'; echo '<result>0</result>'; echo '</response>'; } if ($_GET['action']=='payment') { $sql_result = mysql_query("SELECT * FROM users WHERE id = ".$account." "); $row = mysql_fetch_assoc($sql_result); $account_id = (int)$row['id']; $client_id = $row['id']; $pay_amount = $_GET['amount']; $ndeposit = $row['balance'] + ($pay_amount * 10000 ); mysql_query('UPDATE `users` SET `balance` = '.(int)$ndeposit.' WHERE `id` = '.(int)$account); $source = 'Sberbank Billing System'; $source_id = 2; $serv_code = 2; $source = 'Sberbank Billing System'; mysql_query("INSERT INTO `log` (`date`, `payer`, `type`, `user`, `before`, `payment`) VALUES ('".date("Y-m-d H:i:s")."', '".$source."', ".$source_id.", '".$row['login']."', ".$row['balance'].", ".($pay_amount/100).")"); echo '<?xml version="1.0" encoding="UTF-8"?>'; echo '<response>'; echo '<result>0</result>'; echo '</response>'; } обновил Edited September 23, 2020 by Кошачии ловец Вставить ник Quote
skew_death Posted September 23, 2020 Author Posted September 23, 2020 @Кошачии ловец Спасибо, тоже попробую ваш вариант. Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.