Guide for unified commerce

In this guide you will learn how to integrate your Omnichannel flows.

ENDLESS AISLE

If you have completed the above integration points (master data, price, deliveries and stock levels) you should be well of to start using Front Systems POS with the most common retail functionalities.

In case you are sold out in store of of an item your customer want, you can still sell from other stores or the online store.
Using endless aisle feature in Front Systems is easy for the store associate, and it depends on some basic integration points which is covered in this section to get it up and running in your POS.

The only thing actually happening in the pos is the placing of the online order and taking payment from the customer. The rest is completed in your eCom OMS (Order management system) where you send out order confirmation and eventually a shipment confirmation. Just like a normal online order.

Heres a summery of what you need to integrate

  1. Enriched master data (images and descriptions of products) REQUIRED

  2. Stock availability in online store and other stores REQUIRED

  3. Create Online order in your eCOM / OMS REQUIRED

  4. Search for customers in your CRM OPTIONAL

  5. Delivery / Freight OPTIONAL

Step 1. Enriched master data

To enable your store associates to use front systems as a sales tool, they need to able to see the same images and product descriptions you already have available on your web shop.. Out of the box, Front Systems support the  PIM , InRiver. If that’s your PIM, jackpot! Just send the Api-token to your Front Systems contact person and we will have the integration up and running in no time. In case you have another PIM or you would like to control the integration your self, then go ahead and read.

Loop through your products and update them using
PUT /api/Products

Include only images and description in the body if you only are updating those.
In case you dont have the Front Systems ProductId, then look it up by using the GetProductByGTIN endpoint.

Example update payload

{
"description":" "Our model is 186cm long and is wearing a Medium",
"images":" [
"https://yourpimsourceurlexample/1",
"https://yourpimsourceurlexample/2",
"https://yourpimsourceurlexample/3"
]
}

TIP: The first url in the images array will be set as the main image in Front Systems.

Step 2. Stock levels from eCom

You need to show your store associates what's available online of course.
You do this by mirroring your online store stock levels in a separate stock in Front Systems which is used for Endless aisle sales.
Reach out to your Front Systems contact to get the virtual eCom stock setup and the pos configured toward this stock. Get hold of the Front Systems stockId which you will update as often as you want using the following endpoint.

We recommend that you push updates to Front Systems at the event the changes happen in the warehouse. Eg. subscribe to webhooks in your ERP/eCOM and then use our /api/stock/adjust endpoint to reflect the change in real time.

Update stock level
POST /api/Stock/adjust
{
"description": "Stock adjust from online store",
"stockId": 123, //The stockId of the virtual eCom stock
"items": [
{
"gtin": "7020580008718",
"quantity": 5
}
]
}

In case any changes are missed like lost webhooks or similar, we recommend you to do a full reconsile weekly.
To do so, you should include the parameter isCompleteStockCount which will make sure any skus left out of the api-call, will be set to quantity 0.
Also remeber to add the paramter stockCountTime and set it to the time when your reconsile job started.

Full reconcile
POST /api/Stock/adjust

{
"description": "Weekly full reconcile online warehouse",
"stockId": 123, //The stockId of the virtual eCom stock
"stockCountTime":"2021-12-15T04:29:29", //UTC + 'W. Europe Standard Time'
"isCompleteStockCount": true, //any item not included will be set to stock quantity 0
"items": [
{
"gtin": "7020580008718",
"quantity": 5
},
{
"gtin": "xxxx",
"quantity": xxx
},...
]
}


Step 3. Create Online order in your eCOM / OMS

REQUIRED

When an order is placed from the Front Systems POS, a new order is created in the eCom with already payment and customer info attached.

This is completed by you subscribing to the endless aisle web hook. As soon as a sale is completed in a pos, a web hook with all sales details are sent to your subscribing endpoint. When you receive the data, you can simply create the online order in your eCom/OMS platform including the payment.
Make sure to include the transaction id (txtRef) so you bring the payment transaction reference into the order that you create.

Subscribe to endless aisle sales in pos using webhook
POST /api/Webhooks

Heres an example how to subscribe to an endless aisle webhook

{
"event": "OmniChannelEndlessAisleOrderCreated",
"url": "https://yourcallback.com/url"
}

Hers the payload to expect.

{ 
"receiptNo": "552000035",
"receiptFormatted": "",
"receiptUrl": "https://r.frontsystems.com?id=9104f093-1e26-4a64-bf0d-6f943fc2d3c5",
"orderNo": null,
"createdDateTime": "2021-12-17T09:13:20.098429",
"updatedDateTime": null,
"paymentLines": [
{
"type": "Cash",
"subType": null,
"currency": "NOK",
"currencyTendered": 117,
"txRef": "UPD7001620741609002",
"text": "",
"amount": 117
}
],
"orderLines": [
{
"rowId": "",
"gtin": "2012630084389",
"externalSKU": "ldf2012630084389",
"brand": "01 Decimal",
"name": "Hårbøyle",
"variant": "077",
"number": "H6542",
"colour": "Svart",
"size": "0",
"sizeText": "",
"group": "Accessories",
"season": "Noos",
"imageUrl": "https://image.frontsystems.com/93f2fb83-ab12-47e7-92d2-35b586c16062/2e6.jpg",
"quantity": 1,
"price": 117,
"vat": 23.4,
"vatPercent": 0.25,
"fullPrice": 117,
"discount": 0,
"discountPercent": 0,
"receiptLabel": "01 Decimal Accessorie Hårbøyle 077",
"shipFromOnlineStore": true,
"reasons": []
}
],
"fulfillmentLocation":
{
"stockId": 363,
"stockName": "Demo Syd",
"posId": 5552,
"personId": 16212,
"shipmentInfo": [
"3", //carrier id
"PARCELSHOP", //carrier service name
"2", //shipping rate id
"95416" //pickup point id
]
},
"store":
{
"storeExtId": "1482",
"storeName": "Demo Syd",
"organizationNumber": "999 999 999",
"posId": 5552,
"posName": "Simen iPad testrom",
"salesPerson": "Simen from Front Systems",
"currency": "NOK",
"address":
{
"address1": "Lysaker Torg 25",
"city": "Lysaker 2",
"postalCode": "1366",
"country": "Norway",
"countryCode": "NO"
}
},
"customer":
{
"email": "simen.bohmer@outlook.com",
"firstName": "Simen",
"lastName": "Bøhmer",
"companyName": "",
"phoneCountryPrefix": "47",
"phone": "99933333",
"address":
{
"firstName": "Simen",
"lastName": "Bøhmer",
"address1": "Købmagergade 62",
"city": "København",
"postalCode": "1150",
"country": "Denmark",
"countryCode": "DK"
}
},
"shippingAddress":
{
"firstName": "Simen",
"lastName": "Bøhmer",
"address1": "Købmagergade 62",
"city": "København",
"postalCode": "1150",
"country": "Denmark",
"countryCode": "DK"
},
"vatTotal": 23.4,
"total": 117
}

Step 4 Search for customer in CRM

OPTIONAL

Allowing store associates to quickly lookup existing online customers is very convenient when it comes to placing endless aisle orders, because they dont need to ask for a lengthy address description when placing the order. They can simply search for the customer by phone number or email, and then the POS will return all customer data in a split second from your existing CRM/Loyalty solution.

This integration is setup by Front Systems , so please contact your Front systems contact person, to set it up.

Currently we support SalesForce, Voyado and Placewise out of the box.

Step 5 Freight / Delivery

OPTIONAL

When placing the online order on behalf of the customer, you can also ask your customer how they would like the online order shipped. Eg. Which pickup point suits them best, of if they need express delivery.

Digital receipts

Offering your customers a digital receipt is quite cool and you should offer your customer that. The most important thing to acknowledge is that you need to have a 3rd party email service (eg. CRM) for your own domain which will be doing the email sending. This way, you can mange your email look and feel all on your own.

What you need to do is to subscribe to the receipt web hook. As soon as a sale is completed in a pos and the store associate selects email receipt, a web hook with all sales details are sent to your subscribing endpoint.

Subscribe to digital receipt webhook
POST /api/Webhooks

Heres an example of payload to subscribe to digital receipts.

{
"event": "OmniChannelSendReceiptCreated",
"url": "https://yourcallback.com/url"
}

In case you want to send digital receipts on SMS, thats also possible. Either you can use Front Systems built-in SMS-functionality or in case you have your own SMS-service, you can use that. Let us know what you prefer, and we will configure your preferred setup.

This is how the payload looks like which will be sent to your subscribing endpoint when email/sms receipt is selected in the POS.

{
"sendReceipt": {
"receiptNo": "434000004",
"receiptFormatted": "<ArrayOfPrintLine xmlns=\"http://schemas.datacontract.org/2004/07/KTKservice\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><PrintLine><PType>Bitmap</PType><Value/></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Showroom AS</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Bogstadveien 12</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>0205 Oslo</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Tlf.: 22556444</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>showroom@frontsystems.no</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>showroom.frontsystems.no</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Org.no.: 123456789</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Foretaksregisteret</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>BigCenterBold</PType><Value>SALGSKVITTERING</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value>Tid: 2021.09.27 15:08 Kvittnr.: 0434000004</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Ant. Vare Rab. Pris</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> 1 M Jean Paul Jacket Etienne Kåpe 001 2,999.00</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeftBold</PType><Value>Total: 2,999.00</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value>Her av MVA 599.80</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallLeft</PType><Value>MVA sammendrag:</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> 25.0% 599.80</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Oppgjør:</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> Kontant 2,999.00</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>POSID: 5434 </Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Du ble hjulpet av: Mari </Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>BigCenter</PType><Value>Takk for handelen og velkommen tilbake!</Value></PrintLine><PrintLine><PType>Barcode</PType><Value>SC434000004</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine></ArrayOfPrintLine>",
"receiptUrl": "https://r.frontsystems.com?id=df57b301-8162-4687-9216-70be78ffb38e",
"orderNo": null,
"createdDateTime": "2021-09-27T15:08:20.947328",
"updatedDateTime": null,
"paymentLines": [
{
"type": "Cash",
"subType": null,
"text": "",
"amount": 2999.0
}
],
"orderLines": [{
"rowId": "75590552",
"gtin": null,
"brand": "Jean Paul",
"name": "Etienne Kåpe",
"variant": "001",
"number": "jp_123",
"colour": "Svart: Meteorite Grey",
"size": "9",
"sizeText": "M",
"group": "Jacket",
"season": "S2021",
"imageUrl": "https://image.frontsystems.no/05f687c7-5666-48ce-a760-59dce59b9fca/08bae3d7-f8f9-4388-9c21-a68796f38224.jpg",
"quantity": 1.0,
"price": 2999.0,
"vat": 599.8,
"vatPercent": 0.25,
"fullPrice": 2999.0,
"discount": 0.0,
"discountPercent": 0.0,
"receiptLabel": "M Jean Paul Jacket Etienne Kåpe 001",
"shipFromOnlineStore": false
}
],
"store": {
"storeExtId": "2066",
"storeName": "Showroom AS",
"organizationNumber": "123456789",
"posId": 5434,
"posName": "Fixed Pos 01",
"salesPerson": "Mari",
"currency": "NOK",
"address": {
"address1": "Bogstadveien 12",
"city": "Oslo",
"postalCode": "0205",
"country": "Norge",
"countryCode": "NO"
}
},
"customer": {
"email": "",
"firstName": "",
"lastName": "",
"companyName": "",
"phoneCountryPrefix": "",
"phone": "",
"address": {
"firstName": "",
"lastName": "",
"address1": "",
"city": "",
"postalCode": ""
}
},
"shippingAddress": {
"firstName": "",
"lastName": "",
"address1": "",
"city": "",
"postalCode": "",
"country": "Norge",
"countryCode": "NO"
},
"vatTotal": 599.8,
"total": 2999.0
},
"channel": "Email, // Can be either Email or SMS based on what the store associate selects for the sales transaction.
"recipient": "haakon@frontsystems.com", //If channel is Email, then its an email here. If its sms then its a phone number in the format like <CountryCodePrefix Phonenumber> eg. "47 12345678"
"recipientName": "haakon@frontsystems.com",
"signatureInfo": {
"signature": "ULwIVhYcpDB7W8idr/4nnRxyCO/tCOeIlfXpVi1qmW5Wjb+WZAFLXu5S5IAI+LSfgKn5dhvZGVLuHrWTKII9WkRQsgi5D2KHA7NHyqZ2KnDRr4lPA5anToBdnhME8M/S2BAFcKsmh3767iMrtyZryACmREHbJ80WRjMAHVhK7DI=",
"keyVersion": "2"
}
}


Buy online return in store (BORIS)

Alot of online orders end up being returned. Allowing your customers to return in any of your stores, is not only offering great customer service, but also a great way to get the customer back in your store where you can assist them further.

All online orders needs to be imported into Front Systems in order to make the store associate able to refund them from POS.
So whenever an online order has been fufilled, either from Warehouse or a store, you should insert that order into Front Systems.
Typically you can do this when the OMS/eCom fulfils the order or when the ERP receives it as paid (NAV/BC SalesInvoice). Whatever is most convenient for you.
All imported online orders will be made available as part of the purchase history on the customer within the Front Systems app making returning online orders easily accessible.

NOTE: Exclude any orders which are created as endless aisle order, as these are automatically added to the customers purchase history within Front Systems.

Prerequisites     

Front Systems Stores needs to be created for each country available for the online store.
This will make sure currencies and Tax/VAT rules are followed for any potential return in store.
You need to map the StoreId with the country in the Online store.
For example:
When an online order is placed in Germany, the order needs to be imported into Front Systems
with the corresponding Front Systems StoreId.
To get a list of StoreIds, you can run the /api/GetStores.
A store named Online Store and the relevant country is the one you need to map.
For example Online Store Germany.

 Heres an example of how to import an online order

Import online order
PUT /api/Sale
HEADER: X-StoreId : <the Front Systems StoreId specific for the country the order was placed>
{
"saleGuid": "acc7c950-a6b1-4ca1-953e-6df180cab3df", //use a guid here you get from your OMS/ERP or generate one.
"extRef": "#OnlineOrder_123", //The online order number
"customerID": 2633979, //use PUT /api/Customer to retreive or create a customerID
"saleDateTime": "2022-01-17T11:20:53.085Z",
"salesLines": [
{
"identity": "7031581726143", //EAN/GTIN
"price": 1499,
"qty": 1,
"stockid": -1 //Disable adjustment of stock levels on eCom stock
}
],
"paymentLines": [
{
"amount": 1499,
"paymentType": 99 //Unspecified
}
]
}

Now that the online order is available in Front Systems, its available to be refunded in the POS.

There are two ways of refunding online orders in Front Systems.

1) Process the refund in the eCOM/OMS directly.
In this way the store associate doesnt have to ask the customer for a card to refund to. They simply look up the order on the customer and then click "Refund online order".
The OMS will take care of the refund.

2) Process the refund in POS.
This option allows the customer to get the refund in store on any of the appropriate payment types. Eg Card, Voucher, Cash or wire transfer.
This is typically used in case the online order was a gift or if the customer would like to exchange the item into another size or variant.

Either way, you should make sure to update the OMS (erp, ecom..) to get notified about these refund events.

Subscribe to Order updates webhook
POST /api/Webhooks

Heres an example of payload to subscribe to order updates

{
"event": "OmniChannelOrderRefundUpdated",
"url": "https://yourcallback.com/url"
}

The payload you receive will be like this

{
"refund": {
"orderNo": "1412",
"id": "cbbff93d-9875-4e20-9990-7ba99b078c6d",
"status": "Returned",
"isRefunded": false, //False = your OMS/eCom/ERP should complete the refund. true = pos has refunded the customer already.
"orderLines": [
{
"quantity": 1,
"gtin": "7050250949362",
"id": null,
"status": "Returned"
}
],
"fulfillmentLocation":
{
"stockId": 363,
"stockName": "Demo Syd",
"posId": 5807,
"personId": 1000010,
"shipmentInfo": [] }
}
}

Buy online pickup in store (BOPIS) / Buy online deliver from store (BODFS) / Reserve Online purchase in store (ROPIS).

Expose all stores inventory for either pickup or shipping and sell more online and in-store.
Offering consumers a way to pickup their online orders instore increases customer flexibility and also drives more footfall to your store.
Todays shoppers demands rapid deliveries and for you to accomodate for that, you need to make it super easy for all associates to process such orders quickly.

Ship from store is very similar to pickup in store when it comes to the integration part.
The main difference is that it will be shipped from the store instead of picked up by the customer.

To enable either BODFS, ROPIS or BOPIS in Front Systems, you need to complete these integration steps:

  1. Expose in-store stock levels to eCom.

  2. Create new online orders to Front Systems.

  3. Subscribe to order fulfillment updates.

Step 1. Expose in-store stock levels to eCom

When you are allowing consumers to place "pickup in store"-orders or ship from store, its super important that the stock levels are correct.
To do so, you need to setup an integration so your eCom keeps stock levels up to date in real time.
The best approach to reach real time stock levels is by subscribing to web hooks and periodically (eg. every 24hour) pull all stock levels.

To learn how to pull stock levels and subscribe to stock level changes from all stores, please read the section Stock levels and stock movements

Step 2. Send new online order to Front Systems

When the online order is placed in the eCom, you need to make sure that the relevant store receives the order so the store associates are notified and eventually can process it.
To be able to send the order to the relevant store, you need to have the Front Systems StoreId.
You need to setup a new "Integration User" in the Front Systems Portal. This is how:

  1. Login to the Portal (http://portal.frontsystems.no)

  2. Go to Admin > Integration users and click New Integration User

  3. Give it a descriptive name like "Pickup in Store / Ship from store"

  4. Select type company and then save and generate the token.

Use this token together with the header X-StoreId:<StoreId> for the request to the endpoint listed below

Create new Order
POST /api/Omnichannel
HEADER
x-api-key: ***
Ocp-Apim-Subscription-Key: ***
X-StoreId: <Get this from GetStores endpoint for relevant store>

with a payload like this

{
"orderNo": "1411",
"reservationLengthInHours": 168,
"billingAddress": {
"address1": "Lysaker Torg 123",
"address2": null,
"city": "Lysaker",
"comment": null,
"companyName": null,
"country": "Norway",
"countryCode": "NO",
"firstName": "Marius",
"lastName": "Lindholt",
"postalCode": "1366",
"province": ""
},
"customer": {
"email": "show@frontsystems.com",
"firstName": "Marius",
"lastName": "Lindholt",
"phone": "459 75 268",
"phoneCountryCode": "47"
},
"shippingAddress": { //if shippingAddress is not provided, the order will be treated as a "pickup in store" order
"firstName": "Marius",
"lastName": "Lindholt",
"address1": "Lysaker Torg 123",
"city": "Lysaker",
"postalCode": "1366",
"countryCode": "NO"
},
"orderLines": [
{
"gtin": "7050250949362",
"price": "799.00",
"quantity": "1",
},
{
"gtin": "7050250949363",
"price": "1000.00",
"quantity": "1",
}
],
"paymentLines": [ //if no payment lines added, the customer has to pay in store
{
"amount": "1799.00",
"currency": "NOK",
"type": "Klarna"
}
],
"receiptUrl": "",
"saleDateTime": "2021-09-08T11:57:16+02:00"
"status": "UnHandled",
"store": {
"storeName": "theonlinestore.com",

}
}

Step 3. Subscribe to order fulfillment updates

When the Store associate either updates the order status with "Ready for pickup", "Mark as picked up" or "Declined", your eCom/OMS must reflect that.

With any of those statuses received from Front Systems webhooks, your eCom/OMS can treat them respectively.
Eg. for Pickup-in-store-orders
"Case Ready for Pickup" then notify customer of ready for pickup with pickup instructions.
"Case Mark as picked up", then notify customer that its picked up and capture payment.
"Case declined", then notify customer and refund the reservation.

In case the order is to be shipped from the store to the customers address, then the webhook will fire once the order is picked and packed.
When your OMS receives this webhook, it must create the shipment(s) in at your shipping solution (eg. webshipper, consignor, shipmondo or similar)
which in turn will produce and print shipping labels.

Its super easy to subscribe to these events. Just complete these easy steps

Subscribe to Order updates webhook
POST /api/Webhooks

Heres an example of payload to subscribe to order updates

{
"event": "OmniChannelOrderUpdated",
"url": "https://yourcallback.com/url"
}

The payload you receive will be like this

{
"order": {
"orderNo": "1412",
"id": "cbbff93d-9875-4e20-9990-7ba99b078c6c",
"status": "Shipped", //possible values: UnHandled, Shipped, Picked, Rejected. For BOPIS order Shipped means "Picked Up" and "Picked" means ready for Pickup.
"orderLines": [
{
"quantity": 1,
"gtin": "7027421914610",
"rowId": null,
"status": "Picked",
"reasons": []
},
{
"quantity": 1,
"gtin": "7027421914611",
"rowId": null,
"status": "Picked",
"reasons": []
},
{
"quantity": 1,
"gtin": "7027421914612",
"rowId": null,
"status": "Picked",
"reasons": []
},
{
"quantity": 1,
"gtin": "7027421914613",
"rowId": null,
"status": "Declined",
"reasons": [
{
"code": "222",
"name": "Not found"
}
]
}
],
"fulfillmentLocation": {
"stockName": "Demo store",
"stockId": 363,
"posId": 5807,
"personId": 1000010,
"shipments": [ //Only relevant for Ship from store. in case of pickup order, it will not be present in the payload
{
"id": "1",
"items": [
{
"gtin": "7027421914610"
}
]
},
{
"id": "2",
"items": [
{
"gtin": "7027421914611"
},
{
"gtin": "7027421914612"
}
]
}
]
}
}
}