# Billing Request (Instant Bank Pay feature)

## Using the JavaScript Drop-in

This guide shows how to use the Javascript Drop-in to allow customers to complete the Billing Request Flow without leaving the integrator’s site.

Use the Drop-in when you already have a frontend website, and want to benefit from having customers stay on your site, and avoiding site-to-site redirects.

### Installation

### Javascript

Install the Drop-in by adding the initialise script to your site:

```HTML
<script src="https://pay.gocardless.com/billing/static/dropin/v2/initialise.js"></script>
```

> You are discouraged from bundling the initialisation script or vendoring it, **as GoCardless reserves the right to make non-breaking changes** to the underlying implementation, which you will want your sites to pickup automatically.
>
> _We guarantee backward compatibility between major versions of the initialise script, as denoted by the script source URL._

### React

GoCardless offer a [react-dropin](https://github.com/gocardless/react-dropin) library that provides React bindings and TypeScript definitions for the Drop-in: check the [README](https://github.com/gocardless/react-dropin) for full details, and example implementations.

You can install the package using either npm or yarn.

```shell-session
//With npm:
npm install --save @gocardless/react-dropin

// With yarn:
yarn add @gocardless/react-dropin
```

Once installed, you can import the React bindings:

```javascript
import {
  useGoCardlessDropin,
  GoCardlessDropinOptions,
  GoCardlessDropinOnSuccess,
} from "@gocardless/react-dropin";
```

### Create

### Create a Billing Request

---

**Note** 🇬🇧 🇩🇪 🇫🇷 🇮🇪 Instant Bank Pay supports GBP and EUR, available for transactions in GBP with your customers in the UK, and available for EUR with your customers in Germany, France, and Ireland. For payments in the UK, we also support [Direct Funds Settlement](https://developer.gocardless.com/direct-funds-settlement).

To take both an instant first payment and to set up a mandate you must include both the `payment_request` and `mandate_request` fields when creating your Billing Request.

> Note: You will be allowed to create a Billing Request only if the `mandate_request` and the `payment_request` have the same currency.

Mandates are created against a particular payment scheme, however, an integrator will normally only care about the currency they are using to create payments. We recommend specifying a `currency` and omitting the `scheme`, allowing GoCardless to pick the best scheme for that currency.

Most integrators will use Billing Requests to create a mandate alongside a new customer, so we’ll use that as our example. If you want to create a mandate and take the first payment against an existing customer, just specify the customer ID in `links.customer.`

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" => [
    "payment_request" => [
      "description" => "First Payment",
      "amount" => "500",
      "currency" => "GBP",
      "app_fee" => "500",
    ],
    "mandate_request" => [
      "scheme" => "bacs"
    ]
  ]
]);
```

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

client.billing_requests.create(params={
  "payment_request": {
    "description": "First Payment",
    "amount": "500",
    "currency": "GBP",
    "app_fee": "500",
  },
  "mandate_request": {
    "scheme": "bacs"
  }
})
```

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

@client.billing_requests.create(
  params: {
    payment_request: {
      description: "First Payment",
      amount: "500",
      currency: "GBP",
      app_fee: "500",
    },
    mandate_request: {
      scheme: "bacs"
    }
  }
)
```

```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()
  .withPaymentRequestDescription("First Payment")
  .withPaymentRequestAmount(500)
  .withPaymentRequestCurrency(Currency.GBP)
  .withPaymentRequestAppFee(500)
  .withMandateRequestScheme("bacs")
  .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({
  payment_request: {
    description: "First Payment",
    amount: "500",
    currency: "GBP",
    app_fee: "500",
  },
  mandate_request: {
    scheme: "bacs",
  },
});
```

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

var paymentRequest = new GoCardless.Services.BillingRequestCreateRequest.BillingRequestPaymentRequest
{
  Description = "First payment",
  Amount = 500,
  Currency = "GBP",
  AppFee = 500,
};

var mandateRequest = new gocardless.BillingRequestCreateRequest.BillingRequestMandateRequest
{
  Scheme = "bacs",
};

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

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

```HTTP
POST https://api.gocardless.com/billing_requests HTTP/1.1
{
  "billing_requests": {
    "payment_request": {
      "description": "First Payment",
      "amount": "500",
      "currency": "GBP",
      "app_fee": "50"
    },
    "mandate_request": {
      "scheme": "bacs"
    }
  }
}
```

```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
}

billingRequestCreateParams := gocardless.BillingRequestCreateParams{
  PaymentRequest: &gocardless.BillingRequestCreateParamsPaymentRequest{
    Amount:      1000,
    AppFee:      50,
    Currency:    "GBP",
    Description: "First Payment",
  },
  MandateRequest: &gocardless.BillingRequestCreateParamsMandateRequest{
    Scheme: "bacs",
  },
}

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

```CLI
gc create billing_request \
  -d 'payment_request[amount]=500' \
  -d 'payment_request[app_fee]=50' \
  -d 'payment_request[currency]=GBP' \
  -d 'payment_request[description]="First Payment"' \
  -d 'mandate_request[scheme]=bacs'
```

You’ll receive a full Billing Request, including things like `actions` and `resources`.

It will look like this:

```json
{
  "billing_requests": {
    "id": "BRQ123",
    "status": "pending",
    "mandate_request": {
      "currency": "GBP",
      "scheme": "bacs"
    },
    "payment_request": {
      "currency": "GBP",
      "amount": "500",
      "description": "£5 Instant first payment",
      "scheme": "faster_payments"
    },
    "links": {
      "customer": "CU00016VR36GVW",
      "customer_billing_detail": "CBD000010M15PAC",
      "payment_request": "PRQ123",
      "mandate_request": "MRQ123",
      "organisation": "OR123"
    }
  }
}
```

The Billing Request is currently `pending`, meaning we need to complete the outstanding actions before it can be fulfilled. We can use Billing Request Flows to generate a checkout flow that guides the payer through these actions.

### 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
import gocardless_pro
client = gocardless_pro.Client(access_token="your_access_token_here", environment='sandbox')

client.billing_request_flows.create(params={
  "redirect_uri": "https://my-company.com/landing",
  "exit_uri": "https://my-company.com/exit",
  "links": {
    "billing_request": "BRQ000010NMDMH2"
  }
})
```

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

@client.billing_request_flows.create(
  params: {
    redirect_uri: "https://my-company.com/landing",
    exit_uri: "https://my-company.com/exit",
    links: {
      billing_request: "BRQ000010NMDMH2",
    }
  }
)
```

```java
import static com.gocardless.GoCardlessClient.Environment.SANDBOX;
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({
  redirect_uri: "https://my-company.com/landing",
  exit_uri: "https://my-company.com/exit",
  links: {
    billing_request: "BRQ000010NMDMH2",
  },
});
```

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

var resp = await gocardless.BillingRequestFlows.CreateAsync(
  new GoCardless.Services.BillingRequestFlowCreateRequest()
  {
    RedirectUri = "https://my-company.com/landing",
    ExitUri = "https://my-company.com/exit",
    Links = new GoCardless.Services.BillingRequestFlowCreateRequest.BillingRequestFlowLinks {
      BillingRequest = "BRQ000010NMDMH2",
    },
  }
);

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

```http
POST https://api.gocardless.com/billing_request_flows HTTP/1.1
{
  "billing_request_flows": {
    "redirect_uri": "https://my-company.com/landing",
    "exit_uri": "https://my-company.com/exit",
    "links": {
      "billing_request": "BRQ000010NMDMH2"
    }
  }
}
```

```go
package main

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

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
{
  "billing_request_flows": {
    "authorisation_url": "https://pay.gocardless.com/billing/static/flow?id=<brf_id>",
    "lock_customer_details": false,
    "lock_bank_account": false,
    "auto_fulfil": true,
    "created_at": "2021-03-30T16:23:10.679Z",
    "expires_at": "2021-04-06T16:23:10.679Z",
    "redirect_uri": "https://my-company.com/completed",
    "links": {
      "billing_request": "BRQ123"
    }
  }
}
```

### Initialising the Drop-in

You will need to store a reference to the Billing Request and Billing Request Flow ID, often against an internal customer record.

```javascript
// Handler is an instance of the Dropin, with methods
// open, exit, etc.
//
// You must call open() before the Dropin will activate.
//
// You can pass one of either billingRequestFlowID or billingRequestTemplateID.
const handler = GoCardlessDropin.create({
  billingRequestFlowID: "<generated-on-backend>",
  // billingRequestTemplateID: "BRT123",
  environment: "live", // either live or sandbox
  onSuccess: (billingRequest, billingRequestFlow) => {},
  onExit: (error, metadata) => {},
});
```

```React
// Use an existing Billing Request Flow ID likely generated in
// your backend, then configure hooks for Dropin lifecycle
// events.
const config : GoCardlessDropinOptions = ({
    billingRequestFlowID: "<generated-on-backend>",
    environment: "live", // either live or sandbox
    onSuccess: (billingRequest, billingRequestFlow) => {},
    onExit: (error, metadata) => {},
});

// Create state variables via the useGoCardlessDropin hook
// function, to be used inside a React component render
// function.
//
// You must call open() before the Dropin will activate.
const {
    open, exit, ready, error,
} = useGoCardlessDropin(config);
```

When using [Javascript](/billing-requests/taking-an-instant-bank-payment/using-dropin#installation), `GoCardlessDropin.create` returns an `Object` with two functions, [`open`](https://developer.gocardless.com/getting-started/billing-requests/using-dropin/#open) and [`exit`](https://developer.gocardless.com/getting-started/billing-requests/using-dropin/#exit).

With [React](/billing-requests/taking-an-instant-bank-payment/using-dropin#installation), the `useGoCardlessDropin` hook returns an `Object` with four values, [`open`](https://developer.gocardless.com/getting-started/billing-requests/using-dropin/#open), [`exit`](https://developer.gocardless.com/getting-started/billing-requests/using-dropin/#exit), ready and error. `open` and `exit` behave just as above.

The `ready` value will be `true` once the Drop-in has been loaded and the `open` function is ready to be called. You should watch `error` for any issues that occurred that prevented the Drop-in from properly loading.

### Opening and Closing the modal

### open()

Calling `open` will attach the Drop-in iframe to the DOM, and open the modal ready for a customer to complete the flow. Follow the progress of the customer via the `onSuccess` and `onExit` handlers.

```javascript
const handler = GoCardlessDropin.create({
  billingRequestFlowID: "<generated-on-backend>",
  environment: "live", // either live or sandbox
  onSuccess: (billingRequest, billingRequestFlow) => {},
  onExit: (error, metadata) => {},
});

// Create handler as above
const handler = GoCardlessDropin.create({
  /* ... */
});

// Open the Dropin modal, making it visible to the customer
handler.open();
```

```React
const config : GoCardlessDropinOptions = ({
    billingRequestFlowID: "<generated-on-backend>",
    environment: "live", // either live or sandbox
    onSuccess: (billingRequest, billingRequestFlow) => {},
    onExit: (error, metadata) => {},
});

// Create state variables via the useGoCardlessDropin hook
// function, to be used inside a React component render
// You must call open() before the Dropin will activate.
const {
    open, exit, ready, error,
} = useGoCardlessDropin(config);

// Only open the link if the Dropin is ready
if (ready) {
  open();
}
```

### exit()

Calling `exit` will close the Drop-in, removing the modal from the DOM.

If the customer had successfully completed the flow, this will trigger the `onSuccess` callback. Otherwise, the `onExit` callback is triggered with a `null` error.

### Handling Callbacks (onSuccess & onExit)

### onSuccess

`onSuccess` receives the Billing Request that has been worked.

This is called when the flow exits successfully. Depending on how the flow was configured, it may have completed but not fulfilled the Billing Request - check the status of the request before assuming it has been fulfilled.

### onExit

`onExit` is called with two arguments: an `error` `Object` and a `metadata` `Object`.

The `onExit` callback is called when the customer leaves the flow before completion. This can happen when they voluntarily leave the flow, or due to an unexpected error within it.

The `error` object is `null` if no error was encountered, such as when a customer clicks the exit button. Otherwise it is set to the error that caused the flow to fail.

The `metadata` object is populated with contextual information that can help understand the source or cause of the error.

### React Drop-in Example

```React
import React, { useCallback, useState } from "react";
import {
  useGoCardlessDropin,
  GoCardlessDropinOptions,
  GoCardlessDropinOnSuccess,
} from "@gocardless/react-dropin";

// Display a button that opens the Dropin on click, starting a checkout
// flow for the specified Billing Request Flow.
const DropinButton = (options: GoCardlessDropinOptions) => {
  const { open } = useGoCardlessDropin({ ...options });

  return (
    <button type="button" onClick={() => open()}>
      Start Dropin for <code>{options.billingRequestFlowID}</code> in{" "}
      <code>{options.environment}</code>
    </button>
  );
};

// Example checkout flow, where we create a Billing Request Flow ID by talking
// with our backend API.
const App: FunctionComponent = () => {
  const [flowID, setFlowID] = useState<string | null>(null);

  // Build your backend with an API endpoint that:
  //
  //   1. Creates a Billing Request for the resources you wish to create
  //   2. Create a Billing Request Flow against (1)
  //   3. Return the ID from (2)
  //
  // See an example of this at Taking an Instant Bank Payment:
  // https://developer.gocardless.com/getting-started/billing-requests/taking-an-instant-bank-payment/
  React.useEffect(() => {
    async function createFlow() {
      // Expecting a JSON body like:
      // {
      //   "flow_id": "BRF123456"
      // }
      let response = await fetch("/api/flows", {
        method: "POST",
      });
      const { flow_id } = await response.json();
      setFlowID(flow_id);
    }
    createFlow();
  }, []);

  // Only show the button once we have a Billing Request Flow ID
  return flowID === null ? (
    <div className="loader"></div>
  ) : (
    <DropinButton billingRequestFlowID={flowID} environment={"live"} />
  );
};
```

### What’s next?

### Get started
