API-Integration: Umgebungen, Pflichtfelder und Feldzuordnungen
Test- und Produktivumgebung, Pflichtfelder bei POST /invoices, Datenstruktur für Ein- und Ausgangsrechnungen sowie Feldzuordnungen und bereits angebundene Systeme.
Dieser Artikel beantwortet die häufigsten Fragen rund um die Anbindung eigener Systeme an die faktoora-API. Fehlermeldungen und HTTP-Statuscodes sind gesondert im Artikel API-Fehlerbehandlung beschrieben, die vollständige BT-Feldliste im Artikel Welche BT-Felder unterstützt die faktoora-API? und die Pflichtfelder für XRechnung im Artikel Welche Angaben braucht eine XRechnung mindestens?.
Test- und Produktivumgebung
Die faktoora-API steht unter zwei getrennten Basis-URLs zur Verfügung:
- Produktivumgebung:
https://api.faktoora.com/api/v1 - Demo-/Testumgebung:
https://api.demo.faktoora.com/api/v1
Beide Umgebungen sind eigenständige Instanzen mit eigenen Konten und Daten. Der API-Schlüssel wird jeweils in den Account-Einstellungen der betreffenden Umgebung erzeugt und im Header X-API-KEY übermittelt (siehe Warum werde ich bei API-Aufrufen mit 401 abgewiesen?). Für den Übergang von Test zu Produktivbetrieb wechseln Sie die Basis-URL auf https://api.faktoora.com/api/v1 und verwenden den im Produktiv-Account erzeugten Schlüssel.
Rechnung erstellen: POST /invoices
Beim Invoice-Objekt selbst sind laut Schema nur folgende Felder grundsätzlich verpflichtend:
format— Ausgabeformat, z. B.simple,zf:1,zf:2,xrechnung,peppolissueDate— Rechnungsdatum (BT-2)invoiceNumber— Rechnungsnummer (BT-1)invoiceTypeCode— Rechnungstyp, z. B.380für eine Handelsrechnung (BT-3)invoiceItems— mindestens eine Rechnungspositionbuyer— der Käufer
Innerhalb von buyer und seller sind Name und vollständige Adresse (street, postcode, city, country) Pflicht, sobald Sie den jeweiligen Block mitschicken. Jede Position in invoiceItems benötigt eine id und ein product-Objekt mit name, quantity, unitCode, price und taxes. Die vollständige, formatabhängige Pflichtfeldliste für format: xrechnung steht im Artikel Welche Angaben braucht eine XRechnung mindestens?.
Rechnung abrufen: Ablauf
Die Rechnungserstellung über POST /invoices ist asynchron: Die Antwort ist 202 Accepted mit einer faktooraId, die Rechnung selbst wird im Hintergrund erzeugt. Ein direkter GET /invoices/{faktooraId} unmittelbar danach kann mit 404 fehlschlagen, weil die Verarbeitung noch läuft.
Der korrekte Ablauf:
POST /invoicessenden,faktooraIdaus der202-Antwort speichern.- Verarbeitungsstatus über
GET /invoices/{faktooraId}/statusprüfen oder auf den registrierten Webhook warten (siehe Webhook). - Erst danach
GET /invoices/{faktooraId}aufrufen. Der Endpunkt liefert die fertige Datei direkt alsapplication/pdfoderapplication/xml(kein JSON-Metadatenobjekt).
Details zu den möglichen Statuscodes stehen im Artikel API-Fehlerbehandlung.
Feldzuordnungen
Bestellreferenz (Order Reference)
Auf Rechnungsebene gibt es zwei unterschiedliche Referenzfelder:
orderNumberauf demInvoice-Objekt — Referenz auf die zugehörige Bestellung (BT-14).invoiceItems[].product.orderNumber— Bestellreferenz auf Ebene der einzelnen Position; laut API-Beschreibung nicht zulässig fürformat: xrechnung.
Zusätzlich existiert buyerReference.IssuerAssignedID als Bestellreferenz des Käufers (BT-13), zu unterscheiden von buyerReference.buyerReferenceId — das ist die Käuferreferenz bzw. bei öffentlichen Auftraggebern die Leitweg-ID (BT-10).
Beim Abruf von Rechnungsdaten über die Import-Endpunkte (siehe unten) heißt das entsprechende Feld references.orderReferenceId (BT-13) bzw. references.orderNumber für die Bestellnummer des Käufers — die Feldnamen unterscheiden sich also zwischen Erstellung (POST /invoices) und Abruf importierter Rechnungen.
Bestellnummer: Kopf- oder Positionsebene?
Beide sind möglich und unabhängig voneinander: orderNumber auf dem Invoice-Objekt referenziert die Bestellung auf Kopfebene (BT-14), invoiceItems[].product.orderNumber referenziert eine Bestellung auf Ebene der einzelnen Position. Für xrechnung ist nur die Kopfebene zulässig.
Ansprechpartner des Käufers
Der Ansprechpartner beim Käufer wird über buyer.definedTradeContact gepflegt:
firstName/lastName— Name des Ansprechpartners (BT-56)departmentName— Abteilung (BT-56-0)phone— Telefonnummer (BT-57-00)email— E-Mail-Adresse (BT-58-00)
Das ist getrennt von buyer.phone/buyer.email (BT-57/BT-58), die den allgemeinen Kontakt des Käuferunternehmens abbilden.
DirectDebitMandateID
directDebitMandateID (SEPA-Lastschriftmandat, BG-19/BT-89) gehört zum Objekt specifiedTradePaymentTerms, nicht zu specifiedTradeSettlementPaymentMeans. Wird das Feld versehentlich im Payment-Means-Block statt im Payment-Terms-Block übergeben, wird es nicht in die XML übernommen, weil es dort kein definiertes Schemafeld ist. Prüfen Sie bei einer fehlenden DirectDebitMandateID im erzeugten XML zuerst, ob das Feld im specifiedTradePaymentTerms-Array steht.
Zahlungsart-Codes für PayPal und Kreditkarte
Das Feld specifiedTradeSettlementPaymentMeans[].typeCode (BT-81) verwendet die UNTDID-4461-Codeliste. Verfügbar sind unter anderem 10 (Bar), 20 (Scheck), 30 (Überweisung), 42 (Zahlung auf Bankkonto), 48 (Kartenzahlung), 49 (Lastschrift), 57 (Dauerauftrag), 58 (SEPA-Überweisung), 59 (SEPA-Lastschrift), 97 (Report) sowie der String-Code ZZZ (frei definiert). Es gibt keinen eigenen Code für PayPal.
- Kreditkarte:
typeCode: 48. Für diesen Code sind zusätzlichcardNumber(Pflicht) und optionalholderNamezulässig — beide Felder sind nur beitypeCode: 48erlaubt. - PayPal: Da UNTDID 4461 keinen PayPal-spezifischen Code kennt, verwenden Sie
typeCode: "ZZZ"(frei definiert) und beschreiben die Zahlungsart im Freitextfeldinformation, z. B. „Zahlung per PayPal“.
Datenstruktur der Schnittstelle für ein- und ausgehende Rechnungen
Für importierte Rechnungen — sowohl eingehende (/import/incoming) als auch ausgehende (/import/outgoing) — liefert die API dieselbe grundlegende Struktur, aufgeteilt in einzeln abrufbare Teilressourcen:
content/summary— Übersicht (Status, Beträge, Format)content/seller/content/buyer— Verkäufer- bzw. Käuferdatencontent/lineitems— Rechnungspositionencontent/taxes— Steuerdaten je Steuerkategorie (taxable,rate,amount,category)content/paymentterms— Zahlungsbedingungen, inkl.directDebitMandateIDunddueDateTimecontent/paymentmeans— Zahlungsmittel (typeCode,information,paymentReference)content/delivery— Lieferdatencontent— alle vorstehenden Teilressourcen gesammelt in einem Responseattachments/attachment/{attachmentId}/file— Anhänge des Importsstatus— Verarbeitungsstatus des Importsvalidation/validation/pdf— Validierungsergebnis
Der Import selbst läuft asynchron ab: Ein POST /import/incoming liefert 202 Accepted mit einer importId, bevor Parsing und Validierung abgeschlossen sind. Rufen Sie GET /import/incoming/{importId}/status ab, bis overallStatus nicht mehr pending ist, bevor Sie die Inhalts-Endpunkte auswerten.
Bei ausgehenden importierten Rechnungen (/import/outgoing) enthält content zusätzlich einen references-Block mit den dokumentweiten Referenznummern: orderNumber (Bestellnummer des Käufers), orderReferenceId (BT-13), buyerReferenceId (BT-10), shippingOrderNumber, supplierNumber, contractNumber, assignmentNumber und mandateReference (SEPA-Mandatsreferenz).
Wiederkehrende Rechnungen
Wiederkehrende Rechnungen ("Serienrechnungen") werden in der faktoora-Oberfläche eingerichtet — die Klickanleitung dazu steht im Artikel Serienrechnungen. Über die API steht dafür der Lese-Endpunkt GET /recurring-invoices zur Verfügung: Er liefert die angelegten Zeitpläne (Name, Frequenz, Start-/Enddatum, Status, nextExecutionDate, verknüpftes Rechnungstemplate). Ein Endpunkt zum Anlegen oder Ändern eines Zeitplans über die API ist in der API-Referenz nicht dokumentiert.
Dateiaustausch: SFTP, FTP und WebDAV
Für den Austausch von Rechnungsdateien über ein Verzeichnis lässt sich in den Workflows eine Dateiverbindung einrichten. Als Protokoll stehen FTP, SFTP und WebDAV zur Auswahl. Die Einrichtung erfolgt in der Oberfläche, nicht über die API — die API-Referenz enthält dafür keine Endpunkte.
Daneben gibt es zwei weitere Wege, ein Vorsystem anzubinden:
- Programmatisch über die API: Rechnungsdaten strukturiert per
POST /invoiceserzeugen, oder bereits erzeugte E-Rechnungsdateien perPOST /import/incomingbzw. entsprechend für ausgehende Rechnungen hochladen. - Per E-Mail: siehe Empfang von Rechnungen über eigene Mailserver.
DATEV-Integration: Umgang mit Differenzbeträgen
Beim DATEV-Export gleicht faktoora Rundungsdifferenzen zwischen der Summe der einzelnen Rechnungspositionen und dem konsolidierten Rechnungsbetrag automatisch aus: Weicht die Summe der Positionsbeträge vom konsolidierten Betrag ab, wird die Differenz auf den Betrag der ersten Position im DATEV-Ledger-Export angerechnet, sodass die Summe der exportierten Positionen exakt dem Rechnungsgesamtbetrag entspricht.
Bereits integrierte Systeme
Im Code und in bestehenden Wissensdatenbank-Artikeln belegt sind Anbindungen an: DATEV, Xero, weclapp, HubSpot, Monday, PipeDrive und Bexio. Zusätzlich existiert eine Stripe-Anbindung, die Stripe-Rechnungen und -Kunden als Rechnungen in faktoora synchronisiert; das automatische Erzeugen im XRechnung-Format ist damit nicht dokumentiert — das Ausgabeformat einer Rechnung bestimmen Sie weiterhin selbst über das format-Feld bzw. die Kontoeinstellungen.
Was dit nuttig?