Пример интеграции iKKM на C++

Для начала нам потребуется Curl – как инструмент для передачи данных в URL-синтаксисе, поддерживающий HTTP.

Установка библиотеки CURL

Вам необходимо скачать самые свежие исходники CURL и распаковать архив (для сборки .dll (win) или .so (liniux) файлов).

в зависимости от платформы скачайте нужные исходники 

https://curl.haxx.se/download.html

Visual Studio 2015 сборка библиотеки Libcurl: 

запускаем Visual Studio Command Line Tool

заходим в директорию winbuild скаченного и разархивированного исходника

запускаем команды

Set RTLIBCFG=static

затем

nmake /f Makefile.vc mode=static VC=14 MACHINE=x64 DEBUG=no  // в случае сборки для 32 разрядных меняем х64 на x86 (если надо читаем BUILD.WINDOWS.txt)




в случае удачной сборки, получаем в новой директории ../builds/libcurl-vc14-x64-release-static-ipv6-sspi-winssl/lib

библиотеку libcurl_a.lib

интегрируем её в проект

1


Далее 

во вкладке VC++ Directories

выбираем Library Directories   и добавляем директорию где лежит libcurl_a.lib

во вкладке Configuration Properties –> Linker –> Input 

выбираем Additional Dependencies  добавляем сам фаил libcurl_a.lib
 

создаем .cpp 


#include "stdafx.h"
#include "httpWorker.h"

//объявляем буфер, для хранения возможной ошибки, размер определяется в самой библиотеке
static char errorBuffer[CURL_ERROR_SIZE];

//объялвяем буфер принимаемых данных
static std::string buffer;

//функция обратного вызова
static int writer(char *data, size_t size, size_t nmemb, std::string *buffer)
{
  //переменная - результат, по умолчанию нулевая
  int result = 0;
  //проверяем буфер
  if (buffer != NULL)
  {

    //добавляем к буферу строки из data, в количестве nmemb
    buffer->append(data, size * nmemb);

    //вычисляем объем принятых данных
    result = size * nmemb;

  }
  //вовзращаем результат
  return result;
}


httpWorker::httpWorker() {
}

httpWorker::httpWorker(const httpWorker& orig) {
}

httpWorker::~httpWorker() {
}

httpWorker::stiKKManswer httpWorker::iKKMtest(void){

stiKKManswer restul; // результат 
  
restul.resultCurl = 1; // если все хорошо 
    
    std::stringstream _url; // ip адрес iKKM
    _url.clear();

    std::stringstream _postfield;  // заполняем POST запрос
    _postfield.clear();
    _postfield << "key=" << iKKMconf.APIkey;                     // WEB API ключ
    if (iKKMpostfield.iSale != 0)
    _postfield << "&sale=" <<iKKMpostfield.iSale;              // сумма чека
    if (iKKMpostfield.iCash != 0)
    _postfield << "&cash=" <<iKKMpostfield.iCash;            // сколько дали наличности
    if (iKKMpostfield.iBank != 0)
    _postfield << "&bank=" << iKKMpostfield.iBank;          // сколько оплатили банковской картой
    if (iKKMpostfield.iTara != 0)
    _postfield << "&tara=" <<iKKMpostfield.iTara;              // не только тара, но и купоны и т.д
    if (iKKMpostfield.iCredit != 0)
    _postfield << "&credit=" << iKKMpostfield.iCredit;       // кредитом
    
    
    if (iKKMpostfield.iTemdata != "")
    _postfield << "&itemdata=" << iKKMpostfield.iTemdata;  //наименование товара или услуги для отправки в ОФД
    
    
    if (iKKMpostfield.iPrint != "")
    _postfield << "&print=" << iKKMpostfield.iPrint;             // данные для печати на чеке


    
    
    std::string postfield = _postfield.str();       // формируем запрос

  
  
  
  
  
  CURL *curl;                   //объект типа CURL 
  CURLcode res;             //объект - результат вызова функции curl_easy_perform
  
  
  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();             //инициализация
  
  
  if(curl) {              //проверяем
    
    
    
    _url << iKKMconf.httpAdr << iKKMconf.httpRes;   // формируем ip adrress iKKM  + в зависимости от запроса добавляем /api/  или /apicheck/  
    std::string url = _url.str();
    
   //   устанавливаем опцию, что будем работать по HTTP 
    curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP);      
   
    //  задаем опцию - получить по IP адресу и Порту 8080
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_PORT, iKKMconf.httpPort);
    
    
    buffer.clear(); // готовим буфер
    
     // устанавливаем опцию POST запроса
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfield.c_str());                        
    
    //указываем функцию обратного вызова для записи получаемых данных
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
    
    //указываем куда записывать принимаемые данные
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
   
    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    
    
    /* Check for errors */
    if(res != CURLE_OK){        
            restul.resultCurl = -1; // Неудачно обратились 
            iKKMconf.errorCodeDecr = "error IP iKKM";
    }else{ // по этому адресу что-то есть начнем парсить
        
        long http_code = 0;
        int httpBodycode= 0;
        
        httpBodycode = atoi(buffer.c_str());    // str to int
               
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
        
        if(http_code == 200){ //  все удачно
            restul.resultCurl = 1;
            iKKMconf.errorCodeDecr = "no error";
            if (httpBodycode >= 1){
                iKKMconf.APIkey = httpBodycode;  //получим WEB API для следующего запроса
            } 
        }
        else // связь есть но ошибки на стороне iKKM 
            restul.resultCurl = 0;
            restul.httpErrorCode = httpBodycode;
            iKKMconf.errorCodeDecr = erroCodeDecription(httpBodycode);  // обработаем ошибки
    }        
        
    /* always cleanup */
    curl_easy_cleanup(curl); 
  }
  curl_global_cleanup(); //выполняем обязательное завершение сессии 
  buffer.clear();  
     
 
    
    return restul;
}

std::string httpWorker::erroCodeDecription(int icodeID){
  switch(icodeID)
    {
    case  0:
        return "IP error";
    case -1:
        return "Web-API-key  error";
    case -2:
        return "wait working";
    case -3:
        return "error 24 hours, Z-report";
    case -4:
        return "error 72 hours, block oofd.kz";
    case -5:
        return "battery problem";
    case -6:
        return "error Printer";
    case -7:
        return "Parameter error";
    default:
            std::stringstream _pfield;
            _pfield.clear();
            _pfield << "error code [" << icodeID << "].Answer site help.ikkm.kz";
            return _pfield.str();
    }
}


httpWorker.h

#ifndef HTTPWORKER_H
#define HTTPWORKER_H
#include "curl/curl.h"
#include <sstream>
#include <string>
#include <stdlib.h>
class httpWorker {
public:
    httpWorker();
    httpWorker(const httpWorker& orig);
    virtual ~httpWorker();
    
    struct stiKKMconf{
        std::string httpAdr;
        std::string httpRes;
        int httpPort;
        int APIkey;
        int printerLineLength;
        std::string facSerialNumber;
        std::string errorCodeDecr;
        stiKKMconf():errorCodeDecr("no error"),httpAdr("192.168.0.179"),httpRes("/api/"),httpPort(8080),APIkey(12345678), printerLineLength(24), facSerialNumber("555")
        {
            
        }
    };
    struct stiKKMpostfield{
        double iSale;
        int iCash;
        int iBank;
        int iTara;
        int iCredit;
        std::string iPrint;
        std::string iTemdata;
        stiKKMpostfield():iSale(0), iCash(0), iBank(0), iTara(0), iCredit(0), iPrint(""), iTemdata("")
        {
            
        }
    };
    struct stiKKManswer{
        
        int httpErrorCode;
        int resultCurl;
        stiKKManswer():httpErrorCode(-1), resultCurl(-1)
        {
            
        }
    };
    stiKKMconf iKKMconf;
    stiKKMpostfield iKKMpostfield;
    stiKKManswer iKKMtest(void);
private:
    std::string erroCodeDecription(int icodeID);
};

#endif /* HTTPWORKER_H */



Ваша проблема решена?