Reîncărcare automată pentru sub-conturi (Furnizor de plăți personalizat)
Dacă preferi să gestionezi plățile de credit pentru sub-conturi prin propriul tău furnizor în loc de Stripe (transferuri bancare, gateway-uri de plată locale, sisteme de facturare personalizate), platforma pune la dispoziție o pereche webhook + API pentru a putea rula singur întregul proces de taxare și alocare. Prezentarea generală non-tehnică se află pe pagina Conturi de agenție; această pagină acoperă payload-ul exact al webhook-ului și apelul API pe care îl faci pentru a acorda creditele ulterior.
Webhook-ul este doar una dintre modalitățile prin care se plătesc reîncărcările automate. Dacă ați conectat Stripe sau PayPal în modul SaaS, platforma taxează automat cardul salvat al clientului sau contul PayPal și acordă creditele, deci nu aveți nimic de construit pe această pagină. Citiți mai departe doar dacă doriți să gestionați plata pe cont propriu.
Fluxul pe scurt
- Soldul de credite al unui sub-cont scade sub pragul de reîncărcare automată.
- Platforma apelează URL-ul tău de webhook cu detaliile sub-contului și numărul de credite de care are nevoie.
- Serverul tău taxează clientul prin furnizorul pe care îl utilizezi.
- Serverul tău apelează API-ul de acordare a creditelor pentru a adăuga credite acelui sub-cont.
- Serverul tău răspunde cu
200pentru a confirma primirea webhook-ului.
1. Webhook: agency_sub_account_auto_recharge
Configurați URL-ul webhook-ului făcând clic pe SaaS Mode în bara laterală principală, alegând Use a Custom Payment Provider Instead (sau, odată configurat, deschizând cardul Custom Payment Provider) și completând câmpul Auto-Recharge Webhook.
Când se declanșează
Când soldul de credite al unui sub-cont scade sub pragul de reîncărcare automată configurat.
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"
}
| Câmp | Descriere |
|---|---|
event |
Întotdeauna agency_sub_account_auto_recharge pentru acest webhook. |
sub_account_id |
ID-ul unic al sub-contului care are nevoie de credite. |
sub_account_email |
Adresa de e-mail a sub-contului. |
sub_account_name |
Numele afișat al sub-contului. |
agency_id |
ID-ul unic al contului tău de agenție. |
credits_requested |
Câte credite să acorzi. Aceasta este suma de reîncărcare configurată de tine, dar dacă soldul a scăzut mai mult sub prag decât ar acoperi acea sumă, aceasta este ridicată automat la valoarea necesară pentru a readuce soldul peste prag dintr-o singură mișcare. Taxează întotdeauna pentru (și acordă) valoarea credits_requested din payload — nu introduce manual suma de reîncărcare în cod. |
current_balance |
Soldul de credite al sub-contului în momentul în care a fost trimis webhook-ul. |
threshold |
Pragul de sold care a declanșat reîncărcarea. |
price_per_credit_cents |
Prețul tău configurat per credit, în cenți. |
price_per_credit_currency |
Moneda pentru preț (de exemplu, usd). |
total_amount_cents |
Suma totală de taxat, în cenți (credits_requested × price_per_credit_cents). |
timestamp |
Când a fost trimis webhook-ul (format ISO 8601). |
idempotency_key |
O cheie unică pentru această cerere specifică de reîncărcare. Folosește-o pentru a preveni acordarea creditelor de două ori dacă serverul tău primește același webhook de mai multe ori. |
Note importante
- Interval de răcire de 5 minute — După o încercare de reîncărcare pentru un sub-cont, platforma nu va mai trimite un alt webhook pentru acel sub-cont timp de cel puțin 5 minute, chiar dacă soldul scade și mai mult. Previne taxările duplicate în timpul procesării.
- Folosește cheia de idempotență — Verifică întotdeauna
idempotency_keyînainte de a acorda credite. Dacă serverul tău s-a blocat după acordarea creditelor, dar înainte de a răspunde, platforma ar putea retrimite webhook-ul la următoarea scădere a creditelor. - Eșecurile sunt sigure și se auto-repară — Dacă URL-ul tău de webhook este inaccesibil sau returnează o eroare, nu se acordă niciun credit. Platforma continuă să retransmită webhook-ul (o dată la fiecare interval de răcire de 5 minute) atâta timp cât sub-contul rămâne sub prag — nu necesită ca soldul să urce înapoi peste prag și să scadă din nou mai întâi. O singură taxare ratată nu mai poate lăsa un sub-cont nereîncărcat permanent.
- Setează suma de reîncărcare la sau peste prag — Suma ta de reîncărcare configurată trebuie să fie mai mare sau egală cu pragul de reîncărcare automată, astfel încât o reîncărcare să restabilească întotdeauna soldul peste prag. (Dacă trebuie vreodată să repari un sub-cont care a scăzut mult sub prag, platforma completează automat întregul deficit — vezi
credits_requestedmai sus.)
2. API de acordare a creditelor
După ce serverul tău a procesat plata, apelează acest endpoint pentru a adăuga creditele în sub-cont.
Cerere
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"
}
| Câmp | Obligatoriu | Descriere |
|---|---|---|
email |
Da | Adresa de e-mail a sub-contului (trebuie să corespundă unui sub-cont existent în cadrul agenției tale). |
amount |
Da | Numărul de credite de acordat. |
description |
Nu | O notă care descrie de ce au fost adăugate creditele (afișată în istoricul tranzacțiilor de credit). |
Autentificare: Trimiteți cheia API într-un antet de cerere — fie X-API-Key: YOUR_API_KEY, fie Authorization: Bearer YOUR_API_KEY. Antetele reprezintă metoda recomandată, deoarece o cheie în URL ajunge în istoricul browserului, în jurnalele proxy și în jurnalele de acces ale serverului. Parametrul de interogare ?apiKey=YOUR_API_KEY și un câmp apiKey în corpul JSON funcționează de asemenea, astfel încât integrările mai vechi să continue să ruleze fără modificări.
Răspuns
{
"success": true,
"sub_account_id": "abc123xyz",
"credits_added": 500,
"new_balance": 542
}
Sfat: Stocați idempotency_key din payload-ul webhook-ului și verificați-l înainte de a apela acest endpoint. Acest lucru previne acordarea accidentală a creditelor de două ori în cazul în care serverul dumneavoastră primește același webhook de mai multe ori.
Ce se întâmplă cu creditele acordate la resetarea lunară
Acest lucru depinde de modul în care este configurat sub-contul:
- Revânzare (sub-contul vă plătește pentru credite): creditele pe care le acordați aici sunt înregistrate ca fiind credite achiziționate și se reportează în fiecare lună. Tot ceea ce sub-contul nu a cheltuit rămâne în sold.
- Alocare (oferiți sub-contului o alocație lunară): soldul este completat până la valoarea alocației lunare la data resetării, astfel încât orice sumă necheltuită nu este reportată. Acest lucru este intenționat — alocația este acordată proaspăt în fiecare lună.
Dacă doriți ca soldul rămas al unui sub-cont să fie adăugat peste noua sa alocație lunară în loc să o înlocuiască, activați reportarea creditelor:
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 }
}
Dacă sub-contul — sau planul pe care se află acesta — are setată și o limită de reportare sau o dată de expirare, resetarea are loc în momentul în care acestea se aplică: alocația reportată este redusă la lunile permise, iar alocația neutilizată mai mult decât fereastra de expirare este eliminată, înainte ca noua alocație să fie adăugată. Creditele acordate prin acest endpoint, reîncărcările automate și propriile reîncărcări ale clientului sunt credite unice și nu sunt niciodată eliminate. Consultați Limitarea a ceea ce se reportează.
Exemplu complet
Un handler tipic arată astfel:
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