23.04.2024, 18:57
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
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';
}
|
|
23.04.2024, 22:24
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Расширение 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;
Последний раз редактировалось Nexus, 23.04.2024 в 22:27.
|
|
24.04.2024, 07:53
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
Ответ ниже
Последний раз редактировалось foxxxxx, 24.04.2024 в 11:46.
Причина: Случайно! можно удалить !
|
|
24.04.2024, 11:45
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
Забыл сказать нужно чоб код работал на php 5.3
таблица
stat_pay
Структура вот скрин!
user|data|vremya|inm|outm
user- Логин человека
data- Дата
vremya- время платежа
inm- сумма пополнения
outm- сумма вывода
Сейчас не зачисляется вообще ничего! Можно как то просто добавить в мои таблицы проверку по номеру! Что 1 платёж не зачислялся 2 раза! ? Или может добавить колонку нужно ? по простому! Спасибо!
Последний раз редактировалось foxxxxx, 24.04.2024 в 12:00.
|
|
24.04.2024, 16:07
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
foxxxxx, ну, по идее, код, который я представил в комментарии №2 должен нормально работать, если в таблицу stat_pay добавить поле payment_id.
Чтобы добавить колонку payment_id в вашу табличку выполните эти 2 запроса:
Код:
|
-- Добавить новую колонку payment_id в таблицу stat_pay в самое начало
ALTER TABLE `stat_pay` ADD COLUMN `payment_id` VARCHAR(255) NULL FIRST;
-- добавить уникальный ключ в таблицу stat_pay по полю payment_id
ALTER TABLE `stat_pay` ADD UNIQUE KEY (`payment_id`); |
Последний раз редактировалось Nexus, 24.04.2024 в 16:11.
Причина: payment_id not nullable -> nullable
|
|
24.04.2024, 16:36
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
всё сделал , теперь как исправить скрипт который вы переделали чтоб работал на версии 5,3 php или прощё наш не много переделать!
|
|
24.04.2024, 16:45
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
Сообщение от Nexus
|
foxxxxx, ну, по идее, код, который я представил в комментарии №2 должен нормально работать, если в таблицу stat_pay добавить поле payment_id.
Чтобы добавить колонку payment_id в вашу табличку выполните эти 2 запроса:
Код:
|
-- Добавить новую колонку payment_id в таблицу stat_pay в самое начало
ALTER TABLE `stat_pay` ADD COLUMN `payment_id` VARCHAR(255) NULL FIRST;
-- добавить уникальный ключ в таблицу stat_pay по полю payment_id
ALTER TABLE `stat_pay` ADD UNIQUE KEY (`payment_id`); |
|
В базу не записывает payment_id и не зачисляет и он не работает на версии 5,3!
|
|
24.04.2024, 18:00
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Сообщение от foxxxxx
|
он не работает на версии 5,3!
|
Что конкретно не работает? Какие ошибки в лог ошибок пишутся?
Без логов тут только гадать, что не так.
Код должен быть совместим с версией 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;
Последний раз редактировалось Nexus, 24.04.2024 в 18:07.
|
|
24.04.2024, 18:40
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
С плат системы! Ответ сервера Partnernotfound
ошибок в лог нет но не зачисляет и в базу не записывает наш параметр что мы делали! payment_id
Partner можно полностью убрать с таблицы ! Не использоваться если что !
|
|
24.04.2024, 18:46
|
Новичок на форуме
|
|
Регистрация: 23.04.2024
Сообщений: 8
|
|
Убрал с таблицы
$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
|
|
|
|