
# Ricarica automatica del sub-account (Provider di pagamento personalizzato)

Se preferisci gestire i pagamenti dei crediti dei sub-account tramite il tuo provider invece di Stripe (bonifici bancari, gateway di pagamento locali, sistemi di fatturazione personalizzati), la piattaforma espone una coppia webhook + API in modo che tu possa eseguire autonomamente l'intero ciclo di addebito e concessione. La panoramica non tecnica si trova nella pagina [Account Agenzia](agency-accounts.md#option-2-custom-payment-provider); questa pagina illustra il payload esatto del webhook e la chiamata API da effettuare per concedere i crediti successivamente.

Il webhook è solo uno dei modi in cui vengono pagate le ricariche automatiche. Se hai collegato [Stripe](agency-accounts.md#option-1-connect-stripe) o [PayPal](agency-accounts.md#option-3-connect-paypal) in modalità SaaS, la piattaforma addebita direttamente la carta salvata o il conto PayPal del cliente e assegna i crediti, quindi non c'è nulla da implementare in questa pagina. Continua a leggere solo se desideri gestire il pagamento autonomamente.

***

## Il flusso in sintesi

1. Il saldo crediti di un sub-account scende al di sotto della soglia di ricarica automatica.
2. La piattaforma chiama il tuo **URL webhook** con i dettagli del sub-account e il numero di crediti necessari.
3. Il tuo server addebita il costo al cliente tramite il provider che utilizzi.
4. Il tuo server chiama l'**API di concessione crediti** per aggiungere crediti a quel sub-account.
5. Il tuo server risponde `200` per confermare la ricezione del webhook.

***

## 1. Webhook: `agency_sub_account_auto_recharge`

Configura l'URL del webhook facendo clic su **SaaS Mode** nella barra laterale principale, selezionando **Use a Custom Payment Provider Instead** (o, una volta configurato, aprendo la scheda **Custom Payment Provider**) e compilando il campo **Auto-Recharge Webhook**.

### Quando viene attivato

Quando il saldo crediti di un sub-account scende al di sotto della soglia di ricarica automatica configurata.

### Payload

```json
{
  "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 | Descrizione |
|---|---|
| `event` | Sempre `agency_sub_account_auto_recharge` per questo webhook. |
| `sub_account_id` | L'ID univoco del sub-account che necessita di crediti. |
| `sub_account_email` | L'indirizzo email del sub-account. |
| `sub_account_name` | Il nome visualizzato del sub-account. |
| `agency_id` | L'ID univoco del tuo account agenzia. |
| `credits_requested` | Quanti crediti concedere. Questo è l'importo di ricarica configurato, ma se il saldo è sceso al di sotto della soglia più di quanto tale importo possa coprire, viene automaticamente aumentato a quanto necessario per riportare il saldo al di sopra della soglia in un'unica soluzione. Addebita sempre (e concedi) il valore `credits_requested` dal payload: non impostare l'importo di ricarica come valore fisso nel codice. |
| `current_balance` | Il saldo crediti del sub-account al momento dell'invio del webhook. |
| `threshold` | La soglia di saldo che ha attivato la ricarica. |
| `price_per_credit_cents` | Il prezzo per credito configurato, in centesimi. |
| `price_per_credit_currency` | La valuta per il prezzo (es. `usd`). |
| `total_amount_cents` | L'importo totale da addebitare, in centesimi (`credits_requested` × `price_per_credit_cents`). |
| `timestamp` | Quando è stato inviato il webhook (formato ISO 8601). |
| `idempotency_key` | Una chiave univoca per questa specifica richiesta di ricarica. Usala per evitare di concedere crediti due volte se il tuo server riceve lo stesso webhook più di una volta. |

### Note importanti

- **Cooldown di 5 minuti** — Dopo un tentativo di ricarica per un sub-account, la piattaforma non invierà un altro webhook per quel sub-account per almeno 5 minuti, anche se il saldo dovesse scendere ulteriormente. Ciò previene addebiti duplicati durante l'elaborazione.
- **Usa la chiave di idempotenza** — Controlla sempre `idempotency_key` prima di concedere crediti. Se il tuo server si è arrestato in modo anomalo dopo aver concesso i crediti ma prima di rispondere, la piattaforma potrebbe inviare nuovamente il webhook al calo di credito successivo.
- **I fallimenti sono sicuri e auto-riparanti** — Se il tuo URL webhook non è raggiungibile o restituisce un errore, non vengono concessi crediti. La piattaforma continua a inviare nuovamente il webhook (una volta per ogni cooldown di 5 minuti) finché il sub-account rimane al di sotto della soglia: **non** richiede che il saldo risalga sopra la soglia e scenda di nuovo per primo. Un singolo addebito mancato non può più lasciare un sub-account permanentemente senza ricarica.
- **Imposta l'importo di ricarica pari o superiore alla soglia** — L'importo di ricarica configurato deve essere maggiore o uguale alla soglia di ricarica automatica, in modo che una ricarica ripristini sempre il saldo al di sopra della soglia. (Se avessi mai bisogno di correggere un sub-account che è sceso molto al di sotto della soglia, la piattaforma lo integra automaticamente per l'intero deficit: vedi `credits_requested` sopra.)

***

## 2. API di concessione crediti

Dopo che il tuo server ha elaborato il pagamento, chiama questo endpoint per aggiungere i crediti al sub-account.

### Richiesta

```http
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 | Obbligatorio | Descrizione |
|---|---|---|
| `email` | Sì | L'indirizzo email del sub-account (deve corrispondere a un sub-account esistente sotto la tua agenzia). |
| `amount` | Sì | Il numero di crediti da concedere. |
| `description` | No | Una nota che descrive perché sono stati aggiunti i crediti (mostrata nella cronologia delle transazioni di credito). |

**Autenticazione:** Invia la tua chiave API nell'intestazione della richiesta — tramite `X-API-Key: YOUR_API_KEY` o `Authorization: Bearer YOUR_API_KEY`. L'uso delle intestazioni è il metodo consigliato, poiché una chiave nell'URL finisce nella cronologia del browser, nei log dei proxy e nei log di accesso del server. Il parametro di query `?apiKey=YOUR_API_KEY` e il campo `apiKey` nel corpo JSON continuano a funzionare, in modo che le integrazioni meno recenti continuino a funzionare senza modifiche.

### Risposta

```json
{
  "success": true,
  "sub_account_id": "abc123xyz",
  "credits_added": 500,
  "new_balance": 542
}
```

::: tip
**Suggerimento:** Memorizza il `idempotency_key` dal payload del webhook e verificalo prima di chiamare questo endpoint. Ciò impedisce di assegnare accidentalmente crediti due volte se il tuo server riceve lo stesso webhook più di una volta.
:::


### Cosa succede ai crediti concessi al ripristino mensile

Ciò dipende da come è configurato il sotto-account:

- **Rivendita** (il sotto-account ti paga per i crediti): i crediti che concedi qui vengono registrati come crediti acquistati e **si accumulano** ogni mese. Tutto ciò che il sotto-account non ha speso rimane nel saldo.
- **Allocazione** (assegni al sotto-account una disponibilità mensile): il saldo viene riportato alla disponibilità mensile alla data di ripristino, quindi tutto ciò che non è stato speso non viene accumulato. Questo è intenzionale: la disponibilità viene concessa come nuova ogni mese.

Se desideri che il saldo residuo di un sotto-account venga aggiunto alla sua nuova disponibilità mensile invece di sostituirla, attiva l'accumulo dei crediti:

```
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 il sotto-account — o il piano su cui si trova — ha anche un limite di roll-over o una scadenza impostata, il ripristino avviene nel momento in cui questi vengono applicati: la disponibilità riportata viene ridotta ai mesi consentiti e la disponibilità inutilizzata per un periodo superiore alla finestra di scadenza viene eliminata, prima che venga aggiunta la nuova disponibilità. I crediti concessi tramite questo endpoint, le ricariche automatiche e le ricariche effettuate dal cliente sono crediti una tantum e non vengono mai ridotti. Vedi [Limitare ciò che viene riportato](sub-accounts.md#capping-what-rolls-over).

***

## Esempio end-to-end

Un gestore tipico ha questo aspetto:

```pseudo
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
```
