За последние 24 часа нас посетили 17736 программистов и 1720 роботов. Сейчас ищут 1280 программистов ...

проблема с кодировкой при отправке POST запроса

Тема в разделе "Сделайте за меня", создана пользователем MikhailFedorov, 8 ноя 2017.

  1. MikhailFedorov

    MikhailFedorov Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    4
    Симпатии:
    0
    Здравствуйте!
    Долго мучился сам, но поскольку у меня нет базисных знаний, вопрос оказался не по зубам к сож.. Поэтому с благодарностью приму помощь!

    Суть:
    1. Есть страница с формой для данных оплаты и скриптом я-ты-мы-они.рф/pay/pay.php
    2. Заполненные данные должны лететь на сервер банка как xml через POST запрос
    3. Должна срабатывать переадресация на страницу банка для ввода данных карты.

    И вот тут возникает проблема..
    Банк получает кириллические параметры запроса в виде набора знаков "?" => в свою систему вместо кириллических ФИО, описания заказа и проч - пишет что-то типа этого - "????? ?????"

    Первая мысль - проблемы с кодировкой.
    НО,
    - в скрипте везде указана UTF-8;
    - в настройках Wordpress - UTF-8
    - в .htaccess - тоже прописано
    Код (Text):
    1. AddDefaultCharset UTF-8
    - в БД у меня прописывается все корректно
    - вывод переменной $xml до отправки - корректный в кириллице


    PHP:
    1. <?php
    2. header('Content-Type: text/html;charset=UTF-8');
    3.  
    4.  
    5. $ShopID     = '23082';  //Логин
    6. $ShopPasswd = 'IiOtHhGGtK';  //Пароль
    7. $BackURL     = 'http://xn------5ddshg2a5fc2b.xn--p1ai/pay/avangard_callback.php';   //Адрес возврата
    8. $defaultUser = array(
    9.     'fullname'     => 'Имя',
    10.     'id' => '777',
    11.     'amount'=> '10',
    12.     'address'    => 'Москва',
    13.     'phone'        => '81231231212',
    14.     'email'        => 'devel@user.us',
    15.     'desc'        => 'оплата',
    16.     'ip'        => $_SERVER['REMOTE_ADDR']
    17. );
    18.  
    19.  
    20.  
    21. $Error = false;
    22. $Step = 'form';
    23. /*$id = $_POST['id'];*/
    24. //$id = date('d.m.Y H:i:s', time ());
    25. $id = 'тестовый заказ';
    26. $fullname = $_POST['fullname'];
    27. $amount = $_POST['amount'];
    28. $desc = $_POST['desc'];
    29. $phone = $_POST['phone'];
    30. $email = $_POST['email'];
    31.  
    32. $result = $_POST['submit'];
    33.  
    34. if ( $_POST['oferta'] == '')
    35. {
    36. echo 'Для совершения оплаты Вы должны быть согласны с <a href="http://я-ты-мы-они.рф">офертой</a>';
    37. }
    38.   else {
    39.  
    40.  
    41.  
    42. if (!empty($_POST)) {
    43.     $err = 0;
    44.  
    45.     /*if (empty($_POST['id'])) $err++;*/
    46.     if (empty($_POST['amount'])) $err++;
    47.     if (empty($_POST['fullname'])) $err++;
    48.     if (empty($_POST['desc'])) $err++;
    49.     if (empty($_POST['phone'])) $err++;
    50.  
    51.  
    52.     if ($err == 0) {
    53.         $Step = 'redirect';
    54.         /*$desc = $_POST['desc']." #{$_POST['id']}";*/
    55.  
    56.         $data = requestTicket($id, $_POST['fullname'], $defaultUser['address'], $_POST['phone'], $_POST['email'], $_POST['amount'], $_POST['desc'], $defaultUser['ip']);
    57.         header("Location: {$data['url']}");
    58.  
    59.     }
    60.     else {
    61.         $Error = 'Не заполнены обязательные поля формы, отмеченные звездочкой!';
    62.     }
    63. }
    64. }
    65.  
    66.  
    67. function ticketXML($id, $fullname, $address, $phone, $email, $amount, $desc, $ip) {
    68.     global $ShopID, $ShopPasswd, $BackURL;
    69.  
    70.     $amount = (int) ($amount * 100);
    71.  
    72.     $xml = "<?xml version='1.0' encoding='utf-8'?>
    73. <new_order>
    74. <shop_id>$ShopID</shop_id>
    75. <shop_passwd>$ShopPasswd</shop_passwd>
    76. <amount>$amount</amount>
    77. <order_number>$id</order_number>
    78. <order_description>$desc</order_description>
    79. <language>RU</language>  
    80. <back_url>$BackURL</back_url>  
    81. <client_name>$fullname</client_name>
    82. <client_address>$address</client_address>
    83. <client_email>$email</client_email>
    84. <client_phone>$phone</client_phone>
    85. <client_ip>$ip</client_ip>
    86. </new_order>";
    87.  
    88.  
    89.     return $xml;
    90. }
    91.  
    92. // Запрос тикета
    93. function requestTicket($id, $fullname, $address, $phone, $email, $amount, $desc, $ip) {
    94.     $xml = ticketXML($id, $fullname, $address, $phone, $email, $amount, $desc, $ip);
    95.  
    96. //echo rawurldecode(urlencode($xml));
    97. //exit;
    98.  
    99.  
    100. $resp = file_get_contents('https://www.avangard.ru/iacq/h2h/reg?xml='.urlencode($xml));
    101.  
    102.      if ($respXML = simplexml_load_string($resp)) {
    103.         if ($respXML->response_code == 0 && !empty($respXML->ticket)) {
    104.             $url = "https://www.avangard.ru/iacq/pay?ticket={$respXML->ticket}";
    105.  
    106.  
    107.             // Сохраняем в сессии
    108.             $data = $_SESSION['avangard_order'] = $HTTP_SESSION_VARS['avangard_order'] = array(
    109.                 'form'             => $_POST,
    110.                 'order_id'         => $id,
    111.                 'ticket'         => (string) $respXML->ticket,
    112.                 'ok_code'         => (string) $respXML->ok_code,
    113.                 'failure_code'     => (string) $respXML->failure_code
    114.             );
    115.             $_SESSION['form_xml'] = $xml;
    116.             $_SESSION['form_data_id'] = $POST['id'];
    117.             $_SESSION['form_data_fullname'] = $_POST['fullname'];
    118.             $_SESSION['form_data_amount'] = $_POST['amount'];
    119.             $_SESSION['form_data_desc'] = $_POST['desc'];
    120.             $_SESSION['form_data_phone'] = $_POST['phone'];
    121.             $_SESSION['form_data_email'] = $_POST['email'];
    122.             return array('url' => $url, 'response' => $resp, 'data' => $data);
    123.            
    124.         }
    125.     }
    126.  
    127.     return false;
    128. }
    129.  
    130. ?>
    131.  
    132. <? if ($Step == 'form'): ?>
    133.     <?=$Error ? "$Error<br>" : ''?>
    134.     <div class="login-page">
    135.     <div id="polosa">
    136. <h2>Оплата банковской картой Visa и MasterCard </h2>
    137. </div>
    138.     <link type="text/css" rel="stylesheet" href="/pay/style_form.css" />
    139.     <p>Оплатить наши услуги Вы можете в режиме он-лайн через систему электронных платежей с помощью пластиковых карт Visa, MasterCard или Maestro.</p>
    140.     <div class="form"> <img src="/pay/payment.png" width="200" height="20" />
    141.    
    142.     <form class="login-form" name="forma" action="/pay/pay.php" method="post" charset="utf-8">
    143.  
    144.  
    145.     <!--<input name="id" type="text" placeholder="* Номер договора:" value="">-->
    146.    
    147.     <input name="fullname" type="text" placeholder="* ФИО Плательщика" value="">
    148.  
    149.     <input name="amount" type="text" placeholder="* Сумма оплаты, руб" value="">
    150.    
    151.     <input name="desc" type="text" placeholder="* Назначение платежа" value="">
    152.    
    153.     <input name="phone" type="text" placeholder="* Контактный телефон" value="">
    154.    
    155.     <input name="email" type="email" placeholder="email" value="">
    156.    
    157.     Согласие с  <a href="http://я-ты-мы-они.рф">офертой</a> <input style="text-align: right" type="checkbox" name="oferta" value="1">
    158.  
    159.    
    160.     <input name="result" type="submit" value="Оплатить">
    161.  
    162.     </form>
    163.     </div>
    164.     </div>
    165. <? endif;
    166.  
    167. ?>
    168.  
    169. <?
    170. $phpdb = mysql_connect("localhost","tatjano1_wp2","uTrgprOyr")  or die ("Не могу соединиться с MySQL.");  // Логин и пароль от базы данны);
    171. mysql_select_db("tatjano1_wp2") or die ("Не могу соединиться базой.");   //Имя базы данныхх
    172. $result = mysql_query("insert INTO avangard_temp (`contract`,`fullname`, `summ2`, `description`,`phone`, `email`) VALUES ('$id', '$fullname', '$amount', '$desc', '$phone', '$email')");
    173. ?>
    Техподдержка банка уверяет что к ним данные УЖЕ приходят "битые"
    Предлагают передавать xml как параметр пост запроса, а не как часть url на примере:
    PHP:
    1. $postdata = http_build_query(
    2.  
    3.     array(
    4.         'xml' => '<тут должен быть склеенный xml>'
    5.     )
    6. );
    7. $opts = array('http' =>
    8.  
    9.     array(
    10.         'method'  => 'POST',
    11.         'header'  => 'Content-type: application/x-www-form-urlencoded',
    12.         'content' => $postdata
    13.     )
    14. );
    15. $context  = stream_context_create($opts);
    16. $result = file_get_contents('http://example.com/submit.php', false, $context);
    Но вот, что сделать конкретно, какую часть кода какой заменить - сообщить не могут..
    Я же, к сожалению, уже не могу уделить нужное кол-во времени на изучение/пробы/ошибки.

    Буду благодарен за любую помощь! Спасибо заранее!
     
  2. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.984
    Симпатии:
    759
    остается кодировка самих файлов.
    --- Добавлено ---
    открой файл с помощью notepad++ и в нижнем правом углу посмотри, что написанно. Если написанно не "UTF-8",
    то в верху в меню выбери "Кодировки"->"Преобразовать в UTF-8 без BOM"
     
  3. MikhailFedorov

    MikhailFedorov Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    4
    Симпатии:
    0
    К сожалению, наверное, с кодировкой файлов все в порядке...
    Уже до этого проверял - и сейчас тоже..
    На скриншоте попытка передать строку в кириллице. Строка латиницей - приходит корректно
    https://prnt.sc/h7pbam

    Могут ли быть еще какие-либо варианты при которых кодировка меняется на стороне отправителя?
     
  4. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.984
    Симпатии:
    759
    нужно обеспечить UTF-8 на всём пути.
    - кодировка файла;
    - кодировка соединения с сервером;
    - кодировка соединения сервера с БД (если БД используется);
    - кодировка в таблицах БД (если БД используется);
    - банк должен принимать и отображать UTF-8 (глянь код страницы в банке, на всякий случай).

    Если везде UTF-8, то проблем быть не должно.
    Если проблема есть, значит где-то кодировка отличается.
     
  5. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @MikhailFedorov, стесняюсь спросить, но все-таки: "В какой кодировке данные ожидают в банке?" Что в документации по этому поводу написано?
     
    Fell-x27 нравится это.
  6. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @MikhailFedorov, еще попробуйте вместо 101-й строки:
    PHP:
    1. $url = "https://www.avangard.ru/iacq/h2h/reg";
    2. $params = array(
    3.     'xml' => $xml,
    4. );
    5.         'http' => array(
    6.             'method' => 'POST',
    7.             'header' => 'Content-Type: application/x-www-form-urlencoded',
    8.             'content' => http_build_query($params),
    9.         ),
    10.     ));
    11. $resp = file_get_contents($url, false, $context);
     
  7. СтудПом

    СтудПом Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    17
    Симпатии:
    0
    1) Указанная страница не содержит указание кодировки в заголовке HTTP.
    2) Разбираться надо с того, чтобы на своём сервере получить форму и прочитать "глазами"

    В теге формы указано charset="utf-8" - это ошибка, надо accept-charset. Но, указывать кодировку в форме не разумно.
    В общем - смотрите настройки сервера.
     
  8. MikhailFedorov

    MikhailFedorov Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    4
    Симпатии:
    0
    Цитата из документации:
    Для обмена данных в формате XML допускается использовать кодировки windows- 1251 и UTF-8, система эквайринга будет возвращать ответ в кодировке запроса. Кодировка запроса берется из объявления xml (). Кодировки http-запроса и данных внутри XML-сообщения обязательно должны совпадать. Для протокола SOAP допускается использовать только кодировку UTF-8.
    Поэтому моя страница - везде UTF-8
    НО, как оказалось сегодня, страница заполнения данных карты в windows-1251. При том что уже вторую неделю бьемся с техподдержкой банка над кодировкой...
    Но, с другой стороны, если верить документации - это не важно.

    Касаемо того, как свой запрос вижу я, я его вижу отлично! В т.ч. если прерывать скрипт и выводить $xml через echo.
    Все, что сохраняется в сессию,
    PHP:
    1. $_SESSION['form_xml'] = $xml;
    2.             $_SESSION['form_data_id'] = $POST['id'];
    3.             $_SESSION['form_data_fullname'] = $_POST['fullname'];
    4.             $_SESSION['form_data_amount'] = $_POST['amount'];
    5.             $_SESSION['form_data_desc'] = $_POST['desc'];
    6.             $_SESSION['form_data_phone'] = $_POST['phone'];
    7.             $_SESSION['form_data_email'] = $_POST['email'];
    потом отлично выводится + пишется в БД.

    ЗА остальные советы - спасибо! Посмотрю сейчас.
     
  9. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Этот факт всё сильно упрощает! Есть замечательный инструмент: SoapClient
    Не надо ни xml строить для запроса, ни разбирать xml, возможно, получаемый в ответ при исползовании других методов :)
     
  10. MikhailFedorov

    MikhailFedorov Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    4
    Симпатии:
    0
    В общем, проблему с кодировкой так и не решили. Якобы, данные как-то перекодируются на стороне отправителя, но где - никто не знает..
    Поэтому пришлось переводить в транслит и отправлять данные в банк транслитом... Криво, но работает.
    Всем спасибо!

    Но осадок недопонимания все-равно остался. Ведь xml который я передаю банку и который, по словам банка, уже прилетает к ним "кривой", я вывожу себе в корректном виде. Как так - ?
     
  11. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А вот так. Я недавно яндекс кассу прикручивал, у них в пост-запросах все данные ок передаются, а в гетах кириллица бьется. Причем возвращается в корректных UTF-8 вопросительных знаках. Как если бы прошла где-то у них на серверах двойную конвертацию. Благо, мне эти данные конкретно из гета нафиг не впились. Но вот тоже косяк-с.
     
  12. СтудПом

    СтудПом Новичок

    С нами с:
    8 ноя 2017
    Сообщения:
    17
    Симпатии:
    0
    Попробуйте отправить руками с сервера файл через HTTP POST с копией корректного (по-вашему) запроса. Попросите админа прислать копию запроса с заголовком HTTP. Если админ скажет, что они не присылают "HTTP" или как-то ещё отмажется, выложите здесь переписку с указанием банка. Даже если это дурь клиента, сотрудники банка должны помогать разобраться.