Flavoso APILeitfädenBestellablauf

Bestellablauf

Der Lebenslauf einer Bestellung, ihre Felder, Steuerzeilen, Zahlarten und Quellen.

Der Lebenslauf

pending

neu, wartet auf den Betrieb

confirmed

angenommen

preparing

in Zubereitung

ready

fertig, bei Lieferung bereit für den Fahrer

completed

abgeholt, serviert oder geliefert

cancelled storniert, aus jedem offenen Stand; aus pending heißt das ablehnen

Vorwärts darf übersprungen werden (confirmed → ready), rückwärts geht nichts.

Ein Betrieb kann confirmed, preparing und ready abschalten; Annehmen schaltet dann auf den nächsten Stand, den er benutzt. Welche Stände er benutzt, steht in GET /store unter order_statuses.

Die Stände

statusBedeutungWie man dorthin kommt
pendingNeu, wartet auf den Betrieb.Die Bestellung entsteht.
confirmedAngenommen.POST /orders/{id}/accept (wenn der Betrieb confirmed benutzt; sonst schaltet Annehmen auf seinen nächsten Stand)
preparingIn Zubereitung.POST /orders/{id}/status mit preparing
readyFertig; bei Lieferung bereit für den Fahrer.POST /orders/{id}/status mit ready
completedAbgeholt, serviert oder geliefert.POST /orders/{id}/status mit completed
cancelledStorniert oder abgelehnt.POST /orders/{id}/reject (nur aus pending) oder POST /orders/{id}/cancel

Weiterschalten

  • Vorwärts darf übersprungen werden, etwa confirmed → ready. Rückwärts geht nicht: 409 invalid_transition.
  • Ein Betrieb kann Stände abschalten. Welche er benutzt, steht in GET /store unter order_statuses; ein abgeschalteter Stand antwortet mit 409 stage_not_used.
  • Steht die Bestellung schon auf dem Ziel, kommt sie unverändert mit 200 zurück. accept schaltet eine Bestellung aus pending auf den nächsten Stand, den der Betrieb benutzt (hat er confirmed, preparing und ready abgeschaltet, completed); steht sie schon dahinter, kommt sie unverändert zurück, eine fertige oder stornierte antwortet mit 409 invalid_transition.
  • Ablehnen und Stornieren nehmen einen Grund (reason, bis 200 Zeichen; länger ergibt 400) für das Protokoll des Betriebs; der Gast sieht ihn nicht.
  • Jeder Wechsel läuft wie ein Klick im Dashboard: der Gast bekommt seine Nachricht, das Team seine Meldung, und das Protokoll des Betriebs nennt deine 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"}'

Wann es eine Bestellung gibt

Mit Zahlung vor Ort gibt es die Bestellung sofort. Mit Online-Zahlung erst, wenn die Zahlung bestätigt ist: vorher steht sie in keiner Liste und löst kein Ereignis aus. order.created kommt genau einmal je Bestellung.

Die Felder

FeldBedeutung
codeKurzer Code, den der Gast sieht, etwa 3271CD.
typepickup, delivery oder dine_in.
sourceWoher sie kommt, siehe unten.
requested_forWunschzeit einer Vorbestellung; null heißt so bald wie möglich.
amountssubtotal, delivery_fee, service_fee, discount, tip, total, alles in Cent.
taxDie Steuer nach Satz, siehe unten.
paymentmethod, status, paid_at.
customerName, bei Abholung und Lieferung die Telefonnummer.
deliveryBei Lieferung die Anschrift.
tableAm Tisch: Kennung und Bezeichnung.
noteAnmerkung des Gastes für die Küche. Allergien stehen oft hier.
itemsPositionen mit Menge, Einzel- und Zeilenpreis, Optionen (mit id, group_id und group_name) und dem beim Bestellen eingefrorenen Steuersatz (tax_rate_bps, null ohne hinterlegten Satz).
external_id, acknowledged_atKennung und Übernahme durch deine App, siehe Kassenanbindung. In Ereignissen immer 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": []
    }
  ]
}

Steuerzeilen

tax teilt den Bruttobetrag der Bestellung nach Steuersatz auf: { "included": true, "lines": [{ "rate_bps", "gross", "net", "tax" }] }. Die Zeilen umfassen Positionen, Liefergebühr und Servicegebühr, nach derselben Rechnung wie Bon und DATEV-Export. Die Steuer ist im Preis enthalten (included: true).

Im Beispiel oben: Pizza zu 7 %, Cola zu 19 %, die Liefergebühr anteilig auf beide verteilt. Das Trinkgeld ist kein Umsatz und steht in keiner Zeile.

Hat der Betrieb für einen Anteil keinen Satz hinterlegt, steht dieser Anteil in einer Zeile mit rate_bps: null, und net und tax sind dort null, nicht 0. Buch ihn zur Klärung, nicht als steuerfrei.

Zahlarten

payment.methodpayment.statusBedeutung
onlinepaidOnline bezahlt. Die Bestellung gibt es erst ab hier.
on_siteopenZahlung vor Ort, noch offen: bar oder mit Karte bei Abholung, Lieferung oder am Tisch.
onlineopenNie sichtbar: eine Online-Bestellung gibt es für die Schnittstelle erst, wenn sie bezahlt ist. Zahlungen vor Ort vermerkt Flavoso nicht, on_site bleibt deshalb open.

Das Geld geht bei Online-Zahlung direkt an den Betrieb; Flavoso ist nie Zahlungsempfänger. Das Trinkgeld steht in amounts.tip und ist in total enthalten.

Quellen

sourceWoher
storefrontDie Bestellseite des Betriebs, auch eingebettet auf seiner Website.
tableDer QR-Code am Tisch.
appDie Flavoso-App für Gäste.

Gastdaten

Eine Bestellung enthält nur, was für die Übergabe nötig ist: den Namen, bei Abholung und Lieferung die Telefonnummer, bei Lieferung die Anschrift. Nie die E-Mail-Adresse, nie das Gastkonto. Am Tisch fehlt auch die Telefonnummer. Siehe Datenschutz.

Etwas unklar geblieben? Schreib an support@flavoso.com und nenne die Kennung aus X-Request-Id. Damit finden wir deine Anfrage im Protokoll.