Прием платежей для мобильных телефонов через кассу RK6
Вводная информация
Система R-KEEPER v6 позволяет принимать платежи для сотовых телефонов. Можно сразу вносить деньги на счёт или печатать код активации. Для этого необходимо создать спец. Библиотеку Ipay.dll для связи с внешним сервером авторизации. Пример кода библиотеки приведён в конце документа. Библиотеку разрабатывает разработчик системы авторизации или заказчик.
Как это работает
- В системе создаётся спец блюдо «Платёж» с ценой = 1. Можно назначить отдельную категорию – для скидок и ограничения оплат. Например: счёт нельзя пополнить бонусами.
- Кассир пробивает это блюдо на кассе. Количество выбирает такое, чтобы сумма этого блюда была равна сумме, которую клиент собирается положить на счёт. В счёте могут быть и другие блюда, не связанные с платежами.
- Для того чтобы началась авторизация платежа, кассир нажимает «Оплата». Затем выбирает тип оплаты и вводит сумму, которую дал клиент. Далее - "Ввод".
- Кассир выбирает оператора сотовой связи, вводит номер телефона и дату платежа (если нужно). Нажимает "Ввод" - начинается авторизация платежа.

Если выбрана в качестве оплаты кредитная карточка и в системе установлена авторизация кред. карточек, то в первую очередь начинается авторизация кредитной карточки, а только потом кассир выбирает оператора и номер телефона.
Если авторизация платежа была успешно проведена, печатается финальный чек и чек авторизации. В чеке может печататься любая информация, которую передаёт сервер авторизации через библиотеку Ipay.dll.
Если авторизация платежа не прошла успешно, кассиру выводится информация на экран. Данную информацию передаёт разработчик сервера авторизации и библиотеки Ipay.dll.
Установка
Для приема платежей необходимо установить сервер «MobPay»:
в MobPay.ini указывается имя сервера. Секция [RNBL], параметр Server
В папке запуска сервера должны находится библиотеки RNBL.dll и ipay.dll.
Сервер можно запустить и как службу (ключь –install), и как приложение (ключ –desktop)
На кассе в файле RKEEPER6.INI необходимо добавить следующие параметры:
MOBDish=96 - Код блюда-платежа (см. выше) MobilPayServer=MOBSERV - Имя сервера MobPay (см. выше)
DLL компании ЗАО «Кардлинк»
Для связи с внешней БД компании «Кардлинк» их программистами были написаны модули связи для использования c нашим сервером «MobPay».
- Необходимо на компьютере, где работает MobPay проинсталлировать Microsoft .NET Framework 2.0
- В директорию сервера MobPay скопировать следующие DLL : IndigoClient.dll, IndigoSigner.dll, ipay.dll, Lzwpi.dll, mpi.dll, dict.dic.
- Зарегистрировать компонент IndigoClient.dll при помощи команды (regasm.exe IndigoClient.dll)
- Запустить сервер MobPay. При верных настройках в каталоге сервера должен появиться лог файл (componentDebug.txt).
Схема взаимодействия программного обеспечения для принятия платежей:
Касса R-KEEPER -----> Server MobPay -----> Ipay.dll -----> Сервер авторизации
Версии
Касса RKeeper – 6.76а и выше
MobPay –1.01 и выше
Пример Ipay.dll
{Для интеграции системы внешних оплат нужно сделать такую DLL. Данная возможность в первую очередь предназначена для оплаты мобильных телефонов. Наш пример на DELPHI}.
library ipay;
uses
SysUtils;
{$R *.RES}
type
{Эти типы предназначены для обмена данными с библиотекой}
Tline=array[0..39] of char;
{Для получения списка видов оплат (тел операторов)}
PPaylist=^TPayList;
TPayList=Packed Record
Count:SmallInt; {количество заполненных элементов List}
List:Array [1..50] of packed record
Code:SmallInt; {код для дальнейшеq ccылки}
Name:Tline; {Наименование оператора(услуги)}
end;
end;
Pformat=^Tformat;
TFormat= Packed Record {Для получения данных от кассира}{Передается и текст и поля для заполнения}
Code:SmallInt; {Код оператора (из paylist.list[i].code)}
Amount:Double; {Сумма к оплате}
Count: SmallInt; {количество заполненных элементов List}
list: array [1..15] of packed record
flag:byte; {=1 - поле ввода =0 - коментарий}
Field:TLine; {тект или макет для ввода}
end;
end;
PPrintLines=^TPrintLines;
TPrintLines=Packed record {Для печати чека}
Count:SmallInt;
List:Array[1..70] of Tline;
end;
{Касса вызывает для получения списка доступных видов оплат}
Procedure GetPaysList(PayList:PPayList);stdcall;
begin
PayList.Count:=4;
PayList.List[1].Code:=101;
PayList.list[1].Name:='БиЛайн'#0;
PayList.List[2].Code:=102;
PayList.list[2].Name:='МТС'#0;
PayList.List[3].Code:=200;
PayList.list[3].Name:='Мегафон'#0;
PayList.List[4].Code:=300;
PayList.list[4].Name:='СкайЛинк'#0;
end;{Касса заполняет поле Code Amount }
Procedure GetFormat(Format:PFormat);stdcall;
begin
{Формат ввода может быть разным для разных платежей, но я этого делать не буду}
case format.Code of
101:
format.list[1].Field:='Был выбран БиЛайн'#0;
102:
format.list[1].Field:='Был выбран МТС'#0;
200:
format.list[1].Field:='Был выбран Мегафон'#0;
300:
format.list[1].Field:='Был выбран СкайЛинк'#0;
end;
format.Count:=6;
format.list[1].flag:=0;
format.list[2].Field:='Введите номер телефона:'#0;
format.list[2].flag:=0;
format.list[3].Field:='( ) - - '#0;
Format.list[3].flag:=0;
Format.list[4].Field:='Введите дату активизации платежа'#0;
Format.list[4].flag:=0;
Format.list[5].Field:='В формате ДД-ММ-ГГ'#0;
Format.list[5].flag:=0;
Format.list[6].Field:=' / / '#0;
Format.list[6].flag:=0;
end;
{Это вспомогательная функция}
procedure FillLines(s:String;Lines:PPrintLines);
var ps:Integer;
procedure Add(ss:String);
begin
if Lines.Count=70 then exit;
Inc(Lines.Count);
ss:=copy(ss,1,39)+#0;
move(ss[1],Lines.list[Lines.count],length(ss));
end;
begin
Lines.Count:=0;
while s<>'' do begin
ps:=Pos('\',s);
if ps=0 then ps:=Length(s)+1;
Add(copy(s,1,ps-1));
s:=copy(s,ps+1,length(s));
end;
end;
{В Format все поля заполнены. При этом поля ввода заполнены так, как их заполнил кассир. Функция возвращает хэндл транзакции. В случае отказа нужно вернуть (-1).
В этом случае Lines заполнябт сообщение об ошибке, которое будет показано кассиру. В случае нормального заполения Lines заполняют сообщением для печати}
Function StartTransaction(Format:PFormat;lines:PPrintLines):Integer;stdcall;
var s:ShortString;
begin
{Для примера проверяем что МТС имеет код 916}
s:=StrPas(format.list[3].Field);
case format.Code of
102: begin
if copy(s,2,3)<>'916' then begin
Result:=-1;
FillLines('Номер телефона:\'+s+'\не относится к данному оператору',Lines);
exit;
end;
end;
{и т д}
end;
Result:=101;
FillLines('Прием платежей мобильной связи\'+
'------------------------------\'+
'Платеж на сумму:'+FloatToStr(format.Amount)+'\'+
'Телефон: '+s+'\'+
'Комиссия в размере:............\'+
'................................\'+
'................................\'+
'-------------------------------',Lines);
end;
{Окончательно провести транзакцию}
{Транзакция следует отменить усди она не будет завершега в течении нескольких секунд}
procedure FinishTransaction(hnd:Integer);
begin
end;
exports GetPaysList,GetFormat,StartTransaction,FinishTransaction;
begin
end.