Оплата проходит, но номер почему-то не меняется.
В БД есть колонка с полем ordernum, там я планировал делать номер заказа +1 каждый раз. Изначальное значение ordernum = 10
Файл action php, который собирает данные и отправляет php:
if(!empty($_GET["username"]) && !empty($_GET["email"]) && !empty($_GET["sum"])){ // если был пост
$name = trim(htmlspecialchars(strip_tags($_GET["username"]))); // принимаем параметры с формы
$email = trim(htmlspecialchars(strip_tags($_GET["email"]))); // принимаем параметры с формы
$out_summ = trim(htmlspecialchars(strip_tags($_GET["sum"]))); // принимаем параметры с формы
$mrh_login = "Nextliferp"; // идентификатор магазина
$mrh_pass1 = "U6A2yxKRDh4IpJ6t9mfC"; // пароль #1
$sql = mysqli_query($link, "SELECT ordernum FROM accounts WHERE user_login ='DONTTOUCH' "); //получаем номер заказа
$resul = mysqli_fetch_assoc($sql);
$count = $resul['ordernum'];
$inv_id = (int)$count;
$inv_desc = "Тестовая оплата"; // описание заказа
$shp_item = 1; // тип товара
$in_curr = ""; // предлагаемая валюта платежа
$culture = "ru"; // язык
$encoding = "utf-8"; // кодировка
$crc = md5("$mrh_login:$out_summ:$inv_id:$mrh_pass1:Shp_item=$shp_item:shp_mulo=$email:shp_names=$name"); // формирование подписи
// Перенаправляем пользователя на страницу оплаты
Header("Location: http://auth.robokassa.ru/Merchant/Index.aspx?MrchLogin=$mrh_login&OutSum=$out_summ&InvId=$inv_id&IncCurrLabel=$in_curr".
"&Desc=$inv_desc&SignatureValue=$crc&Shp_item=$shp_item".
"&Culture=$culture&Encoding=$encoding&shp_mulo=$email&shp_names=$name");
}
Если ставлю +1, то касса возвращает ответ 40 (заказ с тем же номером) и причем выводит номер 2. Я совершенно не понимаю, откуда берется цифра 2, делал трассировку, показывает 11.
И есть второй файл, который должен менять в БД данные о том, кто платит или добавлять новые.
result.php
// чтение параметров
$out_summ = $_REQUEST["OutSum"]; // по умолчанию (не трогать)
$inv_id = $_REQUEST["InvId"]; // по умолчанию (не трогать)
$shp_item = $_REQUEST["Shp_item"]; // по умолчанию (не трогать)
$crc = $_REQUEST["SignatureValue"]; // по умолчанию (не трогать)
$shp_mulo = $_REQUEST["shp_mulo"]; // принимаем дополнительный параметр
$shp_names = $_REQUEST["shp_names"]; // принимаем дополнительный параметр
$crc = strtoupper($crc); // переводим ключ в верхний регистр
$my_crc = strtoupper(md5("$out_summ:$inv_id:$mrh_pass2:Shp_item=$shp_item:shp_mulo=$shp_mulo:shp_names=$shp_names")); // формируем новый ключ
if ($my_crc != $crc) // проверка корректности подписи
{
echo "bad sign\n";
exit(); // останавливаем выполнение скрипта, если подписи не совпадают
}
$que = mysqli_query($link, "UPDATE accounts SET ordernum = '".$inv_id."' WHERE user_login ='DONTTOUCH'")
// конвертируем полученные данные в нормальный режим
$email_k = $shp_mulo;
$name_k = $shp_names;
$query = mysqli_query($link, "SELECT user_pay FROM accounts WHERE user_login='".$shp_names."' ");
if (mysqli_num_rows($query))
{
$result = mysqli_fetch_assoc($query);
$shp_total = $result['user_pay'] + $out_summ;
$sql = "UPDATE accounts SET user_pay ='".$shp_total."' WHERE user_login='".$shp_names."' ";
$query = mysqli_query($link,$sql);
}
else
{
$string = "INSERT INTO accounts (user_login, user_email, user_pay) VALUES ('".$shp_names."','".$shp_mulo."','".$out_summ."' )";
$quer = mysqli_query($link,$string);
}
echo "OK$inv_id\n"; // признак успешно проведенной операции (обязательно!)
Вот с таким кодом ОПЛАТА ПРОХОДИТ, но данные совершенно не обновляются, ни данных об оплате, ни изменения номера платежа (Да и, собственно, как оно проходит оплату с одним номером я тоже не понимаю).
Я в отчаянии. Видит кто-нибудь ошибку, почему данные не заполняются, а оплата успешно проходит и редиректит на success.php?
Во-первых, у вас не правильно структурирована БД и скрипт с ней работает тоже не верно. По хорошему должно быть так:
Одна таблица для пользователей с их почтой, логином и счетом. Вторая таблица для заказов пользователей (для истории заказов).
Работа таблицы заказов пользователей такая:
Такая структура позволит вывести в дальнейшем в личном кабинете историю заказов с правильными суммами оплаты. (например: +25 р, +50 р, +1500 р, +11 р, и т.д.) В текущем коде будет выводиться примерно так: 1, 15, 6, 52, 7 и т.д. (значение баланса при достижении которого пользователь решил заплатить).
Вполне возможно, что вы не записываете новые строки для каждого платежа, а пытаетесь работать с одной строчкой на 1 пользователя. В таком случае решение найдете в самом конце.
Давайте посмотрим что можно сделать в вашем случае:
Вот структура вашей БД как я её понимаю.
$sql = mysqli_query($link, "SELECT ordernum FROM accounts WHERE user_login ='DONTTOUCH' "); //получаем номер заказа
$resul = mysqli_fetch_assoc($sql);
$count = $resul['ordernum'];
$inv_id = (int)$count;
Вот здесь вы выбираете ПЕРВУЮ запись в БД и из неё ordernum которые есть у пользователя с логином DONTTOUCH.
$name = "adudnik";
$sql = mysqli_query($link, "SELECT ordernum FROM robo_test WHERE user_login = '$name' "); //получаем номер заказа
$resul = mysqli_fetch_assoc($sql); // первая строчка из БД
$count = $resul['ordernum'];
var_dump($resul );
var_dump($count);
Результат работы скрипта у меня. Как видите берется только первое значение из БД, а не последнее.
mysqli_fetch_assoc создан для того, чтобы потом перебирать его через while.
Чтобы получить последнюю запись из БД нужен следующий запрос.
SELECT ordernum FROM robo_test WHERE user_login = '$name' ORDER BY id DESC LIMIT 1
Если же у вас нет как у меня колонки с ID которая AI и PRIMARY KEY и по которой можно надежно сортировать, то работаем с WHILE.
$sql = mysqli_query($link, "SELECT ordernum FROM robo_test WHERE user_login = '$name'"); //получаем номер заказа
$count = NULL;
while ( $resul = mysqli_fetch_assoc($sql) ) {
$count = $resul['ordernum'];
}
Если $count = null, значит записи нет и её нужно создать, если же любое другое значение - то оно вам и нужно.
Теперь по поводу обновлений в БД.
$que = mysqli_query($link, "UPDATE accounts SET ordernum = '".$inv_id."' WHERE user_login ='DONTTOUCH'")
Вот такой записи быть в принципе не должно. Для каждого номера заказа - своя строка. Но если уж решили обновлять по логину - почему DONTTOUCH? Где переменная логина? Убедитесь что все строчки с логинами уникальные (иначе будете обновлять только первую по описанным выше причинам).
$sql = "UPDATE accounts SET user_pay ='".$shp_total."' WHERE user_login='".$shp_names."' ";
Вот здесь должна быть проверка не по user_login, а по полученному от робокассы id платежа.
Тем не менее, если решили обновлять по логину, то почему DONTTUCH
а не переменная логина? Убедитесь что у вас нет дублей строк с логином.
$string = "INSERT INTO accounts (user_login, user_email, user_pay) VALUES ('".$shp_names."','".$shp_mulo."','".$out_summ."' )";
Лучше создайте отдельную таблицу для платежей и так обновляйте её, а в аккаунте используйте UPDATE таблица с пользователями SET поле с балансом WHERE логин пользователя
Если вам ну ОЧЕНЬ не хочется делать отдельную таблицу - используйте в качестве id платежа временную метку UNIX или случайно сгенерированное число знаков на 6.
Получайте такой ID в момент создания платежа пользователю. Тут же обновляйте в своей БД по user_login (или создавайте нового пользователя), затем направляйте с таким ID заказа на робокассу, получайте ответ и обновляйте баланс.
Если обновлять по id платежа:
Ошибка будет только если два человека начнут пополнять кошелек в одну и ту же секунду на сайте (в случае метки UNIX) или в таблице будет два случайно сгенерированных одинаковых числа. В рамках вашего проекта ни первое, ни второе практически невозможно.
Если обновлять по user_login:
Ошибка будет в случае дублирования строк с user_login в БД.
Настоятельно рекомендую разделить таблицы платежей и пользователей. Это вам будет полезно как для расширения ЛК пользователя, так и для решения проблем по запросу пользователей.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Как правильно скачивать статические файлы с удаленного сервера? 1 запуск скрипта = 1 скачивание файла, те keep-alive не рассматривается
В интернете часто вижу: Если у вас долго выполняется php function, то советуем сделать её на c++