Envio de Transações
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).
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_documentdo 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_typesem tratamento é armazenado e reconhecido como unhandled (nada é descartado).
Endpoint
| Método | URL | Observação |
|---|---|---|
| POST | /api/webhooks/transactions | Canônico — use este. |
| POST | /api/webhooks/payments | Alias antigo (depreciado). Mesmo comportamento. |
Corpo da requisição
O corpo é um envelope com o lote de eventos:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| events | array | sim (mín. 1) | Lote de eventos a processar. |
Objeto do evento
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| event_id | string | sim | Id único do parceiro para este evento — a chave de idempotência. |
| event_type | string | sim | Discriminador no formato recurso.ação (ex.: pos.sale). |
| occurred_at | string (date-time) | não | Quando ocorreu na origem (ISO 8601). Default = hora da ingestão. |
| data | objeto | sim | Payload tipado conforme o event_type (ver abaixo). |
O objeto data (eventos pos.*)
Para eventos de maquininha (pos.*), o data traz:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount.value | inteiro | sim | Valor em centavos (minor units). Ex.: R$100,00 = 10000. |
| amount.currency | string | sim | Moeda ISO-4217 (ex.: BRL). |
| payment_method | string | sim | credit_card, debit_card, pix, … |
| card_brand | string | condicional | Bandeira (visa, master, elo, hiper, amex). Define a taxa de MDR do cartão. Não se aplica ao pix. |
| installments | inteiro | condicional | Parcelas (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. |
| status | string | sim | Situação da transação (ex.: approved). |
| merchant_document | string | sim | Documento 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_code | string | recomendado | Código/NSU da transação no adquirente (rastreabilidade e conciliação). |
| device_serial | string | não | Serial da maquininha que originou a venda. |
| customer_cpf | string | não | CPF do cliente — 11 dígitos, com ou sem pontuação. Quando ele digita na maquininha. Sem CPF, só o lojista é beneficiado. |
| customer_email | string | não | E-mail do cliente (onboarding). |
| customer_phone | string | não | Celular 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. |
Tipos de evento (event_type)
| event_type | Significado |
|---|---|
| pos.sale | Venda aprovada. |
| pos.refund | Estorno / devolução. |
| pos.reversal | Reversão da transação. |
| pos.cancellation | Cancelamento. |
| pos.chargeback | Chargeback. |
Exemplo — uma venda
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"
}
}
]
}'Resposta
A resposta vem no envelope padrão { "data": … }, com o resumo da entrega:
{
"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" }
]
}
}| Campo | Descrição |
|---|---|
| provider | O parceiro, derivado da API key. |
| received | Total de eventos na entrega. |
| ingested | Eventos processados por um decoder (novos). |
| duplicates | Eventos já vistos antes (reentrega idempotente). |
| skipped | Descartados (sem event_id/event_type ou payload inválido). |
| unhandled | Armazenados, mas sem decoder para aquele event_type. |
results | Resultado por evento, na ordem recebida — inspecione para saber exatamente o que houve com cada um (veja abaixo). |
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:
| Campo | Descrição |
|---|---|
| event_id | A chave de idempotência do evento, devolvida. |
| event_type | O resource.action do evento, devolvido. |
| status | ingested (virou transação) · duplicate (já visto) · skipped (payload inválido — veja error) · unhandled (sem decoder para o event_type) · failed (erro de infraestrutura — reenvie). |
| error | Motivo, 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.
{
"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_idjá processado retorna comoduplicates— não gera nova transação nem benefícios em dobro. - Reentrega: em caso de
5xxou 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
skippede os demais seguem.
| HTTP | Quando | Ação |
|---|---|---|
| 200 OK | Entrega aceita (mesmo com itens skipped/unhandled). | Conferir o resumo na resposta. |
| 401 | API key ausente/inválida, ou assinatura ausente/inválida/expirada. | Verificar o token e a assinatura. |
| 403 | Token válido, mas sem a permissão webhooks:ingest. | Ajustar a permissão da chave. |
| 422 | Envelope malformado (ex.: events vazio). | Corrigir o corpo e reenviar. |
| 500/503 | Falha temporária na BackMoney. | Reenviar o lote (idempotente) com backoff. |
