Pular para o conteúdo

Faturas

Fatura você não cria — o motor gera, cerca de 3 dias antes do vencimento (a folga em que o preço variável é apurado e qualquer problema se resolve sem o assinante perceber). A API serve para consultar e para destravar uma fatura retida.

Rota O que faz
GET /v1/invoices Todas as faturas, paginadas, com filtro por estado
GET /v1/invoices/{invoiceId} A fatura com itens e o histórico cru de pricing
POST /v1/invoices/{invoiceId}/retry-pricing Re-dispara o pull de preço fora do cronograma
POST /v1/invoices/{invoiceId}/items/{itemId}/value Destrava um item com valor manual
Campo Tipo Descrição
id string (uuid) Identificador da fatura
subscriptionId string (uuid) Assinatura dona da fatura
cycle integer Ciclo da assinatura que esta fatura representa (1ª fatura = ciclo 1)
status enum Estado no ciclo de vida — ver valores
dueDate string (date) Vencimento (YYYY-MM-DD) — o chargeDay da assinatura
paymentMethod string Método de pagamento desta fatura
installments integer | null Parcelas no cartão — null quando à vista ou método sem parcela
totalCents integer | null Total em centavos — null enquanto houver item aguardando valor
gatewayInvoiceId string | null Id da cobrança no seu gateway, preenchido após a emissão
issuedAt datetime | null Quando foi emitida no gateway
paidAt datetime | null Quando foi paga
createdAt datetime Quando foi gerada
items[] array Itens com snapshot de preço e desconto — só no detalhe
pricingAttempts[] array Histórico cru das chamadas ao seu endpoint de preço — só no detalhe
draft → awaiting_value → ready → issued → paid | overdue
Valor Significado
draft Gerada; itens fixos calculados pela régua do plano
awaiting_value Retida: item variável sem resposta válida — você foi alertado (invoice.held), ação sua destrava
ready Todos os valores congelados; pronta para emissão
issued Cobrança avulsa criada no seu gateway — só registrado depois do gateway confirmar
paid Pagamento confirmado (conciliação com o gateway)
overdue Recusada ou vencida sem pagamento — se você tem a Recuperação, a régua assume daqui
canceled Retirada do fluxo — não será emitida

Duas garantias: nada vira issued antes de o gateway confirmar a criação da cobrança, e fatura de valor total zero não é emitida — o motor a liquida localmente. Retentativa ou reemissão de cobrança acontece na mesma fatura, sem gerar uma nova.

GET /v1/invoices

Query:

Parâmetro Tipo Padrão Descrição
page integer 1 Página, começando em 1
pageSize integer 25 Itens por página, máximo 100
status enum Filtra por estado. status=awaiting_value lista as retidas que precisam de você

Resposta 200: { data: [Fatura…], pagination } — sem items[] nem pricingAttempts[] (use o detalhe).

Janela do terminal
# o que está retido aguardando ação sua
curl "$MOTOR/invoices?status=awaiting_value" -H "$AUTH"
GET /v1/invoices/{invoiceId}

Resposta 200: o objeto Fatura completo, com items[] e pricingAttempts[]. Erros: 404.

Cada item carrega o snapshot congelado na geração — auditável para sempre, mesmo que produto ou plano mudem depois:

Campo Tipo Descrição
id string (uuid) Identificador do item — é o {itemId} do valor manual
productId string (uuid) Produto do catálogo
productName string Nome congelado na geração
pricingSource enum De onde o valor veio — ver abaixo
pricingStatus enum Situação do valor — ver abaixo
months integer Meses cobertos pelo ciclo (o periodMonths do plano)
monthlyPriceCents integer | null Preço mensal congelado — null em item variável
discountPercent integer | null Desconto aplicado pela régua neste ciclonull = sem desconto
amountCents integer | null Valor final do item, congelado — null enquanto pendente
description string | null A linha que o assinante lê

O enum pricingSource:

Valor Significado
table Preço fixo de tabela, com a régua de desconto do plano aplicada
endpoint Valor veio do seu endpoint de preço
manual Valor informado manualmente para destravar

O enum pricingStatus:

Valor Significado
pending Aguardando valor — é o que retém a fatura em awaiting_value
priced Valor fechado e congelado
skipped Seu endpoint respondeu { "skip": true } — item não cobrado neste ciclo

Cada chamada ao seu endpoint de preço fica gravada crua — é com isso que seu time debuga:

Campo Tipo Descrição
attempt integer Número da tentativa
url string URL chamada
outcome enum Resultado — mesmo enum do pricing-test (ok, skip, timeout, http_error, invalid_response, over_cap)
responseStatus integer | null HTTP status devolvido, quando houve resposta
latencyMs integer | null Latência da chamada
responseBody string | null Corpo cru da resposta
createdAt datetime Quando a tentativa aconteceu
POST /v1/invoices/{invoiceId}/retry-pricing

Re-dispara a chamada ao seu endpoint agora, para todo item pendente desta fatura, fora do cronograma de backoff (que sozinho retenta por 12h+). Use depois de corrigir o seu endpoint.

Resposta 200:

Campo Tipo Descrição
retried integer Quantos itens pendentes foram re-disparados agora

Erros: 404. Fatura sem item pendente devolve retried: 0.

POST /v1/invoices/{invoiceId}/items/{itemId}/value

O outro destravamento: fecha um item pending com o valor informado (pricingSource vira manual). Quando todos os itens fecham, a fatura vai a ready e é emitida.

Parâmetro Em Descrição
invoiceId path Id da fatura
itemId path Id do item aguardando valor

Corpo:

Campo Tipo Obrigatório Descrição
amount integer Sim Valor do item em centavos, ≥ 0
description string Não Até 300 caracteres — a linha da fatura
Janela do terminal
curl -X POST $MOTOR/invoices/0199c2…/items/0199c3…/value -H "$AUTH" \
-H "Content-Type: application/json" \
-d '{ "amount": 18760, "description": "Garrafas extras — 4 un." }'

Resposta 200: o objeto Fatura completo após o destravamento. Erros: 404 · 409 (item não está aguardando valor).