Recarga Automática de Subconta (Provedor de Pagamento Personalizado)
Se você prefere gerenciar pagamentos de crédito de subcontas através do seu próprio provedor em vez do Stripe (transferências bancárias, gateways de pagamento locais, sistemas de cobrança personalizados), a plataforma disponibiliza um par de webhook + API para que você possa executar todo o ciclo de cobrança e concessão por conta própria. A visão geral não técnica encontra-se na página Contas de Agência; esta página cobre o payload exato do webhook e a chamada de API que você deve fazer para conceder os créditos posteriormente.
O webhook é apenas uma das maneiras pelas quais as recargas automáticas são pagas. Se você conectou o Stripe ou o PayPal no Modo SaaS, a plataforma cobra o cartão salvo ou a conta PayPal do cliente automaticamente e concede os créditos, portanto, não há nada nesta página para você construir. Continue lendo apenas se quiser processar o pagamento por conta própria.
O fluxo em resumo
- O saldo de crédito de uma subconta cai abaixo do limite de recarga automática.
- A plataforma chama sua URL de webhook com os detalhes da subconta e quantos créditos ela precisa.
- Seu servidor cobra o cliente através do provedor que você utiliza.
- Seu servidor chama a API de Concessão de Créditos para adicionar créditos a essa subconta.
- Seu servidor responde
200para confirmar o recebimento do webhook.
1. Webhook: agency_sub_account_auto_recharge
Configure a URL do webhook clicando em SaaS Mode na barra lateral principal, escolhendo Use a Custom Payment Provider Instead (ou, uma vez configurado, abrindo o cartão Custom Payment Provider) e preenchendo o campo Auto-Recharge Webhook.
Quando é disparado
Quando o saldo de crédito de uma subconta cai abaixo do limite de recarga automática configurado.
Payload
{
"event": "agency_sub_account_auto_recharge",
"sub_account_id": "<sub-account-id>",
"sub_account_email": "customer@example.com",
"sub_account_name": "John Doe",
"agency_id": "<agency-id>",
"credits_requested": 500,
"current_balance": 42,
"threshold": 100,
"price_per_credit_cents": 10,
"price_per_credit_currency": "usd",
"total_amount_cents": 5000,
"timestamp": "2026-04-13T12:00:00.000Z",
"idempotency_key": "auto_recharge_abc123_1681387200000"
}
| Campo | Descrição |
|---|---|
event |
Sempre agency_sub_account_auto_recharge para este webhook. |
sub_account_id |
O ID exclusivo da subconta que precisa de créditos. |
sub_account_email |
O endereço de e-mail da subconta. |
sub_account_name |
O nome de exibição da subconta. |
agency_id |
O ID exclusivo da sua conta de agência. |
credits_requested |
Quantos créditos conceder. Este é o valor de recarga configurado por você, mas se o saldo tiver caído abaixo do limite mais do que esse valor cobriria, ele é automaticamente aumentado para o necessário para elevar o saldo acima do limite de uma só vez. Sempre cobre (e conceda) o valor credits_requested do payload — não defina seu valor de recarga como fixo no código. |
current_balance |
O saldo de crédito da subconta no momento em que o webhook foi enviado. |
threshold |
O limite de saldo que disparou a recarga. |
price_per_credit_cents |
Seu preço configurado por crédito, em centavos. |
price_per_credit_currency |
A moeda do preço (por exemplo, usd). |
total_amount_cents |
O valor total a ser cobrado, em centavos (credits_requested × price_per_credit_cents). |
timestamp |
Quando o webhook foi enviado (formato ISO 8601). |
idempotency_key |
Uma chave exclusiva para esta solicitação de recarga específica. Use-a para evitar conceder créditos duas vezes caso seu servidor receba o mesmo webhook mais de uma vez. |
Observações importantes
- Intervalo de 5 minutos — Após uma tentativa de recarga para uma subconta, a plataforma não enviará outro webhook para essa subconta por pelo menos 5 minutos, mesmo que o saldo caia ainda mais. Isso evita cobranças duplicadas durante o processamento.
- Use a chave de idempotência — Sempre verifique
idempotency_keyantes de conceder créditos. Se seu servidor falhar após conceder os créditos, mas antes de responder, a plataforma pode reenviar o webhook na próxima queda de crédito. - Falhas são seguras e autorrecuperáveis — Se sua URL de webhook estiver inacessível ou retornar um erro, nenhum crédito será concedido. A plataforma continua reenviando o webhook (uma vez a cada intervalo de 5 minutos) enquanto a subconta permanecer abaixo do limite — não é necessário que o saldo suba acima do limite e caia novamente primeiro. Uma única cobrança perdida não deixará mais uma subconta permanentemente sem recarga.
- Defina seu valor de recarga igual ou superior ao limite — Seu valor de recarga configurado deve ser maior ou igual ao limite de recarga automática, para que uma recarga sempre restaure o saldo acima do limite. (Se você precisar corrigir uma subconta que ficou muito abaixo do limite, a plataforma a completa automaticamente com o déficit total — veja
credits_requestedacima.)
2. API de Concessão de Créditos
Após seu servidor ter processado o pagamento, chame este endpoint para adicionar os créditos à subconta.
Solicitação
POST https://api.dmchamp.com/v1/subaccounts/credits
X-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"email": "customer@example.com",
"amount": 500,
"description": "Auto-recharge via webhook"
}
| Campo | Obrigatório | Descrição |
|---|---|---|
email |
Sim | O endereço de e-mail da subconta (deve corresponder a uma subconta existente sob sua agência). |
amount |
Sim | O número de créditos a conceder. |
description |
Não | Uma nota descrevendo por que os créditos foram adicionados (exibida no histórico de transações de crédito). |
Autenticação: Envie sua chave de API em um cabeçalho de requisição — seja X-API-Key: YOUR_API_KEY ou Authorization: Bearer YOUR_API_KEY. Cabeçalhos são a forma recomendada, pois uma chave na URL acaba no histórico do navegador, logs de proxy e logs de acesso do servidor. O parâmetro de consulta ?apiKey=YOUR_API_KEY e um campo apiKey no corpo JSON também ainda funcionam, para que integrações mais antigas continuem funcionando sem alterações.
Resposta
{
"success": true,
"sub_account_id": "abc123xyz",
"credits_added": 500,
"new_balance": 542
}
Dica: Armazene o idempotency_key do payload do webhook e verifique-o antes de chamar este endpoint. Isso evita conceder créditos duas vezes acidentalmente caso seu servidor receba o mesmo webhook mais de uma vez.
O que acontece com os créditos concedidos no redefinir mensal
Isso depende de como a subconta está configurada:
- Revenda (a subconta paga a você pelos créditos): os créditos que você concede aqui são registrados como créditos comprados e são acumulados todos os meses. O que a subconta não gastou permanece no saldo.
- Alocação (você dá à subconta uma mesada mensal): o saldo é reabastecido para o valor da mesada mensal na data de redefinição, portanto, qualquer valor não gasto não é acumulado. Isso é intencional — a mesada é concedida novamente a cada mês.
Se você quiser que o saldo restante de uma subconta seja adicionado à sua nova mesada mensal em vez de substituí-la, ative o acúmulo de créditos:
PUT https://api.dmchamp.com/v1/subaccounts/{subAccountUid}/limits
X-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"usageLimits": { "roll_over_to_next_month": true }
}
Se a subconta — ou o plano em que ela está — também tiver um limite de renovação ou uma data de validade definida, a redefinição ocorre no momento em que eles são aplicados: a franquia acumulada é reduzida para os meses permitidos, e a franquia não utilizada por mais tempo do que a janela de validade é descartada, antes que a nova franquia seja adicionada. Créditos concedidos por meio deste endpoint, recargas automáticas e as próprias recargas do cliente são créditos únicos e nunca são reduzidos. Veja Limitando o que é acumulado.
Exemplo de ponta a ponta
Um manipulador típico se parece com isto:
on POST /your-recharge-webhook:
payload = request.body
if seen(payload.idempotency_key):
return 200 // already processed, ack and exit
charge_result = your_payment_provider.charge(
email = payload.sub_account_email,
amount_cents = payload.total_amount_cents,
currency = payload.price_per_credit_currency,
)
if not charge_result.ok:
return 500 // platform will retry on next balance drop
api.post("/v1/subaccounts/credits", {
email = payload.sub_account_email,
amount = payload.credits_requested,
description = "Auto-recharge via " + your_provider_name,
})
mark_seen(payload.idempotency_key)
return 200