Direct debit is a transaction where funds are withdrawn directly from a customer’s bank account.
This tutorial guides you on using Chargebee.js to integrate Direct debit payments via Single Euro Payment Area(SEPA), Automated Clearing House(ACH) Network, Bacs and Autogiro on your website and creating a subscription after the user checks out.
Currently, Chargebee JS supports the below payment options for Direct debit:
SEPA via Stripe
SEPA via Adyen
SEPA via BlueSnap
SEPA via Checkout.com
SEPA, ACH, BACS, and Autogiro via GoCardless
ACH via Stripe using Plaid authentication.
ACH via Stripe using Stripe Financial Connections authentication
ACH via Checkout.com using Plaid authentication.
ACH via Braintree
ACH via BlueSnap
ACH via Adyen
ACH via Chargebee Payments
BACS via Stripe
Gateway prerequisites
The following is the list of requirements to fulfill before starting the integration steps.
- Enable the payment method of your choice:
- SEPA via Stripe. Learn more.
- SEPA via Adyen. Learn more.
- SEPA via Checkout.com Learn more.
- SEPA, ACH, BACS, Autogiro via GoCardless. Learn more.
- SEPA via BlueSnap. Learn more.
- ACH via Stripe. Learn more.
- ACH via Checkout.com. Learn more.
- ACH via Braintree. Learn more.
- ACH via BlueSnap. Learn more.
- ACH via Adyen Learn more
- BACS via Stripe. Learn more.
- Configure Smart routing to select Direct debit payments for the following currencies:
- USD for ACH
- EUR for SEPA
- GBP for BACS
Set up Chargebee.js
Include the Chargebee.js script on your page and initialize a Chargebee instance before you start. For the script tag, the Chargebee.init options, and the tearDown() caveat, see Set up Chargebee.js.
Create a Payment Intent
You should create a payment intent before submitting the form to authorize the payments.
payment_intent performs the essential function of tracking different events involved in a transaction. This includes:
Automatically changing its status based on the outcome of authorization and capture events.
Automatically refunding in case of an error post-payment.
A payment_intent can be created at your server-side using create a payment intent API and returned to the client side. The payment method handler uses the created payment_intent internally to perform authorization.
Here's the sample code to create a payment_intent.
This must be done from your backend to avoid exposing sensitive data.
Example:
curl https://{site-name}.chargebee.com/api/v2/payment_intents \
-u {fullaccess_api_key}: \
-d amount=500 \
-d currency_code="USD" \
-d payment_method_type="direct_debit"
const express = require('express');
const app = express();
const axios = require('axios');
//API call to Chargebee to create payment_intent
app.post('/payment-intents', async (req, res) => {
axios.request({
url: 'https://{site-name}.chargebee.com/api/v2/payment_intents',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic {API_KEY}'
},
data: {
amount: req.body.amount,
currency_code: req.body.currency_code,
payment_method_type: req.body.payment_method_type,
}
}).then(result => {
res.status(result.status).json({
payment_intent: result.data.payment_intent
});
})
});
app.listen(3000, () => {
console.log('Running on port 3000');
});
The above step should be initiated as a request from your frontend.
Frontend code:
function createPaymentIntent() {
return fetch('/payment-intents', {
method: 'POST',
body: JSON.stringify({
amount: 500,
currency_code: 'USD',
payment_method_type: 'direct_debit'
})
}).then(function(response) {
return response.json();
}).then(function(responseJson) {
return responseJson.payment_intent;
});
}
Authorize payment intent
Follow these steps to integrate Direct debit on your website.
1. Set up Direct debit
Set up Direct debit using the steps below:
- Load Direct debit integration.
loadDirect debit integration usingcbInstance.load("direct_debit"). - Set payment intent. Pass the
payment_intentobject todirectDebitHandler.setPaymentIntent(payment_intent).
2. Handle Payment
Use direct_debit and paymentInfo as the input parameter to directDebitHandler.handlePayment function, as this enables the function to handle Direct debit payments.
Pass scheme- and gateway-specific fields in paymentInfo (customer, bankAccount, useGateway, plaid, or mandateText). For GoCardless, set useGateway to collect bank details on the GoCardless page, or pass bankAccount yourself if your GoCardless plan allows it.
For the complete paymentInfo reference, including per-gateway required if notes and the SEPA via GoCardless countryCode field map, see Direct Debit handlePayment().
Sample Code
cbInstance.load("direct_debit").then(directDebitHandler => {
createPaymentIntent().then((intent) => {
directDebitHandler.setPaymentIntent(intent);
const paymentInfo = {
plaid: {
userId: "123",
}
}
directDebitHandler.handlePayment(paymentInfo).then(intent => {
// SUCCESS!!! payment_intent is authorized.
var response = fetch('/subscriptions', {
method: 'POST',
body: JSON.stringify({
paymentIntentId: intent.id,
plan_id: 'pro_plan',
plan_quantity: 1,
billingAddress: {
...
}, // provide billing address
customer: {
...
} // provide customer details if the subscription is to be created for an existing <code>customer</code> in Chargebee.
})
}).then(function(response) {
return response.json();
});
}).catch(err => {
// OOPS!!! payment_intent is not authorized.
});
});
});
Examples of Promises and Callbacks
Use webhooks for production use, instead of making the subscription creation request from the frontend, it's more secure and reliable to respond to webhooks from Chargebee on the backend. Listen to the payment_intent_updated event via webhooks and create the subscription when the payment_intent.status is authorized.
const paymentInfo = {
plaid: {
userId: "123",
}
}
directDebitHandler.handlePayment(paymentInfo).then(intent => {
// SUCCESS!!! payment_intent is authorized.
var response = fetch('/subscriptions', {
method: 'POST',
body: JSON.stringify({
paymentIntentId: intent.id,
plan_id: 'pro_plan',
plan_quantity: 1,
billingAddress: {
...
}, // provide billing address
customer: {
...
} // provide customer details if the subscription is to be created for an existing <code>customer</code> in Chargebee.
})
}).then(function(response) {
return response.json();
});
}).catch(err => {
// OOPS!!! payment_intent is not authorized.
})
const paymentInfo = {
plaid: {
userId: "123",
}
}
const callbacks = {
success: (intent) => {
// SUCCESS!!! payment_intent is authorized.
var response = fetch('/subscriptions', {
method: 'POST',
body: JSON.stringify({
paymentIntentId: intent.id,
plan_id: 'pro_plan',
plan_quantity: 1,
billingAddress: {
...
}, // provide billing address
customer: {
...
} // provide customer details if the subscription is to be created for an existing <code>customer</code> in Chargebee.
})
}).then(function(response) {
return response.json();
});
},
error: (err) => {
// OOPS!!! payment_intent is not authorized.
}
}
directDebitHandler.handlePayment(paymentInfo, callbacks)
On successful authorization, the payment_intent turns authorized, and Chargebee redirects the user back to your website (payment authorization page).
Learn more about the additional functions supported for Direct debit.
Create a subscription (server)
Pass the ID of the successfully authorized payment_intent to Chargebee’s create a subscription API.
curl https://{site}.chargebee.com/api/v2/customers/__test__8asz8Ru9WhHOJO/subscription_for_items \
-X POST \
-u {site_api_key}: \
-d payment_intent[id]="<Id of authorized payment_intent recieved in last step.>" \
-d subscription_items[item_price_id][0]="basic-USD" \
-d subscription_items[billing_cycles][0]=2 \
-d subscription_items[quantity][0]=1 \
-d subscription_items[item_price_id][1]="day-pass-USD" \
-d subscription_items[unit_price][1]=100
We're always happy to help you with any questions you might have! Click here to reach out to us.