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

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

1
$reqn=_GetReqn();

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

1
2
3
4
5
6
7
8
9
10
11
$rsign=_GetSign($Global_WMID.$reqn);
//Наконец, формируем XML-пакет с запросом:
$xml="
<w3s.request>
      <reqn>$reqn</reqn>
      <wmid>$Global_WMID</wmid>
      <sign>$rsign</sign>
      <getpurses>
           <wmid>$Global_WMID</wmid>
      </getpurses>
</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
2
3
4
5
if(!$xmlres) {
 $result['retval']=1000;
 $result['retdesc']="Не получен XML-ответ";
 return $result;
}

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

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

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

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

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

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

1
return $result;

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

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

)
)

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

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