Php повторные Калбеки
Доброго времени суток Уважаемые форумчане!
Нужна Ваша помощь естественно не бесплатно, благодарность будет отправлена на карту или юсдт! Суть проблемы! Человек в игре пополняет счет на 300 руб, ему зачисляются они 5-10 раз , сколько сколько платёжная система будет оправлять уведомлений, те ему начисляют 10 раз по 300 а не 300. Нужно поправить скрипт чтоб не шли повторные зачисления по платежу! <?php include '../setup.php'; $rbConfig['api_key'] = 'e7ebd'; $rbConfig['project_id'] = 1000; $conf = mysql_query('select * from seting'); $con = mysql_fetch_array($conf); $hash = md5($_POST['project_id'] . $_POST['order_id'] . $_POST['payment_id'] . $_POST['amount'] . $_POST['currency'] . $_POST['status'] . $rbConfig['api_key']); if ($hash != $_POST['hash']) { die('wrong sign'); } else { $out_summ = $_POST['amount']; $bonus = 0; $cost = $out_summ; $order = explode('-', $_POST['order_id']); $out_summ += $bonus; $shpa = $order[1]; $pcash = $out_summ / 100 * $con['pcash']; mysql_query("update partner set cash=cash+'$pcash' where user='$shpa'"); $res = mysql_query("select * from partner where user='$shpa'"); $ro = mysql_fetch_array($res); mysql_query("update users set pcash=pcash+'$pcash' where login='$ro[0]'"); mysql_query("update users set cash=cash+'$out_summ' where login='$shpa'"); mysql_query("update users set cashin=cashin+'$out_summ' where login='$shpa'"); $date = date('d.m.y'); $time = date('H:i:s'); $sqls = "INSERT INTO stat_pay VALUES('$shpa','$date','$time','$out_summ','0.00')"; mysql_query($sqls); $con = mysql_fetch_array(mysql_query('select * from seting')); if ($con[paymail] == 'yes') { include '../mail/in.php'; $to = $con['adm_email']; $subject = $reg_reg_mail_subject; $msg = $reg_reg_mail; $mailheaders = "Content-Type: text/plain; charset=Windows-1251\n"; $mailheaders .= "From: $con[adm_email]\n"; mail($to, $subject, $msg, $mailheaders); } echo 'OK'; } |
Расширение mysql (и все функции mysql_* соответственно) было помечено устаревшим еще в php5.5 и с версии php7.0 было удалено.
Версия 5.5 перестала поддерживаться с 21 июля 2016 года. Вы используете какой-то очень не свежий софт. Далее по делу. Обычно платежные системы ожидают от вашего endpoint'а, который принимает хуки, определенных действий, в кач-ве подтверждения успешной обработки запроса, в противном случае "бомбят" уведомлениями еще определенное кол-во раз. Перво-наперво стоит определиться, что от вашего сервера ожидает платежная система, чтобы она не отправляла одни и те же уведомления по нескольку раз. Второе, но не менее важное: все транзакции лучше всего в хранить системе. У вас на таблицу transactions похожа таблица stat_pay, но ей не хватает колонки с номером (id) самой транзакции. Номер транзакции обычно также передается платежной системой в уведомлении. Если по какой-то причине у вас нет номера транзакции, то можно хранить подпись (hash) уведомления, однако в случае проблем подпись уведомления (или возможно самой транзакции) вряд ли поможет найти проблемный платеж. Благодаря табличке по списком обработанных транзакций, вы сможете проверить уведомление от платежной системы на "уникальность". Если в системе уже есть зарегистрированная транзакция с пришедшим из уведомления номером, то просто отправляем ответ "все хорошо" и не производим дальнейшую обработку уведомления. Вместе с текстом об ошибке стоит также отправлять и соответствующий status code. Вызов функции die выведет текст на страницу, но status code при этом будет "200 - ok". Код не проверял даже на наличие синтаксических ошибок: <?php include '../setup.php'; $OK_RESPONSE_STATUS_CODE = 200; $OK_RESPONSE_MESSAGE = 'OK'; $rbConfig['api_key'] = 'e7ebd'; $rbConfig['project_id'] = 1000;// unused value $con = mysql_fetch_array( mysql_query('select * from seting') ); $hash = md5( $_POST['project_id'] . $_POST['order_id'] . $_POST['payment_id'] . $_POST['amount'] . $_POST['currency'] . $_POST['status'] . $rbConfig['api_key'] ); if ($hash !== $_POST['hash']) { http_response_code(400); echo 'Incorrect signature'; exit; } if (empty($_POST['payment_id'])) { http_response_code(400); echo 'Missing [payment_id] field'; exit; } // Предполагается, что транзакции хранятся в табличке `stat_pay` в колонке `payment_id`, // а номер транзакции передается в поле 'payment_id' $paymentId = mysql_real_escape_string($_POST['payment_id']); $paymentDetails = mysql_fetch_assoc( mysql_query( sprintf( "select * from stat_pay where payment_id = '%s'", $paymentId ) ) ); if (!empty($paymentDetails)) { http_response_code($OK_RESPONSE_STATUS_CODE); echo $OK_RESPONSE_MESSAGE; exit; } $orderNumberSegments = explode('-', $_POST['order_id']); if (count($orderNumberSegments) < 2) { http_response_code(400); echo 'Passed [order_id] is invalid'; exit; } $paymentAmount = $_POST['amount']; $originalPaymentAmount = $paymentAmount; $bonus = 0; $userLogin = mysql_real_escape_string($orderNumberSegments[1]); // Вместо `mysql_fetch_array` лучше использовать `mysql_fetch_assoc`, // но я не знаю названия полей таблички. // Гадать не буду, т.к. дальше по коду используются ну совсем уж "специфические" названия полей $partner = mysql_fetch_array( mysql_query( sprintf("select * from partner where user='%s'", $userLogin) ) ); if (!$partner) { http_response_code(400); echo 'Partner not found'; exit; } $paymentAmount += $bonus; $internalPaymentSize = $paymentAmount / 100 * $con['pcash']; mysql_query( sprintf( "update partner set cash=cash+'%s' where user='%s'", $internalPaymentSize, $userLogin ) ); mysql_query( sprintf( "update users set pcash=pcash+'%s' where login='%s'", $internalPaymentSize, $partner[0] ) ); mysql_query( sprintf( "update users set cash=cash+'%s', cashin=cashin+'%s' where login='%s'", $paymentAmount, $paymentAmount, $userLogin ) ); // Тут неплохо было бы знать названия полей, чтобы не пытаться случайно угадать их порядок, но... // Предполагается, что первым полем в табличке `stat_pay` будет поле `payment_id` mysql_query( sprintf( "insert into stat_pay values('%s', '%s','%s','%s','%s','0.00')", $paymentId, $userLogin, // Вместо подобного хранения даты-времени // лучше добавить timestamp поле со значением по умолчанию CURRENT_TIMESTAMP date('d.m.y'), date('H:i:s'), $paymentAmount ) ); // У нас уже есть конфигурационные данные из этой таблички, // полученные именно с помощью `mysql_fetch_array` /*$con = mysql_fetch_array( mysql_query('select * from seting') );*/ // Т.к. $con - number[] | false, // предполагаю, что `paymail` - константа хранящая индекс колонки, // которую нужно проверить для отправки уведомления. // Однако это может быть и названием глобальной функции, // поэтому проверку defined('paymail') добавлять не стал, хотя хотелось if (!empty($con[paymail]) && $con[paymail] == 'yes') { include '../mail/in.php'; $to = $con['adm_email']; $subject = $reg_reg_mail_subject; $msg = $reg_reg_mail; $mailheaders = "Content-Type: text/plain; charset=Windows-1251\n"; $mailheaders .= "From: $con[adm_email]\n"; mail($to, $subject, $msg, $mailheaders); } http_response_code($OK_RESPONSE_STATUS_CODE); echo $OK_RESPONSE_MESSAGE; exit; |
Ответ ниже
|
Забыл сказать нужно чоб код работал на php 5.3
таблица stat_pay Структура вот скрин! user|data|vremya|inm|outm user- Логин человека data- Дата vremya- время платежа inm- сумма пополнения outm- сумма вывода Сейчас не зачисляется вообще ничего! Можно как то просто добавить в мои таблицы проверку по номеру! Что 1 платёж не зачислялся 2 раза! ? Или может добавить колонку нужно ? по простому! Спасибо! |
foxxxxx, ну, по идее, код, который я представил в комментарии №2 должен нормально работать, если в таблицу stat_pay добавить поле payment_id.
Чтобы добавить колонку payment_id в вашу табличку выполните эти 2 запроса: Код:
-- Добавить новую колонку payment_id в таблицу stat_pay в самое начало |
всё сделал , теперь как исправить скрипт который вы переделали чтоб работал на версии 5,3 php или прощё наш не много переделать!
|
Цитата:
|
Цитата:
Без логов тут только гадать, что не так. Код должен быть совместим с версией 5.3, там ничего такого нет. Upd. функция http_response_code появилась только с версии 5.4, попробуйте так: <?php include '../setup.php'; $OK_RESPONSE_MESSAGE = 'OK'; $rbConfig['api_key'] = 'e7ebd'; $rbConfig['project_id'] = 1000;// unused value $con = mysql_fetch_array( mysql_query('select * from seting') ); $hash = md5( $_POST['project_id'] . $_POST['order_id'] . $_POST['payment_id'] . $_POST['amount'] . $_POST['currency'] . $_POST['status'] . $rbConfig['api_key'] ); if ($hash !== $_POST['hash']) { header('HTTP/1.1 400 Bad Request'); echo 'Incorrect signature'; exit; } if (empty($_POST['payment_id'])) { header('HTTP/1.1 400 Bad Request'); echo 'Missing [payment_id] field'; exit; } // Предполагается, что транзакции хранятся в табличке `stat_pay` в колонке `payment_id`, // а номер транзакции передается в поле 'payment_id' $paymentId = mysql_real_escape_string($_POST['payment_id']); $paymentDetails = mysql_fetch_assoc( mysql_query( sprintf( "select * from stat_pay where payment_id = '%s'", $paymentId ) ) ); if (!empty($paymentDetails)) { header('HTTP/1.1 200 OK'); echo $OK_RESPONSE_MESSAGE; exit; } $orderNumberSegments = explode('-', $_POST['order_id']); if (count($orderNumberSegments) < 2) { header('HTTP/1.1 400 Bad Request'); echo 'Passed [order_id] is invalid'; exit; } $paymentAmount = $_POST['amount']; $originalPaymentAmount = $paymentAmount; $bonus = 0; $userLogin = mysql_real_escape_string($orderNumberSegments[1]); // Вместо `mysql_fetch_array` лучше использовать `mysql_fetch_assoc`, // но я не знаю названия полей таблички. // Гадать не буду, т.к. дальше по коду используются ну совсем уж "специфические" названия полей $partner = mysql_fetch_array( mysql_query( sprintf("select * from partner where user='%s'", $userLogin) ) ); if (!$partner) { header('HTTP/1.1 400 Bad Request'); echo 'Partner not found'; exit; } $paymentAmount += $bonus; $internalPaymentSize = $paymentAmount / 100 * $con['pcash']; mysql_query( sprintf( "update partner set cash=cash+'%s' where user='%s'", $internalPaymentSize, $userLogin ) ); mysql_query( sprintf( "update users set pcash=pcash+'%s' where login='%s'", $internalPaymentSize, $partner[0] ) ); mysql_query( sprintf( "update users set cash=cash+'%s', cashin=cashin+'%s' where login='%s'", $paymentAmount, $paymentAmount, $userLogin ) ); // Тут неплохо было бы знать названия полей, чтобы не пытаться случайно угадать их порядок, но... // Предполагается, что первым полем в табличке `stat_pay` будет поле `payment_id` mysql_query( sprintf( "insert into stat_pay values('%s','%s','%s','%s','%s','0.00')", $paymentId, $userLogin, // Вместо подобного хранения даты-времени // лучше добавить timestamp поле со значением по умолчанию CURRENT_TIMESTAMP date('d.m.y'), date('H:i:s'), $paymentAmount ) ); // У нас уже есть конфигурационные данные из этой таблички, // полученные именно с помощью `mysql_fetch_array` /*$con = mysql_fetch_array( mysql_query('select * from seting') );*/ // Т.к. $con - number[] | false, // предполагаю, что `paymail` - константа хранящая индекс колонки, // которую нужно проверить для отправки уведомления. // Однако это может быть и названием глобальной функции, // поэтому проверку defined('paymail') добавлять не стал, хотя хотелось if (!empty($con[paymail]) && $con[paymail] == 'yes') { include '../mail/in.php'; $to = $con['adm_email']; $subject = $reg_reg_mail_subject; $msg = $reg_reg_mail; $mailheaders = "Content-Type: text/plain; charset=Windows-1251\n"; $mailheaders .= "From: $con[adm_email]\n"; mail($to, $subject, $msg, $mailheaders); } header('HTTP/1.1 200 OK'); echo $OK_RESPONSE_MESSAGE; exit; |
С плат системы! Ответ сервера Partnernotfound
ошибок в лог нет но не зачисляет и в базу не записывает наш параметр что мы делали! payment_id Partner можно полностью убрать с таблицы ! Не использоваться если что ! |
Убрал с таблицы
$partner = mysql_fetch_array( mysql_query( sprintf("select * from partner where user='%s'", $userLogin) ) ); if (!$partner) { header('HTTP/1.1 400 Bad Request'); echo 'Partner not found'; exit; }ответ сервера норм стал .! Ответ сервера OK |
Часовой пояс GMT +3, время: 23:23. |