Aller au contenu principal
API GoCardless · invalid_state

Erreur mandate_is_inactive de GoCardless lors de la création d'un encaissement depuis Odoo

mandate_is_inactive ne vient pas de la banque du client mais de l'API GoCardless elle-même : Odoo a tenté de créer un encaissement avec un mandat qui n'est plus actif. Il s'agit d'une erreur de type invalid_state, et la documentation de GoCardless est claire sur la marche à suivre : prévenir l'utilisateur et ne pas réessayer.

FlexigoTech · Responsable : Víctor Gómez · Mis à jour le 6 novembre 2026

L'essentiel

Versions
Odoo 17, 18, 19 et 20
Vérifié
dans le code du connecteur, version 17.0, 18.0, 19.0 et 20.0 · dans les sources citées à la fin
Lecture
4 min

Ce que dit GoCardless

ReasonTypeTexte de GoCardless
mandate_is_inactiveinvalid_state« Payment could not be created » et « mandate is cancelled, failed, or expired. »

GoCardless sépare les deux parties du texte par un tiret. Les erreurs invalid_state signifient, selon GoCardless, que l'action n'est pas valable dans l'état actuel de la ressource. Ici, la ressource est le mandat : annulé, échoué ou expiré, il n'accepte plus d'encaissements.

Fiche de l'erreur mandate_is_inactive de GoCardless
Le reason, son type invalid_state et le texte avec lequel GoCardless le documente.

Comment on arrive à cette erreur

En général, Odoo apprend qu'un mandat n'est plus valable grâce à un événement GoCardless avant de tenter un encaissement. Cette erreur apparaît lorsque ce n'est pas le cas : l'avis n'est pas arrivé ou est arrivé trop tard, ou le mandat a été annulé juste avant l'encaissement. L'encaissement peut provenir d'un abonnement qui se renouvelle ou d'un paiement enregistré avec le moyen de paiement mémorisé du client. Les avis de GoCardless arrivent par webhook : avec la connexion en deux clics, via FlexigoTech Cloud ; en mode avancé, vers le endpoint que vous avez créé vous-même dans le Dashboard de GoCardless. Si ce chemin échoue, Odoo ne l'apprend pas à temps.

Ce que fait le connecteur

Sans traitement spécifique, vous verriez l'erreur telle quelle, avec le texte de l'API, et le mandat continuerait d'être proposé pour la facture suivante. Le connecteur fait autre chose :

  1. Il reconnaît le reason mandate_is_inactive dans la réponse.
  2. Il interroge GoCardless sur ce mandat pour confirmer son état.
  3. S'il est annulé, échoué, expiré, consommé ou bloqué, il l'archive dans Odoo. Si c'est la première information sur ce mandat invalide, il l'écrit sur la fiche du client, avec l'état du mandat entre parenthèses (« The GoCardless direct debit mandate of … is no longer usable (cancelled). No further collection can be taken against it. Ask the customer to set up a new mandate. »), et crée l'activité « GoCardless mandate lost ».
  4. Il fait passer la transaction à « Erreur » avec son propre message, au lieu de l'erreur brute : « The customer's GoCardless mandate is …, so it cannot be charged. Ask the customer for a new mandate. ».

Si le mandat s'avère actif, le connecteur n'y touche pas et la transaction affiche l'erreur de GoCardless : « GoCardless rejected the request. » suivi du message de l'API et de son request_id. Le même traitement s'applique au bouton de relance d'un encaissement lorsque GoCardless répond mandate_is_inactive.

Le connecteur n'est pas traduit en français : ses messages et libellés sortent toujours en anglais, même dans un Odoo en français. Lorsqu'un encaissement est lancé par une action planifiée, comme le renouvellement d'un abonnement, ces messages s'affichent sans que personne n'intervienne, et ils sont alors en anglais, comme indiqué ci-dessus.

Pourquoi il ne faut pas réessayer

GoCardless l'indique dans la description des erreurs invalid_state : il faut informer l'utilisateur et ne pas le laisser réessayer. Un mandat annulé ne redevient pas actif parce qu'on insiste ; il faut une nouvelle signature du client ou, dans certains cas et seulement avec des autorisations spéciales de GoCardless, une réactivation.

Schéma : ce que répond GoCardless avec mandate_is_inactive et ce que fait Odoo avec le connecteur
Schéma réalisé à partir du code du connecteur (17.0, 18.0, 19.0 et 20.0) et de la documentation de GoCardless.

Que faire

  • Consultez le message de la transaction et la note du connecteur sur la fiche du client. La transaction s'ouvre 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. Les deux textes indiquent l'état du mandat.
  • Demandez au client un nouveau mandat et encaissez avec lui la facture en attente.
  • Si cela arrive souvent, vérifiez que les webhooks de GoCardless parviennent bien à votre Odoo : ce sont eux qui préviennent avant l'encaissement. Malgré tout, le connecteur demande toutes les heures les événements qui auraient été perdus.

Pourquoi le connecteur interroge-t-il le mandat au lieu de l'archiver directement ?

Parce qu'il n'archive que ce que GoCardless confirme comme invalide. Si la vérification indique que le mandat est actif, l'archiver obligerait le client à signer inutilement.

Avec notre connecteur

Dans Odoo 17, 18, 19 et 20, le connecteur transforme une erreur d'API en une tâche claire : le mandat invalide disparaît de la liste des moyens de paiement, le client est averti sur sa fiche et la facture reste en attente jusqu'à ce qu'un mandat fonctionnel soit disponible.

À lire aussi

GoCardless MD01 : mandate_cancelled et authorisation_disputed sur un prélèvement SEPALe code SEPA MD01 arrive dans GoCardless sous mandate_cancelled ou authorisation_disputed, sur un prélèvement échoué, rejeté ou annulé. Ce que fait Odoo.GoCardless bank_account_closed : AC04 et MD07, le compte n'existe plusGoCardless bank_account_closed avec AC04 (compte clôturé) ou MD07 (titulaire décédé) : le mandat est annulé. Ce que fait Odoo avec la facture et le client.Erreur retry_failed de GoCardless lors d'une nouvelle tentative de prélèvement depuis OdooGoCardless répond retry_failed si le paiement n'a pas échoué ou n'admet plus de relance. Quand Odoo montre « Retry collection » et ce que fait le connecteur.
Vérifié dans le code du connecteur (version 17.0, 18.0, 19.0 et 20.0) et dans les sources citées

Sources

  • Code du module : flexigo_payment_gocardless: const.py, ligne 15 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 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_provider.py, ligne 71 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: __manifest__.py, ligne 6 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/mandate
  • Code du module : flexigo_payment_gocardless: models/payment_transaction.py, ligne 278 en 17.0 (d203ee6), ligne 278 en 18.0 (e2ab18b), ligne 278 en 19.0 (ce7f5a3) et ligne 289 en 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: const.py, ligne 33 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) et 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: models/payment_token.py, ligne 131 en 17.0 (d203ee6), ligne 131 en 18.0 (e2ab18b), ligne 131 en 19.0 (ce7f5a3) et ligne 130 en 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: const.py, ligne 134 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_transaction.py, ligne 469 en 17.0 (d203ee6), ligne 469 en 18.0 (e2ab18b), ligne 468 en 19.0 (ce7f5a3) et ligne 487 en 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: i18n/flexigo_payment_gocardless.pot, ligne 1148 en 17.0 (d203ee6), ligne 1148 en 18.0 (e2ab18b), ligne 1148 en 19.0 (ce7f5a3) et ligne 1155 en 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, ligne 495 en 17.0 (d203ee6), ligne 495 en 18.0 (e2ab18b), ligne 495 en 19.0 (ce7f5a3) et ligne 497 en 20.0 (688d86b)
  • 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)
  • docs.gocardless.com/docs/api-reference/events/mandate
  • 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 321 en 17.0 (d203ee6), ligne 321 en 18.0 (e2ab18b), ligne 321 en 19.0 (ce7f5a3) et ligne 332 en 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, ligne 1233 en 17.0 (d203ee6), ligne 1233 en 18.0 (e2ab18b), ligne 1233 en 19.0 (ce7f5a3) et ligne 1240 en 20.0 (688d86b)
  • Code du module : flexigo_payment_gocardless: models/payment_token.py, ligne 83 en 17.0 (d203ee6), ligne 83 en 18.0 (e2ab18b), ligne 83 en 19.0 (ce7f5a3) et ligne 82 en 20.0 (688d86b)
  • github.com/odoo/odoo/blob/20.0/addons/payment/i18n/fr.po
  • 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)
  • 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