четверг, 24 июля 2008 г.

Описание “Click&Buy UkrMoney.com”

Система “Click&Buy UkrMoney.com” (далее Click&Buy) позволяет производить мгновенную оплату товаров и услуг со страниц Интернет-магазина, являющегося клиентом системы UkrMoney.com.

Продавец генерирует ссылку или форму, по которой покупателя переадресовывает на страницу платёжной системы, где он может произвести оплату или отменить ее. После чего, посетитель перенаправляется на заранее определённый URL. При переадресации передаются параметры с помощью которых можно определить была ли произведена оплата или нет (в том числе используется «маркер» по которому определяется достоверность оплаты).Кроме этого, продавец может настроить систему оповещений «об удачной оплате» и «О неудачной оплате» (отмене оплаты пользователя) собственные веб - скрипты в обход пользователя (см. далее настройки merchant).

Описание “Click&Buy UkrMoney.com”

Система “Click&Buy UkrMoney.com” (далее Click&Buy) позволяет производить мгновенную оплату товаров и услуг со страниц Интернет-магазина, являющегося клиентом системы UkrMoney.com.

Продавец генерирует ссылку или форму, по которой покупателя переадресовывает на страницу платёжной системы, где он может произвести оплату или отменить ее. После чего, посетитель перенаправляется на заранее определённый URL. При переадресации передаются параметры с помощью которых можно определить была ли произведена оплата или нет (в том числе используется «маркер» по которому определяется достоверность оплаты).Кроме этого, продавец может настроить систему оповещений «об удачной оплате» и «О неудачной оплате» (отмене оплаты пользователя) собственные веб - скрипты в обход пользователя (см. далее настройки merchant).

вторник, 22 июля 2008 г.

Программная выписка счета в системе WebMoney

Процесс: * Пользователь заходит на страницу, вписывает свой WMID (идентификатор, получаемый при регистрации в системе WebMoney), нажимает кнопку "оплатить" и ему приходит счет для оплаты. * Пользователь платит по счету и переходит по ссылке, указанной в параметрах счета и получает товар.
Следовательно для этого потребуются 2 программы: * Программа обработки данных формы и выписки счета на WMID пользователя. * Программа проверки оплаты счета и выдачи товара.
Для выписки счета на WMID пользователя необходимо выполнить следующий https запрос: https://w3s.webmoney.ru/asp/Invoice.asp?SL=LoginOfStores& SP=PurseOfStores& CL=LoginOfCust& IN=OrderID& D=Desc& AD=InvAddress& A=Amount& E=Experation& P=Period& RN=RequestN& SS=SignStr (эта инофрмация приведена на сайте системы WebMoney, однако если бы задача решалась так просто, я бы не написал эту статью). Теперь про каждый параметр подробнее:


SL=LoginOfStores - WM-идентификатор web-ресурса (просто регистрируете нового пользователя в системе WebMoney для приема платежей с сайта и указываете его WMID);SP=PurseOfStores - кошелек Web-ресурса (номер кошелька, на который будут совершаться платежи - кошелек пользователя с WMID из первого пункта);CL=LoginOfCust - WM-идентификатор покупателя (этот параметр указывает пользователь, программа получает данные из формы);IN=OrderID - номер счета (номер заказа) на Web-ресурсе (в магазине). Номер генерируется программой (1) самостоятельно и хранится в базе Web-ресурса (магазина, сервиса) - по этому номеру в дальнейшем будет определятся состояние счета (оплачен или нет). (номер должен быть целым числом);D=Desc - описание товара, за который выписывается счет. Параметр должен быть строкой от 0 до 255 символов;AD=InvAddress - адрес доставки товара. Параметр должен быть строкой от 0 до 255 символов (сюда будем писать ссылку, по которой пользователь сможет получить товар. Это будет ссылка на программу (2), которой будет передаваться параметр IN=OrderID);A=Amount - сумма счета. Данный параметр формируется программой (1). Параметр должен быть числом с плавающей точкой (разделитель - точка);E=Experation - срок действия счета в днях (целое число от 0 до 255);P=Period - срок действия протекции сделки. Параметр формируется программой (1). (максимальный срок протекции сделки при оплате счета, если указать здесь 0, то счет не будет иметь срока протекции);RN=RequestN - этот параметр является уникальным возрастающим числом. Параметр формируется программой (1) и должен быть всегда больше такого же параметра, указанного в предыдущем запросе. Лучше всего формировать этот параметр из текущего года, месяца, дня, часа, минуты, секунды и сотых секунд. (должен быть целочисленным 16-ти разрядным значением);SS=SignStr - цифровая подписью запроса. Он гарантирует то, что именно ваш Web-ресурс выписал счет.

При подготовке https запроса Основной проблемой является формирование именно SS=SignStr. Сначала должна быть сформирована строка PlanStr как сумма параметров OrderID, LoginOfCust, PurseOfStores, Amount, Desc, InvAddress, Period, Experation, RequestN, описанных выше и точно в таком же порядке. После этого необходимо из строки подписи PlanStr сделать строку цифровой подписи SignStr, для этого используется специальный модуль WMSigner, которому на вход подается строка PlanStr, а он возвращает SignStr.
Исходные коды модуля можно скачать, перейдя по ссылке: go.php?url=download.webmoney.ru/WMSigner.zip, после чего модуль надо будет скомпилировать под ту операционную систему, на которой работает Ваш сайт. Можно отправить этот архив администрации вашего хостинга и попросить скомпилировать, а можно попытать удачу самому, для этого создадим файл poehali.pl со следующим кодом:

#!/usr/bin/perlsystem('g++ cmdbase.cpp crypto.cpp md4.cpp rsalib1.cpp signer.cpp wmsigner.cpp');
print "Content-type:text/html\n\n";print "И все-таки она вертится!";


Теперь создадим папку (ну, например wm) в корневом каталоге сайта и скопируем туда наш скрипт и содержимое архива WMSigner. Права доступа к нашему скрипту необходимо поставить 711. Теперь из строки браузера следует запустить скрипт poehali.pl (записать строку, например go.php?url=www.zahodi-ka.ru/wm/poehali.pl) и подождать ответа скрипта. Если на сервере есть компилятор G++ и необходимые модуля, то в папке wm после запуска окажется файл a.out, который нужно переименовать в wmsigner (маленькими буквами).
Когда модуль уже готов, можно приступить к написанию программы (1), которая и будет его вызывать. В документации на сайте системы WebMoney вызов осуществляется с помощью функции open2, однако такой вариант работает не всегда, поэтому мы будет вызывать с помощью функции system. Создадим программу (назовем ее wschet.pl):

#!/usr/bin/perl
sub dopprobelz # функция дополнения строки нулями вначале{my($str)=@_[0];my($len)=@_[1]; my $delta=$len-length($str);my $hwost='';for (my($a)=0; $a<$delta; $a++) {$hwost=$hwost.'0';};$str=$hwost.$str; return $str;};# подключение модулейuse FileHandle;use IPC::Open2;use CGI;use Socket;use LWP::UserAgent;
# задание параметров запроса# сюда укажите свои данные$OrderID = '999'; # номер счета на Вашем сайте$PurseOfStores ='Z406593169293'; # кошелек сайта$LoginOfStores = '321373645120'; # WMID сайта$LoginOfCust = '083872782699'; # WMID покупателя, зададим как константу$InvAddress = 'INVADDRESS'; # адрес$Amount = '10'; #сумма счета, которую должен оплатить покупатель$Desc = 'DESC'; # описание$Period = '0'; #Срок протекции сделки$Experation = '3'; #Срок действия счета - 3 дня
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time());$RequestN=(1900+$year).dopprobelz($mon, 2);$RequestN=$RequestN.dopprobelz($mday, 2).dopprobelz($hour, 2);$RequestN=$RequestN.dopprobelz($min, 2).dopprobelz($sec, 2).dopprobelz($sec, 2);
$PlanStr="$OrderID$LoginOfCust$PurseOfStores$Amount";$PlanStr=$PlanStr."$Desc$InvAddress$Period$Experation$RequestN";
print "Content-Type: text/html\n\n";
print "Строка подписи \$PlanStr: $PlanStr


";
# вызов модуля WMSigner
pipe(IN,OUT); # создание канала связи (пишешь в OUT, читаешь из IN)OUT->autoflush(1);$pid = open(CHILD,"-"); # разделение на 2 процесса#связывание ввода доч. проц. с дескриптором CHILDif ($pid != 0){ ## если данный поток - родительclose(OUT); # Родителю OUT не нужен, будет писать через CHILDprint CHILD $PlanStr."\004\r\n"; # передача параметров потомкуclose(CHILD); # передача закончена, дескриптор не нужен$SignStr=$_ while (); # Получение данных от клонаclose(IN);waitpid($pid,0);}else{ #### если клон(потомок)close(IN);open(STDOUT,">&=OUT"); # замена стандартного вывода на дескр. OUTclose(OUT);system('./wmsigner'); # запуск модуля WMSigner (будет возвращать данные в OUT)exit;};
print "Цифровая подпись (возвращена WMSigner'ом): $SignStr


";
$W3sUrl="
https://w3s.webmoney.ru/asp/Invoice.asp?SL=$LoginOfStores&";$W3sUrl=$W3sUrl."SP=$PurseOfStores&CL=$LoginOfCust&IN=$OrderID&D=$Desc&";$W3sUrl=$W3sUrl."AD=$InvAddress&A=$Amount&E=$Experation&P=$Period&";$W3sUrl=$W3sUrl."RN=$RequestN&SS=$SignStr";
print "HTTPS запрос к системе:
".$W3sUrl."


";
$ua2 = LWP::UserAgent->new; $res2=$ua2->get($W3sUrl);$buf=$res2->content;
print "Ответ системы:
".$buf; # Далее необходимо произвести разбор буфера и запись счета в базу данных магазина


К этой программе следует положить в папку скомпилированный модуль WMSigner(права доступа 711), резервную копию ключей (при запуске Keeper запросит создать резервную копию кючей и задать пароль для этой копии, после создания скопируйте файл *.kwm на сайт к программе wschet.pl и переименуйте его в keys.kwm, выставьте ему права доступа 440) и файл wmsigner.ini (права доступа 440) следующего содержания

WMID
pass.
/keys.kwm

Где WMID - идентификатор магазина, pass - пароль от резервной копии ключей, ./keys.kwm - путь к файлу ключей.
Теперь детально разберем способ запуска модуля wmsigner из нашей программы. Для вызова модуля используется функция system(), которая связывает потоки ввода-вывода вызываемого процесса с потоками ВВ вызывающей процесс программы, то есть данные, переданные вызывающей программе извне будет получать и запущенный функцией system() процесс и данные, возвращаемые процессом будут выводиться туда же, куда и данные вызывающей программы (в нашем случае в браузер пользователя, что нежелательно). Для разделения потоков ВВ наша программа сначала создает клона, потом этот клон вызывает процесс WMSigner и получает от него данные, а основная программа получает данные уже от своего клона, процесс создания клона и переопределения его стандартного дескриптора ввода на CHILD реализован с помощью функции $pid = open(CHILD,"-").
Если модуль выдаст ошибку -3, знайте, что в wmsigner.ini Вы указали пароль не от резервной копии ключей или скопировали не резервную копию ключей.