Let’s add our first customer, and set them up with a Direct Debit mandate.

  • A customer is a person or company we want to take payments from.
  • A mandate is an authorisation from a customer to take payments from their bank account - once you have a mandate set up, you can charge the customer with future API calls. (A customer can have multiple mandates, but you’ll almost always only want one.)

When setting up a mandate, your setup process (e.g. a set of payment screens on a screen or a paper form) must comply with Direct Debit scheme rules. To make this easy for you, GoCardless hosts secure and fully-compliant payment pages that have been translated into many European languages.

The Redirect Flow API lets you use these hosted payment pages. Once your customer enters their bank details, you will be set up with everything you need at once: a customer, a customer bank account, and a mandate.

If you’d like to build your own white-label payment pages, just get in touch.

We’ll use the API to create a redirect flow, generating a URL which we can send our customer to in order to have them set up a mandate.

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

$client = new \GoCardlessPro\Client([
    // We recommend storing your access token in an
    // environment variable for security, but you could
    // include it as a string directly in your code
    'access_token' => getenv('GC_ACCESS_TOKEN'),
    // Change me to LIVE when you're ready to go live
    'environment' => \GoCardlessPro\Environment::SANDBOX
]);

$redirectFlow = $client->redirectFlows()->create([
    "params" => [
        // This will be shown on the payment pages
        "description" => "Wine boxes",
        // Not the access token
        "session_token" => "dummy_session_token",
        "success_redirect_url" => "https://developer.gocardless.com/example-redirect-uri/",
        // Optionally, prefill customer details on the payment page
        "prefilled_customer" => [
          "given_name" => "Tim",
          "family_name" => "Rogers",
          "email" => "tim@gocardless.com",
          "address_line1" => "338-346 Goswell Road",
          "city" => "London",
          "postal_code" => "EC1V 7LQ"
        ]
    ]
]);

// Hold on to this ID - you'll need it when you
// "confirm" the redirect flow later
print("ID: " . $redirectFlow->id . "<br />");

print("URL: " . $redirectFlow->redirect_url);
import os
import gocardless_pro

client = gocardless_pro.Client(
    # We recommend storing your access token in an
    # environment variable for security, but you could
    # include it as a string directly in your code.
    access_token=os.environ['GC_ACCESS_TOKEN'],
    # Change this to 'live' when you are ready to go live.
    environment='sandbox'
)

redirect_flow = client.redirect_flows.create(
    params={
        "description" : "Ale Casks", # This will be shown on the payment pages
        "session_token" : "dummy_session_token", # Not the access token
        "success_redirect_url" : "https://developer.gocardless.com/example-redirect-uri/",
        "prefilled_customer": { # Optionally, prefill customer details on the payment page
            "given_name": "Tim",
            "family_name": "Rogers",
            "email": "tim@gocardless.com",
            "address_line1": "338-346 Goswell Road",
            "city": "London",
            "postal_code": "EC1V 7LQ"
        }
    }
)

# Hold on to this ID - we'll need it when we
# "confirm" the redirect flow later
print("ID: {} ".format(redirect_flow.id))
print("URL: {} ".format(redirect_flow.redirect_url))
require 'gocardless_pro'

client = GoCardlessPro::Client.new(
  # We recommend storing your access token in an
  # environment variable for security, but you could
  # include it as a string directly in your code
  access_token: ENV['GC_ACCESS_TOKEN'],
  # Remove the following line when you're ready to go live
  environment: :sandbox
)

redirect_flow = client.redirect_flows.create(
  params: {
    description: 'Lager Kegs', # This will be shown on the payment pages
    session_token: 'dummy_session_token', # Not the access token
    success_redirect_url: 'https://developer.gocardless.com/example-redirect-uri/',
    prefilled_customer: { # Optionally, prefill customer details on the payment page
      given_name: 'Tim',
      family_name: 'Rogers',
      email: 'tim@gocardless.com',
      address_line1: '338-346 Goswell Road',
      city: 'London',
      postal_code: 'EC1V 7LQ'
    }
  }
)

# Hold on this ID - we'll need it when we
# "confirm" the redirect flow later
puts "ID: #{redirect_flow.id}"
puts "URL: #{redirect_flow.redirect_url}"
package com.gcintegration;

import com.gocardless.GoCardlessClient;
import com.gocardless.resources.RedirectFlow;

public class CreateRedirectFlow {
    public static void main(String[] args) {
        GoCardlessClient client = GoCardlessClient
            // We recommend storing your access token in an
            // environment variable for security, but you could
            // include it as a string directly in your code
            .newBuilder(System.getenv("GC_ACCESS_TOKEN"))
            // Change me to LIVE when you're ready to go live
            .withEnvironment(GoCardlessClient.Environment.SANDBOX)
            .build();

        RedirectFlow redirectFlow = client.redirectFlows().create()
            .withDescription("Cider Barrels") // This will be shown on the payment pages.
            .withSessionToken("dummy_session_token") // Not the access token
            .withSuccessRedirectUrl("https://developer.gocardless.com/example-redirect-uri/")
            // Optionally, prefill customer details on the payment page
            .withPrefilledCustomerGivenName("Tim")
            .withPrefilledCustomerFamilyName("Rogers")
            .withPrefilledCustomerEmail("tim@gocardless.com")
            .withPrefilledCustomerAddressLine1("338-346 Goswell Road")
            .withPrefilledCustomerCity("London")
            .withPrefilledCustomerPostalCode("EC1V 7LQ")
            .execute();
        // Hold on to this ID - you'll need it when you
        // "confirm" the redirect flow later
        System.out.println(redirectFlow.getId());
        System.out.println(redirectFlow.getRedirectUrl());
    }
}
var redirectFlowResponse = await client.RedirectFlows.CreateAsync(new RedirectFlowCreateRequest()
{
    Description = "Cider Barrels",
    SessionToken = "dummy_session_token",
    SuccessRedirectUrl = "https://developer.gocardless.com/example-redirect-uri/",
    // Optionally, prefill customer details on the payment page
    PrefilledCustomer = new RedirectFlowCreateRequest.RedirectFlowPrefilledCustomer()
    {
        GivenName = "Tim",
        FamilyName = "Rogers",
        Email = "tim@gocardless.com",
        AddressLine1 = "338-346 Goswell Road",
        City = "London",
        PostalCode = "EC1V 7LQ"
    }
});

var redirectFlow = redirectFlowResponse.RedirectFlow;

// Hold on to this ID - you'll need it when you
// "confirm" the redirect flow later
Console.WriteLine(redirectFlow.Id);
Console.WriteLine(redirectFlow.RedirectUrl);

In a real integration:

  • You’d set the success_redirect_url to a cheery success page on your website where you’d “complete” the flow using the API (we’ll show you how to do this next), as well as storing the created customer and mandate details.
  • You’d provide a session_token which identifies the user’s session on your website (for example their session ID in your application). You provide this when creating the redirect flow, and must provide it again when “completing” it at the end. Supplying this token twice makes sure that the person who completed the redirect flow is the person you sent to it.
  • Optionally, you can include a prefilled_customer object with your end customer’s details. These will be pre-filled on the payment page so your customer doesn’t have to enter them. For a full list of the details you can provide, head to the API reference.

The redirect_url we’ve just printed (which will look something like https://pay-sandbox.gocardless.com/flow/RE00006GBDVVP3BBCP9Q5318ZVJWE0DN) is where you send your customer to set up their mandate on our secure payment pages.

Try going to the URL printed by your code and completing the setup process - this is exactly what your customers will see. You can use our example bank details rather than your own while working in the sandbox:

  • In the UK, use the sort code 200000 and the account number 55779911
  • In Sweden, use the clearingnummer (branch code) 5491, the kontonummer (account number) 0000003 and the personnummer (Swedish identity number) 198112289874
  • In Denmark, use the registreringsnummer (bank code) 345, the kontonummer (account number) 3179681 and the CPR-nummer (Danish identity number) 0101701234
  • In Australia, use the BSB 082-082 and the account number 012345678
  • In New Zealand, use the bank code 12, branch code 3113 and the account number 0003869-00
  • In Canada, use the bank code (Financial Institution number) 0003, branch code (Branch Transit number) 00006 and the account number 0000000
  • Everywhere else, use the French IBAN FR1420041010050500013M02606
When you sign up in the sandbox, we’ll give you access to the Direct Debit scheme most appropriate for your location: Bacs in the UK, Autogiro in Sweden, Betalingsservice in Denmark, BECS in Australia, BECS NZ in New Zealand and SEPA elsewhere. If you want to use other schemes, just get in touch. You’ll need to have a bank account where you can receive payouts in the relevant currency.

Completing the redirect flow

Once you’ve completed the form, you’ll be redirected back to our example success page. Note that the redirect_flow_id query parameter in the URL matches the ID of the redirect flow object.

Now we’ll use a second API call to “complete” the redirect flow. In a real integration, we’d build our own success page, setting it as the redirect_url, and this page would perform this step.

We’ll need the ID from above, and the session_token we set earlier:

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

$client = new \GoCardlessPro\Client([
    // We recommend storing your access token in an environment variable for security, but you could include it as a string directly in your code
    'access_token' => getenv('GC_ACCESS_TOKEN'),
    // Change me to LIVE when you're ready to go live
    'environment' => \GoCardlessPro\Environment::SANDBOX
]);

$redirectFlow = $client->redirectFlows()->complete(
    "RE00006GBASX53T7KYWT4051FMC0TZA6", //The redirect flow ID from above.
    ["params" => ["session_token" => "dummy_session_token"]]
);

print("Mandate: " . $redirectFlow->links->mandate . "<br />");
// Save this mandate ID for the next section.
print("Customer: " . $redirectFlow->links->customer . "<br />");

// Display a confirmation page to the customer, telling them their Direct Debit has been
// set up. You could build your own, or use ours, which shows all the relevant
// information and is translated into all the languages we support.
print("Confirmation URL: " . $redirectFlow->confirmation_url . "<br />");
import os
import gocardless_pro

client = gocardless_pro.Client(
    #We recommend storing your access token in an environment variable for
    #security, but you could include it as a string directly in your code.
    access_token=os.environ['GC_ACCESS_TOKEN'],
    #Change this to 'live' when you are ready to go live.
    environment='sandbox'
)

redirect_flow = client.redirect_flows.complete(
    "RE00006GBASX53T7KYWT4051FMC0TZA6", # The redirect flow ID from above.
    params={
        "session_token": "dummy_session_token"
})

print("Mandate: {}".format(redirect_flow.links.mandate))
# Save this mandate ID for the next section.
print("Customer: {}".format(redirect_flow.links.customer))

# Display a confirmation page to the customer, telling them their Direct Debit has been
# set up. You could build your own, or use ours, which shows all the relevant
# information and is translated into all the languages we support.
print("Confirmation URL: {}".format(redirect_flow.confirmation_url))
require 'gocardless_pro'

client = GoCardlessPro::Client.new(
	access_token: ENV['GC_ACCESS_TOKEN'],
	environment: :sandbox
)

redirect_flow = client.redirect_flows.complete(
    'RE00006GBASX53T7KYWT4051FMC0TZA6', # The redirect flow ID from above.
    params: { session_token: 'dummy_session_token' })

puts "Mandate: #{redirect_flow.links.mandate}"
# Save this mandate ID for the next section.
puts "Customer: #{redirect_flow.links.customer}"

# Display a confirmation page to the customer, telling them their Direct Debit has been
# set up. You could build your own, or use ours, which shows all the relevant
# information and is translated into all the languages we support.
puts "Confirmation URL: #{redirect_flow.confirmation_url}"
package com.gcintegration;

import com.gocardless.GoCardlessClient;
import com.gocardless.resources.RedirectFlow;

public class CompleteRedirectFlow {
    public static void main(String[] args) {
        GoCardlessClient client = GoCardlessClient
            // We recommend storing your access token in an
            // environment variable for security, but you could
            // include it as a string directly in your code
            .newBuilder(System.getenv("GC_ACCESS_TOKEN"))
            // Change me to LIVE when you're ready to go live
            .withEnvironment(GoCardlessClient.Environment.SANDBOX)
            .build();

        RedirectFlow redirectFlow = client.redirectFlows()
            // The redirect flow ID from above
            .complete("RE00007201VQ3H3HSTM2V02BYG4DPF1S")
            .withSessionToken("dummy_session_token")
            .execute();

        System.out.println(redirectFlow.getLinks().getMandate());
        // Save this mandate ID for the next section.
        System.out.println(redirectFlow.getLinks().getCustomer());

        // Display a confirmation page to your customer, telling them their Direct Debit
        // has been set up. You could build your own, or use ours, which shows all the
        // relevant information and is translated into all the languages we support.
        System.out.println(redirectFlow.getConfirmationUrl());
    }
}
var redirectFlowResponse = await client.RedirectFlows
    .CompleteAsync("RE00007201VQ3H3HSTM2V02BYG4DPF1S",
        new RedirectFlowCompleteRequest()
        {
            SessionToken = "dummmy_session_token"
        }
    );

var redirectFlow = redirectFlowResponse.RedirectFlow;

// Store the mandate ID against the customer's database record so you can charge
// them in future
Console.WriteLine($"Mandate: {redirectFlow.Links.Mandate}");
Console.WriteLine($"Customer: {redirectFlow.Links.Customer}");

// Display a confirmation page to the customer, telling them their Direct Debit has been
// set up. You could build your own, or use ours, which shows all the relevant
// information and is translated into all the languages we support.
Console.WriteLine($"Confirmation URL: {redirectFlow.ConfirmationUrl}");

The complete method returns the redirect flow object, now including details of the mandate, customer, and customer bank account that have been created.

Keep a note of the mandate ID - you'll need it later. In a real application, you’d write them to a database record associated with your customer.

With the redirect flow completed via the API and the mandate ID stored, show your customer a clear confirmation page telling them that their Direct Debit has been set up, and what will happen next.

You could build your own, or you could use our pre-made one which comes ready translated into all the languages we support - just redirect the customer to the URL found in the confirmation_url attribute of the redirect flow.

GoCardless's ready-made confirmation page

Our provided confirmation page is only available for 15 minutes from the moment when you complete the redirect flow via the API, so you should redirect the customer straight to it.

Let’s try listing our customers again, like we did for our first request. Now, we’ll see the customer we’ve just created:

$customers = $client->customers()->list()->records;
print_r($customers);
customers = client.customers.list().records
print(customers)
print([customer.email for customer in customers])
# `pp` is Ruby's built-in pretty printing functionality
require 'pp'

pp client.customers.list.records
List<Customer> customers = client.customers().list().execute().getItems();
System.out.println(Arrays.toString(customers.toArray()));
var listResponse = await client.Customers.ListAsync();
var customers = listResponse.Customers;
Console.WriteLine("Customers: " + string.Join(", ", customers.Select(c => c.Id)));