bexio API mit WordPress verbinden
Eine Anfrage aus dem Website-Formular soll als Kontakt in bexio landen, eine Bestellung als Rechnung, ein Kunde aus dem Shop als Adresse. Dafür muss WordPress mit der bexio API sprechen. Diese Anleitung zeigt den Weg von der App im Developer Portal bis zum ersten angelegten Kontakt, die Fallen unterwegs und wann sich ein fertiges Plugin mehr lohnt als eigener Code.
Was die bexio API ist
Die bexio API ist eine REST-Schnittstelle mit JSON. Alle Endpunkte liegen unter
https://api.bexio.com, die Pfade beginnen je nach Bereich mit /2.0/, /3.0/ oder neuer,
etwa /2.0/contact für Kontakte und /3.0/users/me für den angemeldeten Benutzer. Die
Referenz steht unter docs.bexio.com. Eine OpenAPI-Beschreibung
bietet bexio laut eigener Doku nicht an, ein Client entsteht also von Hand.
Jeder Zugriff braucht ein Access-Token im Header Authorization: Bearer …. Wie WordPress
zu diesem Token kommt, ist der eigentliche Aufwand.
Schritt 1: App im Developer Portal anlegen
- Im Developer Portal mit dem bexio-Konto anmelden.
- Die Nutzungsbedingungen lesen und annehmen, besonders Ziffer 4.4 zur kommerziellen Nutzung (siehe Stolperfallen).
- Eine neue App anlegen und die Redirect-URL eintragen, auf die bexio nach der Anmeldung zurückleitet, etwa die Einstellungsseite des Plugins im WordPress-Backend. Bis zu zehn Adressen sind möglich, zum Beispiel für Test und Produktion.
- Unter «App Details» Client-ID und Client-Secret ablesen.
Das Client-Secret gehört auf den Server, nie in JavaScript im Browser.
Schritt 2: Anmelden mit OAuth 2
bexio meldet über OpenID Connect auf auth.bexio.com an, mit dem «Authorization Code Flow».
WordPress schickt den Benutzer dazu auf die Anmeldeseite von bexio:
https://auth.bexio.com/realms/bexio/protocol/openid-connect/auth
?client_id=<Client-ID>
&redirect_uri=<eingetragene Redirect-URL>
&response_type=code
&scope=openid offline_access contact_edit note_edit
&state=<Zufallswert>
Der Benutzer meldet sich an und bestätigt die Rechte. bexio leitet mit einem Code zurück,
WordPress tauscht ihn zusammen mit Client-ID und Secret beim Token-Endpunkt
/realms/bexio/protocol/openid-connect/token gegen Access- und Refresh-Token.
Zu den Scopes: Ein Schreibrecht schliesst das Leserecht ein, contact_edit reicht also auch
zum Suchen. offline_access braucht es für das Refresh-Token. Und die API arbeitet immer mit
den Rechten des Benutzers, der die Verbindung hergestellt hat: Darf er in bexio keine Kontakte
sehen, darf es die App auch nicht.
Schritt 3: Token speichern und erneuern
Das Access-Token läuft nach kurzer Zeit ab. Vorher holt WordPress mit dem Refresh-Token und
grant_type=refresh_token ein neues, alle Werte im Body der Anfrage, nicht in der URL. Dabei
gilt:
- Immer das neue Refresh-Token speichern, das bei der Erneuerung zurückkommt.
- Bleibt eine Verbindung ein Jahr lang ohne Erneuerung, schliesst bexio die Sitzung; danach muss sich jemand neu anmelden.
- Tokens in WordPress-Optionen ohne Autoload ablegen, damit sie nicht bei jedem Seitenaufruf mitgeladen werden.
Für eigene Skripte gibt es ausserdem persönliche Zugriffstoken (PAT). Sie haben vollen Zugriff auf alle Daten der Firma und gelten 60 Tage. Für den eigenen Gebrauch sind sie bequem, für ein Plugin auf einer Kundenwebsite taugen sie nicht.
Schritt 4: Kontakt und Notiz anlegen
Ein typischer Ablauf für eine Formularanfrage braucht vier Aufrufe:
GET /3.0/users/meliefert die ID des Benutzers. Sie ist beim Anlegen Pflicht, alsuser_idundowner_id.POST /2.0/contact/searchsucht über die E-Mail-Adresse, ob es den Kontakt schon gibt.- Falls nicht:
POST /2.0/contactlegt ihn an,contact_type_id1 für Firmen, 2 für Personen. POST /2.0/notehängt den Formulartext als Notiz an den Kontakt.
Der Aufruf zum Anlegen einer Firma sieht so aus:
{
"contact_type_id": 1,
"name_1": "Muster AG",
"street_name": "Bahnhofstrasse",
"house_number": "1",
"postcode": "8001",
"city": "Zürich",
"mail": "info@muster.ch",
"user_id": 1,
"owner_id": 1
}
Typische Stolperfallen
- Redirect-URL: Sie muss genau so im Developer Portal stehen, sonst bricht die Anmeldung mit einer Fehlermeldung ab.
- Neue Scopes: Die Rechte einer Verbindung ändern sich bei der Erneuerung nicht. Braucht die App mehr, muss sich der Benutzer neu anmelden.
- Adressfelder: Das Feld
addressist beim Anlegen veraltet. Strasse und Hausnummer gehören instreet_nameundhouse_number. - Zeilenumbrüche in Notizen: bexio zeigt den Text einer Notiz ohne Zeilenumbrüche an.
Wer Absätze will, setzt
<br>und maskiert die Werte als HTML. - Ratenlimit: Zu viele Anfragen pro Minute beantwortet die API mit Status 429. Die Header
RateLimit-RemainingundRateLimit-Resetsagen, wie lange zu warten ist. - Langsame Formulare: Wer bexio direkt beim Absenden aufruft, lässt den Besucher warten und verliert die Anfrage, wenn bexio gerade nicht antwortet. Besser im Hintergrund übertragen und bei Fehlern wiederholen.
- Kommerzielle Nutzung: Laut Ziffer 4.4 der Bedingungen muss bexio informiert werden, wer auf der API ein eigenes Geschäftsmodell betreibt, an das mindestens fünf bexio-Konten angeschlossen sind.
Drei Wege im Vergleich
| Weg | Passt, wenn | Zu bedenken |
|---|---|---|
| Selbst bauen | eigene Entwickler da sind und der Ablauf sehr speziell ist | Anmeldung, Token-Erneuerung, Fehlerbehandlung und Updates bleiben dauerhaft eigene Arbeit |
| Zapier oder Make | schon andere Abläufe dort laufen | ein weiterer Dienst, über den die Formulardaten fliessen, Zuordnung und Duplikate von Hand |
| Fertiges Plugin | der Ablauf einem gängigen Muster folgt | weniger frei als eigener Code |
Make und Zapier bieten bexio als eigene App an. Das Formular-Plugin schickt die Anfrage per Webhook dorthin, und eine bexio-Aktion legt den Kontakt an.
Fertige Lösungen
Für die zwei häufigsten Fälle gibt es meine Anbindungen:
- bexio-Formular-Connector: WordPress-Plugin, Anfragen aus dem Website-Formular werden zu Kontakten mit Notiz in bexio, Duplikate werden an der E-Mail erkannt. Jeder Betreiber verbindet sein bexio über eine eigene App, die Daten gehen direkt von der Website zu bexio.
- bexio ↔ HubSpot: Ein gewonnener Deal in HubSpot wird zur Offerte oder Rechnung in bexio, der Zahlungsstand kommt zurück in den Deal.