Mandates: Responding to Mandate Events

Managing mandates

In the API reference, you’ll find a full list of all the events that can happen to mandates (and other resources too). We’ll take you through the most important cases here.

You don’t necessarily need to handle all of the possible events: for example, when a mandate is sent to the banks for processing, this doesn’t necessarily need to be reflected in your product, but your users will definitely want to know when a customer cancels. Below, we’ll cover the most important paths to be able to deal with.

Every partner integration is different, so this guide does its best to explain the cases you should handle events and give you some ideas on how to provide the best experience for your users.

Mandate cancellations

Mandates can be cancelled at any time. For example, end customers can cancel their mandates by contacting their bank, or your user can cancel a mandate from their GoCardless Dashboard. When this happens, you’ll receive a webhook with a resource_type of “mandates”, and an action of “cancelled”.

We’ve already written some sample code in the previous step for handling mandate cancellations events.

You should build on that basic framework, thinking about what it makes sense to do in your product in response to a cancellation - for example, you might want to:

  • update your UI, so your user can see that the end customer no longer has an active mandate

  • deactivate the end customer’s access to the service being provided

  • email your user to let them know that no more payments will be collected until a new mandate is set-up

The details attribute on the event includes an origincause and description to help you understand why and how the mandate came to be cancelled - you can see a full list of possible attributes for this and other webhook events in the API reference.

You can also cancel mandates yourself via the API if an end customer should no longer be charged. You should only do this if it’s requested by your user:

1<?php 2require 'vendor/autoload.php'; 3 4$client = new \GoCardlessPro\Client([ 5 'access_token' => $currentUser->gocardlessAccessToken, 6 'environment' => \GoCardlessPro\Environment::SANDBOX 7]); 8 9$mandate = $client->mandates()->cancel($mandate_id); 10print("Status: " . $mandate->status);

Mandates can also, in rare cases, expire: when you see the expired action, you’ll probably want to take similar steps as you would for a cancellation.

Mandate failures

Once you’ve created a mandate, it takes a couple of days to be submitted to the bank and fully set up. In certain cases (for example, if the customer’s bank account doesn’t support Direct Debit or the bank account has been closed), the mandate setup will fail, and you’ll receive an event with resource_type “mandates” and action “failed”.

When a mandate fails to be set up, you could consider:

  • emailing the end customer to tell them what went wrong, and suggesting they try again with a different bank account (the cause under the event’s details includes an explanation of what went wrong - either invalid_bank_details, bank_account_closed, bank_account_transferred, direct_debit_not_enabled or other)

  • updating your UI, so your user can see that the end customer no longer has an active mandate

Read more on our user experience guide about requesting a Direct Debit from a customer and clearly displaying error states.

Mandate replacements

If one of your users switches between the GoCardless Standard, Plus and Pro packages, they’ll get their own “scheme identifier” - this means that their own name appears on their customers’ bank statements instead of “”.

When this happens, GoCardless will move the merchant's existing mandates from the GoCardless shared scheme identifier to the user’s own personal one.

For Bacs (UK) mandates, this leads to a change in the mandates’ IDs. You will be alerted by being sent a webhook event with resource_type “mandates” and action “replaced”. The links[new_mandate] attribute will include the ID of the new mandate. If you try to create a payment or subscription against the mandate, you’ll get an error with the “invalid_state” type and the “mandate_replaced” reason, again with a links[new_mandate] attribute.

You should update the mandate ID recorded in your database, as you’ll need to use the new mandate’s ID to charge the customer in the future.

Responding to Billing Requests events

Testing webhooks with the CLI

Supporting mandates set up outside of your product

What's Next?

FX Payments