
# Automatisk påfyllning av underkonto (anpassad betalningsleverantör)

Om du föredrar att hantera kreditbetalningar för underkonton via din egen leverantör istället för Stripe (banköverföringar, lokala betalväxlar, anpassade faktureringssystem), tillhandahåller plattformen ett par bestående av webhook + API så att du själv kan köra hela processen för debitering och tilldelning. Den icke-tekniska översikten finns på sidan [Byråkonton](agency-accounts.md#option-2-custom-payment-provider); den här sidan täcker den exakta webhook-nyttolasten och det API-anrop du gör för att tilldela krediter efteråt.

Webbhooken är bara ett av sätten som automatiska påfyllningar betalas för. Om du har anslutit [Stripe](agency-accounts.md#option-1-connect-stripe) eller [PayPal](agency-accounts.md#option-3-connect-paypal) i SaaS-läge debiterar plattformen kundens sparade kort eller PayPal-konto direkt och tilldelar krediter, så det finns inget på den här sidan som du behöver bygga. Läs vidare endast om du vill hantera betalningen själv.

***

## Flödet i korthet

1. Ett underkontos kreditsaldo sjunker under deras tröskelvärde för automatisk påfyllning.
2. Plattformen anropar din **webhook-URL** med underkontots uppgifter och hur många krediter de behöver.
3. Din server debiterar kunden via den leverantör du använder.
4. Din server anropar **API:et för att tilldela krediter** för att lägga till krediter på det underkontot.
5. Din server svarar `200` för att bekräfta webhooken.

***

## 1. Webhook: `agency_sub_account_auto_recharge`

Konfigurera webhook-URL:en genom att klicka på **SaaS Mode** i huvudsidofältet, välja **Use a Custom Payment Provider Instead** (eller, när den väl är konfigurerad, öppna kortet **Custom Payment Provider**), och fylla i fältet **Auto-Recharge Webhook**.

### När den utlöses

När ett underkontos kreditsaldo sjunker under deras konfigurerade tröskelvärde för automatisk påfyllning.

### Nyttolast

```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"
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `agency_sub_account_auto_recharge` för denna webhook. |
| `sub_account_id` | Det unika ID:t för underkontot som behöver krediter. |
| `sub_account_email` | Underkontots e-postadress. |
| `sub_account_name` | Underkontots visningsnamn. |
| `agency_id` | Ditt byråkontos unika ID. |
| `credits_requested` | Hur många krediter som ska tilldelas. Detta är ditt konfigurerade påfyllningsbelopp, men om saldot har fallit längre under tröskelvärdet än vad det beloppet skulle täcka, höjs det automatiskt till vad som krävs för att få upp saldot över tröskelvärdet igen på en gång. Debitera alltid för (och tilldela) värdet `credits_requested` från nyttolasten — hårdkoda inte ditt påfyllningsbelopp. |
| `current_balance` | Underkontots kreditsaldo vid tidpunkten då webhooken skickades. |
| `threshold` | Saldotröskeln som utlöste påfyllningen. |
| `price_per_credit_cents` | Ditt konfigurerade pris per kredit, i cent. |
| `price_per_credit_currency` | Valutan för priset (t.ex. `usd`). |
| `total_amount_cents` | Det totala beloppet att debitera, i cent (`credits_requested` × `price_per_credit_cents`). |
| `timestamp` | När webhooken skickades (ISO 8601-format). |
| `idempotency_key` | En unik nyckel för denna specifika påfyllningsbegäran. Använd denna för att förhindra att krediter tilldelas två gånger om din server tar emot samma webhook mer än en gång. |

### Viktiga anteckningar

- **5 minuters nedkylning** — Efter ett påfyllningsförsök för ett underkonto kommer plattformen inte att skicka en ny webhook för det underkontot på minst 5 minuter, även om deras saldo sjunker ytterligare. Detta förhindrar dubbla debiteringar under bearbetning.
- **Använd idempotensnyckeln** — Kontrollera alltid `idempotency_key` innan du tilldelar krediter. Om din server kraschade efter att ha tilldelat krediter men innan den svarade, kan plattformen skicka om webhooken vid nästa kreditfall.
- **Fel är säkra och självläkande** — Om din webhook-URL inte kan nås eller returnerar ett fel, tilldelas inga krediter. Plattformen fortsätter att skicka webhooken (en gång per 5-minuters nedkylning) så länge underkontot ligger under tröskelvärdet — det kräver **inte** att saldot först stiger över tröskelvärdet och sjunker igen. En missad debitering kan inte längre lämna ett underkonto permanent utan påfyllning.
- **Ställ in ditt påfyllningsbelopp vid eller över tröskelvärdet** — Ditt konfigurerade påfyllningsbelopp måste vara större än eller lika med tröskelvärdet för automatisk påfyllning, så att en påfyllning alltid återställer saldot över tröskelvärdet. (Om du någonsin behöver fixa ett underkonto som hamnat långt under tröskelvärdet, fyller plattformen automatiskt på hela underskottet — se `credits_requested` ovan.)

***

## 2. API för att tilldela krediter

När din server har behandlat betalningen, anropa denna slutpunkt för att lägga till krediterna på underkontot.

### Begäran

```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"
}
```

| Fält | Krävs | Beskrivning |
|---|---|---|
| `email` | Ja | Underkontots e-postadress (måste matcha ett befintligt underkonto under din byrå). |
| `amount` | Ja | Antalet krediter som ska tilldelas. |
| `description` | Nej | En anteckning som beskriver varför krediter lades till (visas i kredittransaktionshistoriken). |

**Autentisering:** Skicka din API-nyckel i en begärandehuvud — antingen `X-API-Key: YOUR_API_KEY` eller `Authorization: Bearer YOUR_API_KEY`. Huvuden är det rekommenderade sättet, eftersom en nyckel i URL:en hamnar i webbläsarhistorik, proxyloggar och serveråtkomstloggar. Frågeparametern `?apiKey=YOUR_API_KEY` och ett `apiKey`-fält i JSON-kroppen fungerar fortfarande, så äldre integrationer fortsätter att fungera oförändrade.

### Svar

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

::: tip
**Tips:** Spara `idempotency_key` från webhook-nyttolasten och kontrollera den innan du anropar denna slutpunkt. Detta förhindrar att krediter av misstag beviljas två gånger om din server tar emot samma webhook mer än en gång.
:::


### Vad händer med beviljade krediter vid den månatliga återställningen

Detta beror på hur underkontot är konfigurerat:

- **Återförsäljning** (underkontot betalar dig för krediter): krediter som du beviljar här registreras som köpta krediter och **överförs** varje månad. Det som underkontot inte har förbrukat stannar kvar på saldot.
- **Tilldelning** (du ger underkontot en månatlig kvot): saldot fylls på till den månatliga kvoten på återställningsdatumet, så allt som inte förbrukats överförs inte. Detta är avsiktligt – kvoten beviljas på nytt varje månad.

Om du vill att ett underkontos kvarvarande saldo ska läggas till utöver dess nya månatliga kvot istället för att ersätta den, aktivera kreditöverföring:

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

Om underkontot – eller abonnemanget det tillhör – också har en gräns för överföring eller ett utgångsdatum, sker återställningen i det ögonblick dessa tillämpas: den överförda kvoten trimmas till det antal månader du tillåter, och kvot som lämnats oanvänd längre än utgångsperioden tas bort innan den nya kvoten läggs till. Krediter som beviljas via denna slutpunkt, automatiska påfyllningar och kundens egna påfyllningar är engångskrediter och trimmas aldrig. Se [Begränsa vad som överförs](sub-accounts.md#capping-what-rolls-over).

***

## Exempel från början till slut

En typisk hanterare ser ut så här:

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