One cause, four codes
| SEPA Core code | GoCardless text |
|---|---|
| MS02 | The customer refused to accept this payment. |
| MS03, RR04 | The payment failed but the reason for the failure was not provided, usually for regulatory reasons. |
| SL01 | The payment failed due to a restriction on Direct Debit payments from the payer's bank account. |
All three rows come from the failed payments table (payments · failed) in GoCardless's SEPA Core documentation. Unlike other causes, none of them says the mandate is cancelled: the customer is still authorised for you to collect, even though this particular debit did not go through.

What lies behind each code
MS02 is the clearest answer: the customer told their bank not to pay that direct debit. The connector notes in its code that this is the combination it saw in a test SEPA payment in the GoCardless sandbox. MS03 and RR04 are the opposite: the payment fails and the bank gives no reason, usually for regulatory reasons, so the only way to find out what happened is to ask the customer. SL01 points to the account: their bank limits the direct debits that can be charged to it, and only the account holder can change that with their bank.
With MS02, RR04 and SL01, presenting the debit again without first talking to the customer usually ends the same way and may cost another fee. MS03 has an exception: according to Success+ guidance, in Austria, Belgium, Germany, Luxembourg and Slovakia MS03 counts as insufficient funds, and Success+ can retry it. If so, the event arrives with will_attempt_retry set to true.
What Odoo does with the connector
The transaction is opened from the invoice, with the “Payment Transaction” button at the top; the transactions menu only appears in developer mode, and in Odoo 20 it does not exist. The connector stores the cause in the “GoCardless Cause” field, not the SEPA code, and shows “GoCardless could not collect this payment (refer_to_payer).”. Then it follows what the event says:
- If
will_attempt_retrycomes astrue, the transaction is “Pending”, the “Success+ Will Retry” checkbox is ticked and the message says so: “Success+ will retry it automatically; there is nothing to do.”. The retry button does not appear. - Otherwise, the transaction moves to “Error” and the “Retry collection” button appears, if retries remain. If Odoo had already treated the collection as done, the connector cancels its payment and the invoice becomes due for payment again.
- The mandate is left alone.
refer_to_payeris not among the causes for which the connector archives a mandate, so the customer's payment method remains available for the next collection.
This last point is deliberate: archiving the mandate over a one-off refusal would force the customer to sign a new one for no reason.
The connector writes these texts in English, so in an English-language Odoo they appear exactly as quoted here, whether a user or a scheduled action triggers them: “GoCardless could not collect this payment (refer_to_payer).” and “Success+ will retry it automatically; there is nothing to do.”.
What to do for each code
Odoo does not tell you which of the four codes arrived: the connector only stores the cause. You see the code in GoCardless. According to its help centre, the reason for each failure appears in the payment timeline, in the Dashboard (“You are able to view the reason for a payment failure in the status timeline of the payment in your GoCardless dashboard.”). In advanced mode, the exact code also comes in the event (details.reason_code), and the Dashboard keeps the deliveries of the last 3 months under Developers > Webhooks, with their content.
| Code | First step |
|---|---|
| MS02 | Ask the customer why they refused the collection: amount, date or a disagreement with the invoice. |
| MS03 | Check “Success+ Will Retry”: in Austria, Belgium, Germany, Luxembourg and Slovakia, Success+ can retry MS03 as insufficient funds. If it is not ticked, ask the customer to check with their bank. |
| RR04 | Ask the customer to check with their bank: GoCardless does not receive the reason. |
| SL01 | The customer has to lift the direct debit limit on their account, or give you another one. |
Once the customer confirms the collection will go through, use “Retry collection” on the transaction and confirm the fee notice. The connector replies “Retry requested. GoCardless will confirm the new charge date.” and leaves it pending. Remember the limit: a payment can be retried at most 3 times (“Payments can be retried up to 3 times.”).
Is the mandate cancelled if the customer refuses a collection?
No. GoCardless's documentation does not say so for this cause, and the connector does not archive the mandate on refer_to_payer. If the customer wants to stop paying you by direct debit, they will cancel the mandate with their bank, and that arrives with another cause, mandate_cancelled.

With our connector
In Odoo 17, 18, 19 and 20 the connector turns refer_to_payer into an outstanding invoice with the cause in view and a mandate that remains valid. It does not guess the SEPA code: Odoo stores the cause on the transaction, and you check the code in GoCardless. The decision to collect again is yours, after talking to the customer.
Keep reading
Checked in the connector's source code (version 17.0, 18.0, 19.0 and 20.0) and the linked sources
Sources
- docs.gocardless.com/docs/api-reference/events/payment
- docs.gocardless.com/docs/api-reference/payment
- 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: const.py, line 79 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: const.py, line 76 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: const.py, line 71 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 725 in 17.0 (d203ee6), line 725 in 18.0 (e2ab18b), line 724 in 19.0 (ce7f5a3) and line 748 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 729 in 17.0 (d203ee6), line 729 in 18.0 (e2ab18b), line 728 in 19.0 (ce7f5a3) and line 752 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 754 in 17.0 (d203ee6), line 754 in 18.0 (e2ab18b), line 753 in 19.0 (ce7f5a3) and line 777 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: const.py, line 122 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: views/payment_transaction_views.xml, line 13 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 436 in 17.0 (d203ee6), line 436 in 18.0 (e2ab18b), line 436 in 19.0 (ce7f5a3) and line 438 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 356 in 17.0 (d203ee6), line 356 in 18.0 (e2ab18b), line 356 in 19.0 (ce7f5a3) and line 358 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1016 in 17.0 (d203ee6), line 1016 in 18.0 (e2ab18b), line 1016 in 19.0 (ce7f5a3) and line 1031 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1022 in 17.0 (d203ee6), line 1022 in 18.0 (e2ab18b), line 1022 in 19.0 (ce7f5a3) and line 1037 in 20.0 (688d86b)
- 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/optimise/reduced-failed-payments-with-success-plus
- Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 63 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 418 in 17.0 (d203ee6), line 418 in 18.0 (e2ab18b), line 417 in 19.0 (ce7f5a3) and line 432 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: views/payment_transaction_views.xml, line 27 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
- github.com/odoo/odoo/blob/20.0/addons/payment/i18n/payment.pot
- github.com/odoo/odoo/blob/20.0/addons/payment/views/payment_transaction_views.xml
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1083 in 17.0 (d203ee6), line 1083 in 18.0 (e2ab18b), line 1083 in 19.0 (ce7f5a3) and line 1090 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 1063 in 17.0 (d203ee6), line 1063 in 18.0 (e2ab18b), line 1063 in 19.0 (ce7f5a3) and line 1070 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: i18n/flexigo_payment_gocardless.pot, line 567 in 17.0 (d203ee6), line 567 in 18.0 (e2ab18b), line 567 in 19.0 (ce7f5a3) and line 569 in 20.0 (688d86b)
- Module source code: flexigo_payment_gocardless: models/payment_transaction.py, line 461 in 17.0 (d203ee6), line 461 in 18.0 (e2ab18b), line 460 in 19.0 (ce7f5a3) and line 479 in 20.0 (688d86b)
- docs.gocardless.com/docs/api-reference/webhooks
- github.com/odoo/odoo/blob/17.0/odoo/http.py
- support.gocardless.com/hc/en-gb/articles/360001467265
- Module source code: flexigo_payment_gocardless: const.py, line 66 in 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) and 20.0 (688d86b)
- github.com/odoo/odoo/blob/20.0/addons/account_payment/views/account_move_views.xml
