WordPress-Buchungen mit Exchange-Kalender synchronisieren: Zeiten, Titel, Notizen und Löschung

Wenn Buchungen in WordPress entstehen, möchte man sie oft zusätzlich in einem normalen Kalender sehen. Der schwierige Teil ist nicht das einmalige Erstellen eines Termins, sondern die dauerhafte Synchronisation: Was passiert bei Änderung, Storno, Löschung oder einem zweiten Parkplatz?

Für ein kleines Parkplatz-Buchungssystem habe ich WordPress deshalb so aufgebaut, dass jede relevante Buchung in einen Exchange-Kalender gespiegelt wird. Die wichtigsten Erkenntnisse daraus sind allgemeingültig.

1. Der Kalendertermin braucht dieselben Blockzeiten wie die Buchung

Der Exchange-Termin darf nicht einfach die vom Kunden eingegebenen Reisezeiten übernehmen. Im konkreten Projekt wird der Parkplatz bereits zwei Stunden vor dem Abflug benötigt und bleibt bis zwei Stunden nach der Rückkehr blockiert.

event_start = abflug - 2 Stunden
event_end   = rückkehr + 2 Stunden

Genau dieselben berechneten Zeiten müssen auch in der internen Verfügbarkeitslogik verwendet werden. Sonst zeigen WordPress und Exchange unterschiedliche Belegungen.

2. Jeder WordPress-Datensatz braucht eine feste Exchange-Zuordnung

Nach dem Erstellen eines Kalendertermins sollte WordPress dessen Exchange-ID bzw. eindeutige Terminreferenz speichern. Nur so kann derselbe Termin später aktualisiert oder gelöscht werden.

Minimal sinnvoll sind:

booking_id
exchange_event_id
last_synced_at
sync_status
sync_error

Ohne diese Zuordnung passiert schnell Folgendes: Eine Buchung wird geändert und WordPress legt einfach einen zweiten Kalendereintrag an. Nach einigen Wochen ist nicht mehr klar, welcher Termin der richtige ist.

3. Der Sync muss idempotent sein

Idempotent bedeutet hier: Derselbe Synchronisationslauf darf beliebig oft ausgeführt werden, ohne Duplikate zu erzeugen.

Die Logik ist einfach:

  1. Hat die Buchung noch keine Exchange-ID? → Termin anlegen.
  2. Hat sie eine Exchange-ID? → vorhandenen Termin aktualisieren.
  3. Ist die Buchung storniert oder gelöscht? → zugeordneten Termin entfernen.
  4. Ist der Exchange-Termin nicht mehr auffindbar? → Fehler protokollieren und kontrolliert neu anlegen.

4. Titel kurz halten, Details ins Notizfeld

Der Kalender soll beim schnellen Blick sofort zeigen, welche Ressource belegt ist. Deshalb ist ein kurzer Titel besser als eine komplette Kundenbeschreibung.

Beispiel:

P1 belegt – Buchung 12345
P2 belegt – Buchung 12346

Für besondere operative Hinweise kann ein klarer Präfix wie P1 ANREISE oder P2 ANREISE verwendet werden. Entscheidend ist nicht die genaue Schreibweise, sondern ein konsistentes Schema, das im Kalender sofort verständlich ist.

Alle ausführlichen Daten gehören in die Notiz/Beschreibung des Termins:

  • Buchungsnummer,
  • Name,
  • Kontakt,
  • Kennzeichen,
  • Abflug und Rückkehr,
  • berechnete Blockzeit,
  • Parkplatz/Ressource,
  • Zahlungs- bzw. Buchungsstatus.

5. Änderungen müssen Exchange aktualisieren

Viele Integrationen können nur „create“. Das reicht nicht. Ändert der Kunde seinen Rückflug oder wird intern ein anderer Parkplatz zugewiesen, muss der vorhandene Exchange-Termin angepasst werden.

Ich behandle deshalb jede relevante Buchungsänderung als möglichen Sync-Trigger. Dabei wird der aktuelle Zustand aus WordPress vollständig neu aufgebaut und gegen den vorhandenen Kalendereintrag geschrieben.

6. Löschung ist Teil der Synchronisation

Ein besonders unangenehmer Fehler ist: Die WordPress-Buchung wurde gelöscht, aber der Exchange-Termin bleibt stehen. Der Kalender zeigt dann dauerhaft eine Phantom-Belegung.

Deshalb müssen auch Storno und Löschung einen Sync auslösen. Wenn eine Buchung endgültig entfällt:

  1. Exchange-ID aus der Buchung lesen.
  2. Termin in Exchange löschen.
  3. lokale Zuordnung entfernen oder als gelöscht markieren.
  4. Ergebnis protokollieren.

Praxisregel: Ein Kalender-Sync ist erst vollständig, wenn Create, Update und Delete funktionieren. Nur „Termin anlegen“ ist keine Synchronisation.

7. Zeitzonen nicht dem Zufall überlassen

WordPress, PHP, Exchange und der Browser können unterschiedliche Zeitzonen verwenden. Deshalb sollten Datum und Uhrzeit intern eindeutig verarbeitet werden.

Für lokale Termine verwende ich eine fest definierte Site-Zeitzone und konvertiere nur an der Schnittstelle, wenn Exchange ein anderes Format erwartet. Besonders bei Sommer-/Winterzeit ist das sicherer als manuelles Rechnen mit festen UTC-Offsets.

8. Verbindungsdaten gehören nicht in den Quelltext eines Blogartikels

Exchange-Zugangsdaten, Passwörter oder Tokens sollten niemals im sichtbaren Frontend, in JavaScript oder in einem öffentlich dokumentierten Snippet stehen. In WordPress gehören sie in eine geschützte Serverkonfiguration oder einen dafür vorgesehenen Secret-/Optionsspeicher.

Auch Diagnoseausgaben dürfen solche Werte nicht versehentlich protokollieren.

9. Ein Sync-Log spart später Stunden

Jeder Synchronisationsversuch sollte mindestens speichern:

Zeitpunkt
Buchungs-ID
Aktion: create / update / delete
Exchange-Event-ID
Ergebnis
Fehlertext

Bei einem Fehler sieht man dann sofort, ob WordPress den Auftrag überhaupt ausgelöst hat, ob Exchange geantwortet hat und an welcher Buchung das Problem hängt.

10. Regelmäßiger Abgleich als Sicherheitsnetz

Zusätzlich zu ereignisgesteuerten Updates lohnt sich ein periodischer Reconciliation-Lauf. Er vergleicht aktive WordPress-Buchungen mit den bekannten Exchange-IDs und sucht nach Abweichungen.

Damit lassen sich unter anderem finden:

  • Buchungen ohne Kalendertermin,
  • Kalendertermine zu bereits stornierten Buchungen,
  • fehlgeschlagene Updates,
  • Duplikate.

Fazit

Die zuverlässige WordPress-Exchange-Synchronisation besteht aus drei Dingen: eindeutige IDs, idempotente Create/Update/Delete-Logik und saubere Protokollierung. Wenn zusätzlich dieselben Blockzeiten wie in der Buchungslogik verwendet werden, wird der Exchange-Kalender zu einer echten zweiten Sicht auf den Bestand – und nicht zu einer fehleranfälligen Kopie.