Conto cliente: credito e punti fedeltà¶
Ogni cliente (api/v1/customers) gestisce due conti separati e permanenti:
- Credito prepagato (
accountBalance) — credito in denaro reale che il cliente versa in anticipo e utilizza poi come mezzo di pagamento negli acquisti. Rimborsabile. - Punti fedeltà / bonus (
loyaltyPoints/bonusBalance) — punti/bonus che vengono accreditati e riscattati negli acquisti. Non rimborsabili (il bonus decade in caso di liquidazione del credito).
Questa pagina corregge un'indicazione errata più datata nella panoramica REST API: non
esistono POST /customers/{id}/credit né GET /customers/{id}/transactions — queste rotte non
esistono nel codice. Le rotte reali sono documentate di seguito.
Endpoint¶
CustomersController — base api/v1/customers:
| Metodo | Endpoint | Scopo |
|---|---|---|
GET |
/{id}/account-transactions |
Movimenti di credito/conto (registro del prepagato) |
GET |
/{id}/point-transactions |
Movimenti dei punti fedeltà |
POST |
/{id}/payout |
Liquidare il credito residuo (solo accountBalance, non il bonus) |
POST |
/{id}/settle |
Compensare con un versamento un saldo aperto (ad es. un debito Disco) |
GET |
/card/{cardId} |
Risolvere il cliente tramite la carta cliente |
GET |
/{id}/invoice-summary |
Panoramica fatture/abbonamento del cliente |
Entrambi gli endpoint delle transazioni accettano facoltativamente dateFrom/dateTo come
parametri di query per delimitare il periodo.
Movimenti di conto (account-transactions)¶
GET /api/v1/customers/cus_a1b2c3/account-transactions?dateFrom=2026-07-01&dateTo=2026-07-31
Authorization: Bearer eyJ...
{
"success": true,
"data": [
{
"id": "cat_001",
"customerId": "cus_a1b2c3",
"customerName": "Max Mustermann",
"receiptId": "rec_9f8e7d",
"type": 0,
"amount": 50.00,
"balanceAfter": 50.00,
"bonusBalanceAfter": 2.50,
"description": "Guthaben-Aufladung: Guthaben 50€ x 1",
"personalId": "usr_kasse1",
"transactionDate": "2026-07-05T18:22:00Z"
}
]
}
type è un int senza uno schema enum pubblico proprio; valori osservati in pratica: 0 ricarica/
versamento, 1 utilizzo (pagamento con credito), 2 correzione (rettifica manuale di storno),
3 accredito bonus, 4 utilizzo/decadenza bonus, 5 liquidazione.
Movimenti dei punti (point-transactions)¶
{
"success": true,
"data": [
{
"id": "cpt_001",
"customerId": "cus_a1b2c3",
"customerName": "Max Mustermann",
"receiptId": "rec_9f8e7d",
"articleId": "art_cola",
"articleName": "Cola 0,3l",
"type": 0,
"points": 3.5,
"pointsAfter": 42.5,
"description": "Punkte für Verkauf",
"transactionDate": "2026-07-05T18:22:00Z"
}
]
}
type: 0 = accreditati (Earned), 1 = riscattati (Redeemed), 2 = correzione (Correction).
Liquidare (payout)¶
Liquida il credito dall'accountBalance (non dal bonus — questo decade in tal caso).
POST /api/v1/customers/cus_a1b2c3/payout
Authorization: Bearer eyJ...
Content-Type: application/json
{ "amount": 20.00 }
Caso di errore (credito insufficiente) — 400 con errorCode: "INSUFFICIENT_BALANCE".
Compensare il saldo (settle)¶
Per un saldo aperto (negativo) — ad es. un debito Disco (importo residuo scoperto all'uscita, vedi API Disco) — il cliente versa un importo e il saldo si muove verso lo zero:
POST /api/v1/customers/cus_a1b2c3/settle
Authorization: Bearer eyJ...
Content-Type: application/json
{ "amount": 15.00, "method": "EC" }
method è libero (predefinito "Bar") e finisce solo nella descrizione della registrazione —
nessun collegamento a un terminale di pagamento.
Ricaricare il credito — il percorso reale¶
Non esiste un endpoint /credit dedicato. Un credito prepagato viene invece ricaricato
esattamente come qualsiasi altra vendita: tramite i normali endpoint di pagamento
(POST /api/v1/payments/direct o POST /api/v1/payments/table), con due condizioni:
- L'articolo venduto ha
extraOption: 1(KundenAufladung) — un „articolo di ricarica" (ad es. „Credito 50 €"), creato tramite la normale API articoli (POST /api/v1/articles). - Il pagamento è collegato al cliente tramite
customerId.
Il prezzo dell'articolo (× quantità) viene quindi accreditato automaticamente all'accountBalance
del cliente — in aggiunta all'effettiva elaborazione del pagamento (l'ospite paga l'importo di
ricarica del tutto normalmente tramite payments[], ad es. in contanti o con carta). Se
sull'articolo è configurato un bonus di ricarica (cardUploadPercent/cardUploadAmount), viene
accreditato automaticamente anche un bonus aggiuntivo.
POST /api/v1/payments/direct
Authorization: Bearer eyJ...
Idempotency-Key: 6f1c2a9e-3b7d-4e21-9b0a-1f2e3d4c5b6a
Content-Type: application/json
{
"items": [ { "articleId": "art_aufladung50", "quantity": 1 } ],
"payments": [ { "method": "Cash", "amount": 50.00 } ],
"customerId": "cus_a1b2c3"
}
La ricarica compare quindi come voce type: 0 in account-transactions (vedi sopra), collegata
tramite receiptId allo scontrino di cassa generato.
Flusso¶
- Creare il cliente —
POST /api/v1/customers(minimo:name/customerNumber). - Ricaricare il credito — vendita di un articolo
KundenAufladungconcustomerId(POST /api/v1/payments/direct, v. sopra). - Addebitare sul conto — gli acquisti successivi del cliente con
payments[].method = "CustomerAccount"vengono detratti dall'accountBalance(addebitato, non ricaricato). - Controllo —
GET /{id}/account-transactionsverifica lo storico. - Punti — vengono accreditati/riscattati nel normale processo di vendita, consultabili tramite
GET /{id}/point-transactions. - Liquidare/compensare —
POST /{id}/payout(restituzione del credito residuo) oppurePOST /{id}/settle(saldare un saldo aperto/debito).
Distinzione: credito del conto cliente ↔ credito della carta Disco¶
Due concetti diversi, facilmente confusi:
| Credito del conto cliente | Credito della carta Disco | |
|---|---|---|
| Endpoint | payments/* + customers/* |
POST /api/v1/disco/guest/{cardId}/topup |
| Legame | al record del cliente, permanente | alla carta fisica, per una permanenza |
| Liquidazione | POST /{id}/payout |
Credito residuo al checkout (disco/guest/{cardId}/checkout) |
→ Dettagli sulla variante a carta: API Disco (Club Cashless).