Building a Global Logistics checkout
Gain a better understanding of how to build a Global Logisitics checkout using the Direct Integration solution
If you're using the Direct Integration checkout solution and enable the Global Logisitics service, this page contains an overview of how to manage the checkout process. You'll also find more detailed information on how to:
During checkouts, Global Logistics (GL) gives you the capability to request international shipping quotes. Digital River routes your request to the appropriate global logistics provider (GLP) and then uses their response to provide you with a menu of shipping quotes that you can optionally filter and then display to customers.
Once customers select a shipping quote, you'll need to apply their choice to the checkout, and then, assuming they selected a quote with delivered duty paid (DDP) terms, use the duty, fee, and import tax amounts returned by Digital River to present customers with a transaction's full landed cost.
During the early stages of an ecommerce transaction, customers land on your storefront, review products, build a cart, confirm the cart's details, and initiate checkout. This cart-building process is roughly the same for both domestic and international transactions.
Digital River is usually not involved during these early pre-checkout interactions.
Some of your products however might have country restrictions applied to them. In other words, products prohibited from being exported to one or more specific countries.
To handle these prohibitions, you might want to block customers from adding restricted products to their carts. This helps avoid issues at customs as well as unanticipated return costs.
Plug-ins and extensions exist that geo-locate a customer's country. These add-ons then hide products from customers who are located in restricted countries. Some of these extensions also allow you to disable the add-to-cart button for prohibited product-country combinations.
Once you initiate the checkout process, you should obtain the customer's name, email, shipping address, and billing address.
In your shipping address form, we suggest mounting a drop-down list (or some similar graphical control element) that restricts available ship to countries to those defined by your trading patterns.
At this point, you can use the customer's shipping and billing information, along with product data retrieved from the customer's cart, to submit a create checkout request.
After you create a checkout, you need to send a shipping quotes request to Digital River. We transform your request and route it to the appropriate global logistics provider (GLP). The quality of the data you provide in this request determines the accuracy of the returned shipping quotes.
Upon receiving the shipping quote response, you may decide you want to handle the response by applying a filter before displaying the quotes to customers. Once the customer makes a selection, handle that event by retrieving data from the selected quote and sending it in an update checkout request.
A
POST /shipping-quotes
request must pass the checkout's currency, ship to address, and physical product data. You can optionally send a ship from country. In addition, unless you want to use a stored default box, we recommend that you send package weight and dimensions.POST/shipping-quotes
curl --location --request POST 'https: //api.digitalriver.com/shipping-quotes' \
...
--data-raw '{
"currency": "CAD",
"shipFrom": {
"address": {
"country": "US"
}
},
"shipTo": {
"address": {
"line1": "10-123 1/2 MAIN STREET NW",
"city": "MONTREAL",
"postalCode": "H3Z 2Y7",
"state": "QC",
"country": "CA"
},
"name": "JOHN JONES",
"phone": "367-222-4321",
"email": "[email protected]",
"organization": "Digital River"
},
"items": [
{
"productDetails": {
"skuGroupId": "group_1639749011",
"name": "PhysicalSku_1639749025",
"countryOfOrigin": "US"
},
"amount": 850,
"quantity": 1
},
{
"productDetails": {
"skuGroupId": "group_1639749016",
"name": "PhysicalSku_1639749033",
"countryOfOrigin": "US"
},
"amount": 1000,
"quantity": 1
}
],
"packages": [
{
"weight": 1.3,
"weightUnit": "kg",
"height": 8,
"width": 15,
"length": 20
}
]
}'
Earlier in the checkout process, you required customers to select a ship to country from a list of approved values. You also obtained the customer's ship to street address, city, state/region, and postal code and then used this data to set the checkout's
shipTo
.When configuring the shipping quotes request, we recommend you retrieve these same values and use them to set
shipTo
. This helps make the returned shipping quotes as accurate as possible.However, you're only technically required to send
shipTo.address.country
.If you pass a
shipTo.address.country
that is not supported by your defined trading patterns, then the following error is thrown:400 Bad Request
{
"type": "bad_request",
"errors": [
{
"code": "invalid_parameter",
"parameter": "shipTo.address",
"message": "The shipTo.address is invalid with the shipFrom.address"
}
]
}
Each physical product in the customer's cart should be passed in the shipping quote request's
items[]
.- The
id
references the product in your upstream order management system. - The
skuGroupId
references the SKU group associated with the product. From this resource, we retrieve the product's compliance data. - A product's
weight
is technically not required, but it's extremely important data. Without it, the GLP won't be able to precisely determine shipping rates, which meanstotalAmount
in the returned shipping quotes will likely be inaccurate. Productweight
should be as precise as possible. Make sure the value you pass is exclusive of packaging but inclusive of dunnage. For details, refer to defining basic product data in the Pre-deployment section. If you don't sendweight
or the value is inaccurate, then the shipping costs paid by the customer at checkout might be lower than the actual shipping costs assessed by the carrier. In this scenario, you're responsible for paying the difference. Therefore, we highly recommend that you sendweight
in the request. - A product's
url
,image
,countryOfOrigin
, andpartNumber
are generally not used by your GLP when generating shipping quotes. These attributes are however part ofproductDetails
. So, if you sendproductDetails
in checkouts, then, for simplicity's sake, you can reuse the same object in the shipping quotes request.
The product
quantity
is required because it's a key input for accurately calculating shipping rates.In the request,
shipFrom
represents the address of the product's warehouse. In a shipping quotes request, you can also send
packages[]
. The values in this array are used to calculate dimensional weight, which helps determine each shipping quote's totalAmount
.If the products are typically shipped in large or irregularly shaped parcels, we recommend that you send
packages[]
. For each element in the array, you can specify a package's
weight
and weightUnit
. The enumerated values of weightUnit
are oz
, lb
, g
, and kg
. The default value is lb
.You can also send a package's
height
, width
, and length
. These values should be defined in inches.In the request, there doesn't need to be any correlation between
packages[]
and items[]
.If
packages[]
is empty when you submit the request, we determine whether you have a default box, and if you do, we send that box's weight and dimensions to the GLP.If your warehouse management software uses packing algorithms, you might request it to provide recommended box counts and dimensions at checkout time and then pass the returned values in
packages[]
.From your shipping quotes request, Digital River retrieves product and packaging data, and uses it to define another request that gets routed to a GLP.
To determine the appropriate GLP, we use the
shipFrom.address.country
and shipTo.address.country
contained in your request, along with unique rules stored in your account.If we determine that the ship to country is not supported by your trading patterns, we return a
409 Conflict
with a code
of InvalidShipToCountryCode
.When configuring the request, we also determine whether any unique product requirements exist. For details, refer to dangerous goods classifications and signature requirements.
When the GLP responds to our request with a list of shipping quotes, we convert the cost of each back into the same
currency
you specified in your POST /shipping-quotes
request.For each quote returned by the GLP, we also aggregate any carrier assessed fees or surcharges into a single total amount.
Your
POST /shipping-quotes
request returns a currency
and an array of shipping quotes[]
.Shipping quotes
{
"currency": "CAD",
"quotes": [
{
"id": "58SLC-DHL",
"description": "Express",
"estimatedDelivery": "3 - 5 Business Days",
"shippingTerms": "DDP",
"totalAmount": 28.19,
"shipFrom": {
"address": {
"city": "Salt Lake City",
"postalCode": "84604",
"state": "Utah",
"country": "US"
}
},
"fees": {
"details": [
{
"name": "Fuel Surcharge",
"amount": 1.72
},
{
"name": "Temporary Surcharge",
"amount": 0.45
},
{
"name": "Dangerous Goods Fee",
"amount": 1.56
}
],
"amount": 3.72
}
},
{
"id": "58SLC-DHL",
"description": "Express",
"shippingTerms": "DAP",
"totalAmount": 28.19,
"shipFrom": {
"address": {
"city": "Salt Lake City",
"postalCode": "84604",
"state": "Utah",
"country": "US"
}
},
"fees": {
"details": [
{
"name": "Fuel Surcharge",
"amount": 1.72
},
{
"name": "Temporary Surcharge",
"amount": 0.45
},
{
"name": "Dangerous Goods Fee",
"amount": 1.56
}
],
"amount": 3.72
}
}
],
"liveMode": false
}
Each element in
quotes[]
represents a shipping quote and contains the following attributes:Each shipping quote has a unique
id
. This identifier is generated by the GLP.The elements in the array are not a resource. As a result, you can't use
id
to make an API call to retrieve a unique shipping quote.However, when handling a customer's shipping quote selection, you do need to pass
id
to the checkout.The
description
indicates the duration of transportation. In other words, how quickly the goods are transported to the customer and what priority level they are assigned. Some common values are Economy
, Express
, and Priority
. This is a pass-thru value from the GLP.A shipping quote's
estimatedDelivery
defines a minimum and maximum delivery period in days. For example, estimatedDelivery
might be 3 - 5 Business Days
.A shipping quote's
shippingTerms
are designated as either DDP
or DAP
. These values indicate when customers must pay duties, fees, and import taxes.In delivered-duty-paid (
DDP
) shipments, the customer pays all duties, fees, and import taxes upfront during the checkout process. Upon product delivery, there are no additional charges they must pay.To activate the guaranteed landed cost feature, customers must select a shipping quote with
DDP
terms.In delivered-at-place (
DAP
) shipments, customers do not pay the full landed cost at checkout-time. Instead, they pay product and shipping costs, and then, upon delivery, they're responsible for paying duties, fees, and import taxes.For details, refer to:
- The Guaranteed landed cost section
A shipping quote's
totalAmount
represents how much customers must pay to ship an order's products to the final destination address. It includes the estimated cost of handling, transportation, and postage as well as carrier assessed surcharges and fees.In
fees
, we itemize these estimated fees and surcharges. A carrier might collect them to, for example, offset the cost of higher fuel prices, package signature options, or dangerous goods handling requirements.Each quote's
totalAmount
, fees.amount
, and fees.details[].amount
is denominated in the response's single currency
.Each shipping quote's
shipFrom
represents the address where that product is warehoused.In the shipping quotes request, you specified a
shipFrom.address.country
. But if you have multiple warehouses in that country, then the response may contain one or more quotes[]
with the same description
and serviceLevel
but different shipFrom
values.This allows you to filter the shipping quotes you display to the customer based on warehouse location.
Depending on your business objectives, you may decide you want to filter the returned shipping quotes before displaying them to customers.
If you want to activate the guaranteed landed cost feature, then you should only display shipping quotes whose
shippingTerms
are DDP
to customers. To trigger this feature, setting a checkout's shippingTerms
to DDP
is one of the necessary preconditions.For details, refer to:
In an effort to minimize rejections, returns, and chargebacks, you may decide you only want to present shipping quotes with
DDP
terms.Orders with
DAP
terms generally have higher return rates. At the time of delivery, some customers may be unaware of the outstanding balance and, in response, either refuse the delivery altogether or accept the delivery and then return the products.You should be aware however that some carrier and ship to country combinations don't support the prepay
DDP
option. In these cases, the only quotes[]
in the shipping quotes response, and therefore the only quotes[]
you'll be able to display to the customer, are those with DAP
terms.So, if one of your approved ship to countries doesn't support
DDP
, make sure you have logic in place that displays DAP
quotes in the event DDP
quotes are not returned.If you want customers to select a shipping quote associated with a specific warehouse, then you can filter by
shipFrom
. This is useful when you have multiple warehouses but you'd like the products to ship from a facility that's in close proximity to a GLP distribution hub.Radio button controls are commonly used to display shipping quotes. This control requires customers to select a single quote from the mutually exclusive and (potentially) filtered options you present.
For each shipping quote that you display, reveal its
serviceLevel
, estimatedDelivery
, and totalAmount
.If you'd like to provide customers with more shipping cost granularity, you can also display
fees.details[]
and/or fees.amount
.In addition, you should indicate whether the quote's
shippingTerms
are DAP
or DDP
. We recommend however that you don't display these acronyms in your graphical user interface (GUI). Few, if any, customers will understand their meaning. Instead, display a more user-friendly description. For example:Shipping terms | Customer-facing text |
---|---|
DAP | Import charges collected upon delivery |
DDP | No additional import charges at delivery |
Here's an example of what this might look like in your GUI:

When customers select a shipping quote, handle that event by retrieving data from the selection and using it to define the checkout's
shippingChoice
and shipFrom
:Shipping quote | Text | POST /checkouts/{id} |
---|---|---|
id | ➔ | shippingChoice.id |
amount | ➔ | shippingChoice.amount |
description | ➔ | shippingChoice.description |
serviceLevel | ➔ | shippingChoice.serviceLevel |
shippingTerms | ➔ | shippingChoice.shippingTerms |
shipFrom | ➔ | shipFrom |
You can then submit an update checkout request. If all the necessary preconditions are met, this request prompts Digital River to call its landed cost service.
If the checkout's
shippingTerms
are DDP
, then the response to your request provides recalculated duty, fee, and import tax amounts at both the checkout-level and items[]
level.In the Global Logistics solution, the customer is the designated importer of record. As a result, the customer pays the checkout's
totalImporterTax
.If the checkout's
shippingTerms
are DAP
, then checkout-level and items[]
level duty, fee, and import tax amounts are all zero.DDP Checkout
DAP Checkout
{
"id": "206bfba3-7bda-4d0b-b6e3-657875b5cc6c",
"createdTime": "2021-11-11T22:25:24Z",
"currency": "EUR",
"email": "[email protected]",
"shipTo": {
"address": {
"line1": "Neuer Wall 10",
"city": "Hamburg",
"postalCode": "20354",
"country": "DE"
},
"name": "John",
"phone": "9526123456",
"email": "[email protected]"
},
"shipFrom": {
"address": {
"line1": "Landed Cost Cross Order",
"line2": "80 Sunraysia Road",
"city": "INVERMAY",
"postalCode": "3352",
"state": "Victoria",
"country": "AU"
}
},
"totalAmount": 1809.99,
"subtotal": 1809.99,
"totalFees": 0.0,
"totalTax": 0.0,
"totalImporterTax": 288.99,
"importerOfRecordTax": true,
"totalDuty": 221.0,
"totalDiscount": 0.0,
"totalShipping": 100.0,
"items": [
{
"id": "434e3932-a20d-49d3-ad82-0abb25eaa9be",
"skuId": "3c99757b-a543-455f-bbd3-57dc1bb21579",
"amount": 1200.0,
"quantity": 3,
"tax": {
"rate": 0.36,
"amount": 0.0
},
"importerTax": {
"amount": 288.99
},
"duties": {
"amount": 221.0
},
"fees": {
"amount": 0.0,
"taxAmount": 0.0
},
"tariffCode": "6404201000"
}
],
"shippingChoice": {
"id": "testDDP",
"amount": 100.0,
"description": "FedEx Next Day",
"serviceLevel": "Test",
"taxAmount": 0.0,
"shippingTerms": "DDP"
},
"updatedTime": "2021-11-11T22:25:24Z",
"locale": "en_US",
"customerType": "individual",
"sellingEntity": {
"id": "DR_IRELAND-ENTITY",
"name": "Digital River Ireland Ltd."
},
"liveMode": false,
"payment": {
"session": {
"id": "1822d8bd-1531-40da-aedc-10ac9b0eda4c",
"amountContributed": 0.0,
"amountRemainingToBeContributed": 1809.99,
"state": "requires_source",
"clientSecret": "1822d8bd-1531-40da-aedc-10ac9b0eda4c_4b58e8ed-505c-4334-b349-bc65be9029e5"
}
}
}
{
"id": "2554c935-98a4-49e6-95ac-1d179c47b2e4",
"createdTime": "2021-11-11T22:26:22Z",
"currency": "EUR",
"email": "[email protected]",
"shipTo": {
"address": {
"line1": "Neuer Wall 10",
"city": "Hamburg",
"postalCode": "20354",
"country": "DE"
},
"name": "John",
"phone": "9526123456",
"email": "[email protected]"
},
"shipFrom": {
"address": {
"line1": "Landed Cost Cross Order",
"line2": "80 Sunraysia Road",
"city": "INVERMAY",
"postalCode": "3352",
"state": "Victoria",
"country": "AU"
}
},
"totalAmount": 1300.0,
"subtotal": 1300.0,
"totalFees": 0.0,
"totalTax": 0.0,
"totalImporterTax": 0.0,
"totalDuty": 0.0,
"totalDiscount": 0.0,
"totalShipping": 100.0,
"items": [
{
"id": "5fbe0052-7b63-460a-a5f6-c516ab9b900d",
"skuId": "3c99757b-a543-455f-bbd3-57dc1bb21579",
"amount": 1200.0,
"quantity": 3,
"tax": {
"rate": 0.0,
"amount": 0.0
},
"importerTax": {},
"duties": {},
"fees": {
"amount": 0.0,
"taxAmount": 0.0
},
"tariffCode": "6404201000"
}
],
"shippingChoice": {
"id": "testDAP",
"amount": 100.0,
"description": "FedEx Next Day",
"serviceLevel": "Test",
"taxAmount": 0.0,
"shippingTerms": "DAP"
},
"updatedTime": "2021-11-11T22:26:22Z",
"locale": "en_US",
"customerType": "individual",
"sellingEntity": {
"id": "DR_IRELAND-ENTITY",
"name": "Digital River Ireland Ltd."
},
"liveMode": false,
"payment": {
"session": {
"id": "561f72d9-44e0-4002-840b-908df73926c4",
"amountContributed": 0.0,
"amountRemainingToBeContributed": 1300.0,
"state": "requires_source",
"clientSecret": "561f72d9-44e0-4002-840b-908df73926c4_3493ddf5-d60e-474d-b2d3-2bda3237649d"
}
}
}
In both
DAP
and DDP
scenarios, use the checkout's data to update the product, shipping, duties, fees, taxes, and total amounts displayed to customers. When displaying duty and import tax amounts in DAP
scenarios, let customers know that they don't pay these costs at checkout time. We recommend using language such as "Outstanding" or "Collected upon delivery".Here's an example of what this might look like:
DDP selection
DAP selection


Prior to initiating the payment collection process, you obtain the customer's billing information and use it to set (at a minimum) the checkout's
billTo.address.country
. Once you initiate payment collection, Drop-in payments only displays payment methods applicable to that currency and bill to country.
If you're using DigitalRiver.js with elements to collect payment, make sure that only applicable payment methods are presented to the customer by calling
retrieveAvailablePaymentMethods()
.For details, refer to:
After the necessary preconditions are met, you can convert the checkout to an order. Once you synchronously or asynchronously receive an order in an
accepted
state, send a ship request to your third-party logistics (3PL) provider.
Last modified 25d ago