# Verified Mandates

Source: https://docs.gocardless.com/docs/collect-payments/setting-up-mandates/verified-mandates

# Verified Mandates

> **Info:**
> Verified Mandates is only available to approved integrators with the Verified Mandates upgrade.
>   This upgrade is enabled by default for merchants with Standard or Plus packages. [Contact
>   support](mailto:help@gocardless.com) to get access.

This guide shows how to create a Verified Mandate by creating a Billing Request which opts-into customer bank account verification, and sending the customer through a GoCardless hosted [Billing Request Flow](/docs/api-reference/billing-request-flow#create-a-billing-request-flow) to complete the verification.

By verifying the customer has access to the bank account the Direct Debit mandate will be created against, you can protect yourself against fraudulent payers.

### Before we begin: Availability and Preference

Verified Mandates use different mechanisms depending on the scheme of the mandate in the Billing Request.

Here is a full list of supported Bank Debit schemes, whether a verification mechanism is available, and whether scheme compliance requires a customer to perform the verification.

| **Scheme**          | **API**            | **Available**         | **Required by Scheme** |
| ------------------- | ------------------ | --------------------- | ---------------------- |
| 🇺🇸 ACH              | `ach`              | Yes                   | No                     |
| 🇸🇪 Autogiro         | `autogiro`         | Yes                   | Yes                    |
| 🇬🇧 Bacs             | `bacs`             | Yes                   | No                     |
| 🇦🇺 BECS             | `becs`             | No                    | -                      |
| 🇳🇿 BECS NZ          | `becs_nz`          | No                    | -                      |
| 🇩🇰 Betalingsservice | `betalingsservice` | No                    | -                      |
| 🇨🇦 PAD              | `pad`              | No                    | -                      |
| 🇪🇺 SEPA Core        | `sepa_core`        | Germany 🇩🇪, France 🇫🇷 | No                     |

To request verification for your mandate, you must set the `verify` attribute of the `mandate_request` to a level that matches your preference.

Verification preference can be one of:

- **minimum**: only verify if absolutely required, such as when part of scheme rules
- **recommended**: in addition to `minimum`, use Protect+ to decide if a payer should be verified
- **when_available**: if verification mechanisms are available, use them
- **always**: as `when_available`, but fail to create the Billing Request if a mechanism isn't available

> **Info:**
> Protect+ is only available to approved integrators with the corresponding upgrade. If you're
>   interested in trying it out, please [contact support](mailto:help@gocardless.com).

By default, all Billing Requests use the `recommended` verification preference. It uses Protect+ to determine if a payer is fraudulent or not. The verification mechanism is based on the response and the payer may be asked to verify themselves. If the feature is not available, `recommended` behaves like `minimum`.

If you never wish to take advantage of Protect+ and Verified Mandates as they are released in new schemes, please use the `minimum` verification preference.

> **Warning:**
> Whilst we continually improve our verification flows, not all banks are available or supported and
>   some flows may fail due to device-specific issues. We recommend only setting `when_available` or
>   `always` when you are happy with some potential impact on conversion in favour of drastically
>   reduced risk. To help optimise your flows we advise using the `recommended` setting. This can be
>   combined with our anti-fraud product [Protect+](/docs/optimise/prevent-fraud-with-protect-plus)
>   for increased protection and verification while maintaining good conversion rates.

### How-to

In this how-to, we'll opt for `when_available` to ensure we apply the verification if the scheme supports it. And as per our availability, we'll be creating a `bacs` mandate, as that scheme supports verification.

Let's begin!

> **Info:**
> To test the flow in the sandbox environment you will need [a sandbox
>   account](https://manage-sandbox.gocardless.com/sign-in) and [test bank
>   details](/docs/api-reference/local-bank-details).

### Create a Billing Request

Use the [Create a Billing Request](/docs/api-reference/billing-request#create-a-billing-request) endpoint:

```php
$client = new \GoCardlessPro\Client(array(
  'access_token' => 'your_access_token_here',
  'environment'  => \GoCardlessPro\Environment::SANDBOX
));

$client->billingRequests()->create([
  "params" => [
    "mandate_request" => [
      "scheme" => "bacs",
      "verify" => "when_available"
    ]
  ]
]);
```

```python

client = gocardless_pro.Client(access_token="your_access_token_here", environment='sandbox')

client.billing_requests.create(params=
})
```

```ruby
@client = GoCardlessPro::Client.new(
  access_token: "your_access_token",
  environment: :sandbox
)

@client.billing_requests.create(
  params: 
  }
)
```

```java

String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

BillingRequest billingRequest = client.billingRequests().create()
  .withMandateRequestScheme("bacs")
  .withMandateRequestVerify("when_available")
  .execute();
```

```javascript
const constants = require("gocardless-nodejs/constants");
const gocardless = require("gocardless-nodejs");
const client = gocardless("your_access_token_here", constants.Environments.Sandbox);

const billingRequest = await client.billingRequests.create(,
});
```

```cs
String accessToken = "your_access_token";
GoCardlessClient gocardless = GoCardlessClient.Create(accessToken, Environment.SANDBOX);

var mandateRequest = new GoCardless.Services.BillingRequestCreateRequest.BillingRequestMandateRequest
;

var resp = await gocardless.BillingRequests.CreateAsync(
  new GoCardless.Services.BillingRequestCreateRequest()
  
);

GoCardless.Resources.BillingRequest billingRequest = resp.BillingRequest;
```

```http
POST https://api.gocardless.com/billing_requests HTTP/1.1

  }
}
```

```go
package main

	gocardless "github.com/gocardless/gocardless-pro-go/v6"
)

accessToken := "your_access_token_here"
opts := gocardless.WithEndpoint(gocardless.SandboxEndpoint)
config, err := gocardless.NewConfig(accessToken, opts)
if err != nil 
client, err := gocardless.New(config)
if err != nil 

billingRequestCreateParams := gocardless.BillingRequestCreateParams,
}

billingRequest, err := client.BillingRequests.Create(context, billingRequestCreateParams)
```

```CLI
gc create billing_request \
  -d 'mandate_request[scheme]=bacs' \
  -d 'mandate_request[verify]=when_available'
```

This will create a new Billing Request, asking for a Bacs mandate and requesting a `when_available` verification preference.

The response will look like this:

```json
,
    "actions": [
      
    ]
  }
}
```

As Bacs supports verification, you'll see we have a `bank_authorisation` action in the Billing Request response. Note the action is required, which means we cannot fulfil this request without first completing the bank authorisation.

We can use Billing Request Flows to generate a checkout flow that guides the payer through these actions, including the verification via bank authorisation.

### Create a Billing Request Flow

Billing Request Flows can be created against Billing Requests, and provide an entry into a hosted GoCardless flow that completes whatever actions remain against the request.

Create a Billing Request Flow to retrieve a link that can be provided to your customer to complete the request:

```php
$client = new \GoCardlessPro\Client(array(
  'access_token' => 'your_access_token_here',
  'environment'  => \GoCardlessPro\Environment::SANDBOX
));

$client->billingRequestFlows()->create([
  "params" => [
    "redirect_uri" => "https://my-company.com/landing",
    "exit_uri" => "https://my-company.com/exit",
    "links" => [
      "billing_request" => "BRQ000010NMDMH2"
    ]
  ]
]);
```

```python

client = gocardless_pro.Client(access_token="your_access_token_here", environment='sandbox')

client.billing_request_flows.create(params=
})
```

```ruby
@client = GoCardlessPro::Client.new(
  access_token: "your_access_token",
  environment: :sandbox
)

@client.billing_request_flows.create(
  params: 
  }
)
```

```java

String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

BillingRequestFlow billingRequestFlow = client.billingRequestFlows().create()
  .withRedirectUri("https://my-company.com/landing")
  .withExitUri("https://my-company.com/exit")
  .withLinksBillingRequest("BRQ000010NMDMH2")
  .execute();
```

```javascript
const constants = require("gocardless-nodejs/constants");
const gocardless = require("gocardless-nodejs");
const client = gocardless("your_access_token_here", constants.Environments.Sandbox);

const billingRequestFlow = await client.billingRequestFlows.create(,
});
```

```cs
String accessToken = "your_access_token";
GoCardlessClient gocardless = GoCardlessClient.Create(accessToken, Environment.SANDBOX);

var resp = await gocardless.BillingRequestFlows.CreateAsync(
  new GoCardless.Services.BillingRequestFlowCreateRequest()
  ,
  }
);

GoCardless.Resources.BillingRequestFlow billingRequestFlow = resp.BillingRequestFlow;
```

```http
POST https://api.gocardless.com/billing_request_flows HTTP/1.1

  }
}
```

```go
package main

	gocardless "github.com/gocardless/gocardless-pro-go/v6"
)

accessToken := "your_access_token_here";
opts := gocardless.WithEndpoint(gocardless.SandboxEndpoint)
client, err := gocardless.New(accessToken, opts)

billingRequestFlowCreateParams := gocardless.BillingRequestFlowCreateParams
billingRequestFlowCreateParams.RedirectUri = "https://my-company.com/landing"
billingRequestFlowCreateParams.ExitUri = "https://my-company.com/exit"
billingRequestFlowCreateParams.Links.BillingRequest = "BRQ000010NMDMH2"
billingRequestFlow, err := client.BillingRequestFlows.Create(context, billingRequestFlowCreateParams)
```

```CLI
gc create billing_request_flow \
  -d "links[billing_request]= BRQ000010NMDMH2" \
  -d 'redirect_uri=https://my-company.com/landing' \
  -d 'exit_uri=https://my-company.com/exit'
```

This returns a new flow, which has an `authorisation_url` you should send to your customer:

```json

  }
}
```

### Redirect customer to authorisation link

Share your **authorisation link** from the response in Step 2, via a button on your website, SMS, email, or any other way you like.

Preview what your customer will see by following the steps below.

### What the customer will see

When the customer opens the authorisation link, they'll see a form that goes through the following steps. The example is shown for the 🇬🇧 **Bacs** scheme.

### Choose currency

_**Note: This portion of the screen will only be visible if the organisation accepts multiple currencies.**_

Choose a currency to change the currency and scheme for the billing request.

![currency selector screenshot](/images/docs/collect-payments/setting-up-mandates/verified-mandates/01_choose_currency.png)

### Collect customer details

_**Note: This screen is skipped if the details already exist, or the customer details have been locked.**_

Collect customer details in order to complete the billing request.

![bacs-01-customer-details](/images/docs/collect-payments/setting-up-mandates/verified-mandates/02_collect_customer_details.png)

### Collect bank details

**_Optional step: This step is only required when `verify` is set to `recommended` or `minimum`._**

Collect customer bank account details in order to complete the billing request.

![bacs-01b-bank-details](/images/docs/collect-payments/setting-up-mandates/verified-mandates/03_collect_bank_details.png)

### Select bank

**_Optional step: This step is required only when verify is set to `always` or `when_available`. It is sometimes required in supported schemes when using `Protect+` upgrade and the `recommended` option._**

Select bank in order to complete the billing request.

![bacs-01c-bank-select](/images/docs/collect-payments/setting-up-mandates/verified-mandates/04_select_bank.png)

### Start verification

Customers can start the verification process by clicking `Agree and continue` and scanning the QR code.

![bacs-02-bank-connect-request](/images/docs/collect-payments/setting-up-mandates/verified-mandates/05_start_verification.png)

This is an example of a possible verification mechanism, but different schemes and banks have different flows, and we reserve the right to change the mechanism to better suit specific schemes or business needs.

### Complete verification

The customer should log in to their bank account and authorise GoCardless to read their details. This is an example of the Monzo mobile flow.

![bacs-03-bank-authorisation](/images/docs/collect-payments/setting-up-mandates/verified-mandates/bacs-03-bank-authorisation.png)

### Select bank account

**_Optional step: This step is required only if the payer provided consent to access multiple accounts eligible for Direct Debit set up._**

The customer should select the bank account they would like to set up Direct Debit with.

![bacs-03b-select-bank-account](/images/docs/collect-payments/setting-up-mandates/verified-mandates/07_select_bank_account.png)

### Confirm details

Preview the details and Direct Debit guarantee (changes per scheme) before agreeing to set up the mandate.

![bacs-04-confirm-details](/images/docs/collect-payments/setting-up-mandates/verified-mandates/08_confirm_details.png)

### Success

Everything has been set up, and we show a success screen before redirecting back to the Billing Request Flow `redirect_uri`.

![bacs-05-success](/images/docs/collect-payments/setting-up-mandates/4.jpg)

### Done!

The Direct Debit mandate has now been created, and the Billing Request is `fulfilled`. Note that the mandate will have a `verified_at` timestamp set to the last successful verification, which can be used to identify which mandates have been verified.

You can use the [Create Payments](/docs/api-reference/payment#create-a-payment) endpoint to create new payments against the mandate or use the mandate in other resources such as when [Creating a Subscription](/docs/api-reference/subscription#create-a-subscription).

### Examples in other schemes

### 🇺🇸 ACH

For the ACH scheme, the verification is processed by the external provider.

![ach-flow-example-1](/images/docs/collect-payments/setting-up-mandates/verified-mandates/01_personal_details_and_access_info.png)

![ach-flow-example-2](/images/docs/collect-payments/setting-up-mandates/verified-mandates/02_plaid_flow.png)

![ACH VM Confirmation page](/images/docs/collect-payments/setting-up-mandates/verified-mandates/03_confirmation.png)

### 🇸🇪 Autogiro

> **Info: BankId scenario simulators**
> We recommend testing out the BankId success and failure scenarios using our sandbox environment
>   BankId scenario simulators by following the steps outlined in our
>   [guide](https://developer-preview.gocardless.io/resources/bankid-scenario-simulators).

For the Autogiro scheme, it is a requirement to put all the payers setting up the Direct Debit Mandate through BankId verification. This means you will need the Verified Mandates upgrade enabled in order to have mandates set up in the Autogiro scheme.

![bankid-flow-example-1](/images/docs/collect-payments/setting-up-mandates/verified-mandates/01_bankid_collect_details.png)

![bankid-flow-example-2](/images/docs/collect-payments/setting-up-mandates/verified-mandates/02_bankid_screens.png)

![bankid-flow-example-3](/images/docs/collect-payments/setting-up-mandates/verified-mandates/03_confirmation-2.png)

### Frequently asked questions

### How can I test this flow if I have the upgrade for using Protect+?

Set the `verify` option on the `billing_request` to `always` to test the flow.

This means that the institution the payer is trying to use is not supported by our Account Information Service (AIS) provider.

![bacs-verified-mandates-bank-not-supported](/images/docs/collect-payments/setting-up-mandates/verified-mandates/bacs-verified-mandates-bank-not-supported.png)

### How do I know if the verification was successful?

A timestamp for `authorised_at` will be set on the `bank_authorisation` resource for the billing request. The created mandate will also include a 'verified' badge next to the Mandate verification status on the merchant dashboard.

![bacs-verified-mandate-badge](/images/docs/collect-payments/setting-up-mandates/verified-mandates/bacs-verified-mandate-badge.png)

## What's next?

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

Create standard Direct Debit mandates using the Billing Requests API.

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

Handle events fired during the verified mandate setup flow.

  
#### [Offline Mandates](/docs/collect-payments/setting-up-mandates/offline-mandates)

Collect mandates via paper or phone authorisation.

  
#### [Protect+](/docs/optimise/prevent-fraud-with-protect-plus)

Use Protect+ with the recommended verification setting for optimal conversion and fraud
    protection.