С помощью описанного ниже интерфейса вы можете получать информацию о текущих остатках на кошельках вашего WMID. Полное описание интерфейса находится здесь. Интерфейс требует включения путем обращения в службу поддержку WMID 941977853154.

X9 особенно полезен для автоматических обменных пунктов, сайтов, выплачивающих “WM-бонусы” и других проектов, в которых посетитель должен видеть текущие денежные резервы сервиса.

Наш XML-запрос должен выглядеть так:
<w3s.request>
<reqn></reqn>
<wmid></wmid>
<sign></sign>
<getpurses>
<wmid></wmid>
</getpurses>
</w3s.request>

Что означают параметры:
reqn - номер запроса, всякий раз должен быть больше предыдущего (в рамках данного отдельно взятого интерфейса);
wmid - ваш WMID, которым подписывается запрос;
sign - подпись запроса, сформированная из параметров: getpurses\wmid+reqn;
getpurses\wmid - WMID, по кошелькам которого необходимо проверить балансы. Дело в том, что данный интерфейс поддерживает доверенности, т.е. вы можете проверить балансы на кошельках чужого WMID, если владелец этого WMID дал вам соответствующую доверенность на сайте security.webmoney.ru. Запрос в этом случае вы всё равно должны подписывать своим WMID, но в поле getpurses\wmid записать WMID проверяемый. В приведенном ниже примере функции мы будем проверять балансы на собственном WMID. Если же вы захотите проверить балансы по доверенности, вам нужно будет немного видоизменить функцию.

Формат ответа сервера WebMoney следующий:
<w3s.response>
<reqn></reqn>
<retval></retval>
<retdesc></retdesc>
<purses cnt=”n”>
<purse id=”n”>
<pursename></pursename>
<amount></amount>
</purse>
<purse>

</purse>
</purses>
</w3s.response>

Что нас интересует в ответе? Во-первых, поле <retval> (если оно равно 0, то балансы получены успешно, в противном случае retval будет содержать код ошибки, расшифровку которой нужно смотреть в поле <retdesc>). Во-вторых, поля <pursename> и <amount>, содержащие соответственно номера кошельков и их балансы.
Как вы уже поняли, запросить остаток по одному конкретному кошельку, к сожалению, нельзя. Ответ возвращает балансы сразу всех кошельков.

Приведем теперь полностью функцию, которая реализует работу с интерфейсом X9, и добавим её в wmxml.inc.php:

  1. // ИНТЕРФЕЙС X9. ПОЛУЧЕНИЕ БАЛАНСА
  2. // На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
  3. // 'purses'=>массив балансов]
  4. function _WMXML9 () {
  5. global $Global_WMID, $XML_addr;
  6. $reqn=_GetReqn();
  7. $rsign=_GetSign($Global_WMID.$reqn);
  8. $xml="
  9. <w3s.request>
  10. <reqn>$reqn</reqn>
  11. <wmid>$Global_WMID</wmid>
  12. <sign>$rsign</sign>
  13. <getpurses>
  14.   <wmid>$Global_WMID</wmid>
  15. </getpurses>
  16. </w3s.request>";
  17. $resxml=_GetAnswer($XML_addr[9], $xml);
  18. // echo $resxml;
  19. $xmlres = simplexml_load_string($resxml);
  20. if(!$xmlres) {
  21.   $result['retval']=1000;
  22.   $result['retdesc']="Не получен XML-ответ";
  23.   return $result;
  24. }
  25. $result['retval']=strval($xmlres->retval);
  26. $result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
  27. if($result['retval']==0 && $result['retval']!==false) {
  28.  // Формируем массив [номер кошелька] = баланс
  29.  foreach ($xmlres->purses->purse as $purse) {
  30.   $pursename=strval($purse->pursename);
  31.   $amount=floatval($purse->amount);
  32.   $result['purses'][$pursename]=$amount;
  33.  }
  34. }
  35. return $result;
  36. }

Разберём, что происходит в этой функции.
Функция не получает никаких входных параметров.
Генерируем уникальный номер запроса $reqn с помощью функции _GetReqn():

  1. $reqn=_GetReqn();

Получаем подпись XML-пакета с помощью функции _GetSign(). На вход функции подаём строку, полученную в результате склейки параметров, как это предусмотрено в описании интерфейса. Параметры должны склеиваться именно в таком порядке, как это указано ниже.

  1. $rsign=_GetSign($Global_WMID.$reqn);
  2. //Наконец, формируем XML-пакет с запросом:
  3. $xml="
  4. <w3s.request>
  5.       <reqn>$reqn</reqn>
  6.       <wmid>$Global_WMID</wmid>
  7.       <sign>$rsign</sign>
  8.       <getpurses>
  9.            <wmid>$Global_WMID</wmid>
  10.       </getpurses>
  11. </w3s.request>";

Отправляем запрос на сервер WebMoney и получаем от него ответ с помощью функции _GetAnswer(). На вход функции подаём URL интерфейса X9 из глобального массива $XML_addr, а также пакет XML-запроса, сформированный только что:

  1. $resxml=_GetAnswer($XML_addr[9], $xml);

Для отладки и поиска ошибок может потребоваться прочитать XML-ответ “в чистом виде”. Тогда просто раскомментируйте следующую строку:

  1. // echo $resxml;

Вызовом функции simplexml_load_string() из библиотеки SimpleXML создаём на основе XML-ответа, полученного от WebMoney, объект. Параметры XML-ответа становятся свойствами объекта, и мы сможем легко получать к ним доступ.

  1. $xmlres = simplexml_load_string($resxml);

Если $xmlres не создан, значит, мы по какой-то причине не получили ответ от WebMoney. Тогда прерываем работу функции:

  1. if(!$xmlres) {
  2.  $result['retval']=1000;
  3.  $result['retdesc']="Не получен XML-ответ";
  4.  return $result;
  5. }

Читаем следующие свойства объекта: retval (содержит результат выполнения запроса; если балансы успешно получены, то retval равен 0), retdesc (содержит расшифровку результата). Сохраняем эти переменные в массив $result.

  1. $result['retval']=strval($xmlres->retval);
  2. $result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));

Обратите внимание, что содержимое поля мы перекодировали из UTF-8 в Win1251. Дело в том, что XML-ответ от WebMoney приходит в кодировке Windows1251, но SimpleXML при помещении XML-данных в объект принудительно превратил их в Юникод. Такая вот у него особенность. А так как - это строка, и теоретически она может содержать русские символы, то при выемке её из объекта мы возвращаем ей “родную” кодировку. Хотя, в общем, это не обязательно и зависит от ваших нужд и задач.

Если retval равен 0, то можно перейти к сохранению балансов по кошелькам. Номера кошельков и их балансы содержатся внутри одинаковых блоков XML-ответа в и соответственно. Пробегаем эти блоки в цикле и формируем ассоциативный массив, где ключами элементов делаем номера кошельков, а значениями элементов делаем соответствующие этим кошелькам балансы. Сформированный массив сохраняем внутрь элемента purses выходного массива $result:

  1. if($result['retval']==0 && $result['retval']!==false) {
  2. // Формируем массив [номер кошелька] = баланс
  3. foreach ($xmlres->purses->purse as $purse) {
  4.  $pursename=strval($purse->pursename);
  5.  $amount=floatval($purse->amount);
  6.  $result['purses'][$pursename]=$amount;
  7. }
  8. }

На выходе функция _WMXML9() возвращает массив $result:

  1. return $result;

Чтобы было лучше понятно, ещё раз посмотрим на содержимое массива $result (его можно привести в читабельный вид с помощью функции print_r(), например):

Array (
[retval] => код_выполнения
[retdesc] => описание_результата
[purses] => Array (
[номер_кошелька] => баланс
[номер_кошелька] => баланс
[номер_кошелька] => баланс

)
)

Теперь осталось только проверить, как работает то, что мы написали. Создадим скрипт для тестов test.php:

  1. <?php
  2. // test.php - скрипт для тестирования
  3. include("wmxml.inc.php");
  4. $r=_WMXML9();
  5. echo "Результат (0 - успешно) - ".$r['retval']."<br>";
  6. echo "Расшифровка - ".$r['retdesc']."<br>";
  7. while(list($key,$val)=each($r['purses'])) {
  8. echo "* На кошельке ".$key." ".$val." WM<br>";
  9. }
  10. ?>