# Quickstart
Early Access
The Payment Components feature is in early access. To request access, write to eap@chargebee.com.
This quickstart guide helps you set up a JavaScript project that demonstrates Chargebee JS payment components.
# Prerequisites
Before you start, ensure you have the following:
- Set up payment gateways (opens new window) in Chargebee Billing.
- Configure payment methods (opens new window) and Smart Routing (opens new window), if necessary.
- Ensure 3-D Secure is enabled on your payment gateway(s) for the Chargebee payment components to function.
- Set up the Product Catalog (opens new window) in Chargebee.
- Install Node v18 or above.
# Running the sample application locally
You can download and run the sample application (opens new window) locally by following the instructions in its Readme on GitHub (opens new window).
# Code walkthrough
This section explains how the code in the quickstart sample app (opens new window) works.
# Load Chargebee.js (client)
Load Chargebee.js on the checkout page by adding the following script to the <head>
element of the page.
<script src="https://js1.chargebee.com/v2/chargebee.js"></script>
See on GitHub:
/client/index.html
(opens new window)
# Initialize Chargebee.js (client)
Once the page loads, initialize Chargebee.js with a publishable key (opens new window). This creates a Chargebee object used to create components.
const chargebee = window.Chargebee.init({
site: env.site,
publishableKey: env.publishableKey,
})
2
3
4
See on GitHub:
/client/scripts/checkout.js
(opens new window)
# Request a payment_intent
(opens new window) (client)
After the page loads, request your server to create a new payment_intent
(opens new window).
Payment Intent
A payment_intent
is required to manage the payment session for your customer. It tracks the status of the payment status, recording failed attempts, and avoiding duplicate charges.
const url = "http://localhost:8082/payment-intent";
const response = await fetch(url, {
method: "POST",
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const json = await response.json();
2
3
4
5
6
7
8
See on GitHub:
/client/scripts/checkout.js
(opens new window)
# Create a payment_intent
(server)
Create an endpoint on your server that creates (opens new window) a payment_intent
in Chargebee Billing.
app.post('/payment-intent', async (req, res) => {
const url = `https://${env.site}.chargebee.com/api/v2/payment_intents`;
const amount = 5000;
const currencyCode = 'USD';
try {
const result = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa(`${env.apiKey}:`),
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
amount: amount,
currency_code: currencyCode
})
})
const response = await result.json();
console.log(response)
res.status(200);
res.send(response.payment_intent);
} catch (error) {
console.log(error)
res.status(500);
res.send(error);
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
See on GitHub:
/server/server.js
(opens new window)
# Add a <div>
for the payment component (client)
Add an empty placeholder <div>
element to your page as a placeholder for the payment component. Chargebee inserts an <iframe>
into this <div>
to securely collect payment information.
<div id="payment-component"></div>
See on GitHub:
/client/index.html
(opens new window)
# Create and mount the payment component (client)
Create a Components
object and use it to create a PaymentComponent
object. Mount the payment component to the placeholder <div>
. This adds an <iframe>
with a dynamic form that displays the payment methods.
You can restrict the displayed payment methods using the paymentMethods.allowed
option and specify their sort order using paymentMethods.sortOrder
.
The customer provides the details for the payment method and submits the form.
const componentOptions = {
locale: "fr",
style: {
theme: {
accentColor: "gold",
appearance: "light",
},
variables: {
spacing: 2,
accentIndicator: "#ffff00",
},
},
};
const paymentComponentOptions = {
paymentIntent: json,
layout: {
type: "tab",
showRadioButtons: true,
},
paymentMethods: {
sortOrder: ["card", "paypal_express_checkout", "google_pay", "apple_pay"],
allowed: ["apple_pay", "paypal_express_checkout", "card", "google_pay"],
},
};
const components = chargebee.components(componentOptions);
const paymentComponent = components.create("payment", paymentComponentOptions, {
onError,
onSuccess,
onPaymentMethodChange,
onClose,
});
paymentComponent.mount("#payment-component");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
See on GitHub:
/client/scripts/checkout.js
(opens new window)
# (Optional) Add a <div>
for the payment button component (client)
Add an empty <div>
element to your page as a placeholder for the payment button component.
<div id="payment-button-component"></div>
See on GitHub:
/client/index.html
(opens new window)
The payment button component is a dynamic prebuilt UI button that submits the payment form when clicked.
Optional component
The payment button component is recommended but optional. Alternatively, you can implement your own payment button.
# (Optional) Create and mount the payment button component (client)
Use the Components
object to create a PaymentButton
object and mount it to the placeholder <div>
created earlier.
const paymentButtonComponent = components.create(
"payment-button",
{},
{
onError,
onClose,
},
);
paymentButtonComponent.mount("#payment-button-component");
2
3
4
5
6
7
8
9
10
See on GitHub:
/client/scripts/checkout.js
(opens new window)
Chargebee inserts an <iframe>
into the <div>
, creating a dynamic payment button that adjusts based on the selected payment method. When the customer clicks the payment button, Chargebee manages the interaction and collects the payment.
# Handle errors (client)
If there are any errors during payment collection (e.g., card declines), the payment component calls the onError()
callback. Use the error object to display relevant messages to the user so they can retry or select a different payment method.
# Request to create a subscription (client)
Using webhooks
Use webhooks (opens new window) for production use, instead of making the subscription creation request from the client-side, it's more secure and reliable to respond to webhooks from Chargebee on the server-side. Listen to the payment_intent_updated
(opens new window) event via webhooks and create the subscription when the payment_intent.status
(opens new window) is authorized.
In the onSuccess()
callback, request your server to create a subscription for the customer at Chargebee. The callback includes the authorized payment_intent
(opens new window). Pass the payment_intent.id
(opens new window) to your server.
const onSuccess = async (payment_intent, extra) => {
const url = "http://localhost:8082/submit";
console.log(payment_intent, extra);
try {
const response = await fetch(url, {
body: JSON.stringify({ payment_intent_id: payment_intent.id }), // Convert to JSON string
method: "POST",
headers: {
'Content-Type': 'application/json' // Set the content type to JSON
}
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const json = await response.json();
console.log("checkout-complete", json);
} catch (error) {
console.error(error.message);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
See on GitHub:
/client/scripts/checkout.js
(opens new window)
# Create a subscription (server)
Use the create subscription API (opens new window), passing the authorized payment_intent.id
, and customer details to create a subscription in Chargebee.
const createSubscriptionUri = `https://${env.site}.chargebee.com/api/v2/customers/` + customer.id + '/subscription_for_items';
const createSubscriptionResult = await fetch(createSubscriptionUri, {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa(`${env.apiKey}:`),
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'subscription_items[item_price_id][0]': 'Non-Zero-Dollar-Plan-USD-Monthly',
'subscription_items[quantity][0]': '1',
'payment_intent[id]': paymentIntentId
})
})
2
3
4
5
6
7
8
9
10
11
12
13
See on GitHub:
/server/server.js
(opens new window)