Zum Hauptinhalt springen

Integration mit einem durch MotionTools unterstützen Lieferdienstleister

Support avatar
Verfasst von Support
Diese Woche aktualisiert

Dieser Artikel richtet sich an Entwickler, die Aufträge programmatisch an einen Lieferpartner senden möchten, der MotionTools verwendet.

Überblick

Um eine Bestellung an einen MotionTools-betriebenen Lieferpartner zu senden, nutzt du die MotionTools REST API. Weitere Ressourcen und Anleitungen findest du in unserem Help Center.

MotionTools ist eine Multi-Tenant-Plattform, bei der jeder Lieferpartner seinen eigenen Tenant hat. Du sendest Bestellungen an deinen Lieferpartner über ein Konto mit der customer Rolle.

  • Wenn du die URL zum Tenant deines Lieferpartners kennst, kannst du selbst ein Kundenkonto erstellen.

  • Alternativ kannst du deinen Lieferpartner kontaktieren, um ein Kundenkonto zu erhalten.

Du kannst Bestellungen senden, indem du entweder Buchungen oder Pakete über die API erstellst. Wenn du eine Buchung oder ein Paket erstellst, erhältst du als Antwort ein Buchungen/Pakete-Objekt, das deine Bestellung in MotionTools repräsentiert. Erfahre mehr in unseren ausführlichen Artikeln:

Dieses Dokument beschreibt die Integration von Buchungen.

Im Hintergrund werden dann entweder automatisch oder manuell eine oder mehrere Bestellungen (Buchungen oder Pakete) zu optimierten Touren zusammengefasst. Sobald sie sich in einer Tour befinden, können die Mitarbeiter des Lieferpartners mit der Ausführung deiner Bestellung beginnen.

Du kannst den Fortschritt deiner Bestellung auf zwei Arten verfolgen. Du kannst:

  • Webhooks empfangen, die für deinen Anwendungsfall relevant sind. Die vollständige Liste findest du hier ↗️.

  • regelmäßig die Buchung oder das Paket, das dich interessiert, über die MotionTools API abrufen

Wie bereits erwähnt, interagierst du mit der MotionTools API über ein Konto mit der customer Rolle. Bestimmte API-Endpunkte oder Aktionen erfordern die admin Rolle. Solche Aktionen sind in diesem Artikel entsprechend gekennzeichnet. Bitte kontaktiere deinen Lieferpartner oder den MotionTools Support, um dabei Unterstützung zu erhalten. Mehr über Rollen in MotionTools findest du hier

Um eine Verbindung zwischen der Buchung oder dem Paket in MotionTools und der Bestellung in deinem System herzustellen, solltest du unsere Metadaten-Funktion verwenden.


Zu beachtende Aspekte

Modellierung deiner Aufträge: Buchungen vs. Pakete

Bestimmte Betreiber arbeiten ausschließlich mit Buchungen, andere nur mit Paketen. Stelle sicher, dass dein gewünschter Workflow vom Lieferpartner unterstützt wird.

🚴‍♂️ Buchungen:

Eine Buchung ist eine Anfrage von einem Kunden zur Durchführung eines Service. [...] Sie kann einen oder mehrere Stopps beinhalten. Ein Stop ist eine Aufgabe, die an einem bestimmten Ort ausgeführt werden muss.

📦 Pakete:

Ein Paket ist ein individuell verfolgbarer Gegenstand, der typischerweise eigene Eigenschaften wie Größe oder Gewicht hat, mit einem scannbaren Etikett versehen ist und als Abholungs- oder Zustellungsaufgabe einem Stop hinzugefügt werden kann.

Um Pakete nutzen zu können, muss dein Lieferpartner die Paketerweiterung in seinem Tenant aktiviert haben.

Obwohl es einige Überschneidungen zwischen den beiden Konzepten gibt, werden Buchungen in der Regel gewählt, wenn es darum geht, Aufgaben oder kurze Lieferungen zu verfolgen. Pakete eignen sich dagegen besser für die Verfolgung von Gegenständen oder für große Lieferungen mit Dutzenden oder Hunderten von Paketen innerhalb einer Route.

Was den Integrationsaufwand betrifft, ist der Einstieg mit Buchungen einfacher, da sie im Vergleich zu Paketen relativ unkompliziert sind. Pakete bringen, wie bereits erwähnt, zusätzliche Eigenschaften (Größe, Gewicht), Konzepte (scannbares Etikett), Interaktions- und Tracking-Abläufe, Preisgestaltung, Lebenszyklus usw. mit sich. All dies ist zwar nützlich für große Paketlieferungen, wird aber nicht immer für kurze Lieferungen benötigt.

Auch wenn es möglich ist, eine einfache Restaurant → Kunden-Lieferung mit Paketen zu modellieren, bei der die Essenstasche als Paket in MotionTools dargestellt wird, empfehlen wir für diesen speziellen Fall generell Buchungen, da der Fokus auf der Durchführung der Lieferung liegt und nicht auf der Essenstasche selbst.

Der Rest dieses Artikels konzentriert sich auf Buchungen.

Ausführungsmodi: Sofort vs. Geplant

Bei der Erstellung einer Buchung kannst du eine Verzögerung oder Vorlaufzeit zwischen dem Moment der Erstellung und dem Zeitpunkt, an dem der Lieferpartner mit der Ausführung beginnen soll, festlegen.

Aktuell stehen zwei Optionen zur Verfügung: instant & scheduled Buchungen:

  • Sofortige Buchungen: zeigen an, dass die Buchung sofort ohne Vorlaufzeit ausgeführt werden soll

  • Geplante Buchungen: zeigen an, dass sie zu einem späteren Zeitpunkt ausgeführt werden sollen, bekannt als scheduled_at Zeit.

Weitere Details hier.

Granulare, stoppbezogene Zeitfenster & ETAs

Mit MotionTools kannst du für jeden einzelnen Stopp sehr detailliert das Zeitfenster festlegen, in dem dein Lieferpartner eintreffen soll (earliest_arrival_at, latest_arrival_at). Außerdem kannst du die erwartete Aufenthaltsdauer pro Stopp angeben (custom_expected_duration_seconds). Details dazu findest du im Request-Payload des Create Booking Endpoints im booking.stops Modell.

Darüber hinaus erhältst du für jeden Stopp aktuelle ETAs über dedizierte Eigenschaften: expected_arrival_at, expected_departure_at. ETAs kannst du auch über die API abrufen.

Buchungsverlauf

Es ist wichtig, die 3 Hauptkomponenten zu unterscheiden, die eine Bestellung und ihren Fortschritt in MotionTools abbilden: Buchung, Stopp, Tour.

Der Gesamtablauf ist wie folgt:

  • Über die API erstellst du eine Buchung mit einem Konto, das die customer Rolle hat

  • Je nach Ausführungsmodus und Dispositions-Konfiguration wird die Buchung dann entweder sofort oder zu einem bestimmten Zeitpunkt in der Zukunft in eine optimierte Tour eingeplant. Die Dispositions-Entscheidung wird entweder manuell vom Betreiber oder automatisch vom System auf Basis der Regeln des Betreibers getroffen.

  • Mit einem Konto der Rolle customer hast du keinen Zugriff auf die Tour. Nur Konten mit den Rollen admin, organization manager & driver haben Zugriff auf Touren.

  • Um den Fortschritt der Buchungsausführung zu verfolgen, kannst du den Status der von dir erstellten Buchung sowie den Status der einzelnen Stops der Buchung überwachen. Dieser Mechanismus wird im Abschnitt Aktualisierungen über Webhooks empfangen näher beschrieben

Um mehr über das Statusmodell der Buchung und dessen Zusammenhang mit dem einer Tour zu erfahren, lies bitte: Statusmodell von Buchungen

Füge deine Bestellungs-ID als externe ID zu einer Buchung hinzu

Um eine Verbindung zwischen verschiedenen Eigenschaften deines internen Bestellungsmodells (z.B. Bestellungs-id) und der resultierenden Buchung in MotionTools herzustellen, kannst du diese Eigenschaften als Metadaten zur Buchung, zum Stopp oder zu beidem hinzufügen.

Stopp-Metadaten können direkt bei der Erstellung der Buchung hinzugefügt und auch später aktualisiert werden. Buchungs-Metadaten müssen über einen separaten Aufruf des Update Booking Metadata Endpunkts hinzugefügt werden.

Buchungs- vs. Stopp-Metadaten

Wenn eine Buchung in eine optimierte Tour zur Ausführung durch den Lieferpartner übertragen wird, werden die Metadaten der Buchung nicht in die Tour-Metadaten kopiert. Dies geschieht, weil eine Tour aus mehreren verschiedenen Buchungen erstellt werden kann.

Die Stopp-Metadaten sind jedoch im entsprechenden Stopp innerhalb der Tour vorhanden, da die Buchungs-Stopps selbst im Wesentlichen in die Tour kopiert werden.

Praktisch bedeutet dies, dass es am besten ist, relevante Metadaten sowohl bei der Buchung als auch bei den enthaltenen Stopps zu platzieren:

  • Buchungs-Metadaten: helfen dir, die interne Bestellung anhand der Metadaten in der MotionTools-Buchung zu identifizieren

  • Stopp-Metadaten (bei jedem einzelnen Stopp der Buchung): hilft dem Lieferpartner zu erkennen, welcher Stopp in einer Tour zu einer bestimmten Bestellung aus deinem internen System gehört

Neben der internen Bestellungs-ID können Metadaten verwendet werden, um beliebige nützliche Werte aus deiner ursprünglichen Bestellung in Buchungen/Stopps (und mehr) zu speichern. Beispiele könnten die Kunden-ID, Kundenbewertung, interner Preis, interne Lieferprognose usw. sein.


Voraussetzungen für die Integration

Um dich mit deinem durch MotionTools gestützten Lieferpartner zu integrieren, benötigst du Folgendes:

  • Kundenkonto: im MotionTools Tenant deines Lieferpartners

  • Kunden-API-Token: Sobald du Zugang zu deinem Konto hast, musst du einen API-Token erstellen.

  • service_id: Diese wird dir vom Lieferpartner zur Verfügung gestellt und muss beim Erstellen einer Buchung angegeben werden. Wenn der Lieferpartner nur den "Standard-Service" nutzt, kann die service_id beim Erstellen der Buchung weggelassen werden. Mehr über Services findest du hier.


Eine Bestellung per API senden

Beispiel-Payload für eine Abholung, angepasst für Essenslieferungen (zum Anzeigen ausklappen)

{ "booking": { "stops": [ { "type": "pickup", "earliest_arrival_at": null, "latest_arrival_at": null, "place_id": "7d6991cb-d669-40ae-acb7-6a2b964e212b", // add a valid place id for the pickup location "additional_information": "info for pickup, e.g. order id or name", "metadata": { "public_order_id": "value", "external_order_id": "value" }, }, { "type": "dropoff", "earliest_arrival_at": null, "latest_arrival_at": null, "lat": 53.54439, // optional, MotionTools will geocode if n/a "lng": 9.940334, "street": "Große Elbstraße", "number": "123", "zip_code": "20097", "city": "Hamburg", "country": "Deutschland", "location_name": "Große Elbstraße 123", "first_name": "Vorname", "last_name": "Nachname", "phone_number": "+491601234123", "additional_information": "Please don't ring the bell", "metadata": { "public_order_id": "value", "external_order_id": "value" }, } ], "scheduled_at": "now" // if you only push bookings for now, you can leave this out, otherwise you can add a timestamp, please note that only timestamps in the future are allowed and they have to be within the opening hours of the operator. Scheduled_at is typically the time when you want a driver to pickup the order from the restaurant. } }

Gib die Kontaktdaten des Endempfängers der Bestellung als Stopp-Kontaktdaten beim Auslieferungsstopp an, damit Fahrer/Kuriere deines Lieferpartners den Endempfänger kontaktieren können, wenn sie die Buchung bearbeiten.


Updates über Webhooks empfangen

Das Einrichten von Webhooks kann nur von admin Nutzern vorgenommen werden.

Um einen Webhook zu erstellen, musst du die URL, an die du Webhooks empfangen möchtest, entweder mit einem Manager deines Lieferpartners (der admin Zugriff haben sollte) oder mit dem MotionTools Support teilen. Außerdem musst du angeben, welche Events du empfangen möchtest und welche Filter gegebenenfalls angewendet werden sollen.

Allgemeine Informationen

  • MotionTools kann Statusaktualisierungen über Webhooks für fast jedes Ereignis senden, das in MotionTools stattfindet

  • Die Webhooks sind schlank gehalten und enthalten nur die wichtigsten Informationen, wie zum Beispiel das aufgetretene Ereignis und die Buchungs-ID

  • Wenn du detailliertere Informationen benötigst, musst du diese über den entsprechenden Endpunkt abrufen, nachdem du einen Webhook erhalten hast. Nutze dafür zum Beispiel den "Buchung anzeigen" Endpunkt

  • Die API-Dokumentation für Webhooks findest du hier: https://docs.motiontools.io/#tag/Webhooks

  • Um sicherzustellen, dass dein Webhook-Consumer-Endpunkt nur von authentischen MotionTools-Anfragen aufgerufen wird, haben wir eine Webhook-Verifizierung implementiert. Siehe: Webhook-Verifizierung

Relevante Webhooks

Buchungs- & Stopp-Statusaktualisierungen

  • Fahrer zugewiesen + auf dem Weg zur Abholung:

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Abholungsstopps

    • Relevantes Ereignis: start

    • Stopp-Status nach Ereignis: approaching

  • Fahrer bei der Abholung angekommen:

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Abholungsstopps

    • Relevantes Ereignis: arrive

    • Stopp-Status nach Ereignis: arrived

  • Fahrer hat die Abholung abgeschlossen:

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Abholungsstopps

    • Relevantes Ereignis: complete

    • Stopp-Status nach Ereignis: done

  • Fahrer auf dem Weg zur Auslieferung:

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Auslieferungsstopps

    • Relevantes Ereignis: start

    • Stopp-Status nach Ereignis: approaching

  • Fahrer bei der Auslieferung angekommen:

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Auslieferungsstopps

    • Relevantes Ereignis: arrive

    • Stopp-Status nach Ereignis: arrived

  • Fahrer hat die Auslieferung abgeschlossen (sollte gleich der Buchungsabschluss sein, du kannst entweder dies oder die nächste Option mit "Buchung abgeschlossen" implementieren):

    • Zu verwendender Webhook: hailing_booking_stop.transition

    • Zuordnung über Stopp-ID des Auslieferungsstopps

    • Relevantes Ereignis: complete

    • Stopp-Status nach Ereignis: done

  • Buchung abgeschlossen:

    • Zu verwendender Webhook: booking.transition

    • Zuordnung über Buchungs-ID

    • Relevante Ereignisse: complete_stops oder force_end

    • Buchungsstatus nach Ereignis: paid

  • Buchung storniert:

    • Zu verwendender Webhook: booking.transition

    • Zuordnung über Buchungs-ID

    • Relevante Ereignisse: cancel

    • Buchungsstatus nach Ereignis: cancelled

Fahrer-Standort-Updates

Aktuelle Ankunftszeiten

Buchungszyklus

Stopp-Zyklus

  • scheduled → Stopp noch nicht begonnen

  • approaching → Fahrer nähert sich dem Stopp

  • arrived → Fahrer ist am Stopp angekommen

  • done → Fahrer hat den Stopp abgeschlossen

  • failed → Disponent hat den Stopp als fehlgeschlagen markiert (bei bestimmten Konfigurationen dürfen auch Fahrer einen Stopp als fehlgeschlagen markieren)

Webhook-Verifizierung

Um zu überprüfen, ob ein eingehender Webhook-Request nicht böswillig gefälscht oder modifiziert wurde, fügen wir eine Signatur als Teil der Request-Header hinzu. Du musst die Signatur auf deiner Seite gegen den öffentlichen Schlüssel validieren, den du von deinem Lieferpartner erhalten hast, als dieser den Webhook konfiguriert hat.

Als Verschlüsselungsalgorithmus wird Ed25519 verwendet, und die Signatur wird Base64-kodiert im X-Mtools-Signature Request-Header übermittelt.

TypeScript-Beispiel eines Cloudflare Workers zur Überprüfung der Webhook-Authentizität

Das folgende Beispiel ist für die Cloudflare Workers/Deno-Laufzeitumgebung geeignet. Wenn du eine andere JavaScript-Laufzeitumgebung wie NodeJs oder Bun verwendest, wird das Beispiel nicht ohne Anpassungen funktionieren. In NodeJs verwendest du zum Beispiel Ed25519 statt NODE-ED25519 als Algorithmus-Bezeichner. Auch bei der Interaktion mit der crypto-Bibliothek kann es Unterschiede geben. Das folgende Beispiel dient nur zur Veranschaulichung. Bitte passe es entsprechend an die Anforderungen deiner Laufzeitumgebung an.

// Replace this with your actual public key (Base64-encoded)const PUBLIC_KEY_BASE64 = 'YOUR_PUBLIC_KEY_HERE';export default { async fetch(request: Request): Promise<Response> { // Read body as ArrayBuffer (Uint8Array required for crypto.subtle) const body = new Uint8Array(await request.arrayBuffer()); // Get signature from header (Base64-encoded) const signatureBase64 = request.headers.get('X-Mtools-Signature'); if (!signatureBase64) { return new Response('Missing signature header', { status: 400 }); } const signature = Uint8Array.from(atob(signatureBase64), c => c.charCodeAt(0)); // Decode public key const publicKey = Uint8Array.from(atob(PUBLIC_KEY_BASE64), c => c.charCodeAt(0)); // Import public key for Ed25519 verify const cryptoKey = await crypto.subtle.importKey( 'raw', publicKey, { name: 'NODE-ED25519', namedCurve: 'NODE-ED25519' }, // For Deno/Cloudflare false, ['verify'] ); // Verify signature const isValid = await crypto.subtle.verify( 'NODE-ED25519', cryptoKey, signature, body ); if (!isValid) { return new Response('Invalid signature', { status: 401 }); } // Signature valid, process webhook try { await procesWebhook(body) return new Response('Webhook verified!', { status: 200 }); } catch (e) { return new Response('Internal server error: error processing webhook.', { status: 500 }); } }};

Richtlinien zur Nutzung von Webhooks

Um die Leistungsstabilität unserer Plattform zu gewährleisten, gelten folgende Einschränkungen für Webhook-Empfänger:

  • Wir erwarten einen gültigen 2xx Antwort-Code, um die Zustellung eines Webhook-Events als erfolgreich zu betrachten.

  • 15 Sekunden Timeout: Wenn keine 2xx Antwort innerhalb von 15 Sekunden erfolgt, betrachten wir die Zustellung als fehlgeschlagen.

  • 3 Wiederholungsversuche: Jedes Webhook-Event wird 3 Mal wiederholt. Nach 3 Versuchen wird das Webhook-Event nicht mehr erneut gesendet und ist damit verloren.

  • 250 aufeinanderfolgende fehlgeschlagene Zustellungen an dieselbe URL führen zur Blockierung/Deaktivierung des Webhooks und lösen eine E-Mail-Benachrichtigung an den Tenant-Besitzer aus (in diesem Fall dein Lieferpartner). Sollte dies passieren, wird entweder dein Lieferpartner oder der MotionTools-Support dich kontaktieren.

Webhook-Filterung

Wenn du Webhook-Events für Buchungen erhältst, die nicht zu dir gehören, hat dein Lieferpartner möglicherweise die Webhook-Filter nicht korrekt eingerichtet, als er den Webhook für dich konfiguriert hat.

Bitte kontaktiere deinen Lieferpartner, um dies anzupassen. Relevanter Artikel in unserem Help Center: Webhooks an deine Kunden für Buchungsstatus-Updates weiterleiten.


Technische Überlegungen & Empfehlungen

Webhook-Überlegungen

Datenvalidierung

Unsere API & Payload-Strukturen & Status-Modelle entwickeln sich ständig weiter.

Daher empfehlen wir dir:

  • keine strikte Validierung der Payload-Struktur vorzunehmen → deine Integration sollte nicht abstürzen, wenn neue Eigenschaften in einem MotionTools-Payload auftauchen, das du nutzt

  • keine strikte Validierung bekannter Schlüsselwerte als Enums (z.B. Status, Übergänge, andere Schlüsselwerte wie now für die booking.scheduled_at Eigenschaft) → deine Integration sollte fehlerfrei und ohne Abstürze mit neuen, unbekannten Status, Übergängen usw. umgehen können


Integration testen

Für Testzwecke bekommst du Zugriff auf deinen eigenen MotionTools-Mandanten, der dem Mandanten deines Lieferpartners sehr ähnlich sein wird. Dieser Mandant dient als deine Sandbox-Umgebung, in der du während der Entwicklung deiner Integration testen, iterieren und experimentieren kannst.

Beachte jedoch, dass du in dieser Entwicklungs-Sandbox-Umgebung Zugriff auf den Mandanten-admin-Benutzer haben wirst, während du in der Produktionsumgebung nur Zugriff auf einen customer-Benutzer im Produktionsmandanten deines Lieferpartners haben wirst.

Stelle daher sicher, dass du in deiner Sandbox-Umgebung auch einen customer-Account anlegst und dessen API-Schlüssel (d.h. Schlüssel mit der customer-Rolle) während der Entwicklung deiner Integration auf deinem Sandbox-Mandanten verwendest.


Weitere Ressourcen

Hat dies deine Frage beantwortet?