# Build a client to create mandates offline

Collecting your client’s payment authorisation via an online form isn’t always possible or doesn’t match how you would normally interact with your customers.

To help with this, we also offer paper and phone authorisation collection options (subject to regional availability).

> Please note: This feature only applies to merchants on our Custom and self-serve Pro packages, and with our Custom Payment Pages feature enabled. If you’re currently on our Standard or Plus package and wish to upgrade, or would like this feature enabled please get in touch.

### **Collect paper or telephone authorisation from your customers**

[<u>This page</u>](https://hub.gocardless.com/s/article/Paper-and-phone-authorisation) details the steps required for you to collect authorisation this way. Please ensure that you read it and are comfortable with the compliance requirements.

If you're implementing offline mandates for ACH, please follow the instructions on [<u>this page</u>](https://hub.gocardless.com/s/article/Paper-and-phone-authorization-ACH?language=en_GB).

If you are interested in using one or both of these methods but haven’t yet had this feature enabled on your account, please see [<u>here</u>](https://hub.gocardless.com/s/article/Paper-and-phone-authorisation) for more information on how to get this set up.

### **Build a client to create mandates offline**

There are two approaches you may take based on your current integration and future plans.

1. Core Endpoints: This API supports bank debit features. Use it if you are already integrated with it and don’t intend to implement Instant Bank Pay..
2. Billing Requests API: This is our newest API, which supports both bank debit and open banking use cases. Use it if you intend to build open banking functionality in future.

### What are Billing Request Actions?

### Billing Request Actions

Whenever you create a Billing Request, it will have a list of `actions` that require completion before it’s possible to fulfil the request.

The possible actions are:

- `choose_currency`, have the payer choose from a list of supported currencies
- `collect_customer_details`, collect customer details required for the schemes
- `collect_bank_account`, create the bank account for the mandate/payment

- `confirm_payer_details`, confirm customer and bank account details provided by the payer

Once all required actions have been completed, the Billing Request will become `ready_to_fulfil`, and an integrator can use the [fulfil](https://developer.gocardless.com/api-reference/#billing-requests-fulfil-a-billing-request) action to create all associated resources.

### Which actions should I implement?

When [creating](https://developer.gocardless.com/api-reference#billing-requests-create-a-billing-request) a Billing Request, the response will show you which actions you need to implement to complete it. We will also go through the actions you need to implement in the following steps.

### Ordering and control flow

The actions presented on a Billing Request are unordered, but each action may have dependencies, or have other actions depending on it.

These are specified in the fields `completes_actions` and `requires_actions`.

Taking `collect_customer_details` as an example:

```json
{
  "type": "collect_customer_details",
  "required": true,
  "completes_actions": [],
  "requires_actions": ["choose_currency"],
  "status": "pending"
}
```

**Action \*\***`status`\*\* is either `pending` or `completed`.

`**requires_actions: **`Actions can only be executed if the actions listed in `requires_action` have been completed- in this example, we can't complete `collect_customer_details` until we've chosen the currency.

**`completes_actions: `**Actions can complete other actions, which can help streamline checkout flows. In this example, collect_customer_details does not complete any other action as a side effect.

For offline mandates, we suggest building the flow that process the actions in the order of:

1. `collect_customer_details`, requires the `choose_currency` action to be completed but this will be completed automatically when creating the ACH mandate via the Billing Request create API
2. `collect_bank_account`, collect the customer's bank account details
3. `confirm_payer_details`, as a scheme compliance rule it is required to crosscheck the details entered and confirm them

### Create an offline mandate via Billing Request API

Create a Billing Request that specifies the type of mandate you wish to create via the `mandate_request` field. In this example, we are specifying the scheme as ACH which will default the currency to USD.

For ACH specific mandates, you can provide the `authorisation_source` field to create an offline mandate. The `authorisation_source` field specifies the way in which the payer gave authorisation to the merchant. This is sometimes referred to as [SEC code](https://www.moderntreasury.com/learn/sec-codes). This field takes values of either `telephone`, `paper` or `web`.

Use the [Create a Billing Request](https://developer.gocardless.com/api-reference/#billing-requests-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" => "ach",
      "authorisation_source" => "telephone"
    ]
  ]
]);
```

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

client.billing_requests.create(params={
  "mandate_request": {
    "scheme": "ach",
    "authorisation_source": "telephone"
  }
})
```

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

@client.billing_requests.create(
  params: {
    mandate_request: {
      scheme: "ach",
      authorisation_source: "telephone"
    }
  }
)
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

BillingRequest billingRequest = client.billingRequests().create()
  .withMandateRequestScheme("ach")
  .withMandateRequestAuthorisationSource("telephone")
  .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({
  mandate_request: {
    scheme: "ach",
    authorisation_source: "telephone",
  },
});
```

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

var mandateRequest = new gocardless.BillingRequestCreateRequest.BillingRequestMandateRequest
{
  Scheme = "ach",
  AuthorisationSource = "telephone"
};

var resp = await gocardless.BillingRequests.CreateAsync(
  new GoCardless.Services.BillingRequestCreateRequest()
  {
    MandateRequest = mandateRequest,
  }
);

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

```HTTP
POST https://api.gocardless.com/billing_requests HTTP/1.1
{
  "billing_requests": {
    "mandate_request": {
        "scheme": "ach",
        "authorisation_source": "telephone"
    }
  }
}

```

```go
package main

import (
	gocardless "github.com/gocardless/gocardless-pro-go/v3"
)

accessToken := "your_access_token_here"
opts := gocardless.WithEndpoint(gocardless.SandboxEndpoint)
config, err := gocardless.NewConfig(accessToken, opts)
if err != nil {
	fmt.Printf("got err in initialising config: %s", err.Error())
	return
}
client, err := gocardless.New(config)
if err != nil {
	fmt.Println("error in initialisating client: %s", err.Error())
	return
}
billingRequestCreateParams := gocardless.BillingRequestCreateParams{
	MandateRequest: &gocardless.BillingRequestCreateParamsMandateRequest{
		Scheme: "ach",
		AuthorisationSource: "telephone",
  	},
}

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

```CLI
gc create billing_request \
  -d 'mandate_request[scheme]=ach' \
  -d 'mandate_request[authorisation_source]=telephone'
```

You’ll receive a full Billing Request resource back.

It will look like this, some detail omitted:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "payment_request": null,
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010PDF4WD",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    },
    "actions": [
      {
        "type": "collect_customer_details",
        "status": "pending"
      },
      {
        "type": "collect_bank_account",
        "status": "pending"
      }
    ]
  }
}
```

This completes the `choose_currency` action, and we can now continue with completing the rest of the Billing Request actions to set up this mandate.

### Action: collect_customer_details

### Action: `collect_customer_details`

Billing Requests aim to create billing resources against a customer, either a mandate (Direct Debit, PayTo or VRPs), an Instant Bank Payment, or both.

Payment schemes vary in what customer details you are required to collect. The `collect_customer_details` action is about collecting all the details required by either the mandate or the payment scheme, to ensure we meet regulatory needs.

As an example, we can created a Billing Request for ACH scheme:

```http
POST /billing_requests
{
  "billing_requests": {
    "mandate_request": {
       "scheme": "ach",
       "authorisation_source": "telephone"
    }
  }
}
```

This returns a Billing Request that looks like this:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010PDF4WD",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    },
    "actions": [
      {
        "type": "collect_customer_details",
        "required": true,
        "completes_actions": [],
        "requires_actions": [
          "choose_currency"
        ],
        "status": "pending",
        "collect_customer_details": {
          "incomplete_fields": {
            "customer": [
              "email",
              "given_name",
              "family_name"
            ],
            "customer_billing_detail": [
              "address_line1",
              "city",
              "postal_code",
              "country_code",
              "region",
              "ip_address"
            ]
          }
        }
      },
      ...,
    ],
    "resources": {
      "customer": {
        "id": "CU00016WDAM7BS",
        "created_at": "2021-04-08T14:06:30.977Z",
        "email": null,
        "given_name": null,
        "family_name": null,
        "company_name": null,
        "language": "en",
        "phone_number": null,
        "metadata": {}
      },
      "customer_billing_detail": {
        "id": "CBD000010PDF4WD",
        "created_at": "2021-04-08T14:06:30.997Z",
        "address_line1": null,
        "address_line2": null,
        "address_line3": null,
        "city": null,
        "region": null,
        "postal_code": null,
        "country_code": null,
        "swedish_identity_number": null,
        "danish_identity_number": null
      }
    }
  }
}
```

Note that:

- There is a `collect_customer_details `action, which is `pending`
- A new customer has been created for us, as the Billing Request wasn’t attached to an existing customer
- The `customer `and `customer_billing_detail `resources are presented back to us, and they have no filled fields

The `collect_customer_details` action is designed to help us collect the required information from our customers.

Taking a closer look at the action:

```json
{
  "type": "collect_customer_details",
  "required": true,
  "completes_actions": [],
  "requires_actions": ["choose_currency"],
  "status": "pending",
  "collect_customer_details": {
    "incomplete_fields": {
      "customer": ["email", "given_name", "family_name"],
      "customer_billing_detail": [
        "address_line1",
        "city",
        "postal_code",
        "country_code",
        "region",
        "ip_address"
      ]
    }
  }
}
```

The `collect_customer_details.incomplete_fields` object tells us what fields we need to collect, for both resources. Which fields are required changes depending on the schemes of the mandate (or payment).

We can complete this action by POST’ing to the [Collect customer details for the billing request](https://developer.gocardless.com/api-reference/#billing-requests-collect-customer-details-for-the-billing-request) endpoint.

Note that**:**

- For online mandates with `"authorisation_source": "web"`, you will need to provide payer's `ip_address` as a result of their completion of a mandate setup flow in their browser.
- For `paper` and `telephone` mandates, you will <u>still need to provide</u> an `ip_address` in the `customer_billing_detail`, however, this can just be a dummy `ip_address` (e.g. 192.0.0.0).

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

$client->billingRequests()->collectCustomerDetails("BR123", [
  "params" => [
    "customer" => [
      "email" => "user@example.com",
      "given_name" => "Frank",
      "family_name" => "Osborne"
    ],
    "customer_billing_detail" => [
      "address_line1" => "1 Somewhere Lane",
      "city" => "Los Angeles",
      "postal_code" => "90213",
      "country_code" => "US",
      "region" => "CA"
      "ip_address" => "192.0.2.1"
    ]
  ]
]);
```

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

client.billing_requests.collect_customer_details("BR123", params={
  customer: {
    email: "user@example.com"
    given_name: "Frank",
    family_name: "Osborne",
  },
  customer_billing_detail: {
    address_line1: "27 Acer Road",
    city: "Los Angeles",
    postal_code: "90213",
    country_code: "US",
    region: "CA",
    ip_address: "192.0.2.1"
  }
})
```

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

@client.billing_requests.collect_customer_details("BR123", {
  params: {
    customer: {
      email: "user@example.com"
      given_name: "Frank",
      family_name: "Osborne",
    },
    customer_billing_detail: {
      address_line1: "27 Acer Road",
      city: "Los Angeles",
      postal_code: "90213",
      country_code: "US",
      region: "CA",
      ip_address: "192.0.2.1"
    }
  }
})
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

client.billingRequests().collectCustomerDetails("BR123")
  .withCustomerEmail("user@example.com")
  .withCustomerGivenName("Frank")
  .withCustomerFamilyName("Osborne")
  .withCustomerBillingDetailAddressLine1("27 Acer Road")
  .withCustomerBillingDetailCity("Los Angeles")
  .withCustomerBillingDetailPostalCode("90213")
  .withCustomerBillingDetailCountryCode("US")
  .withCustomerBillingDetailRegion("CA")
  .withCustomerBillingDetailIpAddress("192.0.2.1")
  .execute();
```

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

const resp = await client.billingRequests.collectCustomerDetails("BR123", {
  customer: {
    email: "user@example.com"
    given_name: "Frank",
    family_name: "Osborne",
  },
  customer_billing_detail: {
    address_line1: "27 Acer Road",
    city: "Los Angeles",
    postal_code: "90213",
    country_code: "US",
    region: "CA",
    ip_address: "192.0.1.2"
  }
});
```

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

var customer = new GoCardless.Services.BillingRequestCollectCustomerDetailsRequest.BillingRequestCustomer
{
  Emil = "user@example.com"
  GivenName = "Frank",
  FamilyName = "Osborne",
};

var customerBillingDetail = new new GoCardless.Services.BillingRequestCollectCustomerDetailsRequest.BillingRequestCustomerBillingDetail
{
  AddressLine1 = "27 Acer Road",
  City = "Los Angeles",
  PostalCode = "90213",
  CountryCode = "US",
  Region = "CA",
  IpAddress = "192.0.1.2"
};

var resp = await gocardless.BillingRequests.CollectCustomerDetails("BR123",
  new BillingRequestCollectCustomerDetailsRequest
  {
    Customer = customer,
    CustomerBillingDetail = customerBillingDetail,
  });
```

```HTTP
POST /billing_requests/BRQ123/actions/collect_customer_details HTTP/1.1
{
  "data": {
    "customer": {
      "email": "user@example.com",
      "given_name": "Frank",
      "family_name": "Osborne"
    },
    "customer_billing_detail": {
      "address_line1": "27 Acer Road",
      "city": "Los Angeles",
      "postal_code": "90213",
      "country_code": "US",
      "region": "CA",
      "ip_address": "192.0.1.2"
    }
  }
}
```

```go
package main

import (
	gocardless "github.com/gocardless/gocardless-pro-go/v2"
)

accessToken := "your_access_token_here"
config, err := gocardless.NewConfig(accessToken, gocardless.WithEndpoint(gocardless.SandboxEndpoint))
if err != nil {
	fmt.Printf("got err in initialising config: %s", err.Error())
	return
}
client, err := gocardless.New(config)
if err != nil {
	fmt.Println("error in initialisating client: %s", err.Error())
	return
}

billingRequestCollectCustomerDetailsParams := gocardless.BillingRequestCollectCustomerDetailsParams{
  Customer: &gocardless.BillingRequestCollectCustomerDetailsParamsCustomer{
    GivenName:  "Frank",
    FamilyName: "Osborne",
    Email:      "user@example.com",
  },
  CustomerBillingDetail: &gocardless.BillingRequestCollectCustomerDetailsParamsCustomerBillingDetail{
    AddressLine1: "27 Acer Road",
    City:         "Los Angeles",
    PostalCode:   "90213",
    CountryCode:  "US",
    Region:       "CA",
    IpAddress:    "192.0.1.2"
  },
}

billingRequest, err := client.BillingRequests.CollectCustomerDetails(context, "BR123", billingRequestCollectCustomerDetailsParams)
```

As with all action endpoints, the response is the Billing Request. What we get back is:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "scheme": "ach",
      "currency": "USD",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010PDF4WD",
      "organisation": "OR123",
      "mandate_request": "MRQ123"
    },
    "actions": [
      {
        "type": "collect_customer_details",
        "required": true,
        "completes_actions": [],
        "requires_actions": [
          "choose_currency"
        ],
        "status": "completed",
        "collect_customer_details": {
          "incomplete_fields": {
            "customer": [],
            "customer_billing_detail": []
          }
        }
      },
      ...,
    ],
    "resources": {
      "customer": {
        "id": "CU00016WDAM7BS",
        "created_at": "2021-04-08T14:06:30.977Z",
        "email": "user@example.com",
        "given_name": "Frank",
        "family_name": "Osborne",
        "company_name": null,
        "language": "en",
        "phone_number": null,
        "metadata": {}
      },
      "customer_billing_detail": {
        "id": "CBD000010PDF4WD",
        "created_at": "2021-04-08T14:06:30.997Z",
        "address_line1": "27 Acer Road",
        "address_line2": null,
        "address_line3": null,
        "city": "Los Angeles",
        "region": null,
        "postal_code": "90213",
        "country_code": "US",
        "swedish_identity_number": null,
        "danish_identity_number": null
      }
    }
  }
}
```

Note that:

- The `collect_customer_details `action is now `completed`, meaning we can move on to other actions
- As a result of us collecting the details, our `customer `and `customer_billing_detail `has been populated with the details we collected

Most integrators will collect these details via web forms, filled by their payers. Integrators are expected to build forms that can collect all possible `customer` and `customer_billing_detail` fields (see the [Collect customer details](https://developer.gocardless.com/api-reference/#billing-requests-collect-customer-details-for-the-billing-request) schema) but only display the inputs required, as per `incomplete_fields`.

### Action: collect_bank_account

Depending on the scheme, we might need to collect bank account details before fulfilling the Billing Request. An example is a Direct Debit mandate, where we need to capture the payer’s bank in order to create Direct Debit payments against them.

As an example, we created a Billing Request for ACH scheme:

```http
POST /billing_requests
{
  "billing_requests": {
    "mandate_request": {
       "scheme": "ach",
       "authorisation_source": "telephone"
    }
  }
}
```

This returns a Billing Request that looks like this:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010PDF4WD",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    },
    "actions": [
      {
        "type": "collect_bank_account",
        "required": true,
        "completes_actions": [
          "choose_currency"
        ],
        "available_country_codes": [
          "US"
        ],
        "requires_actions": [],
        "status": "pending"
      },
      ...,
    ],
  }
}
```

Note that:

- There is a `collect_bank_account `action that is `pending`
- We have no `links.customer_bank_account`, confirming no bank account is attached

We can complete this action by POST’ing to the [Collect bank account for the billing request](https://developer.gocardless.com/api-reference/#billing-requests-collect-bank-account-for-the-billing-request) endpoint:

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

$client->billingRequests()->collectBankAccount("BRQ000010NMDMH2", [
  "params" => [
    "account_number" => "2715500356",
    "bank_code" => "026073150",
    "account_holder_name" => "Frank Osborne",
    "country_code" => "US",
    "account_type": "checking"
  ]
]);
```

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

client.billing_requests.collect_bank_account("BRQ000010NMDMH2", params={
  account_number: "2715500356",
  bank_code: "026073150",
  account_holder_name: "Frank Osborne",
  country_code: "US",
  "account_type": "checking",
})
```

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

@client.billing_requests.collect_bank_account("BRQ000010NMDMH2", {
  params: {
    account_number: "2715500356",
    bank_code: "026073150",
    account_holder_name: "Frank Osborne",
    country_code: "US",
    account_type: "checking",
  }
})
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

client.billingRequests().collectBankAccount("BRQ123")
  .withAccountNumber("2715500356")
  .withBankCode("026073150")
  .withAccountHolderName("Frank Osborne")
  .withCountryCode("US")
  .withAccountType("checking")
  .execute();
```

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

const resp = await client.billingRequests.collectBankAccount("BRQ123", {
  account_number: "2715500356",
  bank_code: "026073150",
  account_holder_name: "Frank Osborne",
  country_code: "US",
  account_type: "checking",
});
```

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

var resp = await gocardless.BillingRequests.CollectBankAccountAsync("BRQ123",
  new BillingRequestCollectBankAccountRequest
  {
    AccountNumber = "2715500356",
    BankCode = "026073150",
    AccountHolderName = "Frank Osborne",
    CountryCode = "US",
    AccountType = "checking",
  });
```

```HTTP
POST /billing_requests/BRQ123/actions/collect_bank_account HTTP/1.1
{
  "data": {
    "account_number": "2715500356",
    "bank_code": "026073150",
    "account_holder_name": "Frank Osborne",
    "country_code": "US",
    "account_type": "checking"
  }
}
```

```go
package main

import (
	gocardless "github.com/gocardless/gocardless-pro-go/v2"
)

accessToken := "your_access_token_here"
config, err := gocardless.NewConfig(accessToken, gocardless.WithEndpoint(gocardless.SandboxEndpoint))
if err != nil {
	fmt.Printf("got err in initialising config: %s", err.Error())
	return
}
client, err := gocardless.New(config)
if err != nil {
	fmt.Println("error in initialisating client: %s", err.Error())
	return
}

billingRequestCollectBankAccountParams := gocardless.BillingRequestCollectBankAccountParams{
  BankCode:          "026073150",
  CountryCode:       "US",
  AccountNumber:     "2715500356",
  AccountHolderName: "Frank Osborne",
  AccountType:       "checking",
}

billingRequest, err := client.BillingRequests.CollectBankAccount(context, "BRQ123", billingRequestCollectBankAccountParams)
```

As with all action endpoints, the response is the Billing Request. What we get back is:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010P52VRF",
      "customer_bank_account": "BA123",
      "organisation": "OR123"
    },
    "actions": [
      {
        "type": "collect_bank_account",
        "required": true,
        "completes_actions": [
          "choose_currency"
        ],
        "requires_actions": [],
        "status": "completed"
      },
      ...,
    ],
    "resources": {
      "customer_bank_account": {
        "id": "BA123",
        "created_at": "2021-04-08T15:30:36.019Z",
        "account_number_ending": "56",
        "account_holder_name": "FRANK OSBORNE",
        "account_type": "checking",
        "bank_name": "Community Federal Savings Bank",
        "currency": "USD",
        "country_code": "US",
        "metadata": {},
        "enabled": true,
        "links": {
          "customer": "CU00016WDAM7BS"
        }
      }
    }
  }
}
```

Note that:

- The `collect_bank_account `action is now `completed`, meaning we can move on to other actions
- As a result of us collecting the bank account, we have created a `customer_bank_account `resource and you can see the `links.customer_bank_account `ID has been set

### Action: confirm_payer_details

As part of scheme compliance, we need to ensure the payer was presented with a confirmation screen before fulfilling the Billing Request. All mandate requests will require this action.

As an example, we created a Billing Request for ACH scheme:

```http
POST /billing_requests
{
  "billing_requests": {
    "mandate_request": {
       "scheme": "ach",
       "authorisation_source": "telephone"
    }
  }
}
```

This returns a Billing Request that looks like this:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010PDF4WD",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    },
    "actions": [
      {
          "type": "confirm_payer_details",
          "required": true,
          "completes_actions": [],
          "requires_actions": [
              "collect_customer_details",
              "collect_bank_account"
          ],
          "status": "pending"
      }
      ...,
    ],
  }
}
```

Note that:

- There is a `confirm_payer_details `action that is `pending`
- The action is `required`- all mandate requests will require this
- The action requires `collect_customer_details `and `collect_bank_account`, as we can only show the confirmation page once these actions are completed.

We can complete this action by POST’ing to the [confirm payer details](https://developer.gocardless.com/api-reference/#billing-requests-confirm-the-customer-and-bankaccount-details) endpoint:

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

$client->billingRequests()->confirmPayerDetails("BR123");
```

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

client.billing_requests.confirm_payer_details("BR123")
```

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

@client.billing_requests.confirm_payer_details("BR123")
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

client.billingRequests().confirmPayerDetails("BR123").execute();
```

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

const resp = await client.billingRequests.confirmPayerDetails("BR123");
```

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

var resp = await gocardless.BillingRequests.ConfirmPayerDetailsAsync("BR123");
```

```HTTP
POST https://api.gocardless.com/billing_requests/BRQ123/actions/confirm_payer_details HTTP/1.1
```

```go
package main

import (
	gocardless "github.com/gocardless/gocardless-pro-go/v2"
)

accessToken := "your_access_token_here"
config, err := gocardless.NewConfig(accessToken, gocardless.WithEndpoint(gocardless.SandboxEndpoint))
if err != nil {
	fmt.Printf("got err in initialising config: %s", err.Error())
	return
}
client, err := gocardless.New(config)
if err != nil {
	fmt.Println("error in initialisating client: %s", err.Error())
	return
}

billingRequestFulfilParams := gocardless.BillingRequestFulfilParams{}
billingRequest, err := client.BillingRequests.Fulfil(context, "BR123", billingRequestFulfilParams)
```

As with all action endpoints, the response is the Billing Request. What we get back is:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "ready_to_fulfil",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "telephone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010P52VRF",
      "customer_bank_account": "BA0000QDWEEAFB",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    },
    "actions": [
      {
        "type": "confirm_payer_details",
        "required": true,
        "completes_actions": [],
        "requires_actions": [
            "collect_customer_details",
            "collect_bank_account"
        ],
        "status": "completed"
      },
      ...,
    ],
    "resources": {
      ...,
     }
    }
  }
}
```

Note that:

- The `confirm_payer_details` action is now `completed`, and the billing request is in `ready_to_fulfil` state.

We can now move on to fulfilling this Billing Request.

### Action: fulfil

Once the billing request is in `ready_to_fulfil `state we can complete setting up this mandate by POST'ing to the [billing request fulfil](https://developer.gocardless.com/api-reference/#billing-requests-fulfil-a-billing-request) endpoint.

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

$client->billingRequests()->fulfil("BR123");
```

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

client.billing_requests.fulfil("BR123")
```

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

@client.billing_requests.fulfil("BR123")
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
String accessToken = "your_access_token_here";
GoCardlessClient client = GoCardlessClient
    .newBuilder(accessToken)
    .withEnvironment(SANDBOX)
    .build();

client.billingRequests().fulfil("BR123").execute();
```

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

const resp = await client.billingRequests.fulfil("BR123");
```

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

var resp = await gocardless.BillingRequests.FulfilAsync("BR123");
```

```HTTP
POST https://api.gocardless.com/billing_requests/BRQ123/actions/fulfil HTTP/1.1
```

```go
package main

import (
	gocardless "github.com/gocardless/gocardless-pro-go/v2"
)

accessToken := "your_access_token_here"
config, err := gocardless.NewConfig(accessToken, gocardless.WithEndpoint(gocardless.SandboxEndpoint))
if err != nil {
	fmt.Printf("got err in initialising config: %s", err.Error())
	return
}
client, err := gocardless.New(config)
if err != nil {
	fmt.Println("error in initialisating client: %s", err.Error())
	return
}

billingRequestFulfilParams := gocardless.BillingRequestFulfilParams{}
billingRequest, err := client.BillingRequests.Fulfil(context, "BR123", billingRequestFulfilParams)
```

As with all action endpoints, the response is the Billing Request. What we get back is:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "fulfilled",
    "mandate_request": {
      "currency": "USD",
      "scheme": "ach",
      "authorisation_source": "teleohone"
    },
    "links": {
      "customer": "CU00016WDAM7BS",
      "customer_billing_detail": "CBD000010P52VRF",
      "customer_bank_account": "BA123",
      "organisation": "OR123",
      "mandate_request": "MRQ123"
    },
    "actions": [],
    "resources": {
      ...,
     }
    }
  }
}
```

#### Done!

The mandate has now been created and is ready to create payments against. The Billing Request is `fulfilled`, and cannot be modified.
