Przejdź do głównej treści
GoCardless API · invalid_state · 409

GoCardless 409 idempotent_creation_conflict: obciążenie już istniało

Ten błąd budzi większy niepokój, niż powinien. GoCardless odpowiada 409 idempotent_creation_conflict, gdy po raz drugi otrzyma żądanie utworzenia z kluczem idempotentności, którego już użyto. Dobrze obsłużony, jest właśnie tym, co zapobiega dwukrotnemu obciążeniu tej samej należności.

FlexigoTech · Odpowiada: Víctor Gómez · Aktualizacja: 6 listopada 2026

Najważniejsze

Wersje
Odoo 17, 18, 19 i 20
Sprawdzone
w kodzie źródłowym konektora, wersja 17.0, 18.0, 19.0 i 20.0 · w źródłach podanych na końcu
Czas czytania
3 min

Co mówi GoCardless

ReasonTipoHTTPTexto de GoCardless
idempotent_creation_conflictinvalid_state409A resource already exists for the supplied idempotency key.

Strona GoCardless o limitach uzupełnia tę informację: jeśli zasób z tym kluczem już istnieje, odpowiedzią jest 409 z links.conflicting_resource_id, który wskazuje już utworzony zasób. Klucze mogą mieć do 128 znaków, a GoCardless pamięta je przez co najmniej 30 dni.

Karta błędu idempotent_creation_conflict z GoCardless
Reason, kod HTTP 409 oraz tekst, którym GoCardless go opisuje.

Problem, który rozwiązuje

Żądanie może trwać długo: GoCardless przerywa te, które przekraczają 29 sekund, a sieć może zostać przerwana jeszcze wcześniej. Jeśli Odoo prosi o obciążenie i nie dostaje odpowiedzi, nie wie, czy GoCardless je utworzył. Zwykłe powtórzenie żądania jest niebezpieczne; sama dokumentacja GoCardless ostrzega, że ponowienie bez klucza idempotentności po upływie limitu czasu może obciążyć tę samą płatność dwa razy.

Z kluczem drugie wysłanie niczego nie tworzy: jeśli pierwsze dotarło, GoCardless odpowiada tym samym 409 i identyfikatorem już istniejącego obciążenia.

Jak używa tego konektor

Konektor wysyła klucz idempotentności przy każdym żądaniu, które tworzy obciążenie, zwrot, ponowienie lub żądanie mandatu. Klucz nie jest losowy. Powstaje z operacji, transakcji Odoo i identyfikatora bazy danych, dzięki czemu:

  • powtórzenie tego samego obciążenia wysyła dokładnie ten sam klucz;
  • kopia bazy do testów nie koliduje z produkcyjną, nawet jeśli obie wystawią tę samą fakturę.

Gdy nadejdzie 409, konektor odczytuje conflicting_resource_id, pobiera ten zasób z GoCardless i przyjmuje go jako odpowiedź. Dla Ciebie nie ma błędu: transakcja zostaje powiązana z już istniejącym obciążeniem, a faktura toczy się normalnie.

Gdy GoCardless nie odpowiada

Jeśli żądanie pozostaje bez odpowiedzi, konektor powtarza je raz z tym samym kluczem. Bez klucza nie powtarza niczego. Jeśli i wtedy brak odpowiedzi, informuje o tym, nie uznając obciążenia za utracone: „GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.”. Transakcja zostaje w stanie oczekującym, a nie w błędzie, bo przy błędzie Odoo mogłoby wygenerować kolejne obciążenie z inną referencją i innym kluczem.

Konektor nie jest przetłumaczony na polski: te teksty zawsze pojawiają się po angielsku, także w Odoo po polsku, niezależnie od tego, czy uruchamia je użytkownik, czy zaplanowane działanie, takie jak odnowienie subskrypcji lub ponowne wysłanie przez sam konektor: „GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.”.

Schemat: co GoCardless odpowiada na 409 i co robi Odoo z konektorem
Schemat przygotowany na podstawie kodu konektora (17.0, 18.0, 19.0 i 20.0) oraz dokumentacji GoCardless; przekreślone jest to, czego 409 zapobiega.

Co zrobić

W przypadku konektora zwykle nic: 409 rozwiązuje się sam. Jeśli zobaczysz go w innym programie podłączonym do tego samego konta GoCardless, sprawdź dwie rzeczy. Po pierwsze, czy nie używasz tego samego klucza do różnych operacji. Po drugie, czy zasób z conflicting_resource_id jest tym, którego się spodziewasz: jeśli tak, ponowienie zadziałało jak należy. Jeśli nie, zachowaj request_id z odpowiedzi: GoCardless prosi o jego podanie przy kontakcie z pomocą techniczną, a konektor dodaje go do swoich komunikatów o błędach.

Czy 409 oznacza, że klient zapłacił dwa razy?

Wręcz przeciwnie. Oznacza, że GoCardless odmówił utworzenia drugiego obciążenia, bo dla tego klucza istniało już jedno. Klient płaci tylko raz.

Co się stanie, jeśli zmieni się referencja transakcji?

Zmienia się klucz, a GoCardless traktuje to jak nowe obciążenie. Dlatego konektor zostawia obciążenie bez odpowiedzi jako oczekujące, a nie jako błędne: w ten sposób nie powstaje kolejne z inną referencją.

Z naszym konektorem

W Odoo 17, 18, 19 i 20 konektor stosuje regułę, której GoCardless wymaga, aby nie obciążać dwa razy: stały klucz dla każdej operacji, ponawianie wyłącznie z tym samym kluczem oraz przyjmowanie istniejącego zasobu, gdy nadejdzie 409.

Czytaj dalej

Błąd mandate_is_inactive w GoCardless przy tworzeniu pobrania z OdooGoCardless zwraca mandate_is_inactive przy płatności z mandatem anulowanym, nieudanym lub wygasłym. Dlaczego tak się dzieje i jak obsługuje to konektor w Odoo.Błąd retry_failed GoCardless przy ponawianiu płatności z OdooGoCardless odpowiada retry_failed, gdy płatność się nie nie powiodła lub nie można jej ponowić. Kiedy w Odoo jest „Retry collection” i co robi konektor.Webhook GoCardless: 498 Token Invalid, 204 i podpis Webhook-SignatureGoCardless otrzymuje 498, gdy podpis Webhook-Signature nie pasuje, a 204, gdy nie rozpoznaje zdarzenia. Co zwraca Odoo 17, 18, 19 i 20 i czemu w 20 to 401.
Sprawdzone w kodzie źródłowym konektora (wersja 17.0, 18.0, 19.0 i 20.0) i w podlinkowanych źródłach

Źródła

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