Taking Direct Debit payments using Billing Requests and Custom Payment Pages
What is a billing request?
For the purposes of this tutorial, a Billing Request
is a wrapper around all of the GoCardless APIs required to take a payment from a customer. This allows you, the integrator, to define desired outcomes upfront (for example, "I want to take a payment from X") and guides you through the process to achieve them.
What is the aim of this tutorial?
This tutorial aims to familiarise beginners with using Billing Requests
to collect Direct Debit payments using Custom Payment Pages. It will not cover Instant Bank payments (IBP) or VerifiedMandates (VM).
Getting started
For this tutorial, you will need:
An API token
The GoCardless client library of your choice configured in your language of choice
A Creditor to collect payments against
Creating a Billing Request
We can start by creating a Billing Request
. This will allow us to request a Mandate
to take a payment against that is linked to a Creditor
.
1POST https://api.gocardless.com/billing_requests HTTP/1.1
2Content-Type: application/json
3{
4 "billing_requests": {
5 "mandate_request": {
6 "scheme": "bacs"
7 },
8 "links": {
9 "creditor": "CR123"
10 }
11 }
12}
13
14HTTP/1.1 201 Created
15Location: /billing_requests/BRQ123
16Content-Type: application/json
17{
18 "billing_requests": {
19 "id": "BRQ123",
20 "created_at": "2023-03-22T15:20:08.397Z",
21 "status": "pending",
22 "mandate_request": {
23 "currency": "GBP",
24 "scheme": "bacs",
25 "links": {}
26 },
27 ...
28}
For the purposes of this tutorial, we only need to keep track of the ID of the Billing Request
: BRQ123
We request the desired scheme
, in this instance, we are going to use bacs
for a GBP mandate. If you want to collect in EUR, use sepa_core
. We link the Billing Request
to the creditor we wish to pay out to, CR123
.
In the next steps, we complete the required Billing Request
actions
to fulfil our request. The actions
returned from the API describe steps that must be taken for a Billing Request
to be fulfilled
. They can change depending on the type of payment being taken or set up (e.g a Direct Debit or Instant Bank payment). We don’t need to worry about them too much in this tutorial - but it’s good to be aware of them! You can read more about them here if you’re interested.
Collect customer details
Next, we need to collect the details of our customer
1POST https://api.gocardless.com/billing_requests/BRQ123/actions/collect_customer_details HTTP/1.1
2Content-Type: application/json
3{
4 "data": {
5 "customer": {
6 "email": "alice@example.com",
7 "given_name": "Alice",
8 "family_name": "Smith"
9 },
10 "customer_billing_detail": {
11 "address_line1": "1 Somewhere Lane",
12 "city": "London",
13 "postal_code": "E5 8EE",
14 "country_code": "GB"
15 }
16 }
17}
18
19HTTP/1.1 200
20Content-Type: application/json
21{
22 "billing_requests": {
23 "id": "BRQ123",
24 ...
25 "links": {
26 "customer": "CU123",
27 "customer_billing_detail": "CBD123"
28 },
29 ...
30 },
31 "resources": {
32 "customer": {
33 "id": "CU123",
34 "created_at": "2021-03-22T12:20:04.238Z",
35 "email": "alice@example.com",
36 "given_name": "Alice",
37 "family_name": "Smith",
38 ...
39 },
40 "customer_billing_detail": {
41 "id": "CBD123",
42 "created_at": "2021-03-22T12:20:04.374Z",
43 "address_line1": "1 Somewhere Lane",
44 ...
45 }
46 }
47}
Note we now have a link to a Customer
and Customer Billing Detail
Collect bank account details
Now we need to collect the customer bank account details to be able to create a Mandate
against the customer.
1POST https://api.gocardless.com/billing_requests/BRQ123/actions/collect_bank_account HTTP/1.1
2Content-Type: application/json
3{
4 "data": {
5 "account_number": "55779911",
6 "branch_code": "200000",
7 "account_holder_name": "Alice Smith",
8 "country_code": "GB"
9 }
10}
11
12HTTP/1.1 200
13Content-Type: application/json
14{
15 "billing_requests": {
16 "id": "BRQ123",
17 ...
18 "links": {
19 "customer": "CU123",
20 "customer_billing_detail": "CBD123"
21 },
22 ...
23 },
24 "resources": {
25 "customer": {
26 "id": "CU123",
27 "created_at": "2021-03-22T12:20:04.238Z",
28 "email": "alice@example.com",
29 "given_name": "Alice",
30 "family_name": "Smith",
31 ...
32 },
33 "customer_billing_detail": {
34 "id": "CBD123",
35 "created_at": "2021-03-22T12:20:04.374Z",
36 "address_line1": "1 Somewhere Lane",
37 ...
38 },
39 "customer_bank_account": {
40 "id": "BA123",
41 "created_at": "2021-03-22T12:20:04.374Z",
42 "account_holder_name": "Alice Smith",
43 "account_number_ending": "11",
44 "country_code": "GB",
45 "currency": "GBP",
46 "bank_name": "BARCLAYS BANK PLC",
47 "enabled": true,
48 "links": {
49 "customer": "CU123"
50 }
51 }
52 }
53}
Confirm Payer details
This is needed when you have a Mandate Request. As a scheme compliance rule, we are required to allow the payer to crosscheck the details entered by them and confirm them.
For a live integration, you would want to show a summary of the payer details (the information we took in the previous two steps) and give the option to cancel. For the purposes of this tutorial, we can just call the confirm endpoint.
1POST https://api.gocardless.com/billing_requests/BRQ123/actions/confirm_payer_details HTTP/1.1
2
3HTTP/1.1 200
4Content-Type: application/json
5{
6 "billing_requests": {
7 "id": "BRQ123",
8 "mandate_request": {
9 "currency": "GBP",
10 "scheme": "bacs",
11 "links": {
12 "mandate": "MD123"
13 }
14 },
15 "actions": [
16 ...
17 {
18 "type": "confirm_payer_details",
19 "required": true,
20 "requires_actions": [
21 "collect_customer_details",
22 "collect_bank_account"
23 ],
24 "status": "completed"
25 }
26 ...
27 ]
28 }
29}
We want to keep track of our Mandate ID for the step where we take a payment.
Fulfil
This step ‘executes’ the Billing Request
, using the contents of our request to create a Mandate
. This will create a Mandate
within GoCardless to take payments against. The fulfil
action is the step where the collected Information will be submitted to our partner bank(s).
It can be batched with the confirm payer details call above. It is a separate step (and API call) as we may sometimes want to combine different types of payment (e.g Open banking) with the creation of a Mandate
.
1POST https://api.gocardless.com/billing_requests/BRQ123/actions/fulfil HTTP/1.1
2
3HTTP/1.1 200
4Content-Type: application/json
5{
6 "billing_requests": {
7 "id": "BRQ123",
8 "status": "fulfilled",
9 ...
10 },
11 ...
12}
Taking a payment
We can now use the GoCardless Payments API to take a payment against our newly created Mandate
!
1POST https://api.gocardless.com/payments HTTP/1.1
2Content-Type: application/json
3{
4 "payments": {
5 "amount": 1200,
6 "currency": "GBP",
7 "reference": "Wine Box",
8 "metadata": {
9 "order_dispatch_date": "2023-03-29"
10 },
11 "links": {
12 "mandate": "MD123"
13 }
14 }
15}
16
17HTTP/1.1 201 Created
18Location: /payments/PM123
19Content-Type: application/json
20{
21 "payments": {
22 "id": "PM123",
23 "created_at": "2023-03-22T17:01:06.000Z",
24 "charge_date": "2023-03-24",
25 "amount": 1200,
26 "currency": "GBP",
27 "status": "pending_submission",
28 "reference": "WINEBOX001",
29 "metadata": {
30 "order_dispatch_date": "2023-03-29"
31 },
32 ...
33 "links": {
34 "mandate": "MD123",
35 "creditor": "CR123"
36 }
37 }
38}
Note that we charge the amount in the lowest denomination for the currency (e.g. pence in GBP, cents in EUR).
We can see the date that the payment will be taken by looking at the charge_date
in the response.