Guia de integração

Este guia mostra como integrar uma Automação Comercial (AC) — o software de venda, como ERP ou frente de caixa (PDV) — à biblioteca de pagamento Client Conecta.

Esta página e o arquivo da Skill formam um pacote fechado de integração, preparado para ser enviado a clientes e parceiros. Nenhuma leitura adicional do repositório interno do fornecedor é necessária.

O contrato é o mesmo em qualquer linguagem (C, C++, C#, Python via FFI, Java/JNI, entre outras) e nas duas plataformas suportadas: Windows e Linux.

O que a biblioteca faz?

A automação comercial pede um pagamento, e o Client Conecta se comunica com o pin pad e com o backend da Cielo para autorizar, confirmar ou cancelar a transação. Então, a biblioteca encapsula o protocolo do pin pad e a comunicação com o backend. Assim, a automação comercial só precisa montar pacotes JSON e tratar o retorno.

O contrato entre a automação comercial e a biblioteca é idêntico nas duas plataformas: mesma função exportada, mesmos pacotes JSON, mesmos campos e mesmos códigos de retorno. O que muda é o entorno: carga da biblioteca, toolkit gráfico e porta do pin pad. Consulte Diferenças entre Windows e Linux.

Skill para assistentes de IA

A Skill reúne as regras deste guia em um arquivo que um assistente de IA pode ler. Com ela, você gera ou revisa o código de integração aplicando essas regras sem copiá-las a cada pedido.

Para saber como usá-la, consulte Utilizando um assistente de IA.

Primeiros passos

Antes de começar, reúna as informações e os requisitos a seguir.

Informações sobre a aplicação

Tenha estas respostas à mão:

  • Sistema operacional (Windows ou Linux) e arquitetura (x64 ou x86);
  • Linguagem da aplicação;
  • Tipo de aplicação: gráfica (e qual toolkit) ou console;
  • Caminho de onde a biblioteca será carregada.

A arquitetura da automação comercial precisa ser a mesma da biblioteca. Um processo x64 não carrega uma biblioteca x86, e vice-versa.

Requisitos do ambiente

  • Windows: runtime do Visual C++ (VCRUNTIME140.dll / UCRT) presente na máquina de destino;
  • Linux: glibc 2.25 ou superior, pacote ca-certificates instalado e usuário no grupo dialout.

Dados do estabelecimento

Colete os dados a seguir antes de inicializar a biblioteca. Todos os campos são enviados como string.

ParâmetroDescriçãoTipoObrigatório?
CnpjCNPJ válido do estabelecimento.stringSim
ClientIdCredencial de API. Trate como segredo e nunca a escreva no código-fonte.stringSim
ClientSecretCredencial de API. Trate como segredo e nunca a escreva no código-fonte.stringSim
TerminalIdIdentificador do terminal. Obrigatório na primeira inicialização e também após a desassociação do terminal.stringCondicional
EnvironmentAmbiente de execução: "0" Produção (padrão) ou "1" Homologação. Se o campo for omitido ou inválido, a biblioteca assume Produção. Envie "1" explicitamente nos testes.stringNão
ConfirmationStatusSetupModo de confirmação: "1" automática (padrão) ou "0" manual. Consulte a seção Confirmação automática e manual.stringNão
TableParamsUpdateAtualização de tabelas: "0" desabilita; "1" normal (padrão); "2" força parâmetros; "3" força parâmetros e pin pad.stringNão
PortPinpadPorta do pin pad. Vazio significa automático. No Linux, deixe sempre vazio.stringNão

Grave esses dados em um arquivo de configuração local fora do versionamento (por exemplo, listado no .gitignore), nunca no código-fonte. Ao editar o arquivo, não exiba o ClientSecret atual em claro.

Segurança e PCI DSS

A integração está sujeita ao padrão PCI DSS (Payment Card Industry Data Security Standard). Siga estas regras:

  • Nunca envie PAN, validade, CVV ou trilha no JSON de entrada. A captura é feita pelo PINPAD;
  • Nunca registre em log, grave ou exiba PAN completo, CVV ou trilha. O número do cartão que volta da biblioteca já chega mascarado: só os primeiros e os últimos dígitos ficam visíveis, e o meio vem substituído por *. Mantenha assim;
  • Atenção à exceção na operação 009: ao capturar dado pelo teclado do PINPAD, o código de segurança (CVV) e o número do cartão (PAN) voltam em claro no campo de saída. É o único ponto do contrato em que isso acontece. Mascare esses dados antes de registrar, exibir ou gravar. Evite oferecer a captura de PAN pelo teclado sem necessidade real, porque o fluxo normal de venda já lê o cartão pelo PINPAD;
  • Aplique a redação e o mascaramento em um ponto único, na entrada do tratador de resposta, antes de log, tela e arquivo. Se existirem três lugares de consumo (log, tela e arquivo), o que for esquecido é o que vaza;
  • Nunca escreva ClientSecret nem outras credenciais no código-fonte. Use armazenamento seguro;
  • Se a AC guarda campos da resposta para reaproveitar em telas seguintes, use uma lista de campos permitidos. Copiar todo campo string que aparecer é o caminho mais curto para gravar PAN ou CVV em disco por acidente.

Como a biblioteca funciona

Esta seção reúne as regras do contrato entre a AC e a biblioteca: a função exportada, o formato do JSON, a ordem das operações, o modelo de callback e os modos de confirmação.

Contrato da biblioteca

A biblioteca expõe uma única função, RequestDispatcher, que executa todas as operações. A tabela a seguir resume o contrato.

ItemValor
Artefatoclientconecta.dll no Windows e clientconecta.so no Linux.
Função exportadaint RequestDispatcher(const char* inputJson, pDispatchCallback callback).
Tipo do callbackpDispatchCallback = void (*)(const char* outputJson).
LigaçãoC (extern "C", sem name mangling). O nome do símbolo é idêntico nas duas plataformas.
RetornoCódigo numérico CFL_*, em que 0 indica sucesso. É só o resultado imediato da chamada: os dados chegam pelo callback.
OperaçãoEscolhida pelo campo Oper do JSON de entrada, de "001" a "010".
CodificaçãoUTF-8.

Regras do JSON

Todos os campos trocados com a biblioteca, enviados e recebidos, são string. O contrato não tem campos inteiros, booleanos ou numéricos.

{ 
    "Oper": "005", 
    "Amount": "1000", 
    "Installments": "1" 
}

Envie o valor como "1000", nunca como 1000. Envie flags como "1" ou "0".

A tabela a seguir mostra o resultado de cada situação na validação dos campos.

SituaçãoResultado
Campo obrigatório ausente.CFL_ERROR_MANDAT (3)
Campo obrigatório presente com "".CFL_ERROR_INVPARAM (2)
Campo acima do tamanho máximo.CFL_ERROR_INVPARAM (2)
Campo opcional com valor padrão, ausente ou com "".A biblioteca assume o valor padrão interno.

Antes de serializar o JSON, descarte os campos de valor vazio. Não envie "" para "deixar explícito". A busca de chave não diferencia maiúsculas de minúsculas, mas use sempre a caixa exata do contrato.


Diferença entre Oper e PPOper

O campo Oper é convertido numericamente: "5", "05" e "005" são equivalentes. Mesmo assim, padronize em três dígitos.

O campo PPOper (operações 009 e 010) é comparado como uma string literal de dois caracteres. Envie sempre de "00" a "09", com zero à esquerda. Enviar "1" em vez de "01" retorna CFL_ERROR_INVPARAM (2).

Ciclo de vida das operações

A sessão da biblioteca segue esta ordem:

  • 001 (INITIALIZE): obrigatória e sempre a primeira chamada;
  • 002 a 010: operações de negócio e de pin pad;
  • 003 (UNINSTALL): encerra a sessão e exige um novo INITIALIZE para continuar.

Sem o INITIALIZE, qualquer outra operação retorna CFL_ERROR_NOT_INIT (62). Esse retorno é esperado: não o contorne com inicialização automática.

Depois de um UNINSTALL bem-sucedido, limpe também qualquer cache local de PaymentId e MerchantOrderId que a AC mantenha. O banco local da biblioteca foi apagado, e essas referências deixam de ser válidas.

Modelo de callback

A biblioteca pode chamar o callback de 0 a N vezes por operação:

  • Com NotifyMsg: notificação de progresso (aguarde o cartão, senha, processando e similares). Atualize a interface com ela;
  • Sem NotifyMsg: resultado final da operação.

Exceção, TRANSQUERY (008): a resposta é paginada, e todas as páginas chegam sem NotifyMsg, uma por página, em um envelope com Page, TotalPages, TotalPayments e Payments. Acumule todas as páginas. Não trate apenas a última mensagem.

Ao implementar o callback, siga estas regras:

  • Copie a string recebida imediatamente. O ponteiro só é válido durante a chamada;
  • Não chame RequestDispatcher de dentro do callback (reentrância);
  • Mantenha o callback rápido e não bloqueante;
  • Trate-o como potencialmente chamado de uma thread interna da biblioteca e proteja o acesso a estruturas compartilhadas;
  • Em aplicação gráfica, chame RequestDispatcher fora da thread de interface, porque ela é bloqueante. Faça o callback devolver as atualizações para a thread de interface pelo mecanismo do toolkit (por exemplo, Invoke no WinForms e no WPF, wxQueueEvent no wxWidgets e g_idle_add no GTK).

Confirmação automática e manual

O modo de confirmação é definido no INITIALIZE pelo campo ConfirmationStatusSetup:

  • Automática ("1", padrão): a biblioteca confirma sozinha a transação aprovada. A operação 007 (CONFIRMATION) manual fica bloqueada;
  • Manual ("0"): após uma venda aprovada, a AC deve chamar a operação 007 informando "1" (confirmar) ou "2" (desfazer). Sem essa chamada, a transação fica pendente e é reprocessada automaticamente na próxima transação.

Diretório de trabalho

A biblioteca grava arquivos (logs, banco local e recibos) com caminho relativo ao diretório de trabalho do processo. Fixe o diretório de trabalho na pasta da aplicação antes do INITIALIZE.

No Linux, lançadores de desktop e serviços tendem a herdar outro diretório. Nesse caso, uma sessão inicializada antes "desaparece", porque o banco local passa a ser procurado em outro lugar.

Exemplo: Carregar a biblioteca e fazer a primeira venda

O exemplo mínimo em C a seguir carrega a biblioteca, inicializa a sessão e processa uma venda de crédito à vista de R$ 10,00.

Substitua os valores de credencial pelos dados fornecidos pela Cielo para o seu estabelecimento.

Siga estes passos:

  1. Carregue a biblioteca e obtenha o endereço de RequestDispatcher;
  2. Inicialize a sessão com a operação 001, por ação explícita da pessoa usuária, nunca automática;
  3. Envie a venda com a operação 005;
  4. Trate o retorno no callback.
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
  #include <windows.h>
#else
  #include <dlfcn.h>
#endif

typedef void (*pDispatchCallback)(const char* outputJson);
typedef int  (*RequestDispatcherFn)(const char* inputJson, pDispatchCallback callback);

static RequestDispatcherFn RequestDispatcher;

/* O ponteiro recebido só é válido durante esta chamada: copie antes de usar.
 * O callback pode ser chamado de 0 a N vezes por operação (consulte a seção
 * "Modelo de callback"). */
void OnDispatch(const char* outputJson) {
    char copia[8192];
    strncpy(copia, outputJson, sizeof(copia) - 1);
    copia[sizeof(copia) - 1] = '\0';
    /* Grave em log diário e exiba na área de console (consulte a seção
     * "Segurança e PCI DSS") */
    printf("<< %s\n", copia);
}

int main(void) {
#ifdef _WIN32
    HMODULE lib = LoadLibraryA("clientconecta.dll");
    RequestDispatcher = (RequestDispatcherFn)GetProcAddress(lib, "RequestDispatcher");
#else
    /* Use sempre RTLD_NOW | RTLD_LOCAL, nunca RTLD_GLOBAL (consulte a seção
     * "Namespace de símbolos no Linux") */
    void* lib = dlopen("./clientconecta.so", RTLD_NOW | RTLD_LOCAL);
    RequestDispatcher = (RequestDispatcherFn)dlsym(lib, "RequestDispatcher");
#endif

    /* 1) INITIALIZE (001): ação explícita da pessoa usuária, nunca automática */
    const char* init =
        "{"
          "\"Oper\":\"001\","
          "\"Cnpj\":\"12345678000195\","
          "\"ClientId\":\"SEU_CLIENT_ID\","
          "\"ClientSecret\":\"SEU_CLIENT_SECRET\","
          "\"TerminalId\":\"PDV0001\","
          "\"Environment\":\"1\""        /* "1" = Homologação; ausente assume Produção */
        "}";
    int ret = RequestDispatcher(init, OnDispatch);
    printf("INITIALIZE retornou %d\n", ret);
    if (ret != 0) return 1;

    /* 2) TRANSACTION (005): crédito à vista, R$ 10,00 */
    const char* venda =
        "{"
          "\"Oper\":\"005\","
          "\"TransactionType\":\"01\","
          "\"Amount\":\"1000\","
          "\"MerchantOrderId\":\"000000000012345\""
        "}";
    ret = RequestDispatcher(venda, OnDispatch);
    printf("TRANSACTION retornou %d\n", ret);

    return 0;
}

A chamada a RequestDispatcher é bloqueante. Em uma aplicação gráfica, execute-a fora da thread de interface (consulte a seção Modelo de callback).

Troca de JSON do exemplo

Os valores a seguir são ilustrativos.

Operação 001: Requisição

{
  "Oper": "001",
  "Cnpj": "12345678000195",
  "ClientId": "SEU_CLIENT_ID",
  "ClientSecret": "SEU_CLIENT_SECRET",
  "TerminalId": "PDV0001",
  "Environment": "1"
}

Operação 001: Retorno pelo callback

{
  "Oper": "001",
  "Code": "00"
}

Operação 005: Requisição

{
  "Oper": "005",
  "TransactionType": "01",
  "Amount": "1000",
  "MerchantOrderId": "000000000012345"
}

Operação 005: Retorno pelo callback

{
  "Oper": "005",
  "Status": "2",
  "ReturnCode": "0",
  "ReturnMessage": "Transacao aprovada",
  "PaymentId": "a1b2c3d4-0000-0000-0000-000000000000",
  "AuthorizationCode": "123456",
  "ProofOfSale": "000123",
  "Amount": "1000",
  "MerchantOrderId": "000000000012345"
}

No log e no console da AC, exiba o ClientSecret como "***", nunca em claro. O valor real continua sendo enviado à biblioteca; o que se mascara é a exibição e o registro.

Resultado esperado

Ao final do exemplo, você deve ver:

  • INITIALIZE retornou 0, e o callback da operação 001 com "Code": "00";
  • TRANSACTION retornou 0, e o callback da operação 005 com "ReturnCode": "0" e "ReturnMessage": "Transacao aprovada".

O retorno 0 da função RequestDispatcher indica apenas o resultado imediato da chamada. Os dados da operação chegam pelo callback.

Referência

Confira as operações da biblioteca e os códigos de retorno da função RequestDispatcher.

Diferenças entre Windows e Linux

O contrato do Client Conecta é idêntico no Windows e no Linux: mesma função exportada, mesmos pacotes JSON, mesmos campos e mesmos códigos de retorno. O que muda é o entorno: carga da biblioteca, toolkit gráfico e porta do pin pad. Confira as diferenças entre Windows e Linux.

Checklist de integração

Confira os itens a seguir antes de publicar a integração:

  • Sistema operacional e arquitetura da biblioteca confirmados antes de gerar o código;
  • Área de console exibindo entrada e saída com JSON indentado, e log diário em arquivo com credenciais redigidas;
  • Menu ou fluxo respeitando a ordem 001 → 010;
  • INITIALIZE (001) disparado por ação explícita da pessoa usuária, nunca automático;
  • Sair não dispara UNINSTALL (003): são ações separadas;
  • Todos os campos do JSON como string, e campos vazios descartados do pacote;
  • PPOper sempre com dois dígitos;
  • MerchantOrderId numérico, com 15 posições e único por transação;
  • Amount em centavos (string), sem ponto flutuante;
  • Callback que copia a string recebida, não reentra, não bloqueia e é thread-safe;
  • TRANSQUERY (008) acumulando todas as páginas da resposta;
  • Nenhum dado de cartão no JSON de entrada e nenhum log de PAN, CVV ou trilha em claro;
  • Chamadas à biblioteca serializadas, uma por vez;
  • No Linux: dlopen com RTLD_NOW | RTLD_LOCAL, nunca dlclose, encerramento por _exit(), PortPinpad vazio, glibc 2.25 ou superior e ca-certificates presentes, e usuário no grupo dialout;
  • No Windows: runtime do Visual C++ presente na máquina de destino.

Suporte técnico

Entre em contato com o suporte técnico e informe a plataforma (Windows ou Linux), a arquitetura (x64 ou x86) e a linguagem da aplicação. Essas três informações agilizam qualquer atendimento sobre a integração.


Did this page help you?