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-certificatesinstalado e usuário no grupodialout.
Dados do estabelecimento
Colete os dados a seguir antes de inicializar a biblioteca. Todos os campos são enviados como string.
| Parâmetro | Descrição | Tipo | Obrigatório? |
|---|---|---|---|
Cnpj | CNPJ válido do estabelecimento. | string | Sim |
ClientId | Credencial de API. Trate como segredo e nunca a escreva no código-fonte. | string | Sim |
ClientSecret | Credencial de API. Trate como segredo e nunca a escreva no código-fonte. | string | Sim |
TerminalId | Identificador do terminal. Obrigatório na primeira inicialização e também após a desassociação do terminal. | string | Condicional |
Environment | Ambiente 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. | string | Não |
ConfirmationStatusSetup | Modo de confirmação: "1" automática (padrão) ou "0" manual. Consulte a seção Confirmação automática e manual. | string | Não |
TableParamsUpdate | Atualização de tabelas: "0" desabilita; "1" normal (padrão); "2" força parâmetros; "3" força parâmetros e pin pad. | string | Não |
PortPinpad | Porta do pin pad. Vazio significa automático. No Linux, deixe sempre vazio. | string | Nã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
ClientSecretnem 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.
| Item | Valor |
|---|---|
| Artefato | clientconecta.dll no Windows e clientconecta.so no Linux. |
| Função exportada | int RequestDispatcher(const char* inputJson, pDispatchCallback callback). |
| Tipo do callback | pDispatchCallback = void (*)(const char* outputJson). |
| Ligação | C (extern "C", sem name mangling). O nome do símbolo é idêntico nas duas plataformas. |
| Retorno | Código numérico CFL_*, em que 0 indica sucesso. É só o resultado imediato da chamada: os dados chegam pelo callback. |
| Operação | Escolhida pelo campo Oper do JSON de entrada, de "001" a "010". |
| Codificação | UTF-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ção | Resultado |
|---|---|
| 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 PPOperO 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"retornaCFL_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 comPage,TotalPages,TotalPaymentsePayments. 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
RequestDispatcherde 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
RequestDispatcherfora 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,Invokeno WinForms e no WPF,wxQueueEventno wxWidgets eg_idle_addno 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:
- Carregue a biblioteca e obtenha o endereço de
RequestDispatcher; - Inicialize a sessão com a operação 001, por ação explícita da pessoa usuária, nunca automática;
- Envie a venda com a operação 005;
- 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
ClientSecretcomo"***", 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;
PPOpersempre com dois dígitos;MerchantOrderIdnumérico, com 15 posições e único por transação;Amountem 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:
dlopencomRTLD_NOW | RTLD_LOCAL, nuncadlclose, encerramento por_exit(),PortPinpadvazio, glibc 2.25 ou superior eca-certificatespresentes, e usuário no grupodialout; - No Windows: runtime do Visual C++ presente na máquina de destino.
Updated 5 days ago