Salta al contingut principal
GoCardless API · invalid_state · 409

GoCardless 409 idempotent_creation_conflict: el cobrament ja existia

Aquest error fa més por del que hauria. GoCardless respon 409 idempotent_creation_conflict quan rep per segona vegada una petició de creació amb una clau d'idempotència que ja havia utilitzat. Ben gestionat, és justament el que impedeix cobrar dos cops el mateix rebut.

FlexigoTech · Responsable: Víctor Gómez · Actualitzat el 6 de novembre de 2026

L'essencial

Versions
Odoo 17, 18, 19 i 20
Comprovat
al codi del connector, versió 17.0, 18.0, 19.0 i 20.0 · a les fonts enllaçades al final
Lectura
3 min

Què diu GoCardless

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

La pàgina de límits de GoCardless ho completa: si ja existeix un recurs amb aquesta clau, la resposta és un 409 amb links.conflicting_resource_id, que assenyala el recurs que ja està creat. Les claus poden tenir fins a 128 caràcters i GoCardless les recorda almenys 30 dies.

Targeta de l'error idempotent_creation_conflict de GoCardless
El reason, el codi HTTP 409 i el text amb què GoCardless el documenta.

El problema que resol

Una petició pot tardar: GoCardless talla les que passen de 29 segons, i la xarxa pot caure abans. Si Odoo demana un cobrament i no rep resposta, no sap si GoCardless l'ha creat. Repetir la petició sense més és perillós; la pròpia documentació de GoCardless avisa que reintentar sense clau d'idempotència després d'un temps d'espera esgotat pot cobrar el mateix pagament dos cops.

Amb clau, el segon intent no crea res: si el primer ha arribat, GoCardless contesta amb aquest 409 i l'identificador del cobrament que ja existeix.

Com l'usa el connector

El connector envia una clau d'idempotència a cada petició que crea un cobrament, un reemborsament, un reintent o la sol·licitud del mandat. La clau no és aleatòria. Es calcula amb l'operació, la transacció d'Odoo i l'identificador de la base de dades, de manera que:

  • repetir el mateix cobrament envia exactament la mateixa clau;
  • una còpia de la base per a proves no xoca amb la de producció encara que les dues emetin la mateixa factura.

Quan arriba el 409, el connector llegeix conflicting_resource_id, demana aquest recurs a GoCardless i l'adopta com a resposta. Per a tu no hi ha error: la transacció queda enllaçada al cobrament que ja existia, i la factura segueix el seu curs normal.

Quan GoCardless no contesta

Si la petició es queda sense resposta, el connector la repeteix una vegada amb la mateixa clau. Sense clau no repeteix res. Si tampoc hi ha resposta, avisa sense donar el cobrament per perdut: «GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.». La transacció queda pendent, no en error, perquè en error Odoo podria generar un altre cobrament amb una altra referència i una altra clau.

El connector no està traduït al català: aquests textos surten sempre en anglès, també en un Odoo en català, tant si els llança un usuari com una tasca programada, com la renovació d'una subscripció o el reenviament del propi connector: «GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.».

Esquema: què respon GoCardless amb un 409 i què fa Odoo amb el connector
Esquema fet a partir del codi del connector (17.0, 18.0, 19.0 i 20.0) i de la documentació de GoCardless; el que està tatxat és el que el 409 evita.

Què fer

Amb el connector, normalment res: el 409 es resol sol. Si el veus en un altre programa connectat al mateix compte de GoCardless, comprova dues coses. La primera, que no estiguis reutilitzant una clau per a operacions diferents. La segona, que el recurs de conflicting_resource_id sigui el que esperaves: si ho és, el reintent ha funcionat com cal. Si no ho és, guarda el request_id de la resposta: GoCardless demana incloure'l en contactar amb el seu suport, i el connector l'afegeix als seus missatges d'error.

Un 409 vol dir que el client ha pagat dos cops?

Al revés. Vol dir que GoCardless s'ha negat a crear el segon cobrament perquè la clau ja en tenia un. El client paga una sola vegada.

Què passa si es canvia la referència de la transacció?

Canvia la clau, i GoCardless ho tracta com un cobrament nou. Per això el connector deixa pendent, i no en error, un cobrament sense resposta: així no se'n crea un altre amb una altra referència.

Amb el nostre connector

A Odoo 17, 18, 19 i 20 el connector aplica la regla que GoCardless demana per no cobrar dos cops: clau fixa per operació, repetició només amb la mateixa clau i adopció del recurs existent quan arriba el 409.

Continua llegint

Error mandate_is_inactive de GoCardless en crear un cobrament des d'OdooGoCardless respon mandate_is_inactive en crear un pagament amb un mandat cancel·lat, fallit o caducat. Per què passa i com ho resol el connector a Odoo.Error retry_failed de GoCardless en reintentar un cobrament des d'OdooGoCardless respon retry_failed si el pagament no ha fallat o ja no admet reintents. Quan surt a Odoo el botó «Retry collection» i què fa el connector.Webhook de GoCardless: 498 Token Invalid, 204 i la signatura Webhook-SignatureGoCardless demana 498 si la Webhook-Signature no quadra i 204 si no reconeix l'esdeveniment. Què respon Odoo 17, 18, 19 i 20 i per què a la 20 és un 401.
Comprovat al codi del connector (versió 17.0, 18.0, 19.0 i 20.0) i a les fonts enllaçades

Fonts

  • docs.gocardless.com/docs/api-reference/limits
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_provider.py, línia 462 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_provider.py, línia 352 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_transaction.py, línia 68 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_provider.py, línia 391 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_provider.py, línia 357 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_provider.py, línia 373 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_transaction.py, línia 299 a 17.0 (d203ee6), línia 299 a 18.0 (e2ab18b), línia 299 a 19.0 (ce7f5a3) i línia 310 a 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, línia 448 a 17.0 (d203ee6), línia 448 a 18.0 (e2ab18b), línia 448 a 19.0 (ce7f5a3) i línia 450 a 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, línia 29 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: __manifest__.py, línia 31 a 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) i 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_transaction.py, línia 123 a 17.0 (d203ee6), línia 123 a 18.0 (e2ab18b), línia 123 a 19.0 (ce7f5a3) i línia 126 a 20.0 (688d86b)
  • Codi del mòdul: flexigo_payment_gocardless: models/payment_transaction.py, línia 247 a 17.0 (d203ee6), línia 247 a 18.0 (e2ab18b), línia 247 a 19.0 (ce7f5a3) i línia 258 a 20.0 (688d86b)
  • github.com/odoo/odoo/blob/17.0/odoo/http.py