Headless Checkout API - Frontend Integration
The Headless Checkout API is a backend solution designed to enable the creation of a custom checkout experience, eliminating the need for direct frontend integration.
In this article, we offer tips on how to implement the checkout UI using the data provided in our responses.
Presenting delivery options
Here is part of the response from headless checkout:
{
"deliveries": [
{
"id": "1",
"delivery_categories": [
{
"id": "home-delivery-1384f5e83e3b4143a1c2475214a1de2c",
"delivery_type": "DELIVERY",
"display_name": "Home Delivery",
"delivery_options": [
{
"id": "0196f224-1037-7aff-a6aa-972b631188a2",
"carrier": {
"name": "InPost",
"product_id": "inpost-d2d"
}
}
]
}
]
}
]
}
Important data fields:
deliveries
- in most cases there is one delivery, in split checkout there will be multiple deliveries (one for each group of items)
deliveries[].delivery_categories
- (later just category
) each category is an abstraction of delivery choices for user, eg "Home Delivery", "Pickup Points", "Pick in Store"
deliveries[].delivery_categories[].delivery_options[]
- (later just option
) each option is an actual choice, eg
- category "Home Delivery" could have two options: one for PostNord and one for DHL so user can pick actual carrier
- category "Pickup Points" could have multiple options, one for each pickup point
- category "Pick in Store" could have multiple options, one for each store
We expose sort_order
for categories and options. Our api already sorts categories and options according to those values
but if different sort order is needed, you can use this field to get original order.
Home delivery
Depending on the need, you can show:
- all available carriers for home delivery
- just "Home Delivery" and automatically select carrier with custom logic
For mulitple carriers for home delivery, check option.carrier
- this is the carrier and carrier product that will deliver the package to the user, full list in Supported Carrier Products.
Useful display fields:
category.name
- display name for categoryoption.carrier.name
- display name for carrieroption.carrier.product_name
- display name for carrier product
{
"deliveries": [
{
"id": "1",
"delivery_categories": [
{
"id": "home-delivery-1384f5e83e3b4143a1c2475214a1de2c",
"delivery_type": "DELIVERY",
"display_name": "Home Delivery",
"delivery_options": [
{
"id": "0196f224-1037-7aff-a6aa-972b631188a2",
"carrier": {
"name": "InPost",
"product_name": "Kurier",
"product_id": "inpost-d2d"
},
"etd": {
"relative": {
"unit": "TIME_UNIT_BUSINESS_DAY",
"earliest": 4,
"latest": 5
}
},
"expire_time": "2025-05-25T22:00:00Z"
}
]
}
]
}
]
}
Pickup / Instore delivery
In most cases there will be one category for pickup points and each pickup point will have it's own option. Each pickup point typically is presented as a list of locations with a name and address on a map or on a list. User can pick only one pickup point.
It is possible to have one category with multi-carrier pickup point locations.
Check option.carrier
- for carrier and carrier product that will deliver the package to the pickup/instore location, full list in Supported Carrier Products.
Useful display fields:
category.name
- display name for categoryoption.carrier.name
- display name for carrieroption.carrier.product_name
- display name for carrier productoption.pickup_location.title
- display name for location
{
"deliveries": [
{
"id": "1",
"delivery_categories": [
{
"id": "pickup-bc63c26bfdd4480d815a9d4c6f221094",
"delivery_type": "PICKUP",
"display_name": "Pickup Lockers",
"sort_order": 1,
"options_source": "CARRIER",
"delivery_options": [
{
"id": "0196f224-1036-7f2d-8bcf-0b3ac7267a63",
"carrier": {
"name": "DHL eCommerce Netherlands",
"product_name": "DHL Service Point",
"product_id": "dhl-svp",
"sort_order": 2
},
"pickup_location": {
"id": "PL-4513121",
"external_id": "PL-4513121",
"location_type": "STORE",
"title": "Żabka",
"visiting_contact": {
"address": {
"country_code": "PL",
"postal_code": "50-128",
"city": "Wrocław",
"address_lines": [
"Św. Mikołaja 16"
],
"coordinates": {
"lat": 51.111725,
"lng": 17.027769
}
}
},
"operational_hours": {
"monday": [
"06:00-23:00"
],
"tuesday": [
"06:00-23:00"
],
"wednesday": [
"06:00-23:00"
],
"thursday": [
"06:00-23:00"
],
"friday": [
"06:00-23:00"
],
"saturday": [
"06:00-23:00"
],
"sunday": [
"11:00-18:00"
]
},
"distances": {
"walking": {
"meters": "58",
"minutes": "1"
},
"driving": {
"meters": "414",
"minutes": "1"
}
}
},
"etd": {
"relative": {
"unit": "TIME_UNIT_BUSINESS_DAY",
"earliest": 6,
"latest": 8
}
},
"expire_time": "2025-05-25T22:00:00Z"
}
]
}
]
}
]
}
Selecting delivery options
For each deliveries
you need to keep track of deliveries[].delivery_categories[].delivery_options[].id
that user selected.
User can select exactly one option per delivery and all deliveries needs to have an option selected.
To help with initial choice you can use deliveries[].delivery_categories[].delivery_options[].preselected
to show selection when user opens the checkout page for the first time.
There will be only one preselected option per each delivery.
Other topics
Delivery time
Delivery time can be presented to the user based on etd
(estimated time of delivery) object available on option level.
{
"delivery_options": [
{
"id": "0196f224-1037-7aff-a6aa-972b631188a2",
"carrier": {
"name": "InPost",
"product_name": "Kurier",
"product_id": "inpost-d2d",
"external_id": "asdf"
},
"etd": {
"relative": {
"unit": "TIME_UNIT_BUSINESS_DAY",
"earliest": 4,
"latest": 5
}
},
"expire_time": "2025-05-25T22:00:00Z"
}
]
}
Please check swagger for all possible options in etd
object.
Example js:
const formatEtd = (etd: ETD) => {
if (!etd) {
return <span>No estimated time</span>;
}
if (etd.custom !== undefined) {
return <span>{etd.custom.text}</span>;
}
if (etd.relative.unit === 'TIME_UNIT_BUSINESS_DAY' || etd.relative.unit === 'TIME_UNIT_DAY') {
if (etd.relative.earliest === etd.relative.latest) {
return <span>{etd.relative.earliest} {etd.relative.unit === 'TIME_UNIT_BUSINESS_DAY' && 'business '}days</span>
}
return <span>
{etd.relative.earliest}-{etd.relative.latest} {etd.relative.unit === 'TIME_UNIT_BUSINESS_DAY' && 'business '}days
</span>
}
return <span>{etd.relative.earliest} - {etd.relative.latest} {etd.relative.unit}</span>
}
Warehouse
There's option to present warehouse information to the user. It is available in category.
{
"deliveries": [
{
"id": "1",
"delivery_categories": [
{
"id": "home-delivery-1384f5e83e3b4143a1c2475214a1de2c",
"delivery_type": "DELIVERY",
"warehouse": {
"id": "swe-62aac37054cb4b60862e7aebc33b38ab",
"address": {
"country_code": "SE",
"postal_code": "111 34",
"city": "Stockholm",
"address_lines": [
""
]
}
}
}
]
}
]
}
Addons
Addons are selectable extra paid services that can be added to the delivery. Example: "gift wrapped", "extra fast".
Addons are available on category level and can be selected by the user.
{
"deliveries": [
{
"id": "1",
"delivery_categories": [
{
"id": "delivery-a20772d216ff43aa9b45182e6fcfbdc1",
"delivery_type": "DELIVERY",
"display_name": "Home Delivery",
"delivery_options": [],
"addons": [
{
"display_name": "Express delivery",
"price": "500",
"addon_type": "CUSTOM",
"id": "19051ba0-682b-11ee-ae2a-9ee5ca455892"
}
]
}
]
}
]
}
If user selects addon, addon id needs to be sent to backend in complete session request.