Comum a todos os endpoints

Autenticação e assinatura

Toda requisição à API de integração usa dois mecanismos juntos: a API key (identidade) e a assinatura com o certificado (autenticidade). Vale para qualquer endpoint.

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.

Em uma frase
Todo request leva Authorization: Bearer <api-key> + X-BackMoney-Signature: t, kid, sig (assinatura feita com a chave privada do certificado sobre t.corpo). Sem os dois, a requisição é 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).

http
Authorization: Bearer backmoney-SUA_CHAVE_AQUI
Guarde a chave com segurança
A API key age em nome da sua operação. Trafegue sempre por HTTPS, nunca exponha no front-end e gire a chave em caso de suspeita de vazamento.

O 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.
O que entregar a quem vai integrar
Basta a chave privada (private-key.pem) + o kid (fingerprint). O certificado público em si é opcional — a BackMoney já o tem.

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

  1. 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).
  2. Assine essa string com a chave privada (ECDSA P-256, hash SHA-256). A assinatura é ASN.1/DER, codificada em base64.
  3. Envie no header X-BackMoney-Signature com t, kid e sig — junto com o Authorization e o corpo.
Header
X-BackMoney-Signature: t=1751303525, kid=7125327055e6fd14a1b2…, sig=MEUCIQDk…
CampoDescrição
tTimestamp Unix (segundos) do momento da assinatura. Aceito dentro de ±5 min do relógio do servidor (anti-replay).
kidFingerprint do certificado (SHA-256 do DER), copiado no painel.
sigAssinatura 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.

sign.mjs
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
})
Assine os bytes exatos do corpo
O hash é sobre o corpo exatamente como transmitido. Não reserialize o JSON depois de assinar — qualquer diferença de bytes (espaços, ordem de campos) invalida a assinatura.

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 401 imediatamente.