Ce que dit GoCardless
| Reason | Type | HTTP | Texte de GoCardless |
|---|---|---|---|
rate_limit_exceeded | invalid_api_usage | 429 | Rate limit reached. Check headers for reset time. |
La page des limites de GoCardless donne le chiffre : 1 600 requêtes par minute dans une intégration standard, et 1 600 par minute et par marchand dans une intégration partenaire. Au-delà, l'API renvoie le 429, et GoCardless précise que ces requêtes peuvent être renvoyées sans problème : « These requests are safe to retry. ». Pour savoir quand, il renvoie aux en-têtes de la réponse : ratelimit-limit, ratelimit-remaining et ratelimit-reset.

D'où viennent tant de requêtes
La limite compte toutes les requêtes adressées à l'API, pas seulement celles qui créent des prélèvements. Avec le connecteur, chaque prélèvement sur un mandat enregistré est une requête, qu'il provienne d'un abonnement qui se renouvelle ou d'un paiement enregistré avec le moyen de paiement du client. Chaque événement de paiement qui arrive dans Odoo en est une autre, car le connecteur ne se fie pas seulement à la notification : il demande ce paiement à GoCardless et applique l'état qu'il lui renvoie. Un lot important au même moment, comme de nombreux renouvellements simultanés pendant que arrivent les événements des prélèvements précédents, additionne les deux.
GoCardless classe ce reason parmi les erreurs invalid_api_usage, celles qui viennent de la manière dont la requête est faite, et pour celles-ci il demande d'alerter l'équipe technique (« alert your dev team »). Un 429 isolé n'en a pas besoin ; un rejet qui se répète chaque jour, si.
Ce que fait le connecteur
- Il lit l'en-tête
ratelimit-resetet calcule le temps restant : l'heure indiquée moins celle du serveur Odoo. - Il attend ce délai, au minimum 1 seconde et au maximum 65. Si l'en-tête est absent ou illisible, il attend 1 seconde. Le plafond existe pour qu'une horloge mal réglée ne bloque pas indéfiniment le processus Odoo qui attend.
- Il répète la requête une seule fois.
- Si la répétition reçoit de nouveau un 429, il n'attend plus : il la traite comme n'importe quel autre rejet de l'API.
Le connecteur ne compte pas ses requêtes et ne les freine pas à l'avance. Il ne lit pas ratelimit-remaining : il n'attend que lorsque GoCardless a déjà répondu 429.

Si la deuxième tentative échoue aussi
Cela dépend de ce qu'Odoo était en train de faire à ce moment-là.
- S'il s'agissait d'un prélèvement, la transaction passe en « Erreur » avec « GoCardless rejected the request. » et, dessous, le message de GoCardless avec
rate_limit_exceededet lerequest_identre crochets. La facture reste à encaisser. - S'il appliquait un événement de GoCardless, le webhook répond 500 afin que GoCardless renvoie l'envoi, et les événements déjà appliqués ne le sont pas deux fois. La récupération horaire ne laisse pas non plus un événement en échec de côté : elle le redemande lors du passage suivant.
Un 429 n'est pas la même chose qu'un prélèvement sans réponse. Sans réponse, le connecteur ne sait pas si GoCardless a créé le prélèvement : il le laisse en attente et le renvoie, avec la même clé, dans moins d'une heure. Avec un 429, il y a bien une réponse : GoCardless n'a pas accepté la requête, et c'est pourquoi la transaction passe en erreur.
Le connecteur n'est pas traduit en français : ces textes apparaissent toujours en anglais, même dans un Odoo en français, qu'ils soient déclenchés par un utilisateur ou par une action planifiée, comme le renouvellement d'un abonnement : « GoCardless rejected the request. ».
Que faire
- Ouvrez la transaction depuis la facture, avec le bouton « Transaction de paiement » en haut ; le menu des transactions n'apparaît qu'en mode développeur, et il n'existe pas dans Odoo 20. Si le message mentionne
rate_limit_exceeded, GoCardless a rejeté cette requête à cause de la limite, et non à cause du client ou de son mandat. - Après un moment, encaissez de nouveau la facture avec le moyen de paiement enregistré du client.
- Si cela vous arrive souvent, vérifiez l'heure du serveur Odoo : le délai d'attente se calcule en soustrayant celle de
ratelimit-reset, et une horloge en avance le raccourcit. - Si vous devez contacter GoCardless, gardez le
request_iddu message : leur documentation demande de l'inclure lorsque vous contactez leur support.
Le connecteur répartit-il les requêtes pour ne pas atteindre la limite ?
Non. Il ne les compte pas et ne les freine pas à l'avance : il réagit lorsque GoCardless répond 429, avec une attente et une seule répétition.
Pourquoi attend-il au maximum 65 secondes ?
Pendant l'attente, le processus Odoo qui fait la requête ne fait rien d'autre. Le code du connecteur fixe ce plafond pour qu'une horloge mal réglée ne le bloque pas.
Un événement de GoCardless est-il perdu à cause de la limite ?
Il n'est pas considéré comme perdu : le webhook demande à GoCardless de le renvoyer, et la récupération horaire le redemande lors du passage suivant.
Avec notre connecteur
Dans Odoo 17, 18, 19 et 20, le connecteur traite le 429 comme une pause : il attend ce que demande GoCardless, répète une fois et, si la limite persiste, laisse la transaction en erreur avec le request_id afin que vous sachiez ce qui s'est passé et ce que vous pouvez transmettre à GoCardless.
À 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
- docs.gocardless.com/docs/api-reference/responses-and-errors
- Code du module : flexigo_payment_gocardless: const.py, ligne 113 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 378 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 408 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 379 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 383 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 397 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 462 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 281 en 17.0 (d203ee6), ligne 281 en 18.0 (e2ab18b), ligne 281 en 19.0 (ce7f5a3) et ligne 292 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)
- 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: models/payment_transaction.py, ligne 589 en 17.0 (d203ee6), ligne 589 en 18.0 (e2ab18b), ligne 588 en 19.0 (ce7f5a3) et ligne 607 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: controllers/main.py, ligne 124 en 17.0 (d203ee6), ligne 124 en 18.0 (e2ab18b), ligne 124 en 19.0 (ce7f5a3) et ligne 127 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: controllers/main.py, ligne 96 en 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: models/gocardless_webhook_event.py, ligne 7 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
- Code du module : flexigo_payment_gocardless: const.py, ligne 117 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 603 en 17.0 (d203ee6), ligne 603 en 18.0 (e2ab18b), ligne 603 en 19.0 (ce7f5a3) et ligne 605 en 20.0 (688d86b)
- docs.gocardless.com/docs/api-reference/webhooks
- Code du module : flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, ligne 521 en 17.0 (d203ee6), ligne 521 en 18.0 (e2ab18b), ligne 521 en 19.0 (ce7f5a3) et ligne 523 en 20.0 (688d86b)
- github.com/odoo/odoo/blob/20.0/addons/payment/i18n/fr.po
- github.com/odoo/odoo/blob/20.0/addons/payment/views/payment_transaction_views.xml
- github.com/odoo/odoo/blob/17.0/odoo/http.py
- github.com/odoo/odoo/blob/20.0/addons/account_payment/views/account_move_views.xml
- Code du module : flexigo_payment_gocardless: __manifest__.py, ligne 31 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
