Links

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:

Overview

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.

Building a cart

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.

Checking out customers

Once you initiate the checkout process, you should obtain the customer's name, email, shipping address, and billing address.
For details, refer to sequencing the checkout process on the Building checkouts page.

Handling ship to country restrictions

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.

Creating the checkout

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.
For details, refer to sending the create checkout request on the Building checkouts page.

Managing shipping quotes

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.

Defining and sending the shipping quote 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
}
]
}'

Currency

The currency in your shipping quote request should be the same as the checkout's currency.

Ship to

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"
}
]
}

Physical product data

Each physical product in the customer's cart should be passed in the shipping quote request's items[].
The following describes the key data you should send in each items[].productDetails:
  • 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 means totalAmount in the returned shipping quotes will likely be inaccurate. Product weight 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 send weight 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 send weight in the request.
  • A product's url , image , countryOfOrigin, and partNumber are generally not used by your GLP when generating shipping quotes. These attributes are however part of productDetails. So, if you send productDetails 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.

Ship from

In the request, shipFrom represents the address of the product's warehouse.

Packages

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[].
For details, refer to configuring packaging in the Pre-deployment section.

How Digital River handles your request

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.

How Digital River handles the response

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.

The shipping quotes response

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:

Unique identifier

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.

Description

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.

Estimated delivery range

A shipping quote's estimatedDelivery defines a minimum and maximum delivery period in days. For example, estimatedDelivery might be 3 - 5 Business Days.

Shipping terms

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:

Shipping costs and fees

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.

Ship from

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.

Handling the shipping quotes response

Depending on your business objectives, you may decide you want to filter the returned shipping quotes before displaying them to customers.

Filtering shipping quotes

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.

Displaying shipping quotes

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:

Handling the shipping quote selection

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.
For details, refer to how landed cost is represented in checkouts on the Landed cost page.
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

Collecting payment

In Global Logistics, you collect payment in much the same way you would in any checkout flow.
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:

Submitting the order

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.
For details, refer to Managing a Global Logistics order.