Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 13
На сайте нет зарегистрированных пользователей

Пользователей: 13,368
новичок: Goosprin
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Лабораторная работа по динамическим спискам на Turbo Pascal (удаление ду...
Программа тестирования (тест) - вступительные экзамены (математика, физи...
Игра Sokoban на Delphi + Блок схемы

Программная выписка счета в системе WebMoney
Итак в настоящее время активно растет число интернет-магазинов, причем многие из них продают электронные товары (программы, шаблоны сайтов) или оказывают электронные услуги (ведение статистика сайта, доски объявлений, платные каталоги), да и завести себе свой собственный интернет-магазин не составит труда. И есть тому масса примеров - существует очень много мелких сайтов, продающих может быть только одну программу или электронную книгу. С этого же начинался сайт http://www.zahodi-ka.ru, первоначально созданный мной для продажи за символическую сумму самодельной игрушки. Продажа была организована как у всех подобных проектов - на страничке расписывался сложный процесс оплаты, результатом которого должен был стать лицензионный ключ от игрушки. По показаниям счетчика скачиваний можно было понять, что игрушку активно качают, однако за полгода мне пришло всего одно письмо с подобным содержанием: "Дай, пожалуйста, ключ от игрушки. От тебя ж сильно не убудет, если не получишь лишние 10 рублей". (дословно текст письма не вспомню, но было что-то похожее). Ключ я конечно же дал, коль просят, но вывод для себя сделал, что никто не купил именно потому, что платить просто было лень.

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

Процесс:

  • Пользователь заходит на страницу, вписывает свой 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.

Исходные коды модуля можно скачать, перейдя по ссылке: http://download.webmoney.ru/WMSigner.zip, после чего модуль надо будет скомпилировать под ту операционную систему, на которой работает Ваш сайт. Можно отправить этот архив администрации вашего хостинга и попросить скомпилировать, а можно попытать удачу самому, для этого создадим файл poehali.pl со следующим кодом:

#!/usr/bin/perl
system('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 (записать строку, например http://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<br><br><br>";

# вызов модуля WMSigner

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

print "Цифровая подпись (возвращена WMSigner\'ом): $SignStr<br><br><br>";

$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 запрос к системе:<br>".$W3sUrl."<br><br><br>";

$ua2 = LWP::UserAgent->new; 
$res2=$ua2->get($W3sUrl);
$buf=$res2->content;

print "Ответ системы:<br>".$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 Вы указали пароль не от резервной копии ключей или скопировали не резервную копию ключей.

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

Опубликовал Kest October 31 2008 15:56:57 · 0 Комментариев · 7997 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Архив значков
Java 2. Наиболее ...
Assembler. Практикум
Java 2 - Эффектив...
Converter AMR<->W...
Szwavepanel
PDJPack
Программирование ...
SUIPack
Berg
Пример работы с р...
База данных: Книж...
Binary2XMLDemo (Р...
ИНТЕРНЕТ ПРОГРАММ...
Язык программиров...
LaserTank [Исходн...
Добавление басса ...
Borland Delphi 8 ...
Рисование PopupMenu
С/C++ Программиро...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97833
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14191
Borland Delphi ... 10291
Turbo Pascal fo... 7373
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Mostbet ставки на...
9.4. Присоединени...
УПРОЩЕНИЕ МОДЕЛЕЙ ...
5.1. Автоматизация...
Использование техн...
Создание простого ...
Геотермальная энергия
Системный вызов ехес
Пределы числовых д...
Интерфейс и его де...
256 кбит/с, котора...
Пространство имен
Тянем-потянем за с...
Программирование д...
Воспроизведение ст...
Инициализация глоб...
Создание изображен...
Многостраничный ин...
SQL-функции для ...
consult(X)
Планирование имита...
В них можно включа...
Принудительное тун...
IP адрес, подсети,...
Создание нового са...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?