Component checkouts
Acquire a basic understanding of how to integrate components
​Components are a low-code checkout option that consist of UI building blocks. They allow you to create customized checkout flows that connect to Digital River's address validation, logistics, local pricing, payment processing, subscription, fraud detection, tax computation, and compliance services.
​Components make it even easier to integrate with Digital River, reducing the amount of time you spend launching and managing your solution.
You can use all of the available components together to create traditional checkout flows. Alternatively, you might decide to use them selectively to construct specialized flows. For example, by pairing the wallet component with the compliance component, you can offer customers an expedited checkout experience.
On this page, you'll find information on:
After customers successfully complete the checkout process, your application also needs to handle completed checkout-sessions.
During the early stages of an e-commerce transaction, customers land on your storefront, review products and build a cart. Unless you're engaging our local pricing service, Digital River is typically not involved in these pre-checkout interactions. However, once customers initiate checkout, you'll need to start interacting with components.
For each component that you implement, your DOM needs to contain a unique HTML element to display it.
...
<div id="address-container" style="display: block"></div>
<div id="shipping-container" style="display: block"></div>
<div id="tax-identifier-container" style="display: block"></div>
<div id="payment-container" style="display: block"></div>
<div id="wallet-container" style="display: block"></div>
<div id="compliance-container" style="display: block"></div>
<div id="order-summary-container" style="display: block"></div>
<div>
<div>
<button id="previousButton" onclick="onPreviousButtonClick()">Previous</button>
</div>
<div>
<button id="nextButton" onclick="onNextButtonClick()">Next</button>
</div>
</div>
<div id="order-confirmation-container" style="display: none"></div>
...
​
The following example uses all of the available components, but how you design your experience is highly customizable.
Address collection stage
Shipping choice collection stage
Tax identifier collection stage
e-invoice collection stage
Payment collection stage
Order confirmation stage







If you implement multiple components that accept customer input, such as address, shipping, and payment, your experience should also contain buttons, or some other type of navigational control, that allows customers to move the checkout process forward and backward. These button's click events should activate your checkout flow control functionality.
On your checkout page, you should:
In the
head
of your html
, add the DigitalRiverCheckout.js script. If you'd like, you can also include a link
to the DigitalRiver.css
style sheet. <head>
<title>Checkout Page</title>
<script defer="defer" src="https://checkout.digitalriverws.com/v1/DigitalRiverCheckout.js"></script>
<link rel="stylesheet" href="https://js.digitalriverws.com/v1/css/DigitalRiver.css" type="text/css"/>
</head>
let digitalRiverCheckout = new DigitalRiverCheckout("YOUR_PUBLIC_API_KEY");
When your checkout page loads, invoke an asynchronous function that initializes components.
...
initializeComponents();
...
async function initializeComponents() {
//Build a configuration object
const configuration = {
checkoutSessionId: await createComponentsCheckoutSession(),
onReady: function (data) {
//Handle event
},
onChange: function (data) {
//Handle event
},
onSuccess: function (data) {
//Handle event
}
}
//Create components
let components;
components = digitalRiverCheckout.components(configuration);
//Create the individual components
paymentComponent = components.createComponent('payment');
shippingComponent = components.createComponent('shipping');
addressComponent = components.createComponent('address');
walletComponent = components.createComponent('wallet');
thankYouComponent = components.createComponent('thankyou');
complianceComponent = components.createComponent('compliance');
orderSummaryComponent = components.createComponent('ordersummary');
//Mount the individual components
paymentComponent.mount('payment-container');
shippingComponent.mount('shipping-container');
addressComponent.mount('address-container');
walletComponent.mount('wallet-container');
thankYouComponent.mount('order-confirmation-container');
complianceComponent.mount('compliance-container');
orderSummaryComponent.mount('order-summary-container');
}
To set
checkoutSessionId
in the components configuration object, you should invoke an asynchronous function, wrapped by your initialize components function, that defines a checkout-session on your front-end and then passes that data to your server so that it can submit the create request. Alternatively, before loading your checkout page, you could define and create a checkout-session completely server-side.
In either case, the function you implement needs to return the checkout-session's
id
. function createComponentsCheckoutSession() {
//Creates checkout-session
//Returns checkout-session identifier
}
async function initializeComponents() {
//Build a configuration object
const configuration = {
checkoutSessionId: await createComponentsCheckoutSession(),
onReady: function (data) {
//Handle event
},
onChange: function (data) {
//Handle event
},
onSuccess: function (data) {
//Handle event
}
}
...
}
async function initializeComponents() {
...
//Create components
let components;
components = digitalRiverCheckout.components(configuration);
...
}
Use the object returned by
components()
to create the individual components that you want customers to interact with. async function initializeComponents() {
...
//Create the individual components
paymentComponent = components.createComponent('payment');
shippingComponent = components.createComponent('shipping');
addressComponent = components.createComponent('address');
walletComponent = components.createComponent('wallet');
thankYouComponent = components.createComponent('thankyou');
complianceComponent = components.createComponent('compliance');
orderSummaryComponent = components.createComponent('ordersummary');
...
}
async function initializeComponents() {
...
//Mount the individual components
paymentComponent.mount('payment-container');
shippingComponent.mount('shipping-container');
addressComponent.mount('address-container');
walletComponent.mount('wallet-container');
thankYouComponent.mount('order-confirmation-container');
complianceComponent.mount('compliance-container');
orderSummaryComponent.mount('order-summary-container');
}
- Using
data.requiresShipping
to set a boolean variable that controls whether the shipping component needs to be displayed during the checkout process. - Using
data.showTaxIdentifiers
to set a boolean that controls whether the tax identifier component needs to be displayed.
...
onReady: function (data) {
if (data.requiresShipping === false) {
//Update the variable that controls whether to display the shipping component
}
if (data.showTaxIdentifiers === false) {
//Update the variable that controls whether to display the tax identifier component
}
//Call a function that determines the correct component(s) to display
},
...
If you're using the tax identifier component, handle
onChange
by determining whether optionalTaxIdentifiers[]
or requiredTaxIdentifiers[]
exists in the returned data
. If either does, set a variable that controls whether that component is displayed during the checkout process.onChange: function (data) {
...
if (('optionalTaxIdentifiers' in data) || ('requiredTaxIdentifiers' in data)){
//Set a display tax identifier component boolean variable to true
//At some point in the checkout process, display the tax identifier component
};
},
...
If, for whatever reason, you decide not to use the order summary component, you can also use
onChange
to update your custom-built order summary section. There are a variety of ways to do this. The example below retrieves
locale
, currency
, totalAmount
, totalShipping
, totalTax
, and subTotal
, along with each items[].amount
, from the data
returned by onChange
and then constructs JavaScript Int.NumberFormat objects which are then used to set the innerText
of the appropriate HTML element.In this example, the
sku.image
and sku.name
of each items[]
is also displayed. ...
onChange: function (data) {
const locale = data.locale.replace('_', '-');
document.getElementById('total').innerText = new Intl.NumberFormat(locale, { style: 'currency', currency: data.currency }).format(data.totalAmount);
document.getElementById('shipping').innerText = new Intl.NumberFormat(locale, { style: 'currency', currency: data.currency }).format(data.totalShipping);
document.getElementById('tax').innerText = new Intl.NumberFormat(locale, { style: 'currency', currency: data.currency }).format(data.totalTax);
document.getElementById('subtotal').innerText = new Intl.NumberFormat(locale, { style: 'currency', currency: data.currency }).format(data.subtotal);
document.getElementById('items').innerHTML = data.items.map( i => {
return <div>
<img style="height: 30px; width: 30px" src="${i.sku.image}"/> ${i.sku.name} - ${new Intl.NumberFormat(locale, { style: 'currency', currency: data.currency }).format(i.amount)}
</div>
});
},
...
One way to handle
onSuccess
is by passing an argument to your control checkout flow function, instructing it to display the thank you component. Alternatively, you could retrieve
order.id
(and whatever else you need) from data
and use it to build your custom order confirmation page. ...
onSuccess: function (data) {
// Display the thank you component or a customized order confirmation page
},
...
To control the flow of the checkout experience, you'll need to implement asynchronous functionality.
One possible approach is to define a function that checks a position enumeration, each value of which corresponds to a stage in the checkout process, and then, depending on the value, uses
document
to access each HTML element in your experience that holds a component, displaying and hiding the appropriate ones. As you progress through the various checkout stages, make sure you also call
done()
to ensure that the customer's inputs are submitted and valid. For details, refer to Submitting components. Some of the available components collect data from customers. For a subset of these, Digital River handles submitting that data. For others, you must initiate the process.
For example, in the payment component, DigitalRiver.js handles the button click event by sending a create source request, performing any required SCA or redirects to the payment provider, and then, assuming those processes are successful, requesting that the payment object be added to the checkout-session's
sources[]
. On the other hand, the address, shipping, tax identifier, and invoice components require that you invoke a function that submits the data they collect and determines whether it's valid. Specifically, these components require that, inside of an
async
function, you call done()
using the await
operator and then check the returned value to determine whether the checkout should advance to the next stage.Address component
Tax identifier component
Shipping component
Invoice attribute component
...
const addressComponentStatus = await addressComponent.done();
if (!addressComponentStatus) {
//Do not advance checkout to the next stage
return;
} else {
//Advance checkout to the next stage
}
...
...
const taxIdentifierComponentStatus = await taxIdentifierComponent.done();
if (!taxIdentifierComponentStatus) {
//Do not advance checkout to the next stage
return;
} else {
//Advance checkout to the next stage
}
...
...
const shippingComponentStatus = await shippingComponent.done();
if (!shippingComponentStatus) {
//Do not advance checkout to the next stage
return;
} else {
//Advance checkout to the next stage
}
...
...
const invoiceComponentStatus = await invoiceComponent.done();
if (!invoiceComponentStatus) {
//Do not advance checkout to the next stage
return;
} else {
//Advance checkout to the next stage
}
...
For details, refer to:
Last modified 1mo ago