Skip to main content
GoCardless API · invalid_state

GoCardless mandate_is_inactive error when creating a collection from Odoo

mandate_is_inactive does not come from the customer's bank but from the GoCardless API itself: Odoo tried to create a collection with a mandate that is no longer active. It is an invalid_state error, and GoCardless's documentation is clear about what to do: inform the person using the system and do not retry.

FlexigoTech · Editor in charge: Víctor Gómez · Updated 6 November 2026

Key facts

Versions
Odoo 17, 18, 19 and 20
Checked
in the connector's source code, version 17.0, 18.0, 19.0 and 20.0 · against the sources linked at the end
Reading time
4 min

What GoCardless says

ReasonTypeGoCardless text
mandate_is_inactiveinvalid_state“Payment could not be created” and “mandate is cancelled, failed, or expired.”

GoCardless separates the two parts of the text with a dash. invalid_state errors mean, according to GoCardless, that the action is not valid in the resource's current state. Here the resource is the mandate: cancelled, failed or expired, it no longer accepts collections.

GoCardless mandate_is_inactive error card
The reason, its invalid_state type and the text with which GoCardless documents it.

How this error comes about

Normally Odoo learns that a mandate has died through a GoCardless event before it tries to collect against it. This error appears when that did not happen: the notice did not arrive or arrived late, or the mandate was cancelled just before the collection. The collection may come from a subscription that renews or from a payment recorded with the customer's saved payment method. GoCardless notices arrive by webhook: with the two-click connection, through FlexigoTech Cloud; in advanced mode, to the endpoint you created yourself in the GoCardless Dashboard. If that path fails, Odoo does not find out in time.

What the connector does

Without special handling, you would see the error as is, with the API text, and the mandate would keep being offered for the next invoice. The connector does something else:

  1. It recognises the reason mandate_is_inactive in the response.
  2. It asks GoCardless about that mandate to confirm its status.
  3. If it is cancelled, failed, expired, consumed or blocked, it archives it in Odoo. If this is the first news of that dead mandate, it writes it on the customer's record, with the mandate status in brackets (“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.”), and creates the activity “GoCardless mandate lost”.
  4. It moves the transaction to “Error” with its own message, instead of the raw error: “The customer's GoCardless mandate is …, so it cannot be charged. Ask the customer for a new mandate.”

If the mandate turns out to be active, the connector leaves it alone and the transaction shows the GoCardless error: “GoCardless rejected the request.” followed by the API message and its request_id. The retry button for a collection, when GoCardless answers mandate_is_inactive, gets the same treatment.

In an Odoo database in English these texts appear in English, as quoted here, whoever launches the collection. If a scheduled action launches it, such as a subscription renewal, the same applies: they are written with no one present and, in an English Odoo, they appear exactly as quoted: “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.”, “GoCardless mandate lost”, “The customer's GoCardless mandate is …, so it cannot be charged. Ask the customer for a new mandate.” and “GoCardless rejected the request.”

Why it is better not to retry

GoCardless says so in the description of invalid_state errors: the user must be informed and must not be allowed to retry. A cancelled mandate does not become active again by insisting; it needs a new signature from the customer or, in some cases and only with special GoCardless permissions, a reactivation.

Diagram: what GoCardless answers with mandate_is_inactive and what Odoo does with the connector
Diagram drawn from the connector's code (17.0, 18.0, 19.0 and 20.0) and from GoCardless's documentation.

What to do

  • Check the transaction message and the connector note on the customer's record. The transaction is opened from the invoice, with the “Payment Transaction” button at the top; the transactions menu only shows in developer mode, and in Odoo 20 it does not exist. Both texts state the mandate's status.
  • Ask the customer for a new mandate and collect the pending invoice with it.
  • If it happens often, check that GoCardless webhooks reach your Odoo: they are what warns you before the collection arrives. Even so, the connector requests lost events from GoCardless every hour.

Why does the connector check the mandate instead of simply archiving it?

Because it only archives what GoCardless confirms as dead. If the check says the mandate is active, archiving it would force the customer to sign again for no reason.

With our connector

In Odoo 17, 18, 19 and 20 the connector turns an API error into a clear task: the dead mandate leaves the list of payment methods, the customer is warned on their record, and the invoice stays pending until there is a mandate that works.

Keep reading

GoCardless MD01: mandate_cancelled and authorisation_disputed in a SEPA collectionSEPA code MD01 reaches GoCardless as mandate_cancelled or authorisation_disputed, on a failed, charged-back or cancelled collection. What Odoo does with it.GoCardless bank_account_closed: AC04 and MD07, the account no longer existsGoCardless bank_account_closed with AC04 (account closed) or MD07 (holder deceased): the mandate is cancelled. What Odoo does with the invoice and customer.GoCardless retry_failed error when retrying a collection from OdooGoCardless returns retry_failed when a payment has not failed or no longer allows retries. When Odoo shows “Retry collection” and what the connector does.
Checked in the connector's source code (version 17.0, 18.0, 19.0 and 20.0) and the linked sources

Sources

  • Module source code: flexigo_payment_gocardless: const.py, line 15 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 247 in 17.0 (d203ee6), line 247 in 18.0 (e2ab18b), line 247 in 19.0 (ce7f5a3) and line 258 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_provider.py, line 71 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: __manifest__.py, line 6 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/mandate
  • Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 278 in 17.0 (d203ee6), line 278 in 18.0 (e2ab18b), line 278 in 19.0 (ce7f5a3) and line 289 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: const.py, line 33 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_token.py, line 131 in 17.0 (d203ee6), line 131 in 18.0 (e2ab18b), line 131 in 19.0 (ce7f5a3) and line 130 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: const.py, line 134 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_provider.py, line 397 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 469 in 17.0 (d203ee6), line 469 in 18.0 (e2ab18b), line 468 in 19.0 (ce7f5a3) and line 487 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: const.py, line 117 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1148 in 17.0 (d203ee6), line 1148 in 18.0 (e2ab18b), line 1148 in 19.0 (ce7f5a3) and line 1155 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 495 in 17.0 (d203ee6), line 495 in 18.0 (e2ab18b), line 495 in 19.0 (ce7f5a3) and line 497 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 521 in 17.0 (d203ee6), line 521 in 18.0 (e2ab18b), line 521 in 19.0 (ce7f5a3) and line 523 in 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/events/mandate
  • Module source code: flexigo_payment_gocardless: __manifest__.py, line 31 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 321 in 17.0 (d203ee6), line 321 in 18.0 (e2ab18b), line 321 in 19.0 (ce7f5a3) and line 332 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1233 in 17.0 (d203ee6), line 1233 in 18.0 (e2ab18b), line 1233 in 19.0 (ce7f5a3) and line 1240 in 20.0 (688d86b)
  • Module source code: flexigo_payment_gocardless: models/payment_token.py, line 83 in 17.0 (d203ee6), line 83 in 18.0 (e2ab18b), line 83 in 19.0 (ce7f5a3) and line 82 in 20.0 (688d86b)
  • github.com/odoo/odoo/blob/20.0/addons/payment/i18n/payment.pot
  • Module source code: flexigo_payment_gocardless: models/payment_provider.py, line 462 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 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