Ingrid Adapter
Ingrid Delivery Platform, which can be used to power Walley Checkout, connects retailers, carriers and consumers to create a better shopping experience for everyone.
How to get started πβ
- Contact Walley Merchant Services for help with setup in our test environment and for questions regarding integration Ingrid.
- If you do not have one already, then create an account with Ingrid
- Provide Walley Merchant Services with Ingrid API key as well as what fallback strategy to use.
Ingrid linksβ
IngridIngrid developer documentation
Ingrid support documentation for Walley Integration
Loyalty booster synergiesβ
If you are using any of our loyalty boosters, we forward the customer's membership to Ingrid as the cart attribute loyalty-isMember, set to one of Yes, No or New β for example loyalty-isMember=Yes:
- Yes: The customer is an existing member.
- No: The customer is not a member and has opted out of becoming one.
- New: The customer is not a member but has opted in to become one.
Does your loyalty program use membership levels? Then we also send an existing member's level as the cart attribute loyalty-level=<levelName>, for example loyalty-level=Gold β the name exactly as you wrote it, and the same level your customer sees in the checkout. No levels, or no level for that member, means no attribute.
Use it to price shipping by level in Ingrid: free home delivery for your top level, a reduced fee for the one below.
Extending regular Walley API requestsβ
Walley checkout with Ingrid might require more information than a regular walley checkout. Below are examples of how to extend the regular Walley API requests to include the necessary information for Ingrid.
- Initilize checkout
- Update checkout
- Update cart
POST /checkouts HTTP/1.1
Host: api.uat.walleydev.com
Authorization: Bearer bXlVc2VybmFtZTpmN2E1ODA4MGQzZTk0M2VmNWYyMTZlMDE...
Content-Type: application/json
{
...,
"cart": {
"items": [
{
"id": "10001",
"description": "A product description",
"unitPrice": 5.0,
"quantity": 1,
"vat": 25.0,
"requiresElectronicId": true,
"sku": "1111-111-1111",
"shipping": {
"tags": ["session-cart-item-tag"],
"unitWeight": 10,
"dimensions": {
"height": 10,
"length": 10,
"width": 10
},
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
}
]
},
...,
"shipping": {
"tags": ["session-cart-tag"],
"shipments": [
{
"tags": ["session-shipment-tag"],
"id": "shipment-1",
"contents": [
{
"quantity": 1,
"sku": "1111-111-1111"
}
]
}
],
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
},
...
}
PUT /checkouts/1eec44b5-66d3-4058-a31f-3444229fb727 HTTP/1.1
Host: api.uat.walleydev.com
Authorization: Bearer bXlVc2VybmFtZTpmN2E1ODA4MGQzZTk0M2VmNWYyMTZlMDE...
Content-Type: application/json
{
"cart": [
{
"id": "10001",
"description": "A product description",
"unitPrice": 5.0,
"quantity": 1,
"vat": 25.0,
"requiresElectronicId": true,
"sku": "1111-111-1111",
"shipping": {
"tags": ["session-cart-item-tag"],
"unitWeight": 10,
"dimensions": {
"height": 10,
"length": 10,
"width": 10
},
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
},
{
"id": "10002",
"description": "Item two",
"unitPrice": 2.0,
"quantity": 1,
"vat": 25.0,
"shipping": {
"tags": ["session-cart-item-tag"],
"unitWeight": 10,
"dimensions": {
"height": 10,
"length": 10,
"width": 10
},
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
}
],
"shipping": {
"tags": ["session-cart-tag"],
"shipments": [
{
"tags": ["session-shipment-tag"],
"id": "shipment-1",
"contents": [
{
"quantity": 1,
"sku": "1111-111-1111"
}
]
},
{
"tags": ["session-shipment-tag"],
"id": "shipment-2",
"contents": [
{
"quantity": 1,
"sku": "10002"
}
]
}
],
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
}
This only updates shipping information at the cart level β you cannot change global shipping properties with this endpoint. This can lead to conflicts when using split-shipping since a shipment might refer to a specific cart item. If you use split-shipment, use the Update Checkout operation instead.
PUT /checkouts/1eec44b5-66d3-4058-a31f-3444229fb727/cart HTTP/1.1
Host: api.uat.walleydev.com
Authorization: Bearer bXlVc2VybmFtZTpmN2E1ODA4MGQzZTk0M2VmNWYyMTZlMDE...
Content-Type: application/json
{
"items": [
{
"id": "10001",
"description": "A product description",
"unitPrice": 5.0,
"quantity": 1,
"vat": 25.0,
"requiresElectronicId": true,
"sku": "1111-111-1111",
"shipping": {
"tags": ["session-cart-item-tag"],
"unitWeight": 10,
"dimensions": {
"height": 10,
"length": 10,
"width": 10
},
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
},
{
"id": "10002",
"description": "Item two",
"unitPrice": 2.0,
"quantity": 1,
"vat": 25.0,
"shipping": {
"tags": ["session-cart-item-tag"],
"unitWeight": 10,
"dimensions": {
"height": 10,
"length": 10,
"width": 10
},
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00",
"alternatives": [
{
"name": "alternative-name",
"shippingInterval": {
"startDate": "2024-01-01T00:00:00",
"endDate": "2024-01-07T00:00:00"
}
}
]
}
}
}
]
}
Walley β¨ Ingrid data mappingβ
| Walley checkout cart items properties | Ingrid request properties |
|---|---|
| id | cart.items.sku (if sku is not present) |
| description | cart.items.name |
| unitPrice | cart.items.price |
| quantity | cart.items.quantity |
| sku | cart.items.sku |
| shipping.tags | cart.items.attributes |
| shipping.unitWeight | cart.items.weight |
| shipping.dimensions | cart.items.dimensions |
| shipping.shippingInterval.startDate | cart.items.shipping_date.start |
| shipping.shippingInterval.endDate | cart.items.shipping_date.end |
| shipping.shippingInterval.alternatives[].name | cart.items.shipping_date.category_tags.name |
| shipping.shippingInterval.alternatives[].shippingInterval.startDate | cart.items.shipping_date.category_tags.shipping_data.start |
| shipping.shippingInterval.alternatives[].shippingInterval.endDate | cart.items.shipping_date.category_tags.shipping_data.end |
| Walley checkout shipping properties | Ingrid request properties |
|---|---|
| tags | cart.attributes |
| shipments[].tags | cart.groups.attributes |
| shipments[].id | cart.groups.group_id |
| shipments[].contents[].sku | cart.groups.contents.sku |
| shipments[].contents[].quantity | cart.groups.contents.quantity |
| shippingInterval.startDate | cart.shipping_data.start |
| shippingInterval.endDate | cart.shipping_data.end |
| shippingInterval.alternatives[].name | cart.shipping_date.category_tags.name |
| shippingInterval.alternatives[].shippingInterval.startDate | cart.shipping_date.category_tags.shipping_data.start |
| shippingInterval.alternatives[].shippingInterval.endDate | cart.shipping_date.category_tags.shipping_data.end |
Extending regular Walley API GET checkout responseβ
As with any delivery adapter walley provide information about the selected delivery when you get checkout information located in the shipping property.
When using the Ingrid Adapter you will get additional data that you can find in the mapping tables below.
Walley provided shipping dataβ
| Walley checkout properties | Walley provided values |
|---|---|
| shipping.provider | 'Ingrid' or 'MerchantFallback' |
| shipping.shippingFee | Total cost of all deliveries |
| shipping.shipments[] | All of the data in each shipment (except feeItemId) is taken from the Ingrid session, and can be found in the table below. |
| shipping.shipments[].feeItemId | Id for the shipping fee item |
Ingrid β¨ Walley data mappingβ
| Walley checkout shipment properties (found in shipping.shipments[]) | Ingrid delivery group properties (found in session.delivery_groups[]) |
|---|---|
| id | group_id |
| externalShipmentId | tos_id |
| metadata.customerDeliveryPromise.earliest | delivery_time.customer_delivery_promise.earliest |
| metadata.customerDeliveryPromise.latest | delivery_time.customer_delivery_promise.latest |
| metadata.carrierDeliveryPromise.earliest | delivery_time.carrier_delivery_promise.earliest |
| metadata.carrierDeliveryPromise.latest | delivery_time.carrier_delivery_promise.latest |
| metadata.pickupFromMerchant.earliest | delivery_time.pickup_from_merchant.earliest |
| metadata.pickupFromMerchant.latest | delivery_time.pickup_from_merchant.latest |
| shippingChoice.id | shipping.carrier_product_id |
| shippingChoice.name | shipping.product (carrier used if product missing) |
| shippingChoice.fee | pricing.price / 100 |
| shippingChoice.metadata | shipping.meta |
| shippingChoice.destination.id | address.location.external_id |
| shippingChoice.destination.name | address.location.name |
| shippingChoice.destination.metadata.address.addressLines | address.location.address.addressLines |
| shippingChoice.destination.metadata.address.apartmentNumber | address.location.address.apartmentNumber |
| shippingChoice.destination.metadata.address.attn | address.location.address.attn |
| shippingChoice.destination.metadata.address.careOf | address.location.address.careOf |
| shippingChoice.destination.metadata.address.city | address.location.address.city |
| shippingChoice.destination.metadata.address.companyName | address.location.address.companyName |
| shippingChoice.destination.metadata.address.country | address.location.address.country |
| shippingChoice.destination.metadata.address.firstName | address.location.address.firstName |
| shippingChoice.destination.metadata.address.lastName | address.location.address.lastName |
| shippingChoice.destination.metadata.address.postalCode | address.location.address.postalCode |
| shippingChoice.destination.metadata.address.region | address.location.address.region |
| shippingChoice.destination.metadata.address.street | address.location.address.street |
| shippingChoice.destination.metadata.address.streetNumber | address.location.address.streetNumber |
| shippingChoice.options[].id | shipping.delivery_addons[].id |
| shippingChoice.options[].value | shipping.delivery_addons[].external_addon_id |
| shippingChoice.options[].fee | shipping.pricing.price_components[].value |
Total shipping fee per shipmentβ
There is no single property that holds the total shipping cost for a shipment. When using split shipping you calculate the
total fee for each shipment in shipping.shipments[] by summing the fees of the selected delivery:
shippingChoice.fee + shippingChoice.destination.fee + shippingChoice.destination.deliveryDate.fee + sum(shippingChoice.options[].fee)
Properties that are not part of the selected delivery are omitted or null, and should be treated as 0 in the calculation.
The sum of the total fee of all shipments equals shipping.shippingFee.
Exampleβ
GET /checkouts/1eec44b5-66d3-4058-a31f-3444229fb727 HTTP/1.1
Host: api.uat.walleydev.com
Authorization: Bearer bXlVc2VybmFtZTpmN2E1ODA4MGQzZTk0M2VmNWYyMTZlMDE...
Response example:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "1eec44b5-66d3-4058-a31f-3444229fb727",
"data": {
"customer": { ... },
...,
"status": "PurchaseCompleted",
"order": {
"totalAmount": 217,
"items": [
{
"id": "10001",
"description": "A product description",
"unitPrice": 5,
"quantity": 1,
"vat": 25,
"sku": "Item one sku"
},
{
"id": "10002",
"description": "Item two",
"unitPrice": 2,
"quantity": 1,
"vat": 25,
"sku": "Item two sku"
},
{
"id": "Frakt-1",
"description": "PostNord - MyPack Home",
"unitPrice": 100,
"quantity": 1,
"vat": 25
},
{
"id": "Frakt-2",
"description": "PostNord - MyPack Home",
"unitPrice": 110,
"quantity": 1,
"vat": 25
}
]
},
"shipping": {
"provider": "Ingrid",
"shippingFee": 210.0,
"shipments": [
{
"id": "shipment-1",
"externalShipmentId": "01GE6FJ2J52Z2NHRY17HDJ1977",
"feeItemId": "Frakt-1",
"metadata": {
"customerDeliveryPromise": {
"earliest": "2024-01-01T00:00:00",
"latest": "2024-01-07T00:00:00"
},
"carrierDeliveryPromise": {
"earliest": "2024-01-01T00:00:00",
"latest": "2024-01-07T00:00:00"
},
"pickupFromMerchant": {
"earliest": "2024-01-01T00:00:00",
"latest": "2024-01-07T00:00:00"
}
},
"shippingChoice": {
"id": "pnl",
"name": "PostNord - MyPack Home",
"fee": 100.0,
"metadata": null,
"destination": {
"id": "location-external-id",
"name": "Gothenburg",
"metadata": {
"address": {
"addressLines": ["Street 1", "Street 2"],
"apartmentNumber": "1",
"attn": "",
"careOf": "",
"city": "City",
"companyName": "Company name",
"country": "SE",
"firstName": "First Name",
"lastName": "Last Name",
"postalCode": "12345",
"region": "Region",
"street": "Street 1",
"streetNumber": "1"
}
}
}
}
},
{
"id": "shipment-2",
"externalShipmentId": "01GE6FJ2J5D3QHTD57XX0B38TS",
"feeItemId": "Frakt-2",
"metadata": { ... },
"shippingChoice": {
"id": "pnl",
"name": "PostNord - MyPack Home",
"fee": 100.0,
"metadata": { ... },
"destination": { ... },
"options": [
{
"id": "b225eaee-c31d-4c30-b6cf-1770f1d208cd",
"value": "express",
"fee": 10
}
]
}
}
]
},
...
}
}