Conciliação

Confere as suas cobranças contra o que o gateway registrou: status, valor, valor estornado e taxa. O que não bate aparece como divergente, campo a campo.

Funcionalidade liberada por empresa. As rotas abaixo respondem 403 enquanto a funcionalidade reconciliation não estiver liberada para a sua empresa. Fale com o suporte Paygrid para ativar.

Como funciona

Disparar a conciliação

curl -X POST https://api.paygrid.tech/v1/reconciliation/runs \
  -H "X-Api-Key: sk_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{ "days": 90 }'

days é opcional: 1 (as últimas 24 horas a partir de agora), 7, 30 ou 90. Sem corpo, ou sem days, valem 30 dias. Qualquer outro valor dá 400; corpo que não seja JSON dá 415.

A resposta é 202 com o id da execução, que roda em segundo plano:

{ "runId": "8c1f..." }
Já existe uma em andamento? A resposta é 409 com o runId dela. Acompanhe essa execução em vez de disparar outra.
{ "error": "já existe uma conciliação em andamento", "runId": "8c1f..." }

Pode disparar quem é Admin da empresa ou uma chave de API. O papel Operador só consulta.

Agenda automática

Cada empresa tem uma agenda, que define de quanto em quanto tempo a conciliação roda e em que hora. A agenda vale para a empresa toda e é gratuita enquanto estiver desligada; com ela ativa, entra na fatura como Conciliação automática por R$ 1.000,00/mês, independente da frequência escolhida.

curl https://api.paygrid.tech/v1/reconciliation/schedule \
  -H "X-Api-Key: sk_sua_chave"
{
  "configured": false,
  "active": false,
  "intervalDays": 0,
  "hour": 0,
  "weekday": 0,
  "monthlyPriceCents": 100000
}

nextRunAt, updatedAt e updatedBy aparecem quando há agenda. configured: false é resposta 200, não erro: a tela mostra o formulário vazio.

Para criar ou trocar a agenda:

curl -X PUT https://api.paygrid.tech/v1/reconciliation/schedule \
  -H "X-Api-Key: sk_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "intervalDays": 7,
    "hour": 5,
    "weekday": 1,
    "active": true
  }'
CampoRegra
intervalDaysObrigatório, de 1 a 30.
hourObrigatório, de 0 a 23, no horário de Brasília.
weekdayOpcional, de 0 (domingo) a 6. Só é usado quando intervalDays é múltiplo de 7 (7, 14, 21 ou 28); nos outros intervalos é ignorado e zerado. Serve para ancorar o ciclo semanal no dia escolhido.
activeOpcional, padrão true. false pausa a agenda sem apagá-la.

A resposta é a agenda salva, já com nextRunAt. Campo desconhecido, intervalDays ou hour ausentes ou valores fora da faixa dão 400 com { "error": "envie intervalDays (1 a 30) e hour (0 a 23)" } (ausentes) ou, por exemplo, { "error": "conciliacao: agenda inválida: intervalo deve ser de 1 a 30 dias" }. Sem a funcionalidade reconciliation liberada, as três rotas dão 403. Pode salvar quem é Admin da empresa ou uma chave de API; o papel Operador só consulta.

Para desligar de vez e parar a cobrança, remova a agenda:

curl -X DELETE https://api.paygrid.tech/v1/reconciliation/schedule \
  -H "X-Api-Key: sk_sua_chave"

A resposta é 204, mesmo que não houvesse agenda. Sem agenda, a conciliação automática não roda até que uma nova seja salva.

Acompanhar a execução

curl https://api.paygrid.tech/v1/reconciliation/runs/8c1f... \
  -H "X-Api-Key: sk_sua_chave"
{
  "runId": "8c1f...",
  "origin": "api",
  "state": "concluida",
  "since": "2026-07-18T12:00:00Z",
  "until": "2026-10-16T12:00:00Z",
  "reconciled": 118,
  "divergent": 2,
  "withError": 0,
  "total": 120,
  "startedAt": "2026-10-16T12:00:00Z",
  "finishedAt": "2026-10-16T12:00:41Z"
}
stateSignificado
processandoA execução ainda está rodando.
concluidaTerminou. As contagens são finais.
falhouNão pôde rodar; o motivo vem em error.

origin diz quem disparou: agendado (a execução da agenda), botao (painel), api (chave de API, com ou sem lista), csv ou json (lista enviada pelo painel). As execuções recentes estão em GET /v1/reconciliation/runs?limit=20. notFound conta as linhas da sua lista que não entraram na conferência (zero na automática).

Consultar o resultado por pagamento

curl "https://api.paygrid.tech/v1/reconciliation?state=divergente&limit=50" \
  -H "X-Api-Key: sk_sua_chave"
{
  "results": [
    {
      "paymentId": "pay_01H...",
      "state": "divergente",
      "divergences": [
        { "field": "valor_estornado", "local": "0", "gateway": "1990" }
      ],
      "local": { "status": "approved", "amount": 1990, "refundedAmount": 0, "feeAmount": 59 },
      "gateway": { "status": "PAYMENT_STATUS_REFUNDED", "amount": 1990, "canceledAmount": 1990, "feeAmount": 59, "hasFee": true },
      "updatedAt": "2026-10-16T12:00:40Z",
      "runId": "8c1f..."
    }
  ],
  "next": "eyJ..."
}

O que é comparado

fieldPaygridGateway
statusstatus do pagamentostatus no gateway
valoramountamount
valor_estornadorefundedAmountcanceledAmount
taxafeeAmounttaxa cobrada pelo gateway

Taxa que o gateway ainda não gerou não conta como divergência.

Conciliar a sua lista

Em vez de uma janela de dias, mande as transações que você registrou. Só elas são conferidas, e o que você informar entra na comparação. Cada linha precisa de pelo menos um identificador; o resto é opcional.

Campo (JSON / CSV)O que é
providerTransactionId / provider_transaction_idId da cobrança no gateway (ex. ch_...).
transactionId / transaction_idId da transação na Paygrid.
reference / referenceA referência do pedido enviada na cobrança.
amount / amountValor esperado. JSON: centavos (12990). CSV: reais (129,90).
status / statusStatus esperado: approved, pending, declined, failed, cancelled, refunded, partially_refunded ou PAYMENT_STATUS_*.
refundedAmount / refunded_amountValor estornado esperado, na mesma unidade do amount.

A transação é procurada pelo providerTransactionId; se não achar, pelo transactionId; depois pela reference. partially_refunded é aprovado com estorno parcial: confira o valor em refundedAmount. failed vale como recusado.

Pela API (JSON)

curl -X POST https://api.paygrid.tech/v1/reconciliation/runs \
  -H "X-Api-Key: sk_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      { "providerTransactionId": "ch_nJdVwgGilHR9w8Mb", "amount": 12990, "status": "approved" },
      { "reference": "pedido-4472", "status": "refunded", "refundedAmount": 1990 }
    ]
  }'

Pelo painel ou API (CSV)

Envie o arquivo no campo file de um multipart/form-data. Baixe o modelo em GET /v1/reconciliation/template.csv. Cabeçalho obrigatório; vírgula ou ponto e vírgula; UTF-8 com ou sem BOM (pode salvar direto do Excel); linhas começando com # são ignoradas.

provider_transaction_id;transaction_id;reference;amount;status;refunded_amount
ch_nJdVwgGilHR9w8Mb;;;129,90;approved;
;;pedido-4472;19,90;refunded;19,90
curl -X POST https://api.paygrid.tech/v1/reconciliation/runs \
  -H "X-Api-Key: sk_sua_chave" \
  -F "file=@minha-lista.csv"

Limites e erros

Três vias

Para cada campo que você informou, a linha diverge se qualquer dos três discordar:

VocêPaygridGatewayResultado
AAAconciliado
BAAdivergente — só a sua lista discorda
ABAdivergente — a Paygrid discorda
AABdivergente — o gateway discorda
(não informado)ABdivergente, com client vazio

O resultado traz o que você mandou em expected e, em cada divergência, o seu valor em client:

{
  "paymentId": "5183e61a-...",
  "state": "divergente",
  "expected": { "amount": 12990, "status": "PAYMENT_STATUS_APPROVED" },
  "divergences": [
    { "field": "valor", "client": "12990", "local": "1990", "gateway": "1990" }
  ],
  "runId": "8c1f..."
}

Linhas não encontradas

curl https://api.paygrid.tech/v1/reconciliation/runs/8c1f... \
  -H "X-Api-Key: sk_sua_chave"
{
  "runId": "8c1f...",
  "origin": "api",
  "state": "concluida",
  "reconciled": 1,
  "divergent": 0,
  "notFound": 1,
  "total": 2,
  "notFoundLines": [
    { "line": 2, "ids": { "reference": "pedido-0000" }, "reason": "não existe na Paygrid" }
  ]
}

Para ver só o resultado desta lista: GET /v1/reconciliation?runId=8c1f.... Quando a execução terminar, chega o webhook reconciliation.completed.