Co mówi GoCardless
| Reason | Tipo | HTTP | Texto de GoCardless |
|---|---|---|---|
idempotent_creation_conflict | invalid_state | 409 | A 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.

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.”.

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
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
