Autenticação e assinatura
Independente do endpoint que você chama (enviar transações, consultar cliente por CPF, …), toda requisição carrega dois headers: o Authorization com a API key (diz quem é) e o X-BackMoney-Signature com a assinatura do certificado (prova a autenticidade daquela requisição). Esta página explica os dois — o resto da documentação só cita a permissão específica de cada endpoint.
A assinatura é obrigatória em todos os ambientes — tanto em produção quanto em homologação. Não existe modo sem assinatura: uma requisição sem o X-BackMoney-Signature (ou com assinatura inválida/expirada) é sempre rejeitada com 401.
Autenticação (API key)
A requisição é autenticada com um token Bearer — a API key da adquirente, no formato backmoney-…. Uma única chave atende todos os estabelecimentos daquela adquirente; a permissão exigida depende do endpoint (ex.: webhooks:ingest para enviar transações, customers:read para consultar cliente).
Authorization: Bearer backmoney-SUA_CHAVE_AQUIO certificado do adquirente
Cada adquirente recebe um certificado (par de chaves ECDSA P-256) gerado no painel da BackMoney. A chave privada é exibida uma única vez na geração — guarde-a com segurança; a BackMoney retém apenas a parte pública, usada para verificar as assinaturas.
- Chave privada (o único segredo) — fica com você e é usada para assinar.
- kid — o fingerprint do certificado (SHA-256), que identifica qual certificado. Não é segredo; vai no header. Copie o valor completo no painel.
- Certificado público — fica na BackMoney; não trafega na requisição.
Assinatura da requisição
A assinatura dá integridade (o corpo não foi adulterado), proteção contra replay e não-repúdio. Sem uma assinatura válida a requisição recebe 401.
Como assinar
- Monte a string canônica
<t>.<corpo>— o timestamp Unix em segundos (t), um ponto, e o corpo exatamente como será enviado (mesmo padrão do Stripe). - Assine essa string com a chave privada (ECDSA P-256, hash SHA-256). A assinatura é ASN.1/DER, codificada em base64.
- Envie no header
X-BackMoney-Signaturecomt,kidesig— junto com oAuthorizatione o corpo.
X-BackMoney-Signature: t=1751303525, kid=7125327055e6fd14a1b2…, sig=MEUCIQDk…| Campo | Descrição |
|---|---|
| t | Timestamp Unix (segundos) do momento da assinatura. Aceito dentro de ±5 min do relógio do servidor (anti-replay). |
| kid | Fingerprint do certificado (SHA-256 do DER), copiado no painel. |
| sig | Assinatura ECDSA-P256-SHA256 (ASN.1/DER) da string canônica, em base64. |
Exemplos
O exemplo abaixo usa o envio de transações, mas o processo é o mesmo para qualquer endpoint — troque a URL e o corpo; a assinatura é sempre sobre t.corpo.
import crypto from 'node:crypto'
import fs from 'node:fs'
const url = 'https://api.backmoney.com.br/api/webhooks/transactions'
const apiKey = 'backmoney-SUA_CHAVE_AQUI'
const fingerprint = 'SEU_FINGERPRINT' // o "kid", mostrado ao gerar o certificado
const privateKey = crypto.createPrivateKey(fs.readFileSync('private-key.pem'))
// body = o corpo exato do endpoint que você vai chamar
const body = JSON.stringify({
events: [{ event_id: 'evt_9f2c', event_type: 'pos.sale', data: { /* ... */ } }]
})
const ts = Math.floor(Date.now() / 1000)
// Assina "<t>.<corpo>" — ECDSA P-256 + SHA-256, ASN.1/DER em base64
const sig = crypto
.sign('sha256', Buffer.from(`${ts}.${body}`), { key: privateKey, dsaEncoding: 'der' })
.toString('base64')
await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'X-BackMoney-Signature': `t=${ts}, kid=${fingerprint}, sig=${sig}`,
'Content-Type': 'application/json'
},
body
})Rotação e revogação
- Rotação: gere um novo certificado a qualquer momento (o anterior continua válido até ser revogado) e passe a assinar com a nova chave.
- Revogação: revogue um certificado no painel — assinaturas feitas com ele passam a receber
401imediatamente.
