API di FlavosoGuideFlusso degli ordini
Flusso degli ordini
Il ciclo di vita di un ordine, i suoi campi, le righe d'imposta, i metodi di pagamento e le origini.
Il ciclo di vita
pending
nuovo, in attesa del locale
confirmed
accettato
preparing
in preparazione
ready
pronto; per la consegna, pronto per il fattorino
completed
ritirato, servito o consegnato
cancelled annullato, da ogni stato aperto; da pending significa rifiutare
In avanti si possono saltare stati (confirmed → ready), all'indietro non si può.
Un locale può disattivare confirmed, preparing e ready; accettare passa allora allo stato successivo che usa. Quali stati usa è indicato in GET /store sotto order_statuses.
Gli stati
| status | Significato | Come ci si arriva |
|---|---|---|
pending | Nuovo, in attesa del locale. | L'ordine viene creato. |
confirmed | Accettato. | POST /orders/{id}/accept (se il locale usa confirmed; altrimenti accettare passa al suo stato successivo) |
preparing | In preparazione. | POST /orders/{id}/status con preparing |
ready | Pronto; per la consegna, pronto per il fattorino. | POST /orders/{id}/status con ready |
completed | Ritirato, servito o consegnato. | POST /orders/{id}/status con completed |
cancelled | Annullato o rifiutato. | POST /orders/{id}/reject (solo da pending) o POST /orders/{id}/cancel |
Far avanzare
- In avanti si possono saltare stati, per esempio
confirmed→ready. All'indietro non si può: 409invalid_transition. - Un locale può disattivare degli stati. Quali usa è indicato in
GET /storesottoorder_statuses; uno stato disattivato risponde 409stage_not_used. - Se l'ordine è già nello stato di destinazione, torna invariato con 200.
acceptporta un ordinependingallo stato successivo che il locale usa (se ha disattivatoconfirmed,preparingeready,completed); un ordine che ha già superatopendingtorna invariato, uno completato o annullato risponde 409invalid_transition. - Rifiuto e annullamento accettano un motivo (
reason, fino a 200 caratteri; oltre dà 400) per il registro del locale; il cliente non lo vede. - Ogni cambio funziona come un clic nella dashboard: il cliente riceve il suo messaggio, il team la sua notifica e il registro del locale indica la tua app.
# Accept (pending → confirmed)
curl -X POST https://api.flavoso.com/v1/orders/ORDER_ID/accept \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: accept-ORDER_ID"
# Advance: confirmed → preparing → ready → completed (skipping ahead is allowed)
curl -X POST https://api.flavoso.com/v1/orders/ORDER_ID/status \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "preparing"}'
# Reject an order that was not accepted yet; the reason goes to the audit log
curl -X POST https://api.flavoso.com/v1/orders/ORDER_ID/reject \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason": "Out of dough"}'
# Cancel from any open status
curl -X POST https://api.flavoso.com/v1/orders/ORDER_ID/cancel \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason": "Guest called to cancel"}'Quando esiste un ordine
Con il pagamento in loco l'ordine esiste subito. Con il pagamento online solo quando il pagamento è confermato: prima non compare in nessun elenco e non genera alcun evento. order.created arriva esattamente una volta per ordine.
I campi
| Campo | Significato |
|---|---|
code | Codice breve che il cliente vede, per esempio 3271CD. |
type | pickup, delivery o dine_in. |
source | Da dove arriva, vedi sotto. |
requested_for | Orario richiesto di un preordine; null significa il prima possibile. |
amounts | subtotal, delivery_fee, service_fee, discount, tip, total, tutto in centesimi. |
tax | L'imposta per aliquota, vedi sotto. |
payment | method, status, paid_at. |
customer | Nome e, per asporto e consegna, il numero di telefono. |
delivery | Per la consegna, l'indirizzo. |
table | Al tavolo: identificativo e nome del tavolo. |
note | Nota del cliente per la cucina. Spesso qui ci sono le allergie. |
items | Voci con quantità, prezzo unitario e totale di riga, opzioni (con id, group_id e group_name) e l'aliquota congelata al momento dell'ordine (tax_rate_bps, null senza aliquota registrata). |
external_id, acknowledged_at | Identificativo e presa in carico da parte della tua app, vedi Integrazione cassa. Negli eventi sempre null. |
{
"object": "order",
"id": "cce01f52-5188-410f-9659-6ce26ba9b784",
"code": "3271CD",
"type": "delivery",
"status": "pending",
"source": "storefront",
"created_at": "2026-10-04T17:44:59.942Z",
"updated_at": "2026-10-04T17:45:10.118Z",
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2490,
"delivery_fee": 250,
"service_fee": 0,
"discount": 0,
"tip": 200,
"total": 2940
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 2421,
"net": 2263,
"tax": 158
},
{
"rate_bps": 1900,
"gross": 319,
"net": 268,
"tax": 51
}
]
},
"payment": {
"method": "online",
"status": "paid",
"paid_at": "2026-10-04T17:45:10.000Z"
},
"customer": {
"name": "Alex",
"phone": "+49 151 00000000"
},
"delivery": {
"address": "Musterstraße 1",
"postal_code": "10115",
"city": "Berlin"
},
"table": null,
"note": "Please ring twice",
"external_id": null,
"acknowledged_at": null,
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "303b87c9-58a3-4644-9a8b-2841cc1f89d6",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 1100,
"line_total": 2200,
"tax_rate_bps": 700,
"options": [
{
"id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
"name": "Extra cheese",
"price_delta": 150,
"group_id": "8e7d6c5b-4a39-4281-b0f9-e8d7c6b5a4f3",
"group_name": "Extras"
}
]
},
{
"id": "0d1e2f3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
"product_id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
"name": "Cola 0,33 l",
"quantity": 1,
"unit_price": 290,
"line_total": 290,
"tax_rate_bps": 1900,
"options": []
}
]
}Righe d'imposta
tax suddivide l'importo lordo dell'ordine per aliquota: { "included": true, "lines": [{ "rate_bps", "gross", "net", "tax" }] }. Le righe comprendono voci, spese di consegna e costo del servizio, con lo stesso calcolo dello scontrino e dell'esportazione DATEV. L'imposta è inclusa nel prezzo (included: true).
Nell'esempio sopra: pizza al 7%, cola al 19%, le spese di consegna ripartite in proporzione tra le due. La mancia non è fatturato e non compare in nessuna riga.
Se il locale non ha registrato alcuna aliquota per una quota, quella quota compare in una riga con rate_bps: null, e lì net e tax sono null, non 0. Contabilizzala come da verificare, non come esente da imposta.
Metodi di pagamento
| payment.method | payment.status | Significato |
|---|---|---|
online | paid | Pagato online. L'ordine esiste solo da questo momento. |
on_site | open | Pagamento in loco, ancora aperto: in contanti o con carta al ritiro, alla consegna o al tavolo. |
online | open | Mai visibile: un ordine online esiste per l'API solo quando è pagato. Flavoso non registra i pagamenti in loco, quindi on_site resta open. |
Con il pagamento online il denaro va direttamente al locale; Flavoso non è mai il beneficiario. La mancia è in amounts.tip ed è inclusa in total.
Origini
| source | Da dove |
|---|---|
storefront | La pagina ordini del locale, anche incorporata nel suo sito web. |
table | Il codice QR al tavolo. |
app | L'app Flavoso per i clienti. |
Dati dei clienti
Un ordine contiene solo ciò che serve per evaderlo: il nome, per asporto e consegna il numero di telefono, per la consegna l'indirizzo. Mai l'indirizzo e-mail, mai l'account del cliente. Al tavolo manca anche il numero di telefono. Vedi Protezione dei dati.
Qualcosa non è chiaro? Scrivi a support@flavoso.com indicando l'identificativo di X-Request-Id. Così troviamo la tua richiesta nel registro.