# Mandate Events

Source: https://docs.gocardless.com/docs/collect-payments/events-and-webhooks/mandate-events

# Mandate Events

Mandate events are webhook notifications that GoCardless sends whenever a mandate's status changes. This guide covers the key events you should handle and what to do when they occur.

A webhook is a request that GoCardless sends to your server to alert you of an event. Adding support for webhooks allows you to receive real-time notifications from GoCardless when things happen in your account, so you can take automated actions in response.

> **Info:**
> For a full list of mandate events see the [API reference](/docs/api-reference/events/mandates).
>   For general guidance on receiving and processing webhooks see [Webhooks
>   overview](/docs/getting-started/stay-up-to-date-with-webhooks).

> **Info: Storing mandates**
> Keep a mandates table in your database linked to your internal customer records. Store the
>   GoCardless mandate ID and status so you can track the full lifecycle and react to events.

## Mandate lifecycle

A mandate moves through the following statuses:

| **Status**           | **Meaning**                                            |
| -------------------- | ------------------------------------------------------ |
| `pending.submission` | Mandate created, not yet sent to the banks             |
| `submitted`          | Sent to the banks for processing                       |
| `active`             | Confirmed by the banks, ready to collect against       |
| `failed`             | Could not be set up (e.g. invalid bank details)        |
| `cancelled`          | Cancelled by the customer, merchant, or GoCardless     |
| `expired`            | Expired due to inactivity (scheme-dependent)           |
| `consumed`           | Used for a one-off payment and can no longer be reused |

## Events to handle

### Mandate cancelled

Mandates can be cancelled by the customer via their bank, by you via the API, or by GoCardless. When this happens you'll receive:

```json
,
    "details": 
  }
}
```

The `details.cause` field tells you why the mandate was cancelled. Common values:

| **Cause**                  | **Meaning**                                   |
| -------------------------- | --------------------------------------------- |
| `bank_account_closed`      | Customer's bank account has been closed       |
| `invalid_bank_details`     | Bank details were incorrect                   |
| `direct_debit_not_enabled` | Account doesn't support Direct Debit          |
| `customer_approval_denied` | Customer cancelled at their bank              |
| `mandate_cancelled`        | Cancelled via the GoCardless dashboard or API |

When you receive this event you should:

- Update the mandate status in your database
- Prevent further payment attempts against this mandate
- Notify the customer that their Direct Debit has been cancelled and prompt them to set up a new one if needed

Cancelling a mandate yourself:

If you need to cancel a mandate programmatically:

```php
<?php
require 'vendor/autoload.php';

\$client = new \\GoCardlessPro\\Client([
'access_token' => \$currentUser->gocardlessAccessToken,
'environment' => \\GoCardlessPro\\Environment::SANDBOX
]);

\$mandate = \$client->mandates()->cancel(\$mandate_id);
print("Status: " . \$mandate->status);
```

```python
import gocardless_pro

def cancel_mandate(current_user, mandate_id):
client = gocardless_pro.Client(
access_token=current_user.gocardless_access_token,
environment='sandbox'
)

    mandate = client.mandates.cancel(mandate_id)
    print("Status: \".format(mandate.status))
```

```ruby
require 'gocardless_pro'

def cancel_mandate(current_user, mandate_id)
client = GoCardlessPro::Client.new(
access_token: current_user.gocardless_access_token,
environment: :sandbox
)

mandate = client.mandates.cancel(mandate_id)
puts "Status: #\"
end
```

```java
package com.myInvoicingApp;

public class CancelMandate \

\}
```

```javascript
const mandateId = "MD0000123ABC";
console.log(\`Cancelling mandate: \$\\`);

const mandate = await client.mandate.cancel(mandateId);
console.log(\`Status: \$\\`);
```

```csharp
const string mandateId = "MD0000123ABC";
Console.WriteLine($"Cancelling mandate: ");

var cancelResponse = await client.Mandates.CancelAsync(mandateId);
var mandate = cancelResponse.Mandate;
Console.WriteLine($"Status: ");
```

```go
ctx := context.TODO()
mandateCancelParams := gocardless.MandateCancelParams
mandate, err := client.Mandates().Cancel(ctx, mandateId, mandateCancelParams)
fmt.Printf("Status: %s%n", mandate.Status)
```

Only cancel a mandate if the customer has explicitly requested it.

### Mandate failed

If the mandate cannot be set up; for example because the bank account doesn't support Direct Debit or has been closed, you'll receive:

```json
,
    "details": 
  }
}
```

When you receive this event you should:

- Update the mandate status in your database
- Notify the customer and prompt them to set up a new mandate with a different bank account

Use `details.cause` to tailor your error message, the same cause values apply as for cancellations above

### Mandate expired

Mandates can expire after a period of inactivity under certain schemes. Treat an expired event the same way as a cancelled event, update your records and prompt the customer to set up a new mandate if needed.

```json

  }
}
```

### Mandate replaced

When a merchant enables the Merchant name on bank statement add-on, GoCardless moves their mandates from the GoCardless shared scheme identifier to the merchant's own identifier. For BACS mandates this results in a new mandate ID.

You'll receive:

```json

  }
}
```

This requires immediate action. If you attempt to collect a payment against the old mandate ID you'll receive an `invalid_state` error with reason `mandate_replaced`. Update the mandate ID in your database to `links.new_mandate` as soon as you receive this event.

## Full list of mandate events

For all possible mandate events and their details see the [API reference - mandate event types](/docs/api-reference/events/mandates).

## What's next?

  
#### [Setting Up Mandates](/docs/collect-payments/setting-up-mandates)

Create the mandate your event handlers will track through its lifecycle.

  
#### [Subscriptions](/docs/collect-payments/recurring-payments/subscriptions)

Subscription payments depend on the mandate remaining active.

  
#### [Billing Request Events](/docs/collect-payments/events-and-webhooks/billing-request-events)

Events fired earlier in the lifecycle, during mandate creation via Billing Requests.

  
#### [API Reference — Mandate Events](/docs/api-reference/events/mandates)

Full list of mandate event types and their details.