Skip to main content
POST
/
api
/
scheduled-charges
/
{id}
/
charge-now
Cobrar Agora
curl --request POST \
  --url https://garu.com.br/api/scheduled-charges/{id}/charge-now \
  --header 'Authorization: Bearer <token>'

Documentation Index

Fetch the complete documentation index at: https://docs.garu.com.br/llms.txt

Use this file to discover all available pages before exploring further.

Visão Geral

Dispara a cobrança e a notificação ao cliente imediatamente — o mesmo fluxo que o cron diário rodaria no dia do vencimento, só que antecipado. Use quando você quer cobrar antes do dueDate: o cliente já confirmou, você fechou o mês mais cedo, ou está recuperando manualmente uma série que ficou para trás. Não tem corpo de requisição. A cobrança é identificada pelo id no path. Permitido a partir de: scheduled / due_today. Aceita chave de API (sk_test_… / sk_live_…) ou JWT do dashboard. Exige a permissão scheduled_charge:edit e só enxerga cobranças do próprio seller.
Esta ação é idempotente por ciclo. Se o ciclo atual da cobrança já foi disparado (pelo cron ou por uma chamada anterior a charge-now), a Garu não cobra de novo — retorna 200 com outcome: "already_sent". Pode chamar à vontade sem risco de cobrança dupla.

Exemplo de Requisição

curl -X POST https://garu.com.br/api/scheduled-charges/sch_abc123/charge-now \
  -H "Authorization: Bearer sk_test_sua_chave"
Um SDK Flutter com chargeNow será documentado aqui assim que essa biblioteca for publicada.

Parâmetros de Path

id
string
required
ID da cobrança (sch_…). Deve pertencer ao seller autenticado.
Sem corpo de requisição.

Resposta

Sempre 200 quando a cobrança é válida e cobrável. O resultado real fica no campo outcome — ele indica se a Garu disparou, ignorou (já enviado) ou falhou. Trate outcome, não o status HTTP, para saber o que aconteceu.
{
  "outcome": "dispatched",
  "cycleNumber": 1,
  "message": "Cobrança disparada. O cliente já recebeu o e-mail de pagamento."
}
O texto de message neste e nos demais exemplos é ilustrativo — o valor exato é gerado pelo servidor e pode mudar. Faça sua lógica em cima de outcome e reason; use message apenas para exibir ao usuário.

Campos

CampoTipoDescrição
outcomestringResultado do disparo. Um de dispatched, already_sent, not_sent, failed.
cycleNumbernumber | nullNúmero do ciclo cobrado. null quando não há ciclo aberto a reportar.
reasonstringPresente em not_sent e failed; código curto e estável que explica o motivo. Ausente em dispatched e already_sent.
messagestringTexto pt-BR pronto para exibir ao usuário, já adequado ao outcome/reason.

Valores de outcome

outcomeO que significaVocê precisa agir?
dispatchedA cobrança foi disparada agora e o e-mail saiu para o cliente.Não — fluxo normal.
already_sentO ciclo atual já tinha sido disparado; nada foi cobrado de novo (idempotência).Não — é o comportamento esperado em re-chamadas.
not_sentA Garu não chegou a disparar por uma condição de pré-envio (ver reason).Sim — resolva o reason e tente de novo.
failedO disparo foi tentado mas falhou (cartão/cobrança recusada — ver reason).Sim — corrija a causa (ex.: pedir novo cartão).

Valores de reason

Para not_sent:
reasonSignificado da message
no_emailO cliente não tem e-mail de cobrança cadastrado, então não há para quem enviar o link.
no_saved_payment_methodNão existe método de pagamento salvo para cobrar este ciclo (cobrança recorrente sem cartão tokenizado).
lock_lostOutro processo (provavelmente o próprio cron) estava cobrando este ciclo no mesmo instante; a Garu evitou a corrida. Tente de novo em alguns segundos.
Para failed:
reasonSignificado da message
card_expiredO cartão salvo do cliente expirou. Peça um novo método de pagamento.
payment_method_missingO método de pagamento que seria usado não está mais disponível.
customer_missingO cliente vinculado à cobrança não foi encontrado.
<código do gateway>A operadora recusou a cobrança; o reason carrega o código canônico de falha (ex.: insufficient_funds). Veja Códigos de falha.
O campo message já vem com o texto pt-BR correspondente a cada combinação de outcome + reason, pronto para exibir direto na sua interface.

Erros

StatusCaso
400A cobrança não está em status cobrável (scheduled ou due_today) — ex.: já está paid, paused ou canceled. Também 400 se for uma recorrência sem ciclo aberto para disparar.
404A cobrança não existe ou não pertence ao seller que está chamando.
400 e 404 são erros de requisição — a cobrança não pôde sequer ser avaliada. Já um disparo que roda mas não cobra (cartão recusado, sem e-mail) volta como 200 com outcome: "failed" ou "not_sent". Não confunda os dois: trate o HTTP para erros de chamada e o outcome para o resultado do disparo.

Como se relaciona com o cron diário

charge-now roda a mesma rotina de cobrança que o cron dispara no dueDate, compartilhando o lock por ciclo. Por isso o disparo manual e o automático não se atropelam:
  • Se o cron já disparou o ciclo hoje, charge-now devolve already_sent.
  • Se você disparar com charge-now, o cron não dispara de novo aquele ciclo.
maxRecoveryDays (definido na criação) é um mecanismo separado: ele controla por quantos dias o cron tenta recuperar automaticamente um ciclo cujo disparo tenha falhado. charge-now não altera essa janela — é o gatilho manual para disparar o ciclo na hora.

Próximos passos

Criar cobrança agendada

Inclui o campo maxRecoveryDays para recuperação automática de ciclos perdidos

Tentativas de cobrança

Audite cada tentativa por ciclo, com o failureCode canônico de cada recusa