Здравствуйте! Долго мучился сам, но поскольку у меня нет базисных знаний, вопрос оказался не по зубам к сож.. Поэтому с благодарностью приму помощь! Суть: 1. Есть страница с формой для данных оплаты и скриптом я-ты-мы-они.рф/pay/pay.php 2. Заполненные данные должны лететь на сервер банка как xml через POST запрос 3. Должна срабатывать переадресация на страницу банка для ввода данных карты. И вот тут возникает проблема.. Банк получает кириллические параметры запроса в виде набора знаков "?" => в свою систему вместо кириллических ФИО, описания заказа и проч - пишет что-то типа этого - "????? ?????" Первая мысль - проблемы с кодировкой. НО, - в скрипте везде указана UTF-8; - в настройках Wordpress - UTF-8 - в .htaccess - тоже прописано Код (Text): AddDefaultCharset UTF-8 - в БД у меня прописывается все корректно - вывод переменной $xml до отправки - корректный в кириллице PHP: <?php @session_start(); header('Content-Type: text/html;charset=UTF-8'); $ShopID = '23082'; //Логин $ShopPasswd = 'IiOtHhGGtK'; //Пароль $BackURL = 'http://xn------5ddshg2a5fc2b.xn--p1ai/pay/avangard_callback.php'; //Адрес возврата $defaultUser = array( 'fullname' => 'Имя', 'id' => '777', 'amount'=> '10', 'address' => 'Москва', 'phone' => '81231231212', 'email' => 'devel@user.us', 'desc' => 'оплата', 'ip' => $_SERVER['REMOTE_ADDR'] ); $Error = false; $Step = 'form'; /*$id = $_POST['id'];*/ //$id = date('d.m.Y H:i:s', time ()); $id = 'тестовый заказ'; $fullname = $_POST['fullname']; $amount = $_POST['amount']; $desc = $_POST['desc']; $phone = $_POST['phone']; $email = $_POST['email']; $result = $_POST['submit']; if ( $_POST['oferta'] == '') { echo 'Для совершения оплаты Вы должны быть согласны с <a href="http://я-ты-мы-они.рф">офертой</a>'; } else { if (!empty($_POST)) { $err = 0; /*if (empty($_POST['id'])) $err++;*/ if (empty($_POST['amount'])) $err++; if (empty($_POST['fullname'])) $err++; if (empty($_POST['desc'])) $err++; if (empty($_POST['phone'])) $err++; if ($err == 0) { $Step = 'redirect'; /*$desc = $_POST['desc']." #{$_POST['id']}";*/ $data = requestTicket($id, $_POST['fullname'], $defaultUser['address'], $_POST['phone'], $_POST['email'], $_POST['amount'], $_POST['desc'], $defaultUser['ip']); header("Location: {$data['url']}"); } else { $Error = 'Не заполнены обязательные поля формы, отмеченные звездочкой!'; } } } function ticketXML($id, $fullname, $address, $phone, $email, $amount, $desc, $ip) { global $ShopID, $ShopPasswd, $BackURL; $amount = (int) ($amount * 100); $xml = "<?xml version='1.0' encoding='utf-8'?> <new_order> <shop_id>$ShopID</shop_id> <shop_passwd>$ShopPasswd</shop_passwd> <amount>$amount</amount> <order_number>$id</order_number> <order_description>$desc</order_description> <language>RU</language> <back_url>$BackURL</back_url> <client_name>$fullname</client_name> <client_address>$address</client_address> <client_email>$email</client_email> <client_phone>$phone</client_phone> <client_ip>$ip</client_ip> </new_order>"; return $xml; } // Запрос тикета function requestTicket($id, $fullname, $address, $phone, $email, $amount, $desc, $ip) { $xml = ticketXML($id, $fullname, $address, $phone, $email, $amount, $desc, $ip); //echo rawurldecode(urlencode($xml)); //exit; $resp = file_get_contents('https://www.avangard.ru/iacq/h2h/reg?xml='.urlencode($xml)); if ($respXML = simplexml_load_string($resp)) { if ($respXML->response_code == 0 && !empty($respXML->ticket)) { $url = "https://www.avangard.ru/iacq/pay?ticket={$respXML->ticket}"; // Сохраняем в сессии $data = $_SESSION['avangard_order'] = $HTTP_SESSION_VARS['avangard_order'] = array( 'form' => $_POST, 'order_id' => $id, 'ticket' => (string) $respXML->ticket, 'ok_code' => (string) $respXML->ok_code, 'failure_code' => (string) $respXML->failure_code ); $_SESSION['form_xml'] = $xml; $_SESSION['form_data_id'] = $POST['id']; $_SESSION['form_data_fullname'] = $_POST['fullname']; $_SESSION['form_data_amount'] = $_POST['amount']; $_SESSION['form_data_desc'] = $_POST['desc']; $_SESSION['form_data_phone'] = $_POST['phone']; $_SESSION['form_data_email'] = $_POST['email']; return array('url' => $url, 'response' => $resp, 'data' => $data); } } return false; } ?> <? if ($Step == 'form'): ?> <?=$Error ? "$Error<br>" : ''?> <div class="login-page"> <div id="polosa"> <h2>Оплата банковской картой Visa и MasterCard </h2> </div> <link type="text/css" rel="stylesheet" href="/pay/style_form.css" /> <p>Оплатить наши услуги Вы можете в режиме он-лайн через систему электронных платежей с помощью пластиковых карт Visa, MasterCard или Maestro.</p> <div class="form"> <img src="/pay/payment.png" width="200" height="20" /> <form class="login-form" name="forma" action="/pay/pay.php" method="post" charset="utf-8"> <!--<input name="id" type="text" placeholder="* Номер договора:" value="">--> <input name="fullname" type="text" placeholder="* ФИО Плательщика" value=""> <input name="amount" type="text" placeholder="* Сумма оплаты, руб" value=""> <input name="desc" type="text" placeholder="* Назначение платежа" value=""> <input name="phone" type="text" placeholder="* Контактный телефон" value=""> <input name="email" type="email" placeholder="email" value=""> Согласие с <a href="http://я-ты-мы-они.рф">офертой</a> <input style="text-align: right" type="checkbox" name="oferta" value="1"> <input name="result" type="submit" value="Оплатить"> </form> </div> </div> <? endif; ?> <? $phpdb = mysql_connect("localhost","tatjano1_wp2","uTrgprOyr") or die ("Не могу соединиться с MySQL."); // Логин и пароль от базы данны); mysql_select_db("tatjano1_wp2") or die ("Не могу соединиться базой."); //Имя базы данныхх mysql_set_charset('utf8'); $result = mysql_query("insert INTO avangard_temp (`contract`,`fullname`, `summ2`, `description`,`phone`, `email`) VALUES ('$id', '$fullname', '$amount', '$desc', '$phone', '$email')"); ?> Техподдержка банка уверяет что к ним данные УЖЕ приходят "битые" Предлагают передавать xml как параметр пост запроса, а не как часть url на примере: PHP: $postdata = http_build_query( array( 'xml' => '<тут должен быть склеенный xml>' ) ); $opts = array('http' => array( 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata ) ); $context = stream_context_create($opts); $result = file_get_contents('http://example.com/submit.php', false, $context); Но вот, что сделать конкретно, какую часть кода какой заменить - сообщить не могут.. Я же, к сожалению, уже не могу уделить нужное кол-во времени на изучение/пробы/ошибки. Буду благодарен за любую помощь! Спасибо заранее!
остается кодировка самих файлов. --- Добавлено --- открой файл с помощью notepad++ и в нижнем правом углу посмотри, что написанно. Если написанно не "UTF-8", то в верху в меню выбери "Кодировки"->"Преобразовать в UTF-8 без BOM"
К сожалению, наверное, с кодировкой файлов все в порядке... Уже до этого проверял - и сейчас тоже.. На скриншоте попытка передать строку в кириллице. Строка латиницей - приходит корректно https://prnt.sc/h7pbam Могут ли быть еще какие-либо варианты при которых кодировка меняется на стороне отправителя?
нужно обеспечить UTF-8 на всём пути. - кодировка файла; - кодировка соединения с сервером; - кодировка соединения сервера с БД (если БД используется); - кодировка в таблицах БД (если БД используется); - банк должен принимать и отображать UTF-8 (глянь код страницы в банке, на всякий случай). Если везде UTF-8, то проблем быть не должно. Если проблема есть, значит где-то кодировка отличается.
@MikhailFedorov, стесняюсь спросить, но все-таки: "В какой кодировке данные ожидают в банке?" Что в документации по этому поводу написано?
@MikhailFedorov, еще попробуйте вместо 101-й строки: PHP: $url = "https://www.avangard.ru/iacq/h2h/reg"; $params = array( 'xml' => $xml, ); $context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => http_build_query($params), ), )); $resp = file_get_contents($url, false, $context);
1) Указанная страница не содержит указание кодировки в заголовке HTTP. 2) Разбираться надо с того, чтобы на своём сервере получить форму и прочитать "глазами" В теге формы указано charset="utf-8" - это ошибка, надо accept-charset. Но, указывать кодировку в форме не разумно. В общем - смотрите настройки сервера.
Цитата из документации: Для обмена данных в формате XML допускается использовать кодировки windows- 1251 и UTF-8, система эквайринга будет возвращать ответ в кодировке запроса. Кодировка запроса берется из объявления xml (). Кодировки http-запроса и данных внутри XML-сообщения обязательно должны совпадать. Для протокола SOAP допускается использовать только кодировку UTF-8. Поэтому моя страница - везде UTF-8 НО, как оказалось сегодня, страница заполнения данных карты в windows-1251. При том что уже вторую неделю бьемся с техподдержкой банка над кодировкой... Но, с другой стороны, если верить документации - это не важно. Касаемо того, как свой запрос вижу я, я его вижу отлично! В т.ч. если прерывать скрипт и выводить $xml через echo. Все, что сохраняется в сессию, PHP: $_SESSION['form_xml'] = $xml; $_SESSION['form_data_id'] = $POST['id']; $_SESSION['form_data_fullname'] = $_POST['fullname']; $_SESSION['form_data_amount'] = $_POST['amount']; $_SESSION['form_data_desc'] = $_POST['desc']; $_SESSION['form_data_phone'] = $_POST['phone']; $_SESSION['form_data_email'] = $_POST['email']; потом отлично выводится + пишется в БД. ЗА остальные советы - спасибо! Посмотрю сейчас.
Этот факт всё сильно упрощает! Есть замечательный инструмент: SoapClient Не надо ни xml строить для запроса, ни разбирать xml, возможно, получаемый в ответ при исползовании других методов
В общем, проблему с кодировкой так и не решили. Якобы, данные как-то перекодируются на стороне отправителя, но где - никто не знает.. Поэтому пришлось переводить в транслит и отправлять данные в банк транслитом... Криво, но работает. Всем спасибо! Но осадок недопонимания все-равно остался. Ведь xml который я передаю банку и который, по словам банка, уже прилетает к ним "кривой", я вывожу себе в корректном виде. Как так - ?
А вот так. Я недавно яндекс кассу прикручивал, у них в пост-запросах все данные ок передаются, а в гетах кириллица бьется. Причем возвращается в корректных UTF-8 вопросительных знаках. Как если бы прошла где-то у них на серверах двойную конвертацию. Благо, мне эти данные конкретно из гета нафиг не впились. Но вот тоже косяк-с.
Попробуйте отправить руками с сервера файл через HTTP POST с копией корректного (по-вашему) запроса. Попросите админа прислать копию запроса с заголовком HTTP. Если админ скажет, что они не присылают "HTTP" или как-то ещё отмажется, выложите здесь переписку с указанием банка. Даже если это дурь клиента, сотрудники банка должны помогать разобраться.