Ce que dit GoCardless
| Reason | Tipo | HTTP | Texto de GoCardless |
|---|---|---|---|
idempotent_creation_conflict | invalid_state | 409 | A resource already exists for the supplied idempotency key. |
La page des limites de GoCardless le complète : si une ressource existe déjà avec cette clé, la réponse est un 409 avec links.conflicting_resource_id, qui désigne la ressource déjà créée. Les clés peuvent comporter jusqu'à 128 caractères, et GoCardless s'en souvient pendant au moins 30 jours.

Le problème que cela résout
Une demande peut prendre du temps : GoCardless coupe celles qui dépassent 29 secondes, et le réseau peut couper avant. Si Odoo envoie un prélèvement et ne reçoit pas de réponse, il ne sait pas si GoCardless l'a créé. Répéter la demande sans précaution est dangereux ; la documentation même de GoCardless prévient que relancer sans clé d'idempotence après un délai d'attente peut prélever deux fois le même paiement.
Avec une clé, la deuxième tentative ne crée rien : si la première est bien arrivée, GoCardless répond par ce 409 et l'identifiant du prélèvement déjà existant.
Comment le connecteur l'utilise
Le connecteur envoie une clé d'idempotence à chaque demande qui crée un prélèvement, un remboursement, une nouvelle tentative ou la demande de mandat. La clé n'est pas aléatoire. Elle est calculée à partir de l'opération, de la transaction Odoo et de l'identifiant de la base de données, de sorte que :
- répéter le même prélèvement envoie exactement la même clé ;
- une copie de la base destinée aux tests n'entre pas en conflit avec celle de production, même si les deux émettent la même facture.
Lorsque le 409 arrive, le connecteur lit conflicting_resource_id, demande cette ressource à GoCardless et l'adopte comme réponse. Pour vous, il n'y a pas d'erreur : la transaction reste liée au prélèvement qui existait déjà, et la facture suit son cours normal.
Quand GoCardless ne répond pas
Si la demande reste sans réponse, le connecteur la renvoie une fois avec la même clé. Sans clé, il ne renvoie rien. Si la réponse manque toujours, il signale la situation sans considérer le prélèvement comme perdu : « 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 transaction reste en attente, et non en erreur, car en erreur Odoo pourrait générer un autre prélèvement avec une autre référence et une autre clé.
Ce message s'affiche dans la langue de la personne qui lance le prélèvement. Si c'est une action planifiée, comme le renouvellement d'un abonnement ou la relance du connecteur lui-même, il s'affiche sans personne devant : le connecteur n'est pas traduit en français, et ces messages sortent toujours en anglais : « GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour. ».

Que faire
Avec le connecteur, normalement rien : le 409 se résout tout seul. Si vous le voyez dans un autre logiciel connecté au même compte GoCardless, vérifiez deux choses. D'abord, que vous ne réutilisez pas une clé pour des opérations différentes. Ensuite, que la ressource de conflicting_resource_id est bien celle que vous attendiez : si c'est le cas, la nouvelle tentative a fonctionné comme prévu. Si ce n'est pas le cas, conservez le request_id de la réponse : GoCardless le demande lorsqu'on contacte son support, et le connecteur l'ajoute à ses messages d'erreur.
Un 409 signifie-t-il que le client a payé deux fois ?
Bien au contraire. Cela signifie que GoCardless a refusé de créer le second prélèvement parce que la clé en avait déjà un. Le client ne paie qu'une seule fois.
Que se passe-t-il si l'on change la référence de la transaction ?
La clé change, et GoCardless la traite comme un nouveau prélèvement. C'est pourquoi le connecteur laisse en attente, et non en erreur, un prélèvement sans réponse : ainsi, il n'en crée pas un autre avec une autre référence.
Avec notre connecteur
Dans Odoo 17, 18, 19 et 20, le connecteur applique la règle que GoCardless demande pour ne pas prélever deux fois : clé fixe par opération, nouvelle tentative uniquement avec la même clé, et adoption de la ressource existante lorsque le 409 arrive.
À lire aussi
Vérifié dans le code du connecteur (version 17.0, 18.0, 19.0 et 20.0) et dans les sources citées
Sources
- docs.gocardless.com/docs/api-reference/limits
- Code du module : flexigo_payment_gocardless: models/payment_provider.py, ligne 462 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_provider.py, ligne 352 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_transaction.py, ligne 68 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_provider.py, ligne 391 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_provider.py, ligne 357 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_provider.py, ligne 373 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_transaction.py, ligne 299 en 17.0 (d203ee6), ligne 299 en 18.0 (e2ab18b), ligne 299 en 19.0 (ce7f5a3) et ligne 310 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, ligne 448 en 17.0 (d203ee6), ligne 448 en 18.0 (e2ab18b), ligne 448 en 19.0 (ce7f5a3) et ligne 450 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, ligne 29 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: __manifest__.py, ligne 31 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- docs.gocardless.com/docs/api-reference/responses-and-errors
- Code du module : flexigo_payment_gocardless: models/payment_transaction.py, ligne 123 en 17.0 (d203ee6), ligne 123 en 18.0 (e2ab18b), ligne 123 en 19.0 (ce7f5a3) et ligne 126 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/payment_transaction.py, ligne 247 en 17.0 (d203ee6), ligne 247 en 18.0 (e2ab18b), ligne 247 en 19.0 (ce7f5a3) et ligne 258 en 20.0 (688d86b)
- github.com/odoo/odoo/blob/17.0/odoo/http.py
