XML-интерфейсы WebMoney. Часть 2. X2, X6, X8, X11.

pligin

Команда форума
Администратор
Начало работы
Все XML-интерфейсы работают по следующему принципу:
  1. Вы формируете на своем сайте XML-пакет, содержащий параметры запроса (например: "отправить сообщение с текстом textпользователю wmid"). В запрос вы вставляете также электронную подпись XML-пакета, сформированную модулем WMSigner. Это позволяет посылать запросы только от имени вашего WMID.
  2. Сформированный XML-пакет направляете серверу WebMoney методом POST.
  3. Сервер WebMoney расшифровывает подпись вашего XML-запроса и убеждается, что запрос прислали именно вы. Таким образом, никто кроме вас не сможет, например, от вашего имени списать деньги с вашего кошелька. Но и вы не сможете списать деньги с чужого кошелька от лица его владельца.
  4. Если валидность подписи установлена и запрос составлен верно, то сервер WebMoney выполняет запрос и отвечает вам XML-пакетом, содержащим результаты выполнения запроса (например: "успешно отправил сообщение с текстом text пользователю wmid и датировал датой date").
  5. Разбираете (парсите) ответ так, как вам это нужно.
Итак, нам нужно выполнить 3 действия: сформировать XML-запрос, отправить его серверу WebMoney и получить ответ, разобрать XML-ответ. Сформировать. Отправить и получить. Разобрать.

Формировать запрос можно любым методом, главное, чтобы сформированный XML-пакет отвечал требованиям стандарта XML. Можно воспользоваться функциями DOM/DOM XML для PHP, однако мы поступим проще. Формировать тело запроса будем прямо в строке скрипта, например:
PHP:
// некий xml-пакет записываем в переменную $xml
$xml="
<root_element>
    <elem id='1'>
        <param1>...</param1>
        <param2>...</param2>
    </elem>
</root_element>
";
При рассмотрении конкретных интерфейсов мы увидим, что почти все они требуют обязательного указания в XML-запросе поля <reqn> с уникальным номером запроса. Причем, каждый новый запрос должен содержать reqn больший, чем в предыдущем запросе. Сам reqn должен быть целым числом и иметь до 15 цифр. Для генерации такого номера удобно использовать функцию, основанную на текущей отметке времени, которая, как известно, постоянно растет и никогда не повторяется. Чтобы два запроса, отправленные в одну секунду, не получили одинаковый reqn, будем брать эту отметку с точностью до микросекунд.

Поместим такую функцию в наш wmxml.inc.php:
PHP:
// ФУНКЦИЯ ФОРМИРУЕТ УНИКАЛЬНЫЙ УВЕЛИЧИВАЮЩИЙСЯ REQN
function _GetReqn(){
    $time=microtime();
    $int=substr($time,11);
    $flo=substr($time,2,5);
    return $int.$flo;
};
Внимание! Не начинайте экспериментировать с XML-интерфейсами WebMoney без этой функции! Если вы хотя бы раз передадите большой reqn (например, 777777777777777), то в дальнейшем не сможете передавать reqn, который будет меньше этого. В такой ситуации вам придется либо изобретать функцию, генерирующую постоянно растущий reqn больше 777777777777777, либо писать в тех. поддержку с просьбой обнулить для вас счетчик reqn.

Итак, как сформировать пакет - понятно. Теперь его нужно передать серверу WebMoney. Делать это нужно методом POST. Есть несколько вариантов реализации. Мы воспользуемся библиотекой libcurl (CURL). Как правило, она включена в сборку PHP даже на недорогих виртуальных хостингах. Проверить, включена ли поддержка CURL на вашем сервере, можно с помощью функции phpinfo() или так: echo function_exists("curl_init");.

Напишем функцию _GetAnswer(), которая будет отправлять на сервер WebMoney XML-пакет с запросом и получать ответ. Включим функцию в наш модульный файл wmxml.inc.php.
PHP:
// ОТПРАВКА POST-ЗАПРОСА ЧЕРЕЗ CURL
// На входе: URL для отправки и содержимое XML-запроса. На выходе: XML-ответ от WebMoney
function _GetAnswer($address, $xml){
    global $Path_Certs;
    // Инициализируем сеанс CURL
    $ch = curl_init($address);
    // В выводе CURL http-заголовки не нужны
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // Возвращать результат, а не выводить его в браузер
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    // Метод http-запроса - POST
    curl_setopt($ch, CURLOPT_POST,1);
    // Что передаем?
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    // Проверяем корневой сертификат сервера WebMoney
    curl_setopt($ch, CURLOPT_CAINFO, $Path_Certs);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    // Выполняем запрос, ответ помещаем в переменную $result;
    $result=curl_exec($ch);
    return $result;
}
Чтобы (в целях безопасностии и защиты от DNS-атак) во время сеанса CURL мог проверить валидность сертификата на сервере WebMoney, мы используем аргументы CURLOPT_CAINFO и CURLOPT_SSL_VERIFYPEER. Для этого скачиваем файл с корневыми сертификатами (WMunited.cer в прикреплении), которые используются на серверах WebMoney, заливаем его в любой каталог на своём сервере (например, /home/site.ru/data/certs/). Путь к файлу прописываем в переменной $Path_Certs нашей библиотеки wmxml.inc.php:
PHP:
// путь к файлу с корневыми сертификатами
$Path_Certs="/home/site.ru/data/certs/WMunited.cer";
На вход функции _GetAnswer() подается не только XML-пакет с запросом, но и URL на сервере WebMoney, куда нужно передавать этот пакет. Для каждого интерфейса URL свой, отдельный. Создадим в файле wmxml.inc.php массив с адресами всех интерфейсов для удобства:
PHP:
$XML_addr[1]="https://w3s.webmoney.ru/asp/XMLInvoice.asp";
$XML_addr[2]="https://w3s.webmoney.ru/asp/XMLTrans.asp";
$XML_addr[3]="https://w3s.webmoney.ru/asp/XMLOperations.asp";
$XML_addr[4]="https://w3s.webmoney.ru/asp/XMLOutInvoices.asp";
$XML_addr[5]="https://w3s.webmoney.ru/asp/XMLFinishProtect.asp";
... и т.д.

Функция _GetAnswer() получает ответ от сервера WebMoney и возвращает его на выходе:
PHP:
$result=curl_exec($ch);
return $result;
Переходим к последнему этапу. Ответ имеет вид XML-пакета. Нам нужно прочитать из него те поля, которые нам нужны, то есть разобрать (отпарсить) XML. Сделать это можно любым XML-разборщиком PHP: DOM XML, libxml, XML expat parsers и др. Автор этой статьи привык работать с простой и удобной библиотекой SimpleXML (поддерживается только в PHP5, но не в PHP4), поэтому все примеры в статье будут написаны с использованием функций именно этой библиотеки. Вы можете ко мне присоединиться, либо выбрать другое средство разбора XML, которое вам по душе.

На данный момент наш модульный файл wmxml.inc.php содержит следующий код:
PHP:
// wmxml.inc.php - файл с функциями

// БЛОК КОНСТАНТ
$Global_WMID="XXXXXXXXXXXX";  // Ваш WMID
$Path_Folder = "/home/site.ru/data/signer/"; // Путь к директории, в которой лежит .kwm
$Path_Signer = "/home/site.ru/data/signer/wmsigner"; // Путь к WMSigner
$Path_Certs="/home/site.ru/data/certs/WMunited.cer"; // путь к файлу с корневыми сертификатами

// URL интерфейсов
$XML_addr[1]="https://w3s.webmoney.ru/asp/XMLInvoice.asp";
$XML_addr[2]="https://w3s.webmoney.ru/asp/XMLTrans.asp";
$XML_addr[3]="https://w3s.webmoney.ru/asp/XMLOperations.asp";
$XML_addr[4]="https://w3s.webmoney.ru/asp/XMLOutInvoices.asp";
$XML_addr[5]="https://w3s.webmoney.ru/asp/XMLFinishProtect.asp";
$XML_addr[6]="https://w3s.webmoney.ru/asp/XMLSendMsg.asp";
$XML_addr[7]="https://w3s.webmoney.ru/asp/XMLClassicAuth.asp";
$XML_addr[8]="https://w3s.webmoney.ru/asp/XMLFindWMPurse.asp";
$XML_addr[9]="https://w3s.webmoney.ru/asp/XMLPurses.asp";
$XML_addr[10]="https://w3s.webmoney.ru/asp/XMLInInvoices.asp";
$XML_addr[11]="https://passport.webmoney.ru/asp/XMLGetWMPassport.asp";
$XML_addr[13]="https://w3s.webmoney.ru/asp/XMLRejectProtect.asp";
$XML_addr[14]="https://w3s.webmoney.ru/asp/XMLTransMoneyback.asp";
$XML_addr[151]="https://w3s.webmoney.ru/asp/XMLTrustList.asp";
$XML_addr[152]="https://w3s.webmoney.ru/asp/XMLTrustList2.asp";
$XML_addr[153]="https://w3s.webmoney.ru/asp/XMLTrustSave2.asp";
$XML_addr[16]="https://w3s.webmoney.ru/asp/XMLCreatePurse.asp";
$XML_addr[171]="https://arbitrage.webmoney.ru/xml/X17_CreateContract.aspx";
$XML_addr[172]="https://arbitrage.webmoney.ru/xml/X17_GetContractInfo.aspx";
$XML_addr[18]="https://merchant.webmoney.ru/conf/xml/XMLTransGet.asp";
$XML_addr[19]="https://passport.webmoney.ru/XML/XMLCheckUser.aspx";


// ФУНКЦИЯ ФОРМИРУЕТ УНИКАЛЬНЫЙ УВЕЛИЧИВАЮЩИЙСЯ REQN
function _GetReqn(){
    $time=microtime();
    $int=substr($time,11);
    $flo=substr($time,2,5);
    return $int.$flo;
};

// ФУНКЦИЯ ФОРМИРОВАНИЯ ПОДПИСИ
// На входе: строка для подписи. На выходе: строка с результатом подписывания
function _GetSign($inStr) {
    global $Path_Folder, $Path_Signer;
    chdir($Path_Folder);
    $descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "r") );
    $process = proc_open($Path_Signer, $descriptorspec, $pipes);
    fwrite($pipes[0], "$inStr\004\r\n");
    fclose($pipes[0]);
    $s = fgets($pipes[1], 133);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    return $s;
}

// АЛЬТЕРНАТИВНАЯ ФУНКЦИЯ ПОДПИСИ ДЛЯ PHP НИЖЕ 4.3.0
// На входе: строка для подписи. На выходе: строка с результатом подписывания
function _GetSign2($inStr){
    global $Path_Folder, $Path_Signer;
    chdir($Path_Folder);
    $PlanStr = "$inStr\004\r\n";
    $fp = popen($Path_Signer, "r+");
    fwrite($fp,$PlanStr);
    $s = fgets($fp, 133);
    pclose($fp);
    return $s;
}

// ОТПРАВКА POST-ЗАПРОСА ЧЕРЕЗ CURL
// На входе: URL для отправки и содержимое XML-запроса. На выходе: XML-ответ от WebMoney
function _GetAnswer($address, $xml){
    global $Path_Certs;
    // Инициализируем сеанс CURL
    $ch = curl_init($address);
    // В выводе CURL http-заголовки не нужны
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // Возвращать результат, а не выводить его в браузер
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    // Метод http-запроса - POST
    curl_setopt($ch, CURLOPT_POST,1);
    // Что передаем?
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    // Проверяем корневой сертификат сервера WebMoney
    curl_setopt($ch, CURLOPT_CAINFO, $Path_Certs);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    // Выполняем запрос, ответ помещаем в переменную $result;
    $result=curl_exec($ch);
    return $result;
}
Ниже мы познакомимся с некоторыми XML-интерфейсами WebMoney. Надеюсь, вы поймете смысл того, что мы делаем, и сможете наладить работу с остальными интерфейсами самостоятельно.

Описывать интерфейсы мы будем один за другим, но в описании каждого из них будем повторять одни и те же правила и пояснения, поэтому вы можете начинать с любого интерфейса, а не изучать их по очереди.

Продолжение:
Интерфейс X2. Отправка переводов.

Примеры:

Автоматические выплаты на WebMoney для скриптов Фруктовой Фермы - возможно использовать не только в фруктовой ферме
 

Вложения

Последнее редактирование:
Верх