Como fazer

Como automatizar a conciliação financeira

Automatize a conciliação financeira: src do pedido no link, webhook assinado em tempo real e relatório diário por API para fechar venda, taxa e saque.

Para automatizar a conciliação no HeroPay, crie cada link com o ID do pedido em src, registre o pagamento pelo webhook spark_payment_confirmed, que devolve cart.src, e confira diariamente por GET /transactions/by_status.

Conciliação financeira automática é cruzar, sem planilha, três registros que precisam bater: o pedido no seu sistema, a transação no gateway e o dinheiro que entrou e saiu da conta. O src é a chave que liga os três: o webhook registra em tempo real, o job diário pega o que o webhook eventualmente perdeu, com valor bruto, líquido e método de cada transação, e saldo e saques fecham o ciclo pelo GET /financial/balance e GET /financial/withdrawals.

Antes de começar

  • Conta sandbox e token JWT em app.heropay.tech, em HEROPAY_API_URL e HEROPAY_JWT_TOKEN no servidor.
  • Uma tabela de pedidos com colunas para src, payment_id, valor_bruto, valor_liquido, metodo e status_conciliacao.
  • Entender compra vs transação. Uma compra pode ter várias transações (tentativas, parcelas no Pix ou boleto, mensalidades). Concilie transação com lançamento financeiro, nunca some as duas (docs).

Passo a passo

curl -X POST "$HEROPAY_API_URL/payment_links" \
  -H "Authorization: Bearer $HEROPAY_JWT_TOKEN" \
  -H "Accept: application/vnd.herospark.com; version=1" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_link": {
      "name": "Pedido 4821",
      "price_cents": 29700,
      "absorbs_fees": true,
      "payment_methods": ["pix", "credit_card", "bank_slip"],
      "src": "pedido-4821"
    }
  }'

A resposta 201 devolve data.offer.url já com ?src=pedido-4821. Grave data.id no pedido. O src aceita letras, números e . _ - ~ até 255 caracteres, então use um formato previsível (pedido-4821, fatura_2026-09_1042).

Por que um link por pedido: o src é uma etiqueta do link, não um ID único de venda. Se o mesmo link atende vários compradores, cart.src diz a campanha, e a chave da transação passa a ser o payment_id.

2. Registre em tempo real pelo webhook

Cadastre spark_payment_confirmed, refunded e chargeback_request com POST /webhook (um cadastro por gatilho). Recorte dos campos que o handler usa (valores ilustrativos, campos reais do template; o payload completo está na documentação de webhooks):

{
  "payment": {
    "id": "8812345",
    "method": "credit_card",
    "net_value_cents": "28663"
  },
  "cart": { "src": "pedido-4821" }
}

No handler: valide X-HeroPay-Signature, busque o pedido por cart.src, grave payment.id e o líquido (net_value_cents) e marque status_conciliacao = "recebido_webhook". O bruto você já tem no pedido (é o price_cents do link), e o job diário do passo 3 confirma o valor cobrado. Trate os valores do payload como texto e converta para inteiro antes de somar. No exemplo, R$ 297 no cartão à vista pagam 3,49% (R$ 10,37) e entram R$ 286,63.

3. Rode o job diário de conferência

O webhook tem retentativa automática, mas nenhuma retentativa cobre um endpoint fora do ar por tempo indefinido. Todo dia, puxe as transações pagas de ontem:

curl -G "$HEROPAY_API_URL/transactions/by_status" \
  -H "Authorization: Bearer $HEROPAY_JWT_TOKEN" \
  -H "Accept: application/vnd.herospark.com; version=1" \
  -d "status=paid" \
  -d "start_date=2026-09-22" \
  -d "end_date=2026-09-22" \
  -d "page=1" -d "items=100"

Resposta 200 (recorte do exemplo da OpenAPI):

{
  "data": {
    "data": [
      {
        "transaction_id": "645856_1756598",
        "cart": { "id": 9969670, "src": "pedido-4821", "utm": { "source": null } },
        "transaction": {
          "status": "paid",
          "created_at": "22/09/2026 22:48:10",
          "paid_at": "22/09/2026 22:49:29",
          "payment_id": 1756598,
          "payment_method": "PIX",
          "installments": 1,
          "total_amount": 72.8,
          "net_value": 70.2,
          "amount_paid_buyer": 72.8
        }
      }
    ],
    "pagination": { "current_page": 1, "total_pages": 1, "has_next_page": false }
  },
  "message": "Success"
}

Para cada item: ache o pedido por cart.src; se não houver registro do webhook, grave agora e marque recebido_job; se o valor divergir, marque divergente e alerte. Pagine até has_next_page ser false.

Duas pegadinhas desse endpoint, visíveis no próprio exemplo: valores vêm em reais com decimal (72.8), não em centavos como no resto da API, e datas vêm em DD/MM/AAAA HH:MM:SS, não em ISO 8601. Converta para centavos inteiros antes de comparar com o webhook, e cruze os dois lados por cart.src + valor.

Repita com status=refunded e status=chargeback para baixar estornos e disputas, e com status=waiting_payment para boletos e Pix em aberto.

4. Feche os totais e o caixa

Linha a linha resolve o pedido; o fechamento confere o total. Para o dia ou o mês:

curl -G "$HEROPAY_API_URL/reports/transaction/paid/net_value" \
  -H "Authorization: Bearer $HEROPAY_JWT_TOKEN" \
  -H "Accept: application/vnd.herospark.com; version=1" \
  -d "start_date=2026-09-01" -d "end_date=2026-09-30"

Compare com a soma de valor_liquido do seu banco. /reports/transaction/paid/gross_revenue, /reports/transaction/paid/payment_method_distribution e /reports/transaction/refunded/refunded_chargeback_value completam o fechamento. Rode cada relatório uma vez no sandbox e confira o formato da resposta antes de automatizar a comparação; a lista completa está na documentação de relatórios.

O dinheiro fecha em duas chamadas: GET /financial/balance (saldo disponível e a receber, em centavos) e GET /financial/withdrawals (cada saque com amount_cents, fees_cents e status). O saque é o lançamento que aparece no extrato do seu banco: concilie o extrato contra essa lista, não contra as vendas.

Variações

Por prompt, com o llms.txt

Cole https://heropay.tech/llms.txt no Claude, ChatGPT, Cursor, Lovable e outros (mais em /ai) e peça:

Lista as transações pagas de ontem e compara com os pedidos com src
"pedido-*". Me mostra os que não aparecem nos dois lados e o total líquido do dia.

Com o contrato da API no contexto, a IA escreve o job que consulta /transactions/by_status e os relatórios, que são só leitura. Revise o código antes de rodar. Um MCP server oficial está em desenvolvimento.

Sem código, pelo painel

Em app.heropay.tech, confira as vendas do período no painel. Serve para auditar uma divergência pontual sem código; a conciliação recorrente fica no job.

Erros comuns e como ler a mensagem

StatusMensagem (real)Causa e correção
422Start date deve ser uma data válida no formato YYYY-MM-DDData em DD/MM/AAAA. Os filtros usam ISO, mesmo que a resposta venha em formato brasileiro.
422Status can't be blankstatus é obrigatório em /transactions/by_status.
422Status is not included in the listStatus fora da lista (paid, refused, refunded, chargeback, waiting_payment, overdue e outros).
422Limit deve ser um número inteiro entre 10 e 1000limit fora da faixa em /sales/unitary ou /sales/recurring.
500Failed to fetch transactions: Connection errorFalha momentânea. Repita com backoff; a consulta é só leitura.

Perguntas frequentes

O que é conciliação financeira automática?

É o cruzamento sem intervenção manual entre o que você vendeu, o que o gateway processou e o que entrou na conta. Com API, cada venda nasce com uma chave (no HeroPay, o src do link), o gateway devolve essa chave no evento de pagamento e um job diário confere o que faltou. O resultado é saber, todo dia, quais pedidos foram pagos, quanto de taxa saiu e o que está divergente, sem abrir planilha.

Qual campo uso como chave de conciliação?

O cart.src, quando você cria um link por pedido com o ID em src. Ele é concatenado na URL do checkout e volta em todo webhook daquela compra e no /transactions/by_status. Se você reutiliza o mesmo link para vários compradores, src identifica a campanha e a chave da transação é o payment_id. Não use nome ou e-mail do comprador como chave: um cliente pode ter várias compras.

Webhook ou relatório: qual é a fonte de verdade?

Os dois, com papéis diferentes. O webhook é o registro em tempo real: libera o pedido na hora. O relatório por API é a conferência: pega o que o webhook perdeu e fecha o total do dia. Confie no evento para operar e no job diário para fechar. Nunca use só polling: é mais lento e gasta requisição à toa.

Como concilio estornos e chargebacks?

Cadastre os webhooks refunded e chargeback_request para marcar o pedido na hora, e rode o job com status=refunded e status=chargeback em /transactions/by_status. Para o valor total do período, use /reports/transaction/refunded/refunded_chargeback_value e, para as tarifas de disputa, /reports/transaction/refunded/chargeback_fees. Estorno reduz a receita líquida do mês em que acontece, não do mês da venda.

Como bato o extrato do banco com o HeroPay?

Pelo saque, não pela venda. As vendas entram no saldo da conta HeroPay; o que chega ao seu banco é cada saque para a sua chave Pix. GET /financial/withdrawals lista cada um com amount_cents, fees_cents e status. Some os saques confirmados do período e compare com os créditos do extrato. A diferença entre vendas líquidas e saques é o saldo que ficou na conta.

O HeroPay importa extrato OFX ou integra com ERP?

Não. O HeroPay não importa extrato bancário nem tem conector nativo de ERP na v1. O que ele entrega é a ponta do gateway pronta por API e webhook: chave por pedido, evento assinado, transações com bruto e líquido, relatórios e saques. O cruzamento com o extrato e o lançamento no ERP ficam no seu job ou na sua ferramenta de conciliação.

Comece agora

Execute este passo a passo agora

Sandbox grátis e idêntico à produção: cole o código e rode.

Pix e boleto R$ 0 · cartão 3,49% em até 12x · saque sem tarifa