Payment Components Use Cases
This guide covers common Payment Components use cases, from your first integration through to routing payments across multiple gateways. For an introduction to the feature, see Payment Components.
Start with the Payment Components quickstart
If you haven't integrated Payment Components yet, begin here. The quickstart builds a working checkout page from a sample app, covering how to load Chargebee.js, create a payment intent on your server, mount the Payment Component and Payment Button Component, and create a subscription after the payment is authorized.
For the full walkthrough with sample code, see the Payment Components quickstart.
Update the payment amount during checkout
You may need to change the payment amount dynamically on your payment page. Scenarios include adding or removing items in the cart, changing the quantity of the cart items, changes in taxes, applying a coupon, or applying bundle offers.
Warning
Derive the amount and currency on your server, from the cart in the customer's authenticated session, exactly as you did when you created the payment_intent. Never accept an amount or a currency from the browser, because a customer can change either value before the request reaches your server.
Implement dynamic amount changes
1. Request to update the payment intent (client)
When the cart changes, request your server to update the payment_intent. Send only what identifies the cart, such as the cart or checkout session ID. In the following example, the server reads the cart from the session cookie, so the request carries no payment terms at all.
const url = "http://localhost:8082/payment-intent-update";
const response = await fetch(url, {
method: "POST",
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const json = await response.json();
2. Update the payment intent (server)
Recalculate the total from the cart your server holds, then call Chargebee's update payment intent endpoint with that amount and the currency you sell that cart in. If the request from the page does carry an amount or a currency, ignore it.
curl https://{site}.chargebee.com/api/v2/payment_intents/{payment_intent_id} \
-u {site_api_key}:\
-d amount=300 \
-d currency_code="USD"
3. Update the Payment Component (client)
Use the update() method to remount the Payment Component with this change.
paymentComponent.update({
paymentIntent: {
id: '{payment_intent_id}',
},
});
Show payment methods based on cart value
The Payment Component loads the payment methods your site is eligible for from the payment_intent it was created with, so the amount on that payment_intent decides what the customer sees. You can narrow the list further, and set the order the methods appear in, using the paymentMethods.allowed and paymentMethods.sortOrder options. Use this to lead with the method you want customers to pick at a given cart value, such as a low-cost bank debit on a large order and a one-tap wallet on a small one.
Vary payment methods by cart value
1. Map cart values to payment methods (client)
Decide which methods to offer at each cart value. Keep this in one function so the rule stays in a single place. The amount passed in is the one your server returns on the updated payment_intent, not a total calculated in the browser.
const HIGH_VALUE_THRESHOLD = 50000; // 500.00 in the smallest currency unit
function paymentMethodsForAmount(amount) {
if (amount >= HIGH_VALUE_THRESHOLD) {
return {
allowed: ["direct_debit", "card", "paypal_express_checkout"],
sortOrder: ["direct_debit", "card", "paypal_express_checkout"],
};
}
return {
allowed: ["apple_pay", "google_pay", "card", "paypal_express_checkout"],
sortOrder: ["apple_pay", "google_pay", "card", "paypal_express_checkout"],
};
}
Information
allowed can only narrow the methods your site is already eligible for. To offer a method that isn't in the list the component loads, enable it on your gateway first.
2. Update the payment intent with the new amount (server)
When the cart changes, recalculate the total on your server and update the payment_intent with it, as described in Update the payment amount during checkout. Return the updated payment_intent to the page. The component reloads the methods that are eligible for that amount.
3. Update the Payment Component (client)
Call update() with the updated payment_intent and the payment methods for its amount.
async function onCartValueChange() {
// Your endpoint that recalculates the total and updates the payment intent, from step 2.
const response = await fetch("http://localhost:8082/payment-intent-update", {
method: "POST",
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const paymentIntent = await response.json();
paymentComponent.update({
paymentIntent: { id: paymentIntent.id },
paymentMethods: paymentMethodsForAmount(paymentIntent.amount),
});
}
Note
update() remounts the component, which clears any details the customer has already entered. Call it when the cart total settles, such as after a quantity change or a coupon is applied, and not on every keystroke.
Show payment methods based on region
Many payment methods are available only in specific regions, such as iDEAL in the Netherlands, Bancontact in Belgium, and UPI in India. Which methods a customer is eligible for follows the currency on the payment_intent, so when the customer selects a country, update the payment_intent with the currency for that region and pass the country to the component through context.billingAddress.countryCode.
The country is a customer input, so the page sends it to your server, and your server decides what it means. Keep the country-to-currency and country-to-price mapping on the server, and reject a country you don't sell in rather than falling back to a currency the customer picked.
Vary payment methods by region
1. Map countries to payment methods (client)
For each country that needs a local payment method, record the methods to offer, with a fallback for the remaining countries you sell in. This mapping only affects what the component displays, so it can live in the browser. The currency and the amount for each region stay on the server, in step 2.
const REGIONS = {
NL: {
allowed: ["ideal", "card", "paypal_express_checkout"],
sortOrder: ["ideal", "card", "paypal_express_checkout"],
},
BE: {
allowed: ["bancontact", "card", "paypal_express_checkout"],
sortOrder: ["bancontact", "card", "paypal_express_checkout"],
},
IN: {
allowed: ["upi", "netbanking_emandates", "card"],
sortOrder: ["upi", "netbanking_emandates", "card"],
},
};
const DEFAULT_REGION = {
allowed: ["card", "apple_pay", "google_pay", "paypal_express_checkout"],
sortOrder: ["card", "apple_pay", "google_pay", "paypal_express_checkout"],
};
2. Update the payment intent with the region's currency (server)
Look up the country your page sent against the regions you sell in, and take the currency and the amount for that region from your own pricing. If the country isn't one you sell in, return an error rather than falling back to a currency you haven't priced the cart in. Then call Chargebee's update payment intent endpoint with the amount and currency you looked up.
curl https://{site}.chargebee.com/api/v2/payment_intents/{payment_intent_id} \
-u {site_api_key}:\
-d amount=30000 \
-d currency_code="EUR"
3. Update the Payment Component (client)
Call update() with the updated payment_intent, the customer's country, and the payment methods for the region.
async function onCountryChange(countryCode) {
// Your endpoint that resolves the region and updates the payment intent, from step 2.
const response = await fetch("http://localhost:8082/payment-intent-update", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ country_code: countryCode }),
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const paymentIntent = await response.json();
paymentComponent.update({
paymentIntent: { id: paymentIntent.id },
context: {
billingAddress: { countryCode },
},
paymentMethods: REGIONS[countryCode] || DEFAULT_REGION,
});
}
Information
To send payments from a region to a specific gateway account, such as a local acquirer, pair this with Advanced Routing.
Customize the style of Payment Components
Payment Components offer granular styling and presentation options to match your website design. To customize the styling, use the style parameter in the following scenarios:
- When creating the
Componentsobject. This styling is inherited by all Payment Components and Payment Button Components associated with this object. - When creating or updating a Payment Component.
- When creating or updating a Payment Button Component.
Customize field and label text for different languages
To deliver a localized and branded checkout experience, you can override the default translations on the Payment Components UI using the Chargebee Billing Language Pack.
Customize translations in the language pack
In the language-specific folder, such as en, fr, or es, open the internal/components.csv file. Then, update the value column to provide your custom translations for the relevant fields and labels in the Payment Components UI.
Example: Customize the CVV label and placeholder
Update these keys in internal/components.csv:
component.payment.input.label.cvvcomponent.payment.input.label.cvv.placeholder
Example values:
- Label:
Security Code - Placeholder:
123
Track typing or field changes in Payment Components
The parent page of the Payment Components iframe cannot track typing or field-change events, because Payment Components run inside a cross-origin iframe.
Use callbacks to track payment activity
To work around this limitation, Payment Components provide the following callbacks:
- Payment method selected or changed (
onPaymentMethodChange) - Payment button clicked (
onButtonClick) - Payment authorization successful (
onSuccess) - Payment authorization failed (
onError)
Information
Use the validate() function to validate input fields in Payment Components.
Warning
Treat these callbacks as UI signals only. In production, create the subscription on your server in response to the payment_intent_updated webhook, when the payment_intent.status is authorized, rather than from onSuccess() in the browser.
Route payments with Advanced Routing
Advanced Routing directs each transaction to a specific gateway account based on rules you define, such as the customer's region, the plan amount, or the payment method. Use it to improve authorization rates, reduce transaction costs, or meet local acquiring requirements.
- To configure routing rules for your site, see Advanced Routing.
- For a code walkthrough of handling routed payments in your integration, see the Advanced Routing tutorial.
Was this article helpful?