XML-интерфейсы WebMoney. WMSigner.

pligin

Команда форума
Администратор
Введение
WebMoney Merchant позволяет организовать прием WM-платежей на сайте без участия человека. Однако, у интернет-бизнесменов часто возникает необходимость автоматизировать другие операции со своими WebMoney-кошельками. Например, автоматически отправлять покупателю сообщение по внутренней WM-почте, делать выплаты по партнерской программе или выплачивать выигрыши в онлайн-играх, запрашивать баланс своих кошельков, проверять правильность введенного пользователем WM-идентификатора и т.д.

Любая автоматизация упрощает жизнь, позволяет не отвлекаться на рутину, избежать человеческих ошибок. Еще Генри Форд понял, что там, где людей можно заменить роботами, - это нужно делать обязательно.

WebMoney в этом смысле дает нам отличнейшие и не имеющие аналогов инструменты. Почти все процессы, происходящие на вашем web-сервисе и связанные с WebMoney, можно авторматизировать, сделать моментальными, заставить их работать круглые сутки и без какого-либо вашего вмешательства. Для этого нужно всего лишь "научить" ваш сайт "общаться" с сервером WebMoney и отдавать ему команды.

Этот язык общения и команд описывается специальными правилами, которые называются XML-интерфейсами. Данным материалом мы открываем цикл статей, в которых научим вас использовать XML-интерфейсы WebMoney во благо вашего интернет-бизнеса. Немного терпения, немного практики веб-программирования - и через некоторое время работать за вас будут уже роботы. А освободившееся время предлагаю уделить любви или спорту, либо тому и другому сразу :)

Что понадобится для работы?
Итак, первый вопрос на повестке дня - что нужно знать и уметь, чтобы разобраться в XML-интерфейсах? Безусловно, нужно уметь программировать на одном из серверных языков (PHP, ASP, Perl и т.д.) На каком уровне? Пожалуй, на среднем или даже ниже среднего. Там, где ваших знаний будет не хватать - вам помогут примеры, которыми наш материал будет обильно сдобрен.

Гораздо важнее, чтобы вы понимали: как устроено дерево каталогов на сервере, что такое права доступа к файлам, что такое FTP и shell, как передается информация между серверами в интернете, что такое методы POST и GET, наконец, что такое XML. Конечно, мы будем давать комментарии некоторым понятиям, но тем, кто всё это уже знает, - будет намного проще.

Все программные примеры мы будем приводить на языке PHP. Платформа - ОС FreeBSD. Сегодня это наиболее распространенная "связка". Информацию по работе с WMSigner на платформе .Net вы сможете найти на сайте www.wmsigner.com

Важное замечание! Для работы XML-интерфейсов нужен персональный аттестат. Если у вас его еще нет - поспешите получить. Для первой статьи (которую вы сейчас читаете) аттестат не понадобится, а вот для следующих уже будет нужен.

Еще одно замечание перед тем, как мы начнем. При работе с XML-интерфейсами могут использоваться ключи Keeper Classic или сертификаты Keeper Light - на ваш выбор. Результат один и тот же, но вот конкретная реализация немного отличается. Мы будем демонстрировать реализацию XML-интерфейсов на примерах с ключами Keeper Classic. Тот, кто пользуется Лайтом, как вариант, может зарегистрировать новый WMID в Keeper Classic и присоединить его к своему аттестату.

Установка WMSigner
В этой статье нам предстоит познакомиться с модулем аутентификации WMSigner. Он понадобится для работы XML-интерфейсов.

Отыщите ваш файл ключей .kwm. Как вы знаете, он был создан при регистрации Keeper Classic. Отыскали? Теперь вспомните код доступа к файлу ключей. И то, и другое нам понадобится. Те, кто не смог найти файл или вспомнить код доступа - войдите в Кипер и нажмитеИнструменты - Параметры программы - Безопасность - Сохранить ключи в файл, сохраните файл ключей, назначьте пароль доступа. И больше их не теряйте.

Файл .kwm имеет размер 164 байта. В нем содержится закрытый ключ пользователя WebMoney. Информация шифруется закрытым ключем, передается в таком виде на сервер WebMoney, где расшифровывается открытым ключем. Так WebMoney проверяет авторство информации и убеждается в том, что она передана верно, без искажений. Это принцип ассиметричного шифрования.

При работе с Keeper Classiс сообщения, посылаемые к WebMoney, шифрует сам Кипер. В случае с XML-интерфейсами обмен информацией происходит по принципу "сервер-сервер", а не "Кипер-сервер", а в качестве шифровальщика выступает модуль WMSigner.

Скомпилируем WMSigner на сервере. Для этого скачаем последнюю версию WMSigner (на момент написания статьи это версия 2.0) отсюда, например, в zip-архиве. Распакуем содержимое архива и зальем его по FTP в любое место на сервере.

Приступим к компиляции. Для этого нам понадобится доступ к shell.

Примечание! Для доступа к серверной консоли (shell) рекомендуем использовать программу putty. Доступ к shell должен быть предоставлен вашим хостинг-провайдером. Если провайдер не предоставил доступ, попросите его скомпилировать модуль WMSigner за вас.
Напомним основные shell-команды в FreeBSD, которые, возможно, понадобятся вам для работы:
cd каталог - переход в заданный каталог; для перехода в каталог на уровень выше набирайте cd ..;
ls - просмотр содержимого текущего каталога;
pwd - просмотр пути к текущему каталогу.

Войдем в shell, с помощью команды cd доберемся до каталога, куда мы только что залили исходники WMSigner'а. Наберем в командной строке:
Код:
$ make
Через пару секунд компиляция завершена. В том же каталоге появился файл wmsigner. Все файлы и подкаталоги с исходниками WMSigner'а теперь можно удалить, они своё отработали и нам больше не понадобятся.

Прежде чем двигаться дальше, давайте разберемся со структурой каталогов на сервере. Пусть на нашем условном сервере файлы, доступные через web, лежат в каталоге /home/site.ru/data/htdocs/. Там же будут находиться и php-скрипты, работающие с XML-интерфейсами. Из соображений безопасности очень желательно разместить WMSigner таким образом, чтобы он не был недоступен из web'a. Поэтому создадим, например, каталог /home/site.ru/data/signer/. Сделать это можно через FTP или shell.

Если по какой-то причине у вас нет возможности создавать каталоги выше директории web-документов, то вы можете создать подкаталог /home/site.ru/data/htdocs/что-то/, где вместо "что-то" - директория с очень сложным именем, чтобы его было тяжело определить методом подбора. Кроме того, обязательно поместите в эту директорию файл .htaccess, запрещающий web-доступ к содержимому директории. В противном случае, ваши секретные файлы, которые будут находиться в этом каталоге, могут быть скачаны злоумышленником прямо с вашего сайта. Приводим текст файла .htaccess для такого случая. Он состоит всего из 2-х строк:
Код:
Order Allow,Deny
Deny from All
Скопируем WMSigner в только что созданную директорию /home/site.ru/data/signer/

Поместим в тот же каталог файл ключей .kwm.

Создадим в той же директории /home/site.ru/data/signer/ файл wmsigner.ini с 3 строками текста:

ваш WMID
код доступа к ключам
путь к файлу .kwm

Пусть, наш WMID - 123456789012, код доступа - akwru3kdn, а файл ключей называется 123456789012.kwm. Тогда содержимое wmsigner.ini должно быть таким:
Код:
123456789012
akwru3kdn
123456789012.kwm
Либо таким:
Код:
123456789012
akwru3kdn
/home/site.ru/data/signer/123456789012.kwm
Итак, в каталоге /home/site.ru/data/signer/ находится 3 файла: модуль подписи wmsigner, файл ключей .kwm, файл wmsigner.ini. Если они попадут в руки злоумышленника, он сможет подключиться к вашим кошелькам. Поэтому эти файлы нужно тщательно беречь. И именно поэтому мы не стали помещать их в каталог с web-документами, откуда они могли быть скачаны кем-угодно прямо с вашего сайта, а разместили их выше в древе каталогов сервера.

Примечание! 123456789012.kwm может находиться и в другой директории, лежать отдельно от wmsigner.ini и wmsigner. Вам всего лишь нужно прописать правильный путь к нему в wmsigner.ini. Однако, где бы ни находился .kwm, вы должны помнить, что он содержит секретный ключ, и применять к нему меры защиты, в том числе те, которые мы описали выше.
Wmsigner и wmsigner.ini должны обязательно находиться в одном каталоге.

Наконец, установим правильные атрибуты на файлы wmsigner, wmsigner.ini и 123456789012.kwm. Сделать это можно из FTP-менеджера (Total Commander, FAR и др.), либо через shell. Для wmsigner нужно разрешить выполнение. Для wmsigner.ini и 123456789012.kwm будет достаточным разрешение только на чтение и только владельцем. Для установки таких прав доступа через shell перейдите в каталог /home/site.ru/data/signer/ и выполните там команды:
Код:
$ chmod 111 wmsigner
$ chmod 400 wmsigner.ini
$ chmod 400 123456789012.kwm
Тестирование WMSigner в shell
Перейдем к тестированию. Чтобы убедиться в работоспособности скомилированного только что модуля WMSigner, дадим ему на вход строку, которую он должен подписать. На выходе получим строку, сформированную в результате подписывания входной строки вашим закрытым ключем. Формат входной строки такой: строка_для_подписывания\004\r\n

Примечание! Даже при подаче одинаковой входной строки, строка подписи будет каждый раз разная, так как при ее формировании используется текущая метка времени.

Продемонстрируем. В shell'e перейдем в каталог /home/site.ru/data/signer/ и выполним команду:

$ echo -ne "TestString123\004\r\n" | ./wmsigner

Если в ответ получена длинная цифр и букв - значит всё в порядке, wmsigner работает правильно. Если получена ошибка - значит что-то не так. Перечень возможных ошибок:

  • Error 20 - Невозможно загрузить конфигурационный файл wmsigner.ini. Возможно, он отсутствует в той же директории, что и wmsigner.
  • !LoadKeys Error 2 - Невозможно загрузить файл ключей. Возможно, он отсутстует по тому пути, который указан в wmsigner.ini, или имеет другое название.
  • Error -3 - Код доступа неверный. Возможно, Вы используете пароль на вход в Кипер, а не код доступа.
  • Error -4 - Не задан WMID.
  • Error -5 - Не задан код доступа.
  • Error -6 - Не задан файл ключей.
Что происходит при формировании строки подписи?
1) wmsigner ищет файл wmsigner.ini в том же каталоге, где лежит он сам;
2) wmsigner берет из wmsigner.ini WMID, код доступа и путь к файлу .kwm;
3) wmsigner обращается к файлу kwm, чтобы подписать строку.

Тестирование WMSigner в PHP
Теперь то же самое сделаем из PHP. Создадим файл wmxml.inc.php, куда будем складывать все функции, необходимые нам для работы с XML-интерфейсами WebMoney. Этот файл будем вызывать ("инклудить") из наших php-скриптов там, где это нужно. Первой функцией, которую мы создаем в wmxml.inc.php, будет функция _GetSign(). Она будет делать то же самое, что мы только что проделали через shell: получать на вход строку для подписи, вызывать WMSigner, получать результаты его работы и отдавать на выходе строку с результатом подписывания.
Код:
// wmxml.inc.php - файл с функциями

// БЛОК КОНСТАНТ
$Path_Folder = "/home/site.ru/data/signer/"; // Путь к директории, в которой лежит .kwm
$Path_Signer = "/home/site.ru/data/signer/wmsigner"; // Путь к WMSigner

// ФУНКЦИЯ ФОРМИРОВАНИЯ ПОДПИСИ
// На входе: строка для подписи. На выходе: строка с результатом подписывания
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;
}
Создадим также скрипт test.php, подключающий wmxml.inc.php и вызывающий функцию _GetSign():
Код:
// test.php - скрипт для тестирования
include("wmxml.inc.php");
echo _GetSign("blablabla");
Оба файла поместим в каталог web-документов /home/site.ru/data/htdocs/, запустим test.php. Если строка с подписью отобразилась, значит всё работает нормально.

Теперь остановимся и обратим внимание на два момента. Момент первый. Зачем эта строка в функции _GetSign():
Код:
chdir($Path_Folder);
Дело в том, что когда запускается скрипт test.php, то текущим рабочим каталогом является каталог, в котором находится сам скрипт, то есть /home/site.ru/data/htdocs/. Вызваный функцией _GetSign() WMSigner находит в своем каталоге wmsigner.ini, считывает из него путь к ключам 123456789012.kwm и пытается найти его начиная от текущего рабочего каталога, то есть по адресу /home/site.ru/data/htdocs/123456789012.kwm. Там он его, естественно, не обнаруживает.

Для того, чтобы WMSigner правильно нашел файл ключей, мы с помощью php-функции chdir() принудительно установливаем в качестве текущего каталога директорию, в которой находится 123456789012.kwm. Директорию эту мы заранее прописываем в переменную $Path_Folder.

Другой вариант решения вопроса: в wmsigner.ini сразу прописывать полный путь к файлу .kwm начиная от корня сервера (см. пример). Тогда WMSigner будет всегда точно знать, где ему искать .kwm. В этом случае вызов chdir($Path_Folder) можно не использовать.

Момент второй - это использованная php-функция proc_open(). Она появилась в PHP версии 4.3.0. Если у вас установлен PHP более старой версии, вы можете применять php-функцию popen(). C ней пользовательская функция формирования подписи _GetSign() будет выглядеть так:
Код:
// АЛЬТЕРНАТИВНАЯ ФУНКЦИЯ ПОДПИСИ ДЛЯ 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;
}
Примечание! Проверить доступность той или иной функции в вашей сборке PHP можно стандартной php-функцией function_exists(), например: function_exists("proc_open"). Если получаем в ответ TRUE ("1"), то функция proc_open() доступна.

Вызовы WMSigner с опциями командной строки
Мы познакомились со стандратным вызовом модуля WMSigner, когда "на вход" ему подается только строка для подписи, а все остальные данные модуль пытается отыскать самостоятельно. Напомним, как ведет себя WMSigner "по умолчанию":
1) ищет файл wmsigner.ini в своем каталоге;
2) читает из wmsigner.ini WMID, код доступа и путь к файлу .kwm;
3) обращается к файлу .kwm, чтобы сформировать подпись.

Как видим, никакой особой гибкости и адаптируемости под нужды программиста здесь нет. Однако, на самом деле, так шаблонно WMSigner ведет себя только "по умолчанию", и с помощью параметров командной строки можно полностью управлять его поведением.

Вот какие опции поддерживаются:

  • -i [ini-path] -- путь к ini-файлу;
  • -w [wmid] -- WMID;
  • -p [password] -- код доступа;
  • -k [key-path] -- путь к файлу ключей;
  • -K64 [key-base64] -- ключ (содержимое файла .kwm) в base64 закодированном виде;
  • -s [sign] -- строка для подписи.
Приведем пример. Для этого снова зайдем через shell в каталог /home/site.ru/data/signer/, где лежит wmsigner. Напомню, раньше мы делали стандартный вызов:

$ echo -ne "TestString123\004\r\n" | ./wmsigner
Но мы можем, например, передать ему на вход параметр -i и указать путь к ini-файлу. В следующем примере wmsigner получает команду искать не wmsigner.ini, а my.ini в той же директории, где лежит он сам:

$ echo -ne "TestString123\004\r\n" | ./wmsigner -i my.ini
А так wmsigner будет искать не wmsigner.ini, а /home/site.ru/trulala.goaway (обратите внимание, что конфигурационный ini-файл может иметь расширение, отличное от "ini" или даже вообще не иметь расширения!):

$ echo -ne "TestString123\004\r\n" | ./wmsigner -i /home/site.ru/trulala.goaway
Но использовать ini-файл вообще не обязательно. Можно передать все три необходимых параметра - WMID, код доступа и путь к ключам - прямо на вход модуля аутентификации, вот так:

$ echo -ne "TestString123\004\r\n" | ./wmsigner -w 123456789012 -p akwru3kdn -k 123456789012.kwm
Но и это еще не всё. Можно вообще не держать файл .kwm на сервере, а передавать на вход WMSigner'у ключ в кодировке Base64, интерпретирующей байтовую информацию в ввиде последовательности простых символов, через опцию командной строки -K64:

$ echo -ne "TestString123\004\r\n" | ./wmsigner -w 123456789012 -p akwru3kdn -K64 здесь_длинная_
последовательность_символов_в_кодировке_base64

Для полноты картины продемонстрируем, как сконвертировать бинарный файл .kwm в кодировку Base64. Это можно сделать с помощью такого php-кода:
Код:
$fn="123456789012.kwm";
$handle=fopen($fn,"r");
$contents = fread($handle, filesize($fn));
fclose($handle);
$b64 = base64_encode($contents);
В переменную $b64 запишется содержимое нашего файла 123456789012.kwm, кодированное в Base64.

Такой подход при работе с WMSigner, когда все необходимые параметры передаются ему через командную строку, имеет много преимуществ. Мы можем хранить ini-файл и файл ключей в любом месте на сервере, где нам только заблагорассудится. Можем давать им произвольные названия. Можем вообще не хранить эти файлы на сервере, а вместо этого "вшивать" wmid, код доступа и ключ прямо в код программы. Можем держать их в базе данных. Можем применять дополнительное шифрование и другие методы защиты.

Возвращаясь к нашей функции формирования подписи _GetSign(), вызов wmsigner с опциями командной строки отразиться только на одной строке php-кода:
Код:
$process = proc_open($Path_Signer." -опция параметр -опция параметр ...", $descriptorspec, $pipes);
То есть видоизмененная функция _GetSign будет выглядеть, например, так:
Код:
// ФУНКЦИЯ ФОРМИРОВАНИЯ ПОДПИСИ
// На входе: строка для подписи. На выходе: строка с результатом подписывания
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." -w 123456789012
     -p akwru3kdn -k 123456789012.kwm", $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;
}
На этом всё. В ближайшие дни читайте следующую статью, в которой мы перейдем к изучению непосредственно самих XML-интерфейсов WebMoney. Скомпилированный и настроенный WMSigner, а также функция _GetSign() нам в этом пригодятся.

Источник http://owebmoney.ru/
 
Последнее редактирование:
Верх