Drop-in Checkout
Learn how to build a Drop-in Checkout integration
Drop-in Checkout is a configurable checkout experience that allows you to connect an upstream commerce system with Digital River's payment processing, fraud detection, tax exemption, and disclosure services.
The Drop-in Checkout solution reduces the complexity of integrating with the Digital River APIs and the DigitalRiver.js library, thereby shortening your time to deployment.
Once customers build a cart and initiate checkout, a Drop-in Checkout integration needs to:

Building a cart

During the early stages of an ecommerce transaction, customers land on your storefront, review products and build a cart. Digital River is typically not involved in these early pre-checkout interactions. Once the customer initiates checkout, you start interacting with Drop-in Checkout.

Initiating checkout

Add a click event listener to each checkout button on your site. Handle the event by defining a checkout-session request, passing that request data to your back-end server, and then securely sending a create checkout-session request.
Digital River returns a unique checkout-session identifier that you must pass, along with an optional configuration object, to the create modal method on your front-end.

Defining a checkout-session

A checkout-session determines what information and options are presented to customers in the checkout modal.
At a minimum, your create checkout-session request needs to contain currency and product data. You may also want to tell us whether your prices are tax inclusive. When checking out registered customers, send their unique identifier and (optionally) their saved addresses. If the customer’s cart contains physical products, you need to configure the request so the modal displays shipping method options.
For request specifications, refer to the checkout sessions reference documentation.

Currency

After the checkout modal opens, the subtotal, shipping, tax, and total amounts displayed to customers are denoted in the currency you send in the request.

Product data

For each product in the customer’s cart, use items[] to send:
  • A skuId or productDetails. For more information, refer to Product basics.
  • A price or aggregatePrice.
  • A quantity.
1
{
2
"currency": "USD",
3
"items": [
4
{
5
"skuId": "3ea112ec-83b6-45c7-8e22-e2114e903745",
6
"quantity": 1,
7
"price": 300
8
}
9
],
10
...
11
}
Copied!

Tax inclusive

The taxInclusive boolean dictates how prices are displayed in the checkout modal (the default value is false). If you set taxInclusive to true, then the UI indicates that the total amount includes VAT.
The value you assign taxInclusive also determines how we treat product prices when calculating tax.

Registered customers

For checkouts initiated by a registered customer, your request can include:

Customer identifier

To checkout customers who are registered in your system, send their customerId.
1
{
2
...
3
"customerId": "230f61be-8822-4325-9926-e9d0731691b4"
4
...
5
}
Copied!
We use this identifier to look up the customer in our system.
If the referenced customer exists, we retrieve its transaction-applicable taxIdentifiers[] and payment sources[] and present them as options in the checkout modal.
If the customer doesn’t exist in our system, we create a new object and assign it the customerId you provided.
In either case, as registered customers progress through the checkout experience, they are given the option to save their shipping information, tax identifiers, billing information and payment methods for use in future transactions.

Saved addresses

If you persist registered customers’ addresses, and the customer checking out has one or more saved addresses in your system, you can use options.addresses[] to send Digital River this data.
1
{
2
...
3
...
4
"options": {
5
...
6
"addresses": [
7
{
8
"address": {
9
"line1": "10380 Bren Rd W",
10
"city": "Minnetonka",
11
"postalCode": "55129",
12
"state": "MN",
13
"country": "US"
14
},
15
"name": "John Smith",
16
"phone": "952-111-1111",
17
"email": "[email protected]",
18
"organization": "Digital River",
19
"additionalAddressInfo": {
20
"neighborhood": "Centro",
21
"division": "営業部",
22
"phoneticName": "ヤマダ タロ"
23
}
24
},
25
{
26
"address": {
27
"line1": "62 Trinity Crescent",
28
"city": "WHITCHURCH",
29
"postalCode": "CF4 9ZB",
30
"country": "GB"
31
},
32
"name": "Anna Brawner",
33
"phone": "07854319925",
34
"email": "[email protected]",
35
"organization": "Digital River",
36
"additionalAddressInfo": {
37
"neighborhood": "Centro",
38
"division": "営業部",
39
"phoneticName": "ヤマダ タロ"
40
}
41
}
42
]
43
},
44
"customerId": "230f61be-8822-4325-9926-e9d0731691b4"
45
}
Copied!
In the checkout modal’s address collection stage, we present these saved addresses to customers for convenience purposes.
For each element in addresses[], the modal only displays name and address.

Shipping methods

If the product data you send contains physical items, your request must include either static shipping methods or an endpoint that we call to retrieve dynamic shipping methods. Failure to pass this data in a POST/drop-in/checkout-sessions throws the following error:
400 Bad Request
1
{
2
"type": "bad_request",
3
"errors": [
4
{
5
"code": "invalid_request",
6
"message": "Shipping methods are required with physical items"
7
}
8
]
9
}
Copied!
Whether you use static or dynamic shipping methods, the checkout-session needs to contain shipFrom.address.country at the line item-level and/or order-level.

Static shipping methods

If you store static shipping methods in your system, and want to display them as options in the checkout modal, send options.shippingMethods[]. These are methods whose amount and serviceLevel are not dependent on where the checkout’s products are being shipped or how much they weigh.
1
{
2
...
3
"options": {
4
"shippingMethods": [
5
{
6
"amount": 5,
7
"description": "Standard Shipping",
8
"serviceLevel": "SG"
9
},
10
{
11
"amount": 15,
12
"description": "Next Day Air",
13
"serviceLevel": "ND"
14
}
15
],
16
...
17
},
18
"customerId": "230f61be-8822-4325-9926-e9d0731691b4"
19
}
Copied!

Dynamic shipping methods

Alternatively, you can present customers with transaction-specific shipping options that take into account product weight, warehouse location, and shipping destination. To display these types of dynamic shipping methods, use options to send a shippingCalloutEndpoint.
1
{
2
...
3
"options": {
4
"shippingCalloutEndpoint": "https://company.com/checkout/shipping-quotes"
5
...
6
}
7
}
Copied!
After customers submit shipping information, we pass their address (along with the checkout-session’s product data) in a POST/checkout/shipping-quotes. The shippingCalloutEndpoint you provide must be able to receive and handle this request and send a reply that adheres to the response contract.
For specifications, refer to the Drop-in shipping quotes reference documentation.

Creating a checkout-session

To create a checkout-session, send your secret API key and request payload in a POST/drop-in/checkout-sessions.
1
curl --location --request POST 'https://api.digitalriver.com/drop-in/checkout-sessions' \
2
--header 'Content-Type: application/json' \
3
--header 'Authorization: <Secret API Key>' \
4
...
5
--data-raw '{
6
<Request payload>
7
}'
Copied!

The checkout-session identifier

The response to your create checkout-session request contains a unique id.
1
{
2
"id": "eb3b9cc3-d068-4300-9488-c88c0341b5db"
3
...
4
}
Copied!
Use this checkout-session identifier to create a Drop-in Checkout modal.

Creating a Drop-in Checkout modal

Add the following Digital River checkout library link to your checkout pages.
1
<script src="https://checkout.digitalriverws.com/v1/DigitalRiverCheckout.js"></script>
Copied!
Use your public API key to create a Digital River checkout object.
1
const drCheckout = new DigitalRiverCheckout('YOUR_PUBLIC_API_KEY');
Copied!
Respond to checkout button click events by building a configuration object and then passing it and the checkout session identifier to the createModal() method.
1
document.getElementById('YOUR_CHECKOUT_BUTTON_ID').addEventListener('click', async (event) => {
2
3
// An example asynchronous function that creates the checkout session
4
const checkoutSessionId = await createCheckoutSession();
5
6
// Creates and opens the modal
7
drCheckout.createModal(checkoutSessionId, config);
8
});
Copied!

Drop-in Checkout modal window

After createModal() is invoked, the Drop-in Checkout modal window opens and the onReady event occurs.
Customers then proceed through the stages of a checkout. Customers are always required to provide their name, phone number, email address, billing address, and payment method. Depending on how you configure the checkout-session, they may also be prompted to specify a shipping address, shipping option and/or tax identifier.

Name and address stage

In checkouts that contain physical products, the modal first prompts the user for shipping information and then uses this same data to populate billing information. Later, during the payment stage, the customer does however have the option to provide different billing details.
In checkouts that only contain digital products, the modal doesn’t ask for shipping details. Instead, it simply prompts the user for billing information.
If you send customerId in the create checkout-session request, customers are given the option to save their shipping and billing information for use in future checkouts.
If you send options.addresses[] in the create checkout-session request, then the modal has the capability to present these saved addresses to the customer. If the customer uses the radio button control to select one of them, its values are populated in the address collection form.
When customers click the continue checkout button, onAddressComplete triggers an event that contains the customer-submitted address.
1
{
2
“billing”: {
3
“address”: {
4
“line1”: “10380 Bren Rd W”,
5
“city”: “Minnetonka”,Z
6
“postalCode”: “55129”,
7
“state”: “MN”,
8
“country”: “US”
9
},
10
“name”: “Jane Smith”,
11
“phone”: “5555555555”,
12
“email”: “[email protected]”,
13
“saveForLater”: false
14
},
15
“shipping”: {
16
“address”: {
17
“line1”: “10380 Bren Rd W”,
18
“city”: “Minnetonka”,
19
“postalCode”: “55129”,
20
“state”: “MN”,
21
“country”: “US”
22
},
23
“name”: “Jane Smith”,
24
“phone”: “5555555555”,
25
“email”: “[email protected]”,
26
“saveForLater”: true
27
}
28
}
Copied!

Shipping choice stage

In checkouts that contain physical products, the modal prompts the user to make a shipping choice. For each provided static or dynamic shipping method, customers are shown its description and amount.
When customers click the continue checkout button, onDeliveryComplete triggers an event that contains the customer’s selected shippingMethod and its calculated taxAmount.
1
{
2
“amount”: 15,
3
“description”: “Next Day Air”,
4
“serviceLevel”: “ND”,
5
“taxAmount”: 1.11
6
}
Copied!

Tax identifiers stage

In applicable checkouts, the modal prompts the customer for a tax identifier.
In guest checkouts, customers can enter a tax identifier but are not given the option to save the value.
Registered customers with applicable, saved tax identifiers can either select one of the values presented to them or enter a new one.
Registered customers with no stored, transaction-applicable tax identifiers can save a new value for use in future checkouts. If they select this option, Digital River saves the tax identifier to the customer’s record.
In countries that require tax identifiers, customers must enter a value before proceeding to the payment stage. ****

Payment stage

In the payment collection stage, the modal only displays payment methods that are appropriate to the transaction.
When the checkout involves registered customers, we retrieve and display their saved, applicable payment methods.

Order confirmation stage

Once customers provide payment, agree to the terms, and successfully submit the order, onCheckoutComplete triggers an event that contains an order object.
Depending on how you configure the order confirmation stage, you can retrieve relevant data from the object (such as id) and display it to customers on a customized page.
The following is an example of the default order confirmation window.

Handling the checkout session order created event

Prior to deployment, configure a webhook to listen for the checkout_session.order.created event.
1
{
2
"id": "7312d117-4201-4a27-80e3-9e72f7ba2609",
3
"type": "checkout_session.order.created",
4
"data": {
5
"object": {
6
"id": "213614540336",
7
"checkoutId": "5dd0a16c-35e0-4451-a8a9-1ac8dc57008f",
8
"checkoutSessionId": "738d1e74-7efc-488f-9f4b-0f4d18351912",
9
"createdTime": "2022-01-21T16:46:37Z",
10
"currency": "USD",
11
"customerId": "230f61be-8822-4325-9926-e9d0731691b4",
12
"email": "[email protected]",
13
"shipTo": {
14
"address": {
15
"line1": "10380 Bren Rd W",
16
"city": "Minnetonka",
17
"postalCode": "55129",
18
"state": "MN",
19
"country": "US"
20
},
21
"name": "Jane Smith",
22
"phone": "5555555555",
23
"email": "[email protected]",
24
"saveForLater": true
25
},
26
"billTo": {
27
"address": {
28
"line1": "10380 Bren Rd W",
29
"city": "Minnetonka",
30
"postalCode": "55129",
31
"state": "MN",
32
"country": "US"
33
},
34
"name": "John Smith",
35
"phone": "952-111-1111",
36
"email": "[email protected]",
37
"organization": "Digital River",
38
"additionalAddressInfo": {
39
"neighborhood": "Centro",
40
"division": "営業部",
41
"phoneticName": "ヤマダ タロ"
42
},
43
"saveForLater": true
44
},
45
"totalAmount": 338.24,
46
"subtotal": 315.0,
47
"totalFees": 0.0,
48
"totalTax": 23.24,
49
"totalImporterTax": 0.0,
50
"totalDuty": 0.0,
51
"totalDiscount": 0.0,
52
"totalShipping": 15.0,
53
"items": [
54
{
55
"id": "137988690336",
56
"sku": {
57
"id": "3ea112ec-83b6-45c7-8e22-e2114e903745",
58
"name": "Water Dish For Thirsty Dogs",
59
"eccn": "EAR99",
60
"taxCode": "4323.310_A",
61
"image": "https://tools.drapi.io/cm/drop-in-checkout/sku-data/dog_drinking.jpg",
62
"physical": true
63
},
64
"amount": 300.0,
65
"quantity": 1,
66
"tax": {
67
"rate": 0.07375,
68
"amount": 22.13
69
},
70
"importerTax": {
71
"amount": 0.0
72
},
73
"duties": {
74
"amount": 0.0
75
},
76
"availableToRefundAmount": 0.0,
77
"shipFrom": {
78
"address": {
79
"line1": "10380 Bren Rd W",
80
"city": "Minnetonka",
81
"postalCode": "55129",
82
"state": "MN",
83
"country": "US"
84
}
85
},
86
"fees": {
87
"amount": 0.0,
88
"taxAmount": 0.0
89
}
90
}
91
],
92
"shippingChoice": {
93
"amount": 15.0,
94
"description": "Next Day Air",
95
"serviceLevel": "ND",
96
"taxAmount": 1.11
97
},
98
"updatedTime": "2022-01-21T16:46:37Z",
99
"locale": "en_US",
100
"customerType": "individual",
101
"sellingEntity": {
102
"id": "DR_INC-ENTITY",
103
"name": "Digital River Inc."
104
},
105
"payment": {
106
"charges": [
107
{
108
"id": "cfc58ddf-3442-441a-ac9f-52a25ef4f26f",
109
"createdTime": "2022-01-21T16:46:43Z",
110
"currency": "USD",
111
"amount": 338.24,
112
"state": "capturable",
113
"captured": false,
114
"refunded": false,
115
"sourceId": "6eac5b31-dde9-426f-b340-886ccb6b2799",
116
"type": "customer_initiated"
117
}
118
],
119
"sources": [
120
{
121
"id": "6eac5b31-dde9-426f-b340-886ccb6b2799",
122
"type": "creditCard",
123
"amount": 338.24,
124
"owner": {
125
"firstName": "John",
126
"lastName": "Smith",
127
"email": "[email protected]",
128
"address": {
129
"line1": "10380 Bren Rd W",
130
"city": "Minnetonka",
131
"postalCode": "55129",
132
"state": "MN",
133
"country": "US"
134
},
135
"organization": "Digital River",
136
"additionalAddressInfo": {
137
"neighborhood": "Centro"
138
}
139
},
140
"creditCard": {
141
"brand": "MasterCard",
142
"expirationMonth": 12,
143
"expirationYear": 2023,
144
"lastFourDigits": "0008",
145
"fundingSource": "credit"
146
}
147
}
148
],
149
"session": {
150
"id": "edf1e96c-852a-49f8-91db-301f5c8b6b79",
151
"amountContributed": 338.24,
152
"amountRemainingToBeContributed": 0.0,
153
"state": "complete",
154
"clientSecret": "edf1e96c-852a-49f8-91db-301f5c8b6b79_c477ad6f-d6a1-427c-a326-2a836a55a09b"
155
}
156
},
157
"state": "accepted",
158
"stateTransitions": {
159
"accepted": "2022-01-21T16:46:44Z"
160
},
161
"fraudState": "passed",
162
"fraudStateTransitions": {
163
"passed": "2022-01-21T16:46:44Z"
164
},
165
"taxInclusive": false,
166
"liveMode": false
167
}
168
},
169
"liveMode": false,
170
"createdTime": "2022-01-21T16:46:46.413672Z",
171
"digitalriverVersion": "2021-12-13"
172
}
Copied!
This event occurs when a customer successfully completes checkout and an order is created in Digital River’s system. Handle the event by first determining whether customers requested that their shipping and billing information be saved for later, and then, if necessary, update the customer's record in your system.
We don’t recommend that you use checkout_session.order.created to trigger order fulfillment. Instead, listen for the order.accepted event and use it to drive downstream fulfillment processes.
For more information, refer to Events early in the order lifecycle on the Processing orders page.

Save for later

In the event’s data.object, if shipTo.saveForLater and/or billTo.saveForLater are true, then customers opted to save their shipping and/or billing information for use in future transactions. You can use this as a flag to trigger a method that updates the customer’s saved addresses in your system.
1
{
2
"id": "7312d117-4201-4a27-80e3-9e72f7ba2609",
3
"type": "checkout_session.order.created",
4
"data": {
5
"object": {
6
"id": "213614540336",
7
"checkoutId": "5dd0a16c-35e0-4451-a8a9-1ac8dc57008f",
8
"checkoutSessionId": "738d1e74-7efc-488f-9f4b-0f4d18351912",
9
...
10
"shipTo": {
11
...
12
"saveForLater": true
13
},
14
"billTo": {
15
...
16
"saveForLater": false
17
},
18
...
19
}
Copied!

Configuring the checkout modal

You can optionally pass a configuration object to the create Drop-in Checkout modal method. This object allows you to:
1
const config = {
2
options: options,
3
onReady: () => {},
4
onAddressComplete: (address) => {},
5
onDeliveryComplete: (shippingMethod) => {},
6
onPaymentCancel: () => {},
7
onCheckoutComplete: (order) => {},
8
onError: () => {},
9
onClose: () => {}
10
};
Copied!

Defining the checkout experience

In the configuration object, options can be used to stylize and localize the modal, as well as customize order confirmation notifications.
1
const options = {
2
style: {
3
modal: {
4
logo: 'https://www.mysite.com/logo.png',
5
themeColor: {
6
primary: '#00a7e1',
7
highlight: '#b6e8fb',
8
background: {
9
header: '#b6e8fb',
10
mainContent: '#fff',
11
orderSummary: '#e4edf7',
12
footer: '#001c33'
13
},
14
text: {
15
link: '#003058',
16
footerLink: '#0befc5',
17
sectionHeading: '#083bf1',
18
button: '#ffc439',
19
textButton: '#0befc5'
20
}
21
},
22
borderRadius: '3px',
23
fontFamily: 'Arial, Helvetica, sans-serif',
24
fontStyle: 'italic',
25
fontVariant: 'normal',
26
letterSpacing: '3px'
27
},
28
textField: {
29
base: {
30
color: '#00a7e1',
31
fontFamily: 'Arial, Helvetica, sans-serif',
32
fontSize: '20px',
33
fontStyle: 'italic',
34
fontVariant: 'normal',
35
letterSpacing: '3px'
36
},
37
borderRadius: '4px'
38
}
39
},
40
language: 'it',
41
thankYouPage: 'https://www.mysite.com/order-confirmation-page'
42
};
Copied!

Stylize the modal

Set style.modal and style.textField to alter the modal’s default logo, theme, borders, text fields, and fonts.

Localize the modal

By default, Digital River localizes the modal based on the customer’s browser settings. But if you want a checkout experience with a customized locale, set language to one of the following values:
Code value
Language/Locale
ar
Arabic
cs
Czech
da
Danish
de
German
el
Greek
en-gb
English UK
en
English
en-us
English USA
es
Spanish
es-419
Spanish - Latin America
fi
Finnish
fr-ca
French Canadian
fr
French
hu
Hungarian
it
Italian
ja
Japanese
ko
Korean
nl
Dutch
no
Norwegian
pl
Polish

Customize order confirmation

By setting options.thankYouPage, you can configure the order confirmation stage.
  • Custom page: To redirect customers to a custom order confirmation page, pass the appropriate web address.
1
const options = {
2
...
3
thankYouPage: 'https://www.mysite.com/order-confirmation-page'
4
};
Copied!
  • Default window: To display Digital River's default order confirmation, omit thankYouPage from the request. To view an example of the modal, go to the Order confirmation stage section.
  • Close modal: If you want the modal to immediately close after customers place an order, set thankYouPage to none.

Responding to front-end events

The modal's configuration object allows you to define how you want to handle the following front-end events:
  • onReady: The modal is loaded and ready for customer interaction.
  • onAddressComplete: The customer submitted address information. This function returns an address that contains the customer’s billing and shipping data.
  • onDeliveryComplete: The customer submitted a shipping method choice. This function returns a shippingMethod that contains the customer’s shipping method selection.
  • onCheckoutComplete: The customer successfully submitted the order. This function returns an order.
  • onClose: The customer closed the modal.
  • onError: An error occurred during the checkout experience.

Checking the status of the modal

Use getStatus() to check the current status of the Drop-in Checkout modal.
1
const status = drCheckout.getStatus();
Copied!
The method returns a status that indicates the state of the modal and the customer’s currentStep in the experience:
1
{
2
"status": {
3
"modal": "active",
4
"currentStep": "addressInfo"
5
}
6
}
Copied!
The following are the possible modal status values:
  • pending: The checkout-session identifier is not yet created
  • inactive: The checkout-session identifier is created and the modal is initialized
  • active: The modal window is displayed to the customer
  • failed: The modal cannot be displayed to the customer
  • aborted: The customer closed the modal
  • finished: The customer provided payment and submitted the order (i.e., Digital River associated the source with the checkout and created the order)
The following are the possible currentStep values: