SIW API
Overview
All of the examples below are HTTP requests that can be roughly translated to the generated client method calls. The main goal is to get the overall feeling of the API and the data flows.
SIW is responsible for maintaining life cycle of a session that has all the data needed by the shipping selector widget. When a user visits checkout page, makes any changes to cart contents, selects shipping options and completes a purchase, all the relevant data are stored in the session.
Every session contains result
field which provides information about currently selected delivery option.
It contains all important information like:
- pricing,
- category,
shipping method
,external_method_id
,- details of pickup point if applicable.
Result
field should be used in integration to get final result of session.
The example result looks as follows:
{
"session": {
"result": {
"shipping": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "MyPack Collect",
"location": {
"external_id": "586287",
"name": "Direkten Sveavägen",
"address": {
"name": "Direkten Sveavägen",
"address_lines": ["Sveavägen 137"],
"city": "Stockholm",
"postal_code": "11346",
"country": "SE",
"coordinates": {
"lat": 59.34909509999998,
"lng": 18.050284299999994
}
},
"distance": {
"walking": {
"value": 450,
"duration": 5
},
"driving": {
"value": 771,
"duration": 1
}
},
"operational_hours": {
"mon": "08:00-20:00",
"tue": "08:00-20:00",
"wed": "08:00-20:00",
"thu": "08:00-20:00",
"fri": "08:00-20:00",
"sat": "09:00-17:00",
"sun": "10:00-16:00"
}
},
"delivery_time": {
"id": "VMzp-Ei2Lx7PAbmQMbnbFg",
"expires": "2019-07-04T15:00:00+02:00",
"start": "2019-07-05T00:00:00+02:00",
"end": "2019-07-09T00:00:00+02:00"
},
"external_method_id": "pnl-mypack",
"supports": {}
},
"category": {
"id": "category-pickup",
"name": "Category Pickup"
},
"pricing": {
"currency": "SEK",
"price": 1900
}
}
}
}
Create Session
The session.create
method is used to create a new session. It returns the
newly created Session as
well as a html_snippet that can be embedded in the
checkout page. Session
can be created with minimal set of properties - purchase_country
, purchase_currency
, locale
and cart
.
SIW also supports embedding multiple widgets on a single page, see Multiple widgets.
Generic Flow
The sequence diagram below describes the flow between the Customer, Merchant, Shipping Selector and SIW API when creating a new session and rendering shipping selector for that session onto the checkout page.
- Customer loads the checkout page
- Merchant calls the
session.create
method - SIW returns a new
Session
and thehtml_snippet
needed to render the shipping selector. - Merchant renders
html_snippet
on the page.
A minimal set of fields required to create a session is purchase_country
, purchase_currency
, locale
and cart
.
A new session is returned along with an identifier and a token for authorization.
We support Canada and United States regions, such as states and army regions that can be passed in the address (and on which the filtering of configured shipping methods can be done).
Supported Languages
The following locales are supported:
- cs-CZ - Czech
- da-DK - Danish
- de-AT - Austrian German
- de-BE - Belgian German
- de-CH - Swiss German
- de-DE - German
- de-LU - Luxembourgish German
- el-GR - Greek
- en-AU - Australian English
- en-CA - Canadian English
- en-GB - British English
- en-IE - Irish English
- en-US - American English
- es-ES - Spanish
- et-EE - Estonian
- fi-FI - Finnish
- fi-SE - Swedish Finnish
- fr-BE - Belgian French
- fr-CA - Canadian French
- fr-CH - Swiss French
- fr-FR - French
- fr-LU - Luxembourgish French
- hr-HR - Croatian
- hu-HU - Hungarian
- is-IS - Icelandic
- it-CH - Swiss Italian
- it-IT - Italian
- ja-JP - Japanese
- ko-KR - Korean
- lt-LT - Lithuanian
- lv-LV - Latvian
- ms-MY - Malay
- nb-NO - Norwegian Bokmål
- nl-BE - Flemish
- nl-NL - Dutch
- nn-NO - Norwegian Nynorsk
- no-NO - Norwegian
- pl-PL - Polish
- pt-PT - Portuguese
- ru-RU - Russian
- sk-SK - Slovak
- sl-SI - Slovenian
- sv-FI - Finland Swedish
- sv-SE - Swedish
- th-TH - Thai
- tr-TR - Turkish
- vi-VN - Vietnamese
- zh-CN - Simplified Chinese
Example Calls
Request
POST /v1/siw/session.create HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"purchase_country": "SE",
"purchase_currency": "SEK",
"locales": [
"sv-SE"
],
"search_address": {
"postal_code": "11239",
"country": "SE"
},
"cart": {
"cart_id": "unique_id",
"total_value": 129900,
"currency": "SEK",
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"quantity": 1,
"attributes": [
"shoes",
"indigo",
"class_one"
]
}
]
}
}
Response
HTTP/1.1 200 OK
Date: Wed, 15 May 2024 11:47:58 GMT
Content-Type: application/json
Content-Length: 311
Connection: close
Vary: Accept-Encoding
x-trace-id: S20240515114757SPN9ME35YF2VS5SV
{
"session": {
"id": "07225531-5158-4dc4-8429-915f465104f0",
"status": "ACTIVE",
"cart": {
"total_value": 129900,
"total_discount": 0,
"currency": "SEK",
"pre_order": false,
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"attributes": [
"shoes",
"indigo",
"class_one"
],
"out_of_stock": false,
"quantity": 1,
"price": 0
}
],
"cart_id": "unique_id"
},
"selected_shipping_option": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"price": 0,
"currency": "SEK",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"time_slot": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
}
},
"shipping_price": 0,
"expires_at": "2024-05-15T17:00:00+02:00",
"search_address": {
"postal_code": "11239",
"country": "SE",
"coordinates": {
"lat": 59.33122199302237,
"lng": 18.030565761645196
}
},
"result": {
"shipping": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"delivery_time": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
},
"supports": {},
"warehouse": {
"address": {
"name": "Ingrid Swedish Warehouse",
"address_lines": [
"Mälarvarvsbacken 8"
],
"city": "Stockholm",
"postal_code": "11733",
"country": "SE",
"coordinates": {
"lat": 59.320672,
"lng": 18.035503
}
}
}
},
"category": {
"id": "pickup-points-0c4eaf85363f4fc98197faf9a2ab8830",
"name": "Pickup Points",
"presented_category_name": "Till utlämningsställe",
"custom_text": "Leverans av din order sker med fossilfritt drivmedel bestående av el, muskelkraft eller biodrivmedel från e-handlarens lager fram till din valda leveransplats. Gäller ej returer. Läs mer här (länk till utökad information)."
},
"pricing": {
"currency": "SEK",
"price": 0,
"price_components": [
{
"type": "PRICE_COMPONENT_TYPE_SHIPPING"
}
]
},
"selection": "PRESELECTED_CHOICE",
"delivery_time": {
"pickup_from_merchant": {
"earliest": "2024-05-16T12:00:00+02:00",
"latest": "2024-05-16T12:00:00+02:00"
},
"customer_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
},
"carrier_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
}
}
}
},
"html_snippet": "<div id='ingrid'> ... </div>"
}
Update Session
The session.update
method can be used to update the Cart
or Customer
of the session if needed. You can updated either Cart
, Customer
or
both at the same time.
There are two flows that should be used when it comes to updating the session.
- When customer changes the shipping option
- When cart contents change
Generic flow when customer changes shipping option
The sequence diagram below describes the flow between the Customer, Merchant, Shipping Selector and SIW API when updating a session. In this scenario shipping selector is the master so there is no need to suspend it.
- Customer changes shipping option
- Merchant is notified via JS event subscription
- Merchant makes the Ajax call to its backend
- Merchant fetches Ingrid
Session
usingsession.get
and extracts the shipping cost - Merchant updates its order data in the backend
- Merchant completes Ajax call and returns updated shipping cost
- Merchant updates total cart cost with newly updated shipping cost
Generic flow when cart contents change
The sequence diagram below describes the flow between the Customer, Merchant, Shipping Selector and SIW API when updating a session and checkout page is master.
- Put shipping selector in suspend mode using the Javascript API
- Call Merchant backend to make the change, for example remove item from the cart.
- Apply the update to the
Session
using thesession.update
call - Updated session is returned
- Merchant update order with updated shipping cost
- Complete the Ajax call in the checkout
- Resume shipping selector using the Javascript API
- Shipping selector will then refresh its state
Example Calls
Request
POST /v1/siw/session.update HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"id": "07225531-5158-4dc4-8429-915f465104f0",
"cart": {
"cart_id": "unique_id",
"total_value": 274800,
"currency": "SEK",
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"quantity": 1,
"price": 129900,
"attributes": [
"shoes",
"indigo",
"class_one"
]
},
{
"sku": "SKU65432",
"name": "Michigan Coat XL",
"quantity": 1,
"price": 144900,
"attributes": [
"tops",
"spring_campaign"
]
}
]
}
}
Response
HTTP/1.1 200 OK
Date: Wed, 15 May 2024 11:48:01 GMT
Content-Type: application/json
Content-Length: 357
Connection: close
Vary: Accept-Encoding
x-trace-id: S20240515114759KXY8M81DWC4R2J45
{
"session": {
"id": "07225531-5158-4dc4-8429-915f465104f0",
"status": "ACTIVE",
"cart": {
"total_value": 274800,
"total_discount": 0,
"currency": "SEK",
"pre_order": false,
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"attributes": [
"shoes",
"indigo",
"class_one"
],
"out_of_stock": false,
"quantity": 1,
"price": 129900
},
{
"sku": "SKU65432",
"name": "Michigan Coat XL",
"attributes": [
"tops",
"spring_campaign"
],
"out_of_stock": false,
"quantity": 1,
"price": 144900
}
],
"cart_id": "unique_id"
},
"selected_shipping_option": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"price": 0,
"currency": "SEK",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"time_slot": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
}
},
"shipping_price": 0,
"expires_at": "2024-05-15T17:00:00+02:00",
"search_address": {
"postal_code": "11239",
"country": "SE",
"coordinates": {
"lat": 59.33122199302237,
"lng": 18.030565761645196
}
},
"result": {
"shipping": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"delivery_time": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
},
"supports": {},
"warehouse": {
"address": {
"name": "Ingrid Swedish Warehouse",
"address_lines": [
"Mälarvarvsbacken 8"
],
"city": "Stockholm",
"postal_code": "11733",
"country": "SE",
"coordinates": {
"lat": 59.320672,
"lng": 18.035503
}
}
}
},
"category": {
"id": "pickup-points-0c4eaf85363f4fc98197faf9a2ab8830",
"name": "Pickup Points",
"presented_category_name": "Till utlämningsställe",
"custom_text": "Leverans av din order sker med fossilfritt drivmedel bestående av el, muskelkraft eller biodrivmedel från e-handlarens lager fram till din valda leveransplats. Gäller ej returer. Läs mer här (länk till utökad information)."
},
"pricing": {
"currency": "SEK",
"price": 0,
"price_components": [
{
"type": "PRICE_COMPONENT_TYPE_SHIPPING"
}
]
},
"selection": "PRESELECTED_CHOICE",
"delivery_time": {
"pickup_from_merchant": {
"earliest": "2024-05-16T12:00:00+02:00",
"latest": "2024-05-16T12:00:00+02:00"
},
"customer_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
},
"carrier_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
}
}
}
},
"html_snippet": "<div id=\"shipwallet-container\" style=\"min-height:350px\"> <style> #ingrid-loader { min-height: 350px; padding: 32px 12px 12px 12px; border: 1px solid #e6e6e6; border-radius: 6px; background-color: white; } ._ingrid-skeleton { background-color: #ededed; position: relative; overflow: hidden; -webkit-mask-image: -webkit-radial-gradient(white, black); } ._ingrid-skeleton::before { content: ''; background-image: linear-gradient(90deg, #ededed 0px, #f8f8f8 80px, #ededed 160px); animation: transform 1.8s ease-out infinite; transform-origin: 0 0; width: 100vw; height: 100%; left: -160px; position: absolute; display: block; } ._ingrid-skeleton-text { height: 10px; } ._ingrid-skeleton-shipping-indicator { height: 45px; width: 100%; } ._ingrid-skeleton-shipping-indicator-label { margin-bottom: 20px; width: 100px; } ._ingrid-skeleton-delivery-categories-wrapper { display: flex; flex-direction: column; width: 100%; padding-bottom: 9px; } ._ingrid-skeleton-shipping-option-first-row { display: flex; align-items: center; width: 100%; } ._ingrid-skeleton-checkbox { width: 20px; height: 20px; border-radius: 10px; margin-right: 8px; } ._ingrid-skeleton-flex-1 { flex: 1; } ._ingrid-skeleton-shipping-option-name { width: 60%; } ._ingrid-skeleton-price { width: 30px; margin-right: 12px; } ._ingrid-skeleton-shipping-option-second-row { display: flex; width: 100%; } ._ingrid-skeleton-delivery-description { width: 35%; } ._ingrid-skeleton-delivery-logo { width: 32px; height: 32px; border-radius: 50%; } ._ingrid-skeleton-delivery-categories-label { width: 200px; } ._ingrid-skeleton-delivery-category-wrapper { padding-bottom: 16px; } @keyframes transform { to { transform: translateX(120%); } } ._ingrid-skeleton-zipcode-label { width: 70px; margin-bottom: 12px; } ._ingrid-skeleton-zipcode-input { height: 50px; width: 100%; margin-bottom: 28px; } </style> <div id=\"ingrid-loader\"> <div style=\"width: 100%\"> <div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-zipcode-label\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-zipcode-input\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-shipping-indicator-label\" ></div> <div class=\"_ingrid-skeleton-delivery-categories-wrapper\"> <div class=\"_ingrid-skeleton-delivery-category-wrapper\"> <div class=\"_ingrid-skeleton-shipping-option-first-row\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-shipping-option-name\" ></div> </div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-price\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-delivery-logo\"></div> </div> <div class=\"_ingrid-skeleton-shipping-option-second-row\"> <div class=\"_ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-delivery-description\" ></div> </div> </div> </div> <div class=\"_ingrid-skeleton-delivery-category-wrapper\"> <div class=\"_ingrid-skeleton-shipping-option-first-row\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-shipping-option-name\" ></div> </div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-price\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-delivery-logo\"></div> </div> <div class=\"_ingrid-skeleton-shipping-option-second-row\"> <div class=\"_ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-delivery-description\" ></div> </div> </div> </div> <div class=\"_ingrid-skeleton-delivery-category-wrapper\"> <div class=\"_ingrid-skeleton-shipping-option-first-row\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-shipping-option-name\" ></div> </div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-price\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-delivery-logo\"></div> </div> <div class=\"_ingrid-skeleton-shipping-option-second-row\"> <div class=\"_ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-delivery-description\" ></div> </div> </div> </div> <div class=\"_ingrid-skeleton-shipping-option-first-row\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-shipping-option-name\" ></div> </div> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-price\"></div> <div class=\"_ingrid-skeleton _ingrid-skeleton-delivery-logo\"></div> </div> <div class=\"_ingrid-skeleton-shipping-option-second-row\"> <div class=\"_ingrid-skeleton-checkbox\"></div> <div class=\"_ingrid-skeleton-flex-1\"> <div class=\"_ingrid-skeleton _ingrid-skeleton-text _ingrid-skeleton-delivery-description\" ></div> </div> </div> </div> </div> </div> </div> <script> (function(window, instanceId, containerId, document) { window[instanceId] = window[instanceId] || function() { (window[instanceId].q = window[instanceId].q || []).push(arguments) }; var bootstrapURL = \"https://cdn-stage.ingrid.com/checkout-widget/6a784a5/bootstrap.js\"; var bootstrapFallbackURL = \"https://cdn-stage.ingrid.com/checkout-widget/516071d/bootstrap.js\"; if (/MSIE|Trident/.test(window.navigator.userAgent)) { bootstrapURL = bootstrapFallbackURL; } window[instanceId].config = { container: document.getElementById(containerId), bootstrapURL: bootstrapURL, bootstrapFallbackURL: bootstrapFallbackURL, features: {\"hide_toc\":false,\"show_shipping_price_on_service_points_view\":true,\"show_carrier_icons\":true,\"new_search_address\":true,\"door_code\":false,\"show_map\":true,\"hide_street_on_address_fields\":true,\"disable_address_form\":false,\"show_city_on_address_fields\":false,\"display_upfront_address\":false,\"autocomplete_street\":false,\"display_location_type\":false,\"dont_require_street_on_address_fields\":false,\"show_state_on_address_fields\":false,\"show_delivered_by\":false,\"show_street_on_address_module\":false,\"show_city_on_address_module\":false,\"require_street_on_address_module\":false,\"enable_ingrid_logo\":true,\"enable_widget_border\":true,\"enable_transparent_background\":false,\"show_shipping_categories_before_address\":true,\"enable_accent_color_for_widget_elements\":false,\"dark_color_enabled\":true,\"show_slogan\":false,\"show_carrier_logos_in_shipping_categories_placeholder\":true,\"enable_free_shipping_indicator\":true,\"enable_free_shipping_indicator_category_name_message\":true,\"enable_free_shipping_indicator_carrier_logo\":false,\"enable_delivery_address_form\":false,\"show_privacy_policy\":false,\"show_region\":false,\"require_region\":false,\"shipping_categories_visible_when_folded_count\":1,\"enable_multiple_home_delivery_in_category\":false,\"display_currency_iso_code\":false,\"enable_postal_code_in_location_address\":false,\"enable_analytics\":false,\"show_currency_before_price\":false,\"show_cancel_button_on_modal\":false,\"enable_full_sentry_tracing\":false,\"enable_state_get_retry\":false,\"external_address_book_provider\":\"\"}, instanceId: instanceId, locale: \"sv-SE\", logging: \"https://c7a68a2a3cfe4024bf719e6485aa8751@sentry.io/141995\", status: \"ACTIVE\", style: {}, session: \"07225531-5158-4dc4-8429-915f465104f0\", token: \"Y2xpZW50dHdvOjkwYmZhYzZmNTBhMzRjNzg5NDM0MTVhOWU2ODNhOGQx\", version: \"9cf08063\", loaderId: \"ingrid-loader\" }; var container = document.getElementById(containerId); var bootstrapScript = document.createElement(\"script\"); bootstrapScript.async = true; bootstrapScript.src = bootstrapURL; bootstrapScript.className = \"ingrid-bootstrap-script\"; bootstrapScript.addEventListener(\"load\", function (e) { if (typeof _ingrid_initializeWidgetInstance === \"function\") { _ingrid_initializeWidgetInstance(instanceId); } }); container.appendChild(bootstrapScript); })(window, '_sw', 'shipwallet-container', document); </script> <noscript> Please <a href=\"https://enable-javascript.com\">enable JavaScript</a>. </noscript></div>"
}
The difference between the search address and the customer address is that the first one simply points us to which area package should be delivered, but it doesn't need to be customer real address. The customer address must be provided by the merchant.
For example, if you want to have a package delivered close to your work, you can fill search address with your office address. The customer is a customer home address. It allows performing fraud detection if someone is ordering an expensive item and customer and search addresses are distant to each other. The merchant could compare both addresses and verify if the order is valid by contacting the customer before shipping goods.
Complete Session
The session.complete
method is used to mark a session as complete. At this
point, if the customer haven't made a choice we'll generate one for the
customer based on the information in the Customer
property provided in the request.
::: tip
Search address and customer address are two different entities, that serve separate purposes during session lifetime.
Search address is provided by the customer and the customer address is always provided by merchant.
Search address is used to generate the shipping options that will be presented to the customer. Customer address is the address where the parcel will be sent and should be provided sometime during session lifetime (at the latest during session.complete
).
Shipping options may be regenerated under some conditions when the customer address is provided and it differs from the search address. :::
The sequence diagram below describes the flow between the Customer, Merchant, Shipping Selector and SIW API when completing a session when the customer checkout.
- Customer completes the transaction
- Merchant completes the session using
session.complete
method - SIW API returns session in a completed state. The
SelectedShippingOption
andtos_id
are also returned. - Merchant redirects the customer to the confirmation page
On session complete call a tos_id will be returned. This id is important if you need to re-open a session as a completed session is "frozen" and cannot be modified. You can use tos_id to clone a completed session.
Example Calls
Request
POST /v1/siw/session.complete HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"id": "07225531-5158-4dc4-8429-915f465104f0",
"customer": {
"email": "erik@ingrid.com",
"phone": "0709997711",
"address": {
"name": "Erik Johansson",
"address_lines": [
"Industrigatan 5"
],
"city": "Stockholm",
"postal_code": "11239",
"country": "SE"
}
}
}
Response
HTTP/1.1 200 OK
Date: Wed, 15 May 2024 11:48:01 GMT
Content-Type: application/json
Content-Length: 233
Connection: close
Vary: Accept-Encoding
x-trace-id: S20240515114801YPS40YH4SFPG71VQ
{
"session": {
"id": "07225531-5158-4dc4-8429-915f465104f0",
"status": "COMPLETE",
"cart": {
"total_value": 274800,
"total_discount": 0,
"currency": "SEK",
"pre_order": false,
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"attributes": [
"shoes",
"indigo",
"class_one"
],
"out_of_stock": false,
"quantity": 1,
"price": 129900
},
{
"sku": "SKU65432",
"name": "Michigan Coat XL",
"attributes": [
"tops",
"spring_campaign"
],
"out_of_stock": false,
"quantity": 1,
"price": 144900
}
],
"cart_id": "unique_id"
},
"selected_shipping_option": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"price": 0,
"currency": "SEK",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"time_slot": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
}
},
"shipping_price": 0,
"expires_at": "2024-05-15T17:00:00+02:00",
"customer": {
"address": {
"name": "Erik Johansson",
"address_lines": [
"Industrigatan 5"
],
"city": "Stockholm",
"postal_code": "11239",
"country": "SE"
},
"phone": "0709997711",
"email": "erik@ingrid.com"
},
"search_address": {
"postal_code": "11239",
"country": "SE",
"coordinates": {
"lat": 59.33122199302237,
"lng": 18.030565761645196
}
},
"tos_id": "01HXY19BKD3GRM48VR6K2BRY8T",
"result": {
"shipping": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"delivery_time": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
},
"supports": {},
"warehouse": {
"address": {
"name": "Ingrid Swedish Warehouse",
"address_lines": [
"Mälarvarvsbacken 8"
],
"city": "Stockholm",
"postal_code": "11733",
"country": "SE",
"coordinates": {
"lat": 59.320672,
"lng": 18.035503
}
}
}
},
"category": {
"id": "pickup-points-0c4eaf85363f4fc98197faf9a2ab8830",
"name": "Pickup Points",
"presented_category_name": "Till utlämningsställe",
"custom_text": "Leverans av din order sker med fossilfritt drivmedel bestående av el, muskelkraft eller biodrivmedel från e-handlarens lager fram till din valda leveransplats. Gäller ej returer. Läs mer här (länk till utökad information)."
},
"pricing": {
"currency": "SEK",
"price": 0,
"price_components": [
{
"type": "PRICE_COMPONENT_TYPE_SHIPPING"
}
]
},
"selection": "PRESELECTED_CHOICE",
"delivery_time": {
"pickup_from_merchant": {
"earliest": "2024-05-16T12:00:00+02:00",
"latest": "2024-05-16T12:00:00+02:00"
},
"customer_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
},
"carrier_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
}
}
}
},
"tos_id": "01HXY19BKD3GRM48VR6K2BRY8T"
}
- Customer loads the checkout page
- Merchant calls the
session.get
method - SIW API returns a new
Session
and thehtml_snippet
to render shipping selector - Merchant renders
html_snippet
in the checkout page
Get Session
The session.get
method is used to get session details.
Example Calls
Request
GET /v1/siw/session.get?id=07225531-5158-4dc4-8429-915f465104f0 HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
Response
HTTP/1.1 200 OK
Date: Wed, 15 May 2024 11:48:01 GMT
Content-Type: application/json
Connection: close
Vary: Accept-Encoding
x-trace-id: S20240515114801V6JBYDCC93HG7A56
{
"session": {
"id": "07225531-5158-4dc4-8429-915f465104f0",
"status": "COMPLETE",
"cart": {
"total_value": 274800,
"total_discount": 0,
"currency": "SEK",
"pre_order": false,
"items": [
{
"sku": "SKU12345",
"name": "Saucony Shadow 6000",
"attributes": [
"shoes",
"indigo",
"class_one"
],
"out_of_stock": false,
"quantity": 1,
"price": 129900
},
{
"sku": "SKU65432",
"name": "Michigan Coat XL",
"attributes": [
"tops",
"spring_campaign"
],
"out_of_stock": false,
"quantity": 1,
"price": 144900
}
],
"cart_id": "unique_id"
},
"selected_shipping_option": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"price": 0,
"currency": "SEK",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"time_slot": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
}
},
"shipping_price": 0,
"expires_at": "2024-05-15T17:00:00+02:00",
"customer": {
"address": {
"name": "Erik Johansson",
"address_lines": [
"Industrigatan 5"
],
"city": "Stockholm",
"postal_code": "11239",
"country": "SE"
},
"phone": "0709997711",
"email": "erik@ingrid.com"
},
"search_address": {
"postal_code": "11239",
"country": "SE",
"coordinates": {
"lat": 59.33122199302237,
"lng": 18.030565761645196
}
},
"tos_id": "01HXY19BKD3GRM48VR6K2BRY8T",
"result": {
"shipping": {
"shipping_method": "pnl-mpc",
"delivery_type": "pickup",
"carrier": "PostNord",
"product": "PostNord MyPack Collect",
"location": {
"external_id": "592131",
"name": "Postnord Stockholm Fridhemsg",
"address": {
"name": "Postnord Stockholm Fridhemsg",
"address_lines": [
"Fridhemsgatan 11"
],
"city": "Stockholm",
"postal_code": "11240",
"country": "SE",
"coordinates": {
"lat": 59.3309901,
"lng": 18.0270445
}
},
"distance": {
"walking": {
"value": 237,
"duration": 2
},
"driving": {
"value": 252,
"duration": 1
}
},
"operational_hours": {
"mon": "08:30-19:00",
"tue": "08:30-19:00",
"wed": "08:30-19:00",
"thu": "08:30-19:00",
"fri": "08:30-19:00",
"sat": "10:00-15:00"
},
"meta": {
"pnl.service_point_box_location": ""
},
"location_type": "MANNED"
},
"delivery_time": {
"id": "YFtU9eCnsGhHV_zoQ2KIvQ",
"expires": "2024-05-16T12:00:00+02:00",
"start": "2024-05-17T18:00:00+02:00",
"end": "2024-05-17T18:00:00+02:00"
},
"supports": {},
"warehouse": {
"address": {
"name": "Ingrid Swedish Warehouse",
"address_lines": [
"Mälarvarvsbacken 8"
],
"city": "Stockholm",
"postal_code": "11733",
"country": "SE",
"coordinates": {
"lat": 59.320672,
"lng": 18.035503
}
}
}
},
"category": {
"id": "pickup-points-0c4eaf85363f4fc98197faf9a2ab8830",
"name": "Pickup Points",
"presented_category_name": "Till utlämningsställe",
"custom_text": "Leverans av din order sker med fossilfritt drivmedel bestående av el, muskelkraft eller biodrivmedel från e-handlarens lager fram till din valda leveransplats. Gäller ej returer. Läs mer här (länk till utökad information)."
},
"pricing": {
"currency": "SEK",
"price": 0,
"price_components": [
{
"type": "PRICE_COMPONENT_TYPE_SHIPPING"
}
]
},
"selection": "PRESELECTED_CHOICE",
"delivery_time": {
"pickup_from_merchant": {
"earliest": "2024-05-16T12:00:00+02:00",
"latest": "2024-05-16T12:00:00+02:00"
},
"customer_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
},
"carrier_delivery_promise": {
"earliest": "2024-05-17T18:00:00+02:00",
"latest": "2024-05-17T18:00:00+02:00"
}
}
}
},
"html_snippet": "<div id='ingrid'> ... </div>"
}
Errors
Concurrent updates
Session get, update and complete calls can fail when another concurrent call is made, that updates the session resource.
In that case, the response to this call would be a message with HTTP 409 Conflict
code, and the call would have to be made again.