Введение

Требования к процессинговому серверу:

  • Сервер может отдавать ответ, используя http или https
  • Кодировка XML — только UTF-8
  • Обязательно использование getcardinfoex и transactionsex. Остальные функции являются опциональными

Требования к ПО:

  • Farcards версии 6.04 и выше

Dll состоит из 2-х модулей:

  • Dll для Farcards, ExtDllHTTP.dll
  • Утилита для работы с лицензированием, Http_LicGen.exe

Описание ExtDllHttp.ini

Файл ExtDllHttp.ini используется обоими модулями.

[Server]
;Точка входа процессингового сервера
Address=http://192.168.101.141:80
;адрес обработчика функции GetCardInfoEx, т.е. это выполнится http://192.168.101.141:80/getcardinfoex.php
GetCardInfoEx=getcardinfoex.php
;адрес обработчика функции TransactionsEx
TransactionsEx=transactionsex.php
;адрес обработчика функции FindEmail
FindEmail=findemail.php
;адрес обработчика функции GetCardImageEx
GetCardImageEx=getcardimageex.php
;адрес для нотификации ошибок лицензирования
LicenseInfo=licenseinfo.php

;Прокси используется для запросов к системе лицензирования rkeeper
[Proxy]
;Использовать прокси (1-да, 0 - нет)
UseProxy=0
BasicAuthentication=0
Server=127.0.0.1
Port=9944
UserName=
Password
CODE

Получение информации по карте

Вызывается метод по адресу, определенному параметром getcardinfoex

Метод: POST

Пример тела запроса:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<QRY Card="8002" Restaurant="9999" UnitNo="2">
    <INPBUF>
    <CHECK stationcode="2" restaurantcode="199999999" cashservername="FOCUS_MIDSERV2" generateddatetime="2013-08-2116:2316:23:56">
    <EXTINFO>
        <INTERFACES>
            <INTERFACE type="PDS" id="1" mode="0">
                <HOLDERS>
                    <ITEM cardcode="8002"/>
                </HOLDERS>
            </INTERFACE>
        </INTERFACES>
    </EXTINFO>
    </CHECK>
    </INPBUF>
</QRY>
</ROOT>
XML

Где:

Пример ответа:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 08:22:20 GMT
Content-Length: 346
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0" encoding="utf-8"?>
<Root>
    <GetCardInfoEx CardCode="8002" Account="8002" Deleted="0" Locked="0" Seize="0" Discount="25" Bonus="4" 
    Summa="15000" DiscLimit="10000" Holder="Test farcards person 8002" unpay="4" 
    Sum2="2000" Sum3="3000" Sum4="4000" Sum5="0" 
    DopInfo="additional info" WhyLock="" 
    ScrMessage="** Message for SCREEN **" 
    PrnMessage="* Message for PRINT *" Result="0" >
 
        <OutBuf OutKind="4">
            <ident_info>
              <overide_info code="123456"/>
              <parent_ident code="4547059" printname="Василий Петрович"/>
                          <item_content hint="Ваш купон позволяет выбрать 2 товара из первой группы и любой товар из второй.">
                          <group name="group name" printname="Имя группы" order="1" maxquant="2">
                                  <item code="123" kind="summ" val="10.00" order="3" max="3" default="1" disccode="13"/>     
                                  <item code="321" kind="percent" val="10.00"order="2" max="2" disccode="123"/>            
                                  <item code="213" kind="price" val="10" order="10" max="1"  />                 
                          </group>
                          <group name="group name2" printname="Имя группы2" order="2">
                                  <item code="423" kind="summ" val="130" order="1" line_id="433242" />     
                                  <item code="621" kind="percent" val="1230"order="3" />            
                                  <item code="713" kind="price" val="110" order="2" />          
                          </group>     
                          </item_content>
            </ident_info>  
        </OutBuf>
    </GetCardInfoEx>
</Root>
XML

Здесь важен Result:

  • 0 — без ошибок, структура Info заполнена  
  • 1 — карта не существует

Пример ответа, когда карта не найдена:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 08:23:20 GMT
Content-Length: 346
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0" encoding="utf-8"?>
<Root>
    <GetCardInfoEx  Result="1" />
</Root>
XML

Получение изображения по карте

Вызывается метод по адресу, определенному параметром getcardimageex.

Метод: POST
Пример тела запроса:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
    <QRY CardCode="8002"/>
</ROOT>
XML

Где

  • Code — номер карты

В зависимости от того, было ли найдено изображение, вариант ответа будет разным.

Если изображение было найдено, то ответ может выглядеть следующим образом:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 08:22:20 GMT
Content-Length: 5862
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/jpg
CODE

И будет получена картинка средствами DLL.

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

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 08:22:20 GMT
Content-Length: 125
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0"?>
<Root>
<GetCardImageEx ErrorText="Card or image not found"/>
</Root>
CODE

Поиск счета по e-mail

Вызывается метод по адресу, определенному параметром findemail.

Метод: POST

Пример тела запроса:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
    <QRY Email="director@rkeeper.ru"/>
</ROOT>
CODE

Где

  • E-mail — интересующий e-mail.

Пример успешного ответа:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 12:40:51 GMT
Content-Length: 123
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0"?>
<Root>
<FindEmail Account="8002" CardCode="8002" Name="rkeeper director" Result="0"/>
</Root>
CODE

Пример ответа, если счет не найден:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 12:40:51 GMT
Content-Length: 123
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0"?>
<Root>
<FindEmail  Result="1"/>
</Root>
CODE


FarCards: список команд CQXXXX - протокол связи кассового сервера с FarCards

Поиск счетов

запрос:

CQFindA Byte
Kind: Byte; 1 - по email, 2 - по номеру комнаты, 3 - по QR коду; Тип данных для поиска
StringSize: Byte; Размер строки для поиска
StringData: string; Данные строки для поиска. Кодировка UTF-8 или ANSI
CODE


ответ:

ErrorCode: Byte; Код ошибки, i.e. CErrOk = 0
Account: integer; Идентификатор счёта
CardData: int64; Код карты
HolderSize: byte; Размер поля держатель карты
HolderText: string; Держатель карты (клиент). Кодировка UTF-8 или ANSI
CODE


Запросить значения скидок и бонусов для карты за определенный период

запрос:

CQCHist Byte
CardCode Int64
Start TDateTime
Stop TDateTime
CODE

ответ:

Error Byte ; CErrOk
N блоков (N >= 1) вида:
Start TDateTime с этого момента и до следующего
Discount Smallint номер скидки
Bonus Smallint Номер бонуса
DenyPay Byte 0 - разрешена оплата; не 0 - запрещена оплата
CODE


Запросить информацию о дисконтном уровне 

Этот запрос реализован с версии Cardserv 7.10


запрос:

CQAccDL Byte
Account Longint
CODE

ответ:

Error Byte ; см коды ошибок CE...
CurName String ; Название текущего дисконтного уровня. Если счет не использует дисконтных уровней, то ''
NextName String ; Название следующего дисконтного уровня. Если текущий является последним, то ''
ToNext Comp ; Сколько санти-баллов до следующего уровня. Если текущий является последним, то 0.
CODE


Запросить сумму транзакций за стандартный период

запрос:

CQAccSum Byte
Account Longint
Period Byte ; 2-день 3-неделя 4-месяц
CODE

ответ:

Error Byte ; 
Sum1 Comp ; сумма взносов (+)
Sum2 Comp ; сумма оплат (-)
Sum3 Comp ; сумма скидок (-)
Sum4 Comp ; сумма бонусов (+)
CODE


Передать XML информацию о чеке

запрос:

CQInfoch Byte
CardCode Int64 Номер карты
Info Bytes Здесь информация о чеке, сжатая LZ
CODE

ответ:

Error Byte
CODE


Проверяет к какому серверу подключился и по какому максимальному протоколу работает

запрос:

CQIdent Byte
CODE

ответ:

Ident Longint ; $AC123456
MaxProt Word ; Максимальный протокол, поддерживаемый сервером
Can_UTF8 Byte ; если 1, то есть возможность общаться в UTF-8
CODE


Сообщает серверу по какому протоколу касса хочет работать и с какими правами

без этого будут права ReadOnly


запрос:

CQSetProt Byte
Protocol Word ; указывать желаемый протокол
Access Byte ; указывай CACash
{добавлено с протокола 31, необязательные поля}
LP Word 
Use_UTF8 Byte ; если =1 и сервер поддерживает UTF-8 
CODE

ответ:

Error Byte ; если CErrOk - нормально.
если Error = CErrProt, то еще
MaxProt Word ; предельный номер протокола
CODE


Паркинг XML для DOS кассы 

Этот запрос реализован с версии Farcards 6.03

Запрос:

CQParseXml Byte
CodePage Longint ; Требуемая кодировка строк, если 0, то будет взята
настройка в Farcards.ini "XMLCP"
OptLen Word ; длина следующей за этим доп. информации
OptInf Bytes ; XML, упакованный LZ
CODE

ответ:

Error Byte ; 0-Ok, и есть остальные поля
Parsed Byte ; 0-Exception в парсинге, текст в Value; 1-без ошибок
CodePage Longint ; Кодировка строк
OutLen Longint ; длина следующей за этим информации в спец. формате
OutBuf Bytes
CODE


Транзакции для кассового чека

Вызывается метод по адресу, определенному параметром transactionsex.

Метод: POST

Пример тела запроса:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <Transactions>
        <TransactionsEx  Card="32" PersonID="202" Account="145" Kind="160" Summa="15" Restaurant="73" RKDate="2014-08-14T00-00-00" RKUnit="201" RKCheck="139" VatSumA="86" VatPrcA="143" VatSumB="125" VatPrcB="146" VatSumC="93" VatPrcC="119" VatSumD="28" VatPrcD="189" VatSumE="161" VatPrcE="72" VatSumF="178" VatPrcF="80" VatSumG="82" VatPrcG="42" VatSumH="200" VatPrcH="127"/>
        <TransactionsEx  Card="3" PersonID="143" Account="127" Kind="157" Summa="202" Restaurant="73" RKDate="2014-08-14T00-00-00" RKUnit="201" RKCheck="139" VatSumA="77" VatPrcA="59" VatSumB="186" VatPrcB="121" VatSumC="7" VatPrcC="125" VatSumD="254" VatPrcD="161" VatSumE="253" VatPrcE="36" VatSumF="87" VatPrcF="45" VatSumG="178" VatPrcG="81" VatSumH="47" VatPrcH="185"/>
        <TransactionsEx  Card="152" PersonID="86" Account="181" Kind="229" Summa="206" Restaurant="73" RKDate="2014-08-14T00-00-00" RKUnit="201" RKCheck="139" VatSumA="160" VatPrcA="210" VatSumB="93" VatPrcB="120" VatSumC="22" VatPrcC="117" VatSumD="67" VatPrcD="95" VatSumE="199" VatPrcE="95" VatSumF="100" VatPrcF="228" VatSumG="51" VatPrcG="162" VatSumH="56" VatPrcH="190"/>
    </Transactions>
 
    <INPBUF>
        <CHECK stationcode="6" restaurantcode="199999999" cashservername="SHOWRK7MIDSRV1" generateddatetime="2015-05-29T19:09:20" chmode="0">
        <EXTINFO reservation="0">
                    <INTERFACES current="1007682">
                        <INTERFACE type="PDS" id="1007682" mode="0">
                        <HOLDERS>
                                  <ITEM cardcode="777777"/>
                        </HOLDERS>
                        </INTERFACE>
                    </INTERFACES>
        </EXTINFO>
        </CHECK>
 
     </INPBUF>
  </Root>
CODE

Где:

  • Card — карта
  • PersonID — идентификатор владельца карты
  • Account — номер счета
  • Kind — тип транзакции
  • INPBUF — буфер, содержащий XML, в котором лежит расширенная информация о карте и чеке. Подробнее читайте в статье XML описание кассового документа для предоставления внешним системам.
    • 0 — платеж: снятие денег со счета
    • 1 — скидка
    • 2 — бонус: начисление денег на счет
    • 3 — затраты гостя: сколько заплатил своих денег
  • Summa — сумма, в копейках:
    • Для типа 0 — платеж:
      • Оплата снятием денег с карты — отрицательная сумма
      • Отмена оплаты — положительная сумма
    • Для типа 1 — скидка:
      • Скидка клиенту — отрицательная сумма
      • Отмена скидки — положительная сумма
    • Для типа 2 — бонус:
      • Клиенту начисляется бонус — положительная сумма
      • Отмена бонуса — отрицательная сумма
    • Для типа 3 — затраты:
      • Клиент заплатил — положительная сумма
      • Отмена чека — отрицательная сумма.
  • Restaurant — код ресторана
  • RKDate — кассовая дата: 0 → 30/12/1899
  • RKUni — номер кассы
  • RKCheck — номер чека
  • Далее информация о налогах в чеке (8 штук)
    • VatSumA — сумма с налогом A
    • VatPrcA — размер налога A в процентах * 100 (1500 → 15.00%)
    • VatSumB — сумма с налогом B
    • VatPrcB — размер налога B в процентах * 100
    • VatSumC — сумма с налогом C
    • VatPrcC — размер налога C в процентах * 100
    • VatSumD — сумма с налогом D
    • VatPrcD — размер налога D в процентах * 100
    • VatSumE — сумма с налогом E
    • VatPrcE — размер налога E в процентах * 100
    • VatSumF — сумма с налогом F
    • VatPrcF — размер налога F в процентах * 100
    • VatSumG — сумма с налогом G
    • VatPrcG — размер налога G в процентах * 100
    • VatSumH — сумма с налогом H
    • VatPrcH — размер налога H в процентах * 100

Пример успешного ответа:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 12:56:25 GMT
Content-Length: 65
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0"?>
<Root>
<TransactionsEx Result="0"/>
                <OutBuf OutKind="1">
              <TRRESPONSE error_code="0" err_text="">
                         <TRANSACTION ext_id="1111111" num="222222" cardcode="777777" slip="Текст для печати" value="%d" />
                 </TRRESPONSE>          
          </OutBuf>
</Root>
CODE

Пример ответа с ошибкой:

HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 12:56:25 GMT
Content-Length: 65
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
 
<?xml version="1.0"?>
<Root>
<TransactionsEx Result="1"/>
                <OutBuf OutKind="1">
              <TRRESPONSE error_code="100500" err_text="Ошибка связи с банком"/>       
          </OutBuf>
</Root>
CODE

Нотификация об ошибках лицензирования

Предназначено для того, чтобы в случае ошибки лицензирования dll, сервер мог узнать об этом, получив XML с текстом ошибки. Вызывается метод по адресу, определенному параметром LicenseInfo.

Метод: POST

Пример тела запроса:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
    <QRY Restaurant="199990053" Status="License was expired"/>
</ROOT>
CODE

Особенности лицензирования

Утилита Http_LicGen.exe должна лежать рядом с dll.

  1. Закажите мастер-лицензию R-Keeper интерфейс Farcards-HTTP ПО
  2. Для генерации лицензии используйте утилиту Http_LicGen.exe. Для входа в приложение используйте дилерский логин и пароль
  3. Выберите нужный ресторан из списка
  4. Нажмите на кнопку Получить лицензию
  5. Выберите дату окончания лицензии. Узнать максимальную дату окончания лицензии автоматически 
  6. Нажмите на кнопку Далее…

При успешном запросе появится сообщение об успешном создании лицензии.

При возникновении ошибки, появится ее текст.

Приложение Http_LicGen.exe можно закрыть. Запустите Farcards.