Zum Hauptinhalt springen
GoCardless API · invalid_state · 409

GoCardless 409 idempotent_creation_conflict: Die Abbuchung existierte bereits

Dieser Fehler wirkt bedrohlicher, als er ist. GoCardless antwortet mit 409 idempotent_creation_conflict, wenn es zum zweiten Mal eine Erstellungsanfrage mit einem bereits verwendeten Idempotenzschlüssel erhält. Richtig eingesetzt, verhindert genau das, dass dieselbe Lastschrift zweimal eingezogen wird.

FlexigoTech · Verantwortlich: Víctor Gómez · Aktualisiert am 6. November 2026

Das Wichtigste

Versionen
Odoo 17, 18, 19 und 20
Geprüft
im Quellcode des Connectors, Version 17.0, 18.0, 19.0 und 20.0 · in den Quellen am Ende
Lesezeit
3 Min.

Was GoCardless sagt

ReasonTypHTTPText von GoCardless
idempotent_creation_conflictinvalid_state409A resource already exists for the supplied idempotency key.

Die Seite zu den Limits von GoCardless ergänzt: Existiert bereits eine Ressource mit diesem Schlüssel, lautet die Antwort 409 mit links.conflicting_resource_id, die auf die bereits angelegte Ressource verweist. Schlüssel dürfen bis zu 128 Zeichen lang sein, und GoCardless merkt sie sich mindestens 30 Tage.

Fehlerkarte idempotent_creation_conflict von GoCardless
Der Reason, der HTTP-Code 409 und der Text, mit dem GoCardless ihn dokumentiert.

Das Problem, das er löst

Eine Anfrage kann dauern: GoCardless bricht solche ab, die länger als 29 Sekunden laufen, und das Netz kann vorher abreißen. Fordert Odoo eine Abbuchung an und erhält keine Antwort, weiß es nicht, ob GoCardless sie angelegt hat. Die Anfrage einfach zu wiederholen ist gefährlich; die Dokumentation von GoCardless warnt, dass ein Wiederholen ohne Idempotenzschlüssel nach einem Timeout dieselbe Zahlung doppelt einziehen kann.

Mit Schlüssel legt der zweite Versuch nichts neu an: Ist der erste angekommen, antwortet GoCardless mit diesem 409 und der Kennung der bereits bestehenden Abbuchung.

Wie der Konnektor ihn nutzt

Der Konnektor sendet bei jeder Anfrage, die eine Abbuchung, eine Rückerstattung, einen Wiederholungsversuch oder die Mandatsanfrage anlegt, einen Idempotenzschlüssel. Der Schlüssel ist nicht zufällig. Er wird aus dem Vorgang, der Odoo-Transaktion und der Datenbankkennung berechnet, sodass:

  • die Wiederholung derselben Abbuchung exakt denselben Schlüssel sendet;
  • eine Testkopie der Datenbank nicht mit der Produktivdatenbank kollidiert, auch wenn beide dieselbe Rechnung ausstellen.

Kommt der 409, liest der Konnektor conflicting_resource_id, fordert diese Ressource bei GoCardless an und übernimmt sie als Antwort. Für Sie entsteht kein Fehler: Die Transaktion wird mit der bereits bestehenden Abbuchung verknüpft, und die Rechnung läuft normal weiter.

Wenn GoCardless nicht antwortet

Bleibt eine Anfrage ohne Antwort, wiederholt der Konnektor sie einmal mit demselben Schlüssel. Ohne Schlüssel wiederholt er nichts. Bleibt auch dann die Antwort aus, meldet er es, ohne die Abbuchung als verloren zu betrachten: «GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.». Die Transaktion bleibt ausstehend, nicht im Fehlerzustand, denn im Fehlerzustand könnte Odoo eine weitere Abbuchung mit einer anderen Referenz und einem anderen Schlüssel erzeugen.

Der Konnektor ist nicht ins Deutsche übersetzt: Diese Texte erscheinen immer auf Englisch, auch in einem deutschen Odoo, egal ob ein Benutzer oder eine geplante Aktion sie auslöst, etwa die Verlängerung eines Abonnements oder die erneute Übermittlung durch den Konnektor selbst: «GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.».

Schema: was GoCardless mit einem 409 antwortet und was Odoo mit dem Konnektor tut
Schema auf Grundlage des Konnektor-Codes (17.0, 18.0, 19.0 und 20.0) und der Dokumentation von GoCardless; das Durchgestrichene ist das, was der 409 verhindert.

Was zu tun ist

Mit dem Konnektor normalerweise nichts: Der 409 löst sich selbst auf. Sehen Sie ihn in einem anderen Programm, das mit demselben GoCardless-Konto verbunden ist, prüfen Sie zwei Dinge. Erstens, ob Sie einen Schlüssel nicht für unterschiedliche Vorgänge wiederverwenden. Zweitens, ob die Ressource aus conflicting_resource_id die erwartete ist: Ist sie es, hat der Wiederholungsversuch wie vorgesehen funktioniert. Ist sie es nicht, notieren Sie die request_id der Antwort: GoCardless verlangt sie bei einer Kontaktaufnahme mit dem Support, und der Konnektor nimmt sie in seine Fehlermeldungen auf.

Bedeutet ein 409, dass der Kunde zweimal bezahlt hat?

Im Gegenteil. Es bedeutet, dass GoCardless die zweite Abbuchung abgelehnt hat, weil der Schlüssel bereits eine besaß. Der Kunde zahlt nur einmal.

Was passiert, wenn die Referenz der Transaktion geändert wird?

Dann ändert sich der Schlüssel, und GoCardless behandelt es als neue Abbuchung. Deshalb lässt der Konnektor eine Abbuchung ohne Antwort ausstehend und nicht im Fehlerzustand: So entsteht keine weitere mit einer anderen Referenz.

Mit unserem Konnektor

In Odoo 17, 18, 19 und 20 wendet der Konnektor die Regel an, die GoCardless fordert, um nicht doppelt abzubuchen: fester Schlüssel pro Vorgang, Wiederholung nur mit demselben Schlüssel und Übernahme der bestehenden Ressource, wenn der 409 eintrifft.

Weiterlesen

GoCardless-Fehler mandate_is_inactive beim Anlegen einer Zahlung aus OdooGoCardless meldet mandate_is_inactive bei Zahlungen mit gekündigtem, fehlgeschlagenem oder abgelaufenem Mandat. Ursache und Lösung im Odoo-Konnektor.GoCardless-Fehler retry_failed bei der Wiederholung einer Lastschrift aus OdooGoCardless antwortet mit retry_failed, wenn die Zahlung nicht fehlgeschlagen ist oder keine Wiederholung mehr zulässt. Wann Odoo den Button zeigt.GoCardless-Webhook: 498 Token Invalid, 204 und die Webhook-SignatureGoCardless fordert 498 bei falscher Webhook-Signature und 204 bei unbekanntem Ereignis. Was Odoo 17, 18, 19 und 20 antwortet und warum es in 20 ein 401 ist.
Geprüft im Quellcode des Connectors (Version 17.0, 18.0, 19.0 und 20.0) und in den verlinkten Quellen

Quellen

  • docs.gocardless.com/docs/api-reference/limits
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_provider.py, Zeile 462 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_provider.py, Zeile 352 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_transaction.py, Zeile 68 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_provider.py, Zeile 391 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_provider.py, Zeile 357 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_provider.py, Zeile 373 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_transaction.py, Zeile 299 in 17.0 (d203ee6), Zeile 299 in 18.0 (e2ab18b), Zeile 299 in 19.0 (ce7f5a3) und Zeile 310 in 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, Zeile 448 in 17.0 (d203ee6), Zeile 448 in 18.0 (e2ab18b), Zeile 448 in 19.0 (ce7f5a3) und Zeile 450 in 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, Zeile 29 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: __manifest__.py, Zeile 31 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) und 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_transaction.py, Zeile 123 in 17.0 (d203ee6), Zeile 123 in 18.0 (e2ab18b), Zeile 123 in 19.0 (ce7f5a3) und Zeile 126 in 20.0 (688d86b)
  • Quellcode des Moduls: flexigo_payment_gocardless: models/payment_transaction.py, Zeile 247 in 17.0 (d203ee6), Zeile 247 in 18.0 (e2ab18b), Zeile 247 in 19.0 (ce7f5a3) und Zeile 258 in 20.0 (688d86b)
  • github.com/odoo/odoo/blob/17.0/odoo/http.py