# JavaScript Drop-in Flow Overview

Source: https://docs.gocardless.com/docs/collect-payments/integration-types/javascript-drop-in-flow

# JavaScript Drop-in Flow

Embed a pre-built payment flow directly in your website. The customer completes mandate setup and payment authorisation without leaving your domain.

Supports: **Direct Debit only.** Does not support Pay By Bank or Commercial VRP. For these payments, use [Hosted Pages](/docs/collect-payments/integration-types/gocardless-hosted-pages) or [Custom Payment Pages](/docs/collect-payments/integration-types/custom-payment-pages).

### Best for

- Keeping customers on your site throughout the payment flow
- Moderate customisation with less development than a full custom build
- Modern web applications (React, Vue, etc.)
- Balance between speed of implementation and control

## How it works

- Create a Billing Request and Billing Request Flow via the API (same as Hosted Pages)
- Include the GoCardless Drop-in JavaScript library on your page
- Initialise the component with the flow ID
- The component renders the payment flow inline on your page
- Listen for completion events and webhooks

### Customisation

- Style the component to match your brand colours and fonts
- Control the container element and placement
- Handle events (success, exit, error) in your application code

## Step-by-step guide

### Create a billing request

The Billing Request defines what you're collecting.

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

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

````

```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")
  .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'
```

Response:

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

### Create a billing request flow

This generates the hosted URL where the customer completes authorisation.

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

Response:

```json

  }
}
```

### Initialise the Drop-in Component

Include the GoCardless Drop-in script on your page and initialise it with the billing_request_flow_id from the previous step.

```javascript

GoCardlessDropin.create(,
    onExit: function(error, metadata) 
    }
  }).mount("#gc-dropin-container");
```

### Handle Webhooks

| Event                      | **Meaning**                                 | What to do                                               |
| -------------------------- | ------------------------------------------- | -------------------------------------------------------- |
| billing_requests.fulfilled | Customer completed the flow                 | Record the mandate_id from links.mandate_request_mandate |
| mandates.active            | Mandate is ready to collect against         | Enable payment collection in your system                 |
| payments.confirmed         | A payment against the mandate was collected | Mark the associated period/invoice as paid               |
| payments.failed            | A payment failed                            | Notify the customer, retry if appropriate                |
| mandates.cancelled         | Mandate was cancelled                       | Stop future payment creation                             |

#### Pre-collecting customer details

If you already have the customer's name, email, and address, submit them before creating the flow. The hosted page skips those fields or locks them if you prefer.

### Collect customer details (optional)

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

$client->billingRequests()->collectCustomerDetails("BR123", [
"params" => [
"customer" => [
"email" => "paddington@bearthings.com"
"given_name" => "Paddington",
"family_name" => "Bear"
],
"customer_billing_detail" => [
"address_line1" => "32 Windsor Gardens",
"city" => "London",
"postal_code" => "W9 3RG",
"country_code" => "GB"
]
]
]);

````

```python

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

client.billing_requests.collect_customer_details("BR123", params=,
  customer_billing_detail: 
})
````

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

@client.billing_requests.collect_customer_details("BR123", ,
    customer_billing_detail: 
  }
})
```

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

@client.billing_requests.collect_customer_details("BR123", ,
    customer_billing_detail: 
  }
})
```

```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_billing_detail: 
});
```

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

var customer = new GoCardless.Services.BillingRequestCollectCustomerDetailsRequest.BillingRequestCustomer
;

var customerBillingDetail =new GoCardless.Services.BillingRequestCollectCustomerDetailsRequest.BillingRequestCustomerBillingDetail
;

var resp = await gocardless.BillingRequests.CollectCustomerDetails("BR123",
  new GoCardless.Services.BillingRequestCollectCustomerDetailsRequest
  );
```

```http
POST /billing_requests/BRQ000010NMDMH2/actions/collect_customer_details HTTP/1.1
,
    "customer_billing_detail": 
  }
}
```

```go
package main

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

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

billingRequestCollectCustomerDetailsParams := gocardless.BillingRequestCollectCustomerDetailsParams,
  CustomerBillingDetail: &gocardless.BillingRequestCollectCustomerDetailsParamsCustomerBillingDetail,
}

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

**Response:** Updated Billing Request with collect_customer_details marked completed.

### Collect bank account (optional)

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

$client->billingRequests()->collectBankAccount("BRQ000010NMDMH2", [
"params" => [
"account_number" => "55779911",
"branch_code" => "200000",
"account_holder_name" => "Frank Osborne",
"country_code" => "GB"
]
]);

````

```python

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

client.billing_requests.collect_bank_account("BRQ000010NMDMH2", params=)
````

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

@client.billing_requests.collect_bank_account("BRQ000010NMDMH2", 
})
```

```java

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

client.billingRequests().collectBankAccount("BRQ000010NMDMH2")
  .withAccountNumber("55779911")
  .withBranchCode("200000")
  .withAccountHolderName("Frank Osborne")
  .withCountryCode("GB")
  .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("BRQ000010NMDMH2", );
```

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

var resp = await gocardless.BillingRequests.CollectBankAccountAsync("BRQ000010NMDMH2",
  new BillingRequestCollectBankAccountRequest
  );
```

```http
POST /billing_requests/BRQ000010NMDMH2/actions/collect_bank_account HTTP/1.1

}
```

```go
package main

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

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

billingRequestCollectBankAccountParams := gocardless.BillingRequestCollectBankAccountParams

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

**Response:** Updated Billing Request with collect_bank_account marked completed.

> **Info:**
> When creating the Billing Request Flow, pass `lock_customer_details: true` and/or
>   `lock_bank_account: true` to prevent customers editing pre-filled values.

## What's next?

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

Create mandates and collect bank account details via the API.

  
#### [Prefill Customer Details](/docs/optimise/prefill-customer-details)

Skip form steps by supplying customer details before the drop-in loads.

  
#### [GoCardless Hosted Pages](/docs/collect-payments/integration-types/gocardless-hosted-pages)

Redirect to a GoCardless-hosted checkout — no frontend JavaScript required.

  
#### [Custom Payment Pages](/docs/collect-payments/integration-types/custom-payment-pages)

Full API control for teams that want complete UX ownership.