Integração da adquirente

Envio de Transações

Como a adquirente ou subadquirente envia cada transação processada para a BackMoney.

Toda transação processada nas maquininhas é enviada para a BackMoney pela própria adquirente/subadquirente, em tempo real, por webhook. O estabelecimento nunca lança transações manualmente — a fonte da verdade é o fluxo da adquirente. A partir de cada evento, a BackMoney concilia a venda e dispara os benefícios (cashback, vouchers, cupons, multinível).

Em uma frase
A adquirente faz POST de um lote de eventos para POST /api/webhooks/transactions, autenticando com a API key dela e assinando a requisição com o certificado (X-BackMoney-Signature). A BackMoney responde com um resumo da entrega.

Visão geral

  • Direção: a adquirente envia (push) para a BackMoney — não somos nós que consultamos.
  • Em lote: cada requisição leva um array events (1 ou mais eventos).
  • Idempotente: cada evento tem um event_id único; reenviar o mesmo id é tratado como duplicado, sem dupla contagem.
  • Identificação por chave: o parceiro é identificado pela própria API key — o provider é derivado dela, então não há como forjar a origem de outro.
  • Resolução do lojista: a loja é resolvida pelo merchant_document do evento — CPF (11 dígitos) ou CNPJ (14), já que o estabelecimento pode ser pessoa jurídica ou pessoa física/MEI; um documento ainda desconhecido é cadastrado automaticamente.
  • Sem perda de dados: um event_type sem tratamento é armazenado e reconhecido como unhandled (nada é descartado).
Autenticação e assinatura
Como todo endpoint, este exige a API key (Bearer) + a assinatura do certificado (X-BackMoney-Signature) — veja o passo a passo e os exemplos em Autenticação e assinatura. A permissão necessária aqui é webhooks:ingest.

Endpoint

MétodoURLObservação
POST/api/webhooks/transactionsCanônico — use este.
POST/api/webhooks/paymentsAlias antigo (depreciado). Mesmo comportamento.

Corpo da requisição

O corpo é um envelope com o lote de eventos:

CampoTipoObrigatórioDescrição
eventsarraysim (mín. 1)Lote de eventos a processar.

Objeto do evento

CampoTipoObrigatórioDescrição
event_idstringsimId único do parceiro para este evento — a chave de idempotência.
event_typestringsimDiscriminador no formato recurso.ação (ex.: pos.sale).
occurred_atstring (date-time)nãoQuando ocorreu na origem (ISO 8601). Default = hora da ingestão.
dataobjetosimPayload tipado conforme o event_type (ver abaixo).

O objeto data (eventos pos.*)

Para eventos de maquininha (pos.*), o data traz:

CampoTipoObrigatórioDescrição
amount.valueinteirosimValor em centavos (minor units). Ex.: R$100,00 = 10000.
amount.currencystringsimMoeda ISO-4217 (ex.: BRL).
payment_methodstringsimcredit_card, debit_card, pix, …
card_brandstringcondicionalBandeira (visa, master, elo, hiper, amex). Define a taxa de MDR do cartão. Não se aplica ao pix.
installmentsinteirocondicionalParcelas (1 = à vista). Afeta a taxa da maquininha no cartão. Não se aplica ao pix, cujo custo é uma tarifa fixa por transação e não varia com o valor nem com o parcelamento.
statusstringsimSituação da transação (ex.: approved).
merchant_documentstringsimDocumento do estabelecimento — CPF (11 dígitos) ou CNPJ (14), com ou sem pontuação (o tipo é inferido pelo tamanho). Resolve a loja; um documento novo é cadastrado automaticamente. Alias legado: merchant_cnpj (só CNPJ).
transaction_codestringrecomendadoCódigo/NSU da transação no adquirente (rastreabilidade e conciliação).
device_serialstringnãoSerial da maquininha que originou a venda.
customer_cpfstringnãoCPF do cliente — 11 dígitos, com ou sem pontuação. Quando ele digita na maquininha. Sem CPF, só o lojista é beneficiado.
customer_emailstringnãoE-mail do cliente (onboarding).
customer_phonestringnãoCelular com DDI — 12–13 dígitos incluindo o 55 (ex.: +5511998877665 ou 5511998877665); o + e a pontuação são removidos. Usado no cadastro automático na 1ª compra.
Formato inválido não derruba a requisição — mas ignora o evento
Um campo mal formatado (ex.: telefone sem o DDI 55, CPF com nº de dígitos errado) faz aquele evento entrar como skipped (não vira transação). A resposta ainda é 200 — confira o campo skipped no resumo.

Tipos de evento (event_type)

event_typeSignificado
pos.saleVenda aprovada.
pos.refundEstorno / devolução.
pos.reversalReversão da transação.
pos.cancellationCancelamento.
pos.chargebackChargeback.

Exemplo — uma venda

POST /api/webhooks/transactions
curl -X POST https://api.backmoney.com.br/api/webhooks/transactions \
  -H "Authorization: Bearer backmoney-SUA_CHAVE_AQUI" \
  -H "X-BackMoney-Signature: t=1751380000, kid=SEU_FINGERPRINT, sig=BASE64_DA_ASSINATURA" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "event_id": "evt_9f2c7a13b8",
        "event_type": "pos.sale",
        "occurred_at": "2026-06-30T14:12:05Z",
        "data": {
          "device_serial": "PAX-A920-00237",
          "transaction_code": "NSU-882211",
          "amount": { "value": 10000, "currency": "BRL" },
          "payment_method": "credit_card",
          "card_brand": "visa",
          "installments": 1,
          "status": "approved",
          "merchant_document": "12.345.678/0001-90",
          "customer_cpf": "390.533.447-05",
          "customer_phone": "+5511987654321"
        }
      }
    ]
  }'
O header X-BackMoney-Signature é obrigatório
t, kid e sig são calculados a cada requisição (a sig é feita com a chave privada sobre t.corpo). Veja como gerar em Autenticação e assinatura — sem uma assinatura válida a requisição é rejeitada com 401.

Resposta

A resposta vem no envelope padrão { "data": … }, com o resumo da entrega:

200 OK
{
  "data": {
    "provider": "deltapay",
    "received": 2,
    "ingested": 1,
    "duplicates": 0,
    "skipped": 1,
    "unhandled": 0,
    "results": [
      { "event_id": "evt_abc123", "event_type": "pos.sale", "status": "ingested" },
      { "event_id": "evt_def456", "event_type": "pos.sale", "status": "skipped",
        "error": "payment_method must be one of: credit_card, debit_card, pix, boleto, wallet, cash, other" }
    ]
  }
}
CampoDescrição
providerO parceiro, derivado da API key.
receivedTotal de eventos na entrega.
ingestedEventos processados por um decoder (novos).
duplicatesEventos já vistos antes (reentrega idempotente).
skippedDescartados (sem event_id/event_type ou payload inválido).
unhandledArmazenados, mas sem decoder para aquele event_type.
resultsResultado por evento, na ordem recebida — inspecione para saber exatamente o que houve com cada um (veja abaixo).
200 não significa que tudo virou transação
O HTTP 200 confirma que a entrega foi aceita e registrada — não que todo evento foi processado. Eventos skipped/unhandled são gravados mas NÃO viram transação. Sempre inspecione results[] (ou os contadores skipped/unhandled), não só o código HTTP.

O array results

Cada item traz o desfecho de um evento, para você agir sobre ele (corrigir um skip, notar um tipo sem tratamento) — não só ver o total:

CampoDescrição
event_idA chave de idempotência do evento, devolvida.
event_typeO resource.action do evento, devolvido.
statusingested (virou transação) · duplicate (já visto) · skipped (payload inválido — veja error) · unhandled (sem decoder para o event_type) · failed (erro de infraestrutura — reenvie).
errorMotivo, quando skipped/unhandled/failed (ex.: campo inválido).

Envio em lote

Você pode agrupar vários eventos numa única entrega — recomendado para reduzir chamadas. Cada evento é processado de forma independente; o resumo da resposta soma os resultados.

json
{
  "events": [
    { "event_id": "evt_001", "event_type": "pos.sale",   "data": { /* ... */ } },
    { "event_id": "evt_002", "event_type": "pos.sale",   "data": { /* ... */ } },
    { "event_id": "evt_003", "event_type": "pos.refund", "data": { /* ... */ } }
  ]
}

Idempotência, reentrega e erros

  • Idempotência: reenviar um event_id já processado retorna como duplicates — não gera nova transação nem benefícios em dobro.
  • Reentrega: em caso de 5xx ou timeout, reenvie o lote inteiro; os eventos já recebidos serão deduplicados.
  • Parcial: um evento inválido não derruba o lote — ele entra como skipped e os demais seguem.
HTTPQuandoAção
200 OKEntrega aceita (mesmo com itens skipped/unhandled).Conferir o resumo na resposta.
401API key ausente/inválida, ou assinatura ausente/inválida/expirada.Verificar o token e a assinatura.
403Token válido, mas sem a permissão webhooks:ingest.Ajustar a permissão da chave.
422Envelope malformado (ex.: events vazio).Corrigir o corpo e reenviar.
500/503Falha temporária na BackMoney.Reenviar o lote (idempotente) com backoff.
Precisa de uma chave de homologação?
Fale com o time de integração da BackMoney para receber a API key de sandbox e o checklist de homologação.