2026-05-05
v0.9.0 — Log por tentativa para auditoria de billing recorrente
A tabela scheduled_charge_cycle_attempt foi criada na v0.8.0 mas ficou sem ninguém escrevendo nela — uma tabela vazia em produção. A v0.9.0 fecha essa ponta e expõe os dados via API, SDK e MCP. Com isso, sellers podem auditar exatamente o que aconteceu em cada cobrança recorrente que falhou.
Toda tentativa lógica de cobrança gera uma linha em scheduled_charge_cycle_attempt:
pending aguardando webhook), recusa.Cada linha captura: origem (source), método, paymentMethodId + snapshot de cardLast4/cardBrand (sobrevive a LGPD removal), status, failureCode canônico + failureReason + gatewayFailureCode raw, gatewayChargeId, transactionId. attemptNumber é monotônico por ciclo.
A escrita é best-effort: erros são logados + capturados pelo Sentry mas nunca quebram o pipeline de billing.
GET /api/scheduled-charges/:id/attemptsEndpoint paginado que retorna todas as tentativas de uma série, com filtro opcional por cycleNumber. Junta com o ciclo pai para incluir cycleNumber em cada linha — sem precisar de uma segunda chamada.
curl 'https://garu.com.br/api/scheduled-charges/sch_abc/attempts?cycleNumber=3' \
-H "Authorization: Bearer $GARU_API_KEY"
garu.scheduledCharges.listAttempts@garuhq/node@0.8.0 traz o método e os tipos:
const { data } = await garu.scheduledCharges.listAttempts('sch_abc', {
cycleNumber: 3,
});
const declines = data.filter((a) => a.status === 'declined');
// → cada declines[i].failureCode é um GaruFailureCode estável
Tipos exportados: ScheduledChargeAttempt, ScheduledChargeAttemptList, ScheduledChargeAttemptSource, ScheduledChargeAttemptStatus, ListScheduledChargeAttemptsParams.
list_scheduled_charge_attemptsAgentes podem inspecionar histórico de cobrança como parte de fluxos de suporte. @garuhq/mcp@0.8.0 expõe a ferramenta com filtro por cycleNumber + paginação.
overdue.Aditivo. Nada quebra. A tabela scheduled_charge_cycle_attempt já existia desde a v0.8.0; a v0.9.0 apenas começa a escrever nela e a expor via API. Séries existentes não terão linhas para tentativas anteriores à v0.9.0 (não há backfill de histórico).
listAttempts + tipos (paridade @garuhq/node).