Skip to main content

Custom Delivery Adapter

If you want total control of the provided delivery methods, you can build and host an own adapter that will empower Walley Checkout with delivery methods. This allows you to separate the items in the cart in different shipments, set specific pickup/delivery dates, add options to each delivery etc.

How to get started πŸš€β€‹

  1. Contact Walley Merchant Services for help with setup in our test environment and for questions regarding integration with the Delivery Module.
  2. Build a delivery adapter (api) with an endpoint that Walley Checkout will do a GET request towards to get the delivery methods that should respond according to the response below. Use basic auth as authentication.
  3. Provide Walley Merchant Services with the adapter endpoint url, basic auth credentials as well as what fallback strategy to use.

How delivery methods are fetched​

Walley Checkout fetches the list of available delivery methods every time the customer changes any information that might lead to a change in available delivery methods, e.g. the customer changes delivery address or updates the cart.

Default Request Query Parameters

When the Checkout sends the GET request to the delivery adapter, it will include some default query parameters.

ParameterExplanation
storeIdThe storeId for the checkout session
privateIdThe checkout's private id which can be used to fetch information about the checkout
storeTypeCustomerType for the checkout session, b2b or b2c
currencyCurrency used for the checkout session
languageThe display language used for the checkout session. Supported language are: sv, no, fi, da, en
cartPriceThe total price for cart
cartWeightThe total weight for the cart, sum of all the article's weights sent in set cart request
emailThe customer's email address
addressThe address for the customer's current delivery address
postalCodeThe postal code for the customer's current delivery address
countryCodeThe country code for the customer's current delivery address

When requesting for available shipping methods, apart from all the parameters above, you can set custom parameters that is related to articles in the cart. This is done by adding shippingProperties to the cart object in either Initialize Checkout or Update Cart as a JSON object that will be be added in the request query parameters automatically the following way:

{
"items": [
{
"id": "2",
"description": "A bulky product",
"unitPrice": 100,
"unitWeight": 2,
"quantity": 1,
"vat": 20,
"requiresElectronicId": true,
"sku": "a unique alphanumeric code for article identification"
}
],
"shippingProperties": {
"height": 10,
"width": 20,
"isBulky": true
}
}

The following scenario would result in the following query parameters when the GET-request is sent to your adapter:

https://{UriToAdapter}?storeId={storeId}&....&address={address}&height=10&width=20&isBulky=true
Please note

Since the privateId is sent in the query, it is possible to Acquire Checkout Information to get more information. Consider that this will add some time for your customer in the checkout.

Adapter response​

The response can contain a lot of data and options that will be presented for the customer, but not many of them are required. Here is an example of a successful response as well as an error response:

Response header​

HeaderRequiredExplanation
ExpiresNoA DateTime set if the choices should be valid only for a certain time. We will force the customer to reload delivery methods if a selection is made with delivery methods that has expired

Response body​

PropertyRequiredExplanation
shipmentsYesArray of shipments, at least one must be present but it is possible to split the cart items into multiple shipments

Shipment Property

PropertyRequiredExplanation
idYesId of the shipment
nameYesName of shipment, will be displayed as a header for the entire shipment selection
shippingChoicesYesArray of choices that the customer can choose from for the shipment, at least one must be present
metadataNoAny metadata for the delivery, will not be used in checkout but returned every time you aquire checkout information

ShippingChoice Property

PropertyRequiredExplanation
idYesId of the choice
nameYesName of the choice, will be the title for the selection
descriptionNoDescription of the choice, will be the subtitle for the selection
iconNoIcon for the choice. Available icon propery values can be found below. If none is provided, a default icon will be used.
feeNoFee for the option, if combined with destinations and/or options, this fee will be added to all of them. Set to 0 if not present
destinationsNoArray of destinations that will be a subselection for the shipping choice
optionsNoArray of options that the customer can add optionally to add to the shipping choice
metadataNoAny metadata for the shipping choice, will not be used in checkout but returned every time you aquire checkout information

Destinations Property

PropertyRequiredExplanation
idYesId of the destination
nameYesName of the destination, will be the title of the selectable destination
descriptionNoDescription of the destination, will be the subtitle of the selectable destination
deliveryDatesNoArray of available delivery dates for the ShippingChoice
metadataNoAny metadata for the destination, will not be used in checkout but returned every time you aquire checkout information

DeliveryDate Property

PropertyRequiredExplanation
dateYesDateTime of the selectable delivery date
timeFromYesTime of the day from where the selectable delivery date option starts
timeToYesTime of the day from where the selectable delivery date option ends
feenoFee for the specified delivery date. Set to 0 if not present
metadataNoAny metadata for the delivery date, will not be used in checkout but returned every time you aquire checkout information

Option Property

PropertyRequiredExplanation
idYesId of the option
descriptionYesDescription of the option
typeYesType of the option, available types: "bool" - checkbox, "string" - text field, "number" - digits only
metadataNoAny metadata for the option, will not be used in checkout but returned every time you aquire checkout information

Icons​

The icons for a shippingChoice can either have a company logo or a generic icon. Below are the available icons:

Icon property valueIconIcon property valueIcon
postnordwalley-home
dbschenkerwalley-mail
dhlwalley-plane
airmeewalley-ship
bestwalley-store
bringwalley-truck
budbeedefault *
citymail
dsv
earlybird
helthjem
instabox
posti

*Default icon is used if no value is provided, or if the value mismatches with any of the available icon property values.

Fallback strategy​

If, for any reasons, Walley Checkout does not receive any delivery methods from your adapter, there is a setting that you will set up in advance that will decide if the purchase should be stopped or not

  • true: We will show an error and stop the purchase if we cannot fetch at least one valid delivery method
  • false: We will allow the customer to complete the purchase, saying that a delivery method will be selected automatically without cost

Error message response​

If the GET-request is received successfully but no delivery methods can be returned, you can choose to return a non-2xx response with the following properties to inform the customer what is wrong and what action to take. This requires the fallback strategy to be set to true.

PropertyRequiredExplanation
titleNoThe title of the failure displayed in the Checkout. Truncated to max 512 chars.
messageNoThe message with a more descriptive text why no delivery methods was found, and how the customer should proceed. Truncated to max 512 chars.

A default message will be shown if not overridden with title and message from the response. Both title and message must be specified in the response to be used.

Response examples​

/*
Expires: "1/1/0001 12:00:00 AM +00:00"
*/

{
"shipments": [
{
"id": "shipmentId-1",
"name": "Delivery 1",
"metadata": {
"key-for-shipment": "metadata-for-shipment",
"from-store-id": "1234"
},
"shippingChoices": [
{
"id": "choiceId-1",
"name": "Pickup in store",
"icon": "walley-store",
"description": "Pick up your order within five days from your chosen day for pick up",
"destinations": [
{
"id": "destinationId-gothenburg",
"name": "Gothenburg",
"description": "Kortedala",
"deliveryDates": [
{
"date": "2021-02-25T00:00:00+00:00",
"timeFrom": "07:00",
"timeTo": "17:00",
"fee": 0.0,
"metadata": {
"duringOpenHours": "true"
}
},
{
"date": "2021-02-25T00:00:00+00:00",
"timeFrom": "17:00",
"timeTo": "21:00",
"fee": 250.0,
"metadata": {
"duringOpenHours": "true"
}
},
{
"date": "2021-02-25T00:00:00+00:00",
"timeFrom": "21:00",
"timeTo": "22:00",
"fee": 500.0,
"metadata": {
"duringOpenHours": "false"
}
},
{
"date": "2021-02-26T00:00:00+00:00",
"timeFrom": "07:00",
"timeTo": "17:00",
"fee": 100.0
},
{
"date": "2021-03-01T00:00:00+00:00",
"timeFrom": "07:00",
"timeTo": "17:00",
"fee": 0.0
}
]
},
{
"id": "destinationId-varberg",
"name": "Varberg",
"description": "Hunnestad",
"deliveryDates": [
{
"date": "2021-02-28T00:00:00+00:00",
"timeFrom": "09:00",
"timeTo": "16:00",
"fee": 0.0
},
{
"date": "2021-02-28T00:00:00+00:00",
"timeFrom": "16:00",
"timeTo": "18:00",
"fee": 250.0
}
]
}
],
"fee": 0,
"options": [
{
"id": "option-1",
"description": "Rent trailer",
"type": "bool",
"fee": 500
},
{
"id": "option-2",
"description": "Help to pack",
"type": "bool",
"fee": 250
},
{
"id": "option-3",
"description": "Additional information",
"type": "string",
"fee": 0
}
]
},
{
"id": "choiseId-2",
"name": "Home delivery",
"icon": "walley-home",
"description": "Goods will be delivered as close to your home as possible",
"destinations": [
{
"id": "destinationId-home",
"name": "The most comfortable delivery",
"description": "Select day for delivery",
"deliveryDates": [
{
"date": "2021-03-11T00:00:00+00:00",
"timeFrom": "07:00",
"timeTo": "17:00",
"fee": 200.0
},
{
"date": "2021-03-12T00:00:00+00:00",
"timeFrom": "07:00",
"timeTo": "17:00",
"fee": 50.0
}
]
},
{
"id": "destinationId-home-express",
"name": "Express - a lot faster",
"description": "When you are in a hurry",
"fee": 500,
"deliveryDates": [
{
"date": "2020-10-01T00:00:00+00:00",
"timeFrom": "08:00",
"timeTo": "18:00"
}
]
}
],
"fee": 500,
"options": [
{
"id": "option1",
"description": "Notify when delivered",
"type": "bool",
"fee": 500
}
]
},
{
"id": "choiceId-3",
"name": "Pick up at service point with Postnord",
"icon": "postnord",
"description": "Select service point",
"destinations": [
{
"id": "service-point-1",
"description": null,
"name": "Postnord store, Avenyn"
},
{
"id": "service-point-2",
"description": null,
"name": "Postnord store, Backa"
}
],
"fee": 29
},
{
"id": "choiceId-4",
"name": "Pick up at service point with Schenker",
"icon": "dbschenker",
"description": "Select service point",
"destinations": [
{
"id": "service-point-1",
"description": null,
"name": "Schenker store, Avenyn"
},
{
"id": "service-point-2",
"description": null,
"name": "Schenker store, Backa"
}
],
"fee": 29
},
{
"id": "choice-without-destination",
"name": "Pick up at central warehouse, Kalmar",
"icon": "walley-store",
"description": "Kalmar street 8",
"destinations": null,
"fee": 100
}
]
},
{
"id": "shipmentId-2",
"name": "Delivery 2",
"shippingChoices": [
{
"id": "choice-home-delivery",
"name": "Home delivery",
"icon": "walley-home",
"destinations": [
{
"id": "standard-home-delivery",
"description": "Delivery within 5-7 days",
"name": "Standard, the most comfortable delivery"
},
{
"id": "express-home-delivery",
"description": "Delivery within 2 days",
"name": "Express - a lot faster",
"fee": 500
}
],
"fee": 1500,
"options": [
{
"id": "option1",
"description": "Bring my old stuff out",
"type": "bool",
"fee": 500
}
]
},
{
"id": "choice-without-destination-2",
"name": "Pick up at warehouse",
"icon": "walley-store",
"destinations": null,
"fee": 100
}
]
}
]
}

The 200-response from the example above will render the following delivery methods to the customer.

Fetch the customer's selected delivery method​

When Acquiring Checkout Information, a data.shipping object will be available that will reflect the customer's current delivery selection. If this value is null, there are no selection at that current state of the checkout. After purchase the selections are included in the order.

// Simplified Get Checkout Information response with focus on shipping and order object
{
"id": "9eec015f-4b97-44be-a711-d22f3af75069",
"data": {
"customer": {...},
...,
...,
"status": "PurchaseCompleted",
"order": {
"totalAmount": 2757,
"items": [
{
"id": "11111",
"description": "Item one",
"unitPrice": 5,
"quantity": 1,
"vat": 25,
"sku": "Item one sku"
},
{
"id": "222222",
"description": "Item two",
"unitPrice": 2,
"quantity": 1,
"vat": 25,
"sku": "Item two sku"
},
{
"id": "Frakt-1",
"description": "Pickup in store",
"unitPrice": 750,
"quantity": 1,
"vat": 25
},
{
"id": "Frakt-2",
"description": "Home delivery",
"unitPrice": 2000,
"quantity": 1,
"vat": 25
}
]
},
"shipping": {
"provider": "DeliveryAdapterName",
"shippingFee": 2750,
"shipments": [
{
"id": "shipmentId-1",
"feeItemId": "Frakt-1",
"metadata": {
"key-for-shipment": "metadata-for-shipment",
"from-store-id": "1234"
},
"shippingChoice": {
"id": "choiceId-1",
"fee": 0,
"metadata": {
"key-for-choice-1": "metadata-for-choice-1"
},
"destination": {
"id": "destinationId-gothenburg",
"fee": 0,
"metadata": {
"key-for-destination": "metadata-for-destination"
},
"deliveryDate": {
"fee": 0,
"metadata": {
"duringOpenHours": "true"
},
"date": "2021-02-25",
"timeFrom": "07:00",
"timeTo": "17:00"
}
},
"options": [
{
"id": "option-1",
"description": "Rent trailer",
"type": "bool",
"fee": 500,
"value": true
},
{
"id": "option-2",
"description": "Help to pack",
"type": "bool",
"fee": 250,
"value": true
},
{
"id": "option-3",
"description": "Additional information",
"type": "string",
"fee": 0,
"value": "Some info"
}
]
}
},
{
"id": "shipmentId-2",
"feeItemId": "Frakt-2",
"metadata": null,
"shippingChoice": {
"id": "choice-home-delivery",
"fee": 1500,
"metadata": null,
"destination": {
"id": "standard-home-delivery",
"fee": 0,
"metadata": null,
"deliveryDate": null
},
"options": [
{
"id": "option1",
"description": "Bring my old stuff out",
"type": "bool",
"fee": 500,
"value": true
}
]
}
}
]
},
...
},
"error": null
}