Zuverlässiger Bestelldruck: Idempotenz, Wiederholungen und der Drucker offline

Drucken wirkt wie Feuern und Vergessen, bis der erste doppelte Bon kommt. Drei Entscheidungen decken fast jeden Produktionsvorfall ab: zuerst den Webhook beantworten, den Auftrag schlüsseln, die Offline-Regel festlegen.

Ein Druckaufruf ist eine einzige HTTP-Anfrage, was Bestelldruck wie die einfachste Integration der Roadmap aussehen lässt. Er bleibt einfach bis zu dem Abend, an dem eine Kundin zwei Bons für eine Bestellung bekommt, oder bis zu dem Abend, an dem vierzig Bestellungen nie in der Küche ankommen und es bis zum Schließen niemand merkt.

Kurze Antwort: Drei Entscheidungen verhindern nahezu jeden Produktionsvorfall. Beantworten Sie den Webhook, bevor Sie drucken, geben Sie jedem Auftrag einen stabilen Schlüssel, damit eine Wiederholung erkennbar ist, und legen Sie ausdrücklich fest, was passiert, wenn der Drucker offline ist. Keine davon ist schwierig, und alle drei lassen sich jetzt leichter ergänzen als nach dem ersten Vorfall.

Die drei Fehlerbilder

Symptom Tatsächliche Ursache Behebung
Derselbe Bon druckt zweimal Die Plattform hat einen langsamen Webhook wiederholt, oder ein Status wurde erneut gesetzt Ein stabiler Schlüssel je Bestellung
Bestellungen nie gedruckt, niemand wusste es Der Drucker war offline und der Fehler wurde verschluckt Eine ausdrückliche Offline-Regel plus Alarm
Der Checkout wirkt langsam oder läuft ab Der Druckaufruf läuft in der Anfrage, die die Bestellung bestätigt Erst antworten, dann drucken

Die drei hängen zusammen. Ein langsamer Druckaufruf verursacht die Wiederholung, die das Duplikat verursacht, also beseitigt die Behebung des ersten den größten Teil des zweiten.

1. Den Webhook beantworten, bevor Sie drucken

Shopify, WooCommerce, Stripe und jede ernsthafte Plattform wiederholen, wenn Ihr Endpunkt langsam ist oder einen Fehler zurückgibt. Druckt Ihr Handler synchron und braucht die Druck-API zwei Sekunden, haben Sie einen Wiederholungsgenerator gebaut.

export default async function handler(req, res) {
  const order = req.body;

  // Sofort quittieren: die Plattform hoert auf zu wiederholen.
  res.status(200).end();

  // Dann drucken, ausserhalb der Anfrage, auf die die Plattform wartet.
  await printOrder(order).catch((err) => {
    logger.error({ err, orderId: order.id }, 'Druck fehlgeschlagen');
    alertOps(order);
  });
}

Die Regel lautet: Das Timeout-Budget der Plattform und die Latenz Ihres Druckers dürfen sich nie eine Frist teilen. Aus demselben Grund drucken die Konnektoren für Shopify und WooCommerce nicht innerhalb der Webhook-Transaktion.

2. Jedem Auftrag einen Schlüssel geben

Idempotenz ist hier kein Luxus verteilter Systeme. Eine Bestellung kann Ihren Handler berechtigterweise mehrfach auslösen: ein Gateway-Callback, der doppelt eintrifft, eine Händlerin, die einen Bezahlt-Status von Hand erneut setzt, eine Webhook-Wiederholung, die mit Ihrer Quittung um die Wette lief.

Legen Sie einen stabilen Wert in origin und speichern Sie auf Ihrer Seite ein Gedruckt-Kennzeichen:

async function printOrder(order) {
  const key = `bestellung-${order.id}`;
  if (await alreadyPrinted(key)) return;

  await fetch(`https://www.expedy.fr/api/v2/printers/${PRINTER_UID}/print`, {
    method: 'POST',
    headers: {
      Authorization: `${process.env.API_SID}:${process.env.API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ printer_msg: buildTicket(order), origin: key }),
  });

  await markPrinted(key);
}

Zwei Dinge verdienen sich hier ihren Platz. Das lokale Kennzeichen stoppt das Duplikat, bevor es ins Netz geht, und origin macht ein durchgerutschtes Duplikat im Druckverlauf sichtbar, was aus "ich glaube, das hat zweimal gedruckt" eine beantwortbare Frage macht.

Schreiben Sie das Kennzeichen nach Möglichkeit in derselben Transaktion wie die übrige Bestellverarbeitung. Ein nach einem erfolgreichen HTTP-Aufruf geschriebenes Kennzeichen lässt ein kleines Fenster offen, und genau aus diesem Fenster kommen die doppelten Bons.

3. Die Offline-Regel bewusst wählen

Fragen Sie, was passieren soll, wenn dem Drucker das Papier ausgeht, er ausgesteckt ist oder hinter einem neu gestarteten Router hängt. Es gibt nur drei sinnvolle Antworten, und die falsche ist, nicht zu wählen:

  • In die Warteschlange und später zustellen. Richtig für Versandetiketten und Lagerdokumente, wo ein zwanzig Minuten später gedruckter Beleg noch nützlich ist.
  • Kurz wiederholen, dann alarmieren. Richtig für Küchenbons, wo ein zwanzig Minuten später gedruckter Bon schlimmer als nutzlos ist, weil der Betrieb weitergezogen ist.
  • Sofort alarmieren. Richtig, wenn ein Mensch handeln kann, und die einzige Option, die aus einem stillen Verlust ein bekanntes Problem macht.

Was Sie auch wählen, setzen Sie die Alarmierung um. Der Unterschied zwischen einem kleinen Ärgernis und einem schlechten Abend ist nicht, ob der Drucker ausgefallen ist, sondern ob es jemand wusste.

Was Sie nicht bauen sollten

Teams bauen routinemäßig Maschinerie nach, die die API bereits liefert. Bevor Sie eine Warteschlange, einen Scheduler und eine Wiederholungsleiter schreiben, prüfen Sie die vorhandenen Zustellgarantien: Eine Push-API, die den Auftrag hält und zustellt, sobald das Gerät wieder verbunden ist, macht den größten Teil dieses Codes überflüssig. Bauen Sie die Teile, die Ihre Geschäftsregeln abbilden, etwa welcher Drucker welche Bestellung bekommt, und überlassen Sie die Transportzuverlässigkeit dem Transport.

Vor der Produktion testen

Drei Tests fangen das meiste ab, was sonst in die Produktion gelangt:

  1. Spielen Sie denselben Webhook zweimal ein. Es soll genau ein Bon herauskommen.
  2. Stecken Sie den Drucker aus und senden Sie eine Bestellung. Ihre gewählte Regel muss sichtbar greifen, samt Alarm.
  3. Bestellen Sie ein Produkt mit einem Emoji im Namen. Thermodrucker sprechen ESC/POS; transliterieren Sie vor dem Senden, sonst entdecken Sie das im ungünstigsten Moment. Die Layout-Referenz dokumentiert, was das Format akzeptiert.

Führen Sie alle drei gegen einen echten Drucker aus, nicht gegen einen Mock. Die interessanten Fehler sind physisch.

Legen Sie ein kostenloses Konto an und verdrahten Sie die drei Tests in Ihrem Integrationsbranch, bevor die erste Kundenbestellung durchläuft.

Weiterführend: Shopify-Bestellungen drucken und WooCommerce-Bestellungen drucken zeigen, wo diese Hooks je Plattform sitzen.

FAQ

Warum druckt dieselbe Bestellung manchmal zweimal?

Fast immer, weil die Plattform einen Webhook wiederholt hat, den Ihr Endpunkt langsam beantwortet hat, oder weil ein Bezahlt-Status mehrfach gesetzt wurde. Quittieren Sie den Webhook vor dem Druck und schlüsseln Sie jeden Auftrag mit einem stabilen Wert wie der Bestell-ID.

Soll ich im Webhook-Handler drucken?

Nein. Antworten Sie sofort mit 200 und drucken Sie dann außerhalb dieser Anfrage. Eine geteilte Frist zwischen Plattform-Timeout und Druckerlatenz erzeugt die Wiederholungen, und Wiederholungen erzeugen die Duplikate.

Was soll passieren, wenn der Drucker offline ist?

Wählen Sie bewusst eine Regel: in die Warteschlange und später zustellen, kurz wiederholen und dann alarmieren, oder sofort alarmieren. Die Warteschlange passt zu Versandetiketten, der Alarm zu Küchenbons. Die einzige falsche Antwort ist, nichts festzulegen.

Muss ich eine eigene Druckwarteschlange bauen?

Meist nicht. Eine Push-API, die den Auftrag hält und bei Wiederverbindung des Geräts zustellt, leistet das bereits. Schreiben Sie den Code für Ihre Geschäftsregeln, etwa das Drucker-Routing, nicht eine zweite Transportschicht.

Wie teste ich die Druckzuverlässigkeit vor dem Livegang?

Spielen Sie einen Webhook zweimal ein und erwarten Sie genau einen Bon, stecken Sie den Drucker aus und prüfen Sie, ob Offline-Regel und Alarm greifen, und bestellen Sie ein Produkt mit einem Emoji im Namen. Führen Sie alle drei gegen einen echten Drucker aus.