Shipping Addons

This document describes all necessary steps to implement an addon providing a new shipping method. Such a shipping method can be very flexible in offering delivery options and calculating price.

!! The functionality is not fully implemented and both code and documentation might be subject of change !!

Shipping registry

A new shipping addon must be agreed with API team. There will be a code (identifier) registered for the addon (usually two – one for development purposes and one for production). The following has to be provided:

Shipping addon options

In the API Partner section, Addon details screen, there is a tab dedicated to shipping settings (visible after API team approval):

Shipping method in eshop administration

To make the shipping available in an eshop, two steps have to be done:

Ordering process

JavaScript file specified in the addon setings will be linked in the HTML page.

Shipping details popup

During ordering process, the buyer will select the addon shipping and click on the link to open the popup with detailed options. The content of the popup is defined in the main function of the addon JavaScript file with several required objects. You can find self describing sample JavaScript file on, let’s take a closer look on it.

In this part you set up the content of modal window, which is displayed when buyer chooses your shipping. You are free to create any HTML structure you need. In link.addEventListener part of sample above, random data are set up – this is the part, where you should communicate with your API and retrieve necessary information abbout shipping. Fields label and price with/without VAT (in case price is calculated by the addon) are required items. shoptet.modal.close(); should be called after all necessary operation to close currently opened modal window.

Attach custom object to the external shipping

To make it all work, you have to create an object with the same value as the code your shipping is saved in Shoptet database with (you’ll be acquainted with this name) – call it custom object furthermore. custom object is in camelCase syntax, externalShippingOne in example above. Do not ever overwrite shoptet.externalShipping, only add your own object to it.

Required keys of custom object

Required keys of custom object are:
modalContent – previously set up content of modal window
onComplete – you have access to element, which had triggered the modal open there. You should call shoptet.modal.resize(); after all another operations.
onClosed – if the selected shipping has changed (search for occurrences of myCustomRuntimeObject.updated in example above), you have to create and dispatch event on passed element in strictly same form as shown in example. Name of event (ShoptetExternalShippingChanged) and the detail attribute with price and label information are required.

The popup will be provided with the following information:

There is an event ShoptetBaseShippingInfoObtained fired only once after page load. You can then access shoptet.checkoutShared.deliveryCountryId, shoptet.checkoutShared.regionCountryId and shoptet.checkoutShared.currencyCode.

The addon must call endpoint /api/shipping-request/{shippingRequestCode} with valid access token of the given eshop on the backend (AJAX call to addon backend). In the response there is key information about the eshop and current cart.

The popup content can be fully defined by the addon. It should however respect design and language of the eshop as much as possible.

Delivery address

To be able to confirm the shipping and/or calculate the price, the addon might need to know the delivery address. This is however not yet know, because in the Shoptet ordering process, the address fields are located in the next screen of the order process. If this is too late for the addon, it has to provide its own address fields within the popup. They will be provided to Shoptet via API call and Shoptet will supress the standard address fields.

Note: The addon might need to know, which fields are set mandatory in the eshop – see endpoint Eshop mandatory fields.

Eshop stock location and ready-to-ship time

The addon might need to know where the products will be prepared for delivery and how much time is needed for package preparation. This information is not available in Shoptet databases, so the addon has to provide GUI or imports for this in its own system if needed.

Submitting shipping offer

Once the buyer selects all options and the popup window is closed, the addon has to provide a shipping offer.

For the frontend side, it has to provide price and label using custom RuntimeObject in the JavaScript file.

Also the following information has to be sent via API to the backend:

To do so, use endpoint PUT shipping request. Make sure the request is handled properly (success is returned) before closing the popup window to ensure the backend has the price offer store and is consistent with the frontend. At this moment, this is just a shipping offer, because the buyer can still select another shipping method. The data will be stored for the winning shipping method when the order is finally submited. Shipping, price and address data from this endpoint will be stored in the order.

The PUT shipping request returns a verification code. This verification code has to be submitted with the formular. Shoptet checks, if the verification code on the backend and the one delivered from the frontend are equal to ensure the offer presented on the frontend is the same as stored on the backend.

It is also possible the addon cannot fulfill the shipping and will refuse to provide an offer. The reason can be insufficient delivery capacity or something similar and the order must be completed with another shipping. In this case you need to treat this in your .js file.

It is necessary to take into account the buyer can open the popup multiple times, modify the parameters and eventualy change the shipping methods multiple times.

Changes after shipping details selection

After the popup is displayed, shipping details are selected and price is calculated, the buyer can change value of some of the fields on the page – currency, delivery country or payment method. The currency and delivery country change implies page reload. Payment method will invoke a JavaScript notification.

In general, there are 3 consequences possible:

Events you should listen to

ShoptetShippingMethodUpdated and ShoptetBillingMethodUpdated are fired every time when the shipping/billing method is changed/confirmed; even if it is caused by your shipping method.

After the event is fired you can access shoptet.checkoutShared.activeShipping(Billing). Currently the shoptet.checkoutShared.activeShipping is HTML div element containing all information about shipping/billing, you can access necessary information by query selector.

Submitting the order

Once the order is finalized and submitted, we will send a webhook to confirm the shipping offer was accepted and used in the order and to share the assigned order code. The webhook looks like:

    "eshopId": 222651,
    "event": "shippingRequest:confirmed"
    "eventCreated": "2019-01-08T15:13:39+0100",
    "eventInstance": "os8FtURz7PpO46Z87euEAoBAn9RClB2d"

There are two webhook events:

Item eventInstance contains the shippingRequestCode. It can be used to ask for the shipping request status using Shiping request status endpoint.

    "status": "completed",
    "orderCode": "20200001"

Possible statuses are:

If Shoptet detects the buyer will not use your shipping, we will try to deliver a notification with status cancelled to your addon. It is however not possible to always detect such case. The addon can however make use of expiration (see below) and it can ask for the Shiping request status endpoint anytime. Even the webhook might be missed, so it is a good practise to keep a list of open orders and to periodically check their status.

Shipping request expiration

While some shippings actually do not care, whether the shipping offer will be finally selected or not (such as package delivery), this is crucial in some other case. For example short-time deliveries might reserve a car or a timeframe and need to release it in case the shipping should not be used. This timeout is very individual for each shipping addon.

To manage this, there is expires item in the Shiping request update endpoint. When an addon submits a shipping offer, it can define a deadline, until when it has to be confirmed (order submitted) or it will expire. The expiration is checked by Shoptet ordering process and it is disallowed to submit an order with an expired shipping request.

After an order is submitted

After the order is submitted, there are next steps and events for an addon:

Events important for the particular shipping can be monitored using webhooks (event order:update) and endpoint Last order changes. The addon has to filter orders of interest – either by maintaining orders list or by veryfing the shipping GUID (Shipping GUID is different for each eshop!).

Most probably the addon has to provide settings for each eshop to define, which order status signalizes readiness for shipping or which is the cancellation status.

Order maintenance in eshop administration

Once the order is submitted and shipping request confirmed, particular shipping options cannot be changed in Shoptet administration anymore. It is possible to modify the order and its shipping item, additional text or price, these changes will be however not automatically synchronized to the shipping provider’s system. Such situations have to be clarified with the shipping company or settled manually in the shipping provider’s administration.

Shipping variants

Multiple shipping options (e.g. the company offers package delivery as well as a pickup service) can be implemented in two ways:

Security and consistence

Part of the shipping options and price calculations must be performed in the JavaScript during ordering process. This part can be easily read and modified, if the buyer tries to cheat somehow. It is therefore necessary to replicate all imporatnt information to the backend by means of AJAX and API calls. For Shoptet, the information provided via API on the backend side will be the source of truth.

It is not secure (and therefore must not be used) to transfer API access token to the frontend and to perform API calls from the frontend JavaScript.

Related endpoints