Building a Sales Channel Integration with Zentail

The purpose of this guide is to walk developers through the process of building a Sales Channel integration using Zentail's Open API.

Here is a high level overview of the steps involved in the process. Each is documented in more detail below:

  1. Application Registration
  2. Taxonomy and attribute mapping
  3. Implementing authentication and installation flows
  4. Sending Sales Orders to Zentail
  5. Retrieveing Shipment Notifications from Zentail
  6. Cancelling an order on Zentail
  7. Handling refunds and returns
  8. Retrieving listings
  9. Testing & Verification
  10. Release

This document is intentionally high-level. For details on making specific calls, please refer to our API Specification, all relevant calls used below also will deep link to the relevant call specification.

Registering an application

In order to build the most native feeling and maintainable integration, Sales Channel integrations should first register as a part of Zentail's application registry.

Registration requires:

  1. A unique Application Name
  2. A Contact Email
  3. A Callback URI for sending authentication process communication
  4. A Square Logo at least 50px x 50px that can be used in the Zentail UI

Fill out this form which will kick off the internal process of registering the app and provide you with a clientID and clientSecret that will be used during the authentication flow.

As a sales channel application, you will be granted access to the following APIs:

Taxonomy and Attribute Mapping

In order to leverage Zentail's SMART Type system, we will require your categorization taxonomy and your attribute taxonomy. Zentail will then ingest this data into our system so we can:

  1. Leverage the SMART Type system to make listing products to your channel as easy as possible for our sellers.
  2. Provide you listings via the API in terminology your system already understands (no attribute name mapping required on the developers end)

Templates will be provided to you to fill out and send back to Zentail so we can complete the mapping. The process will likely take some time to complete so it is important to provide this info as early as possible. In the meantime however, you can continue with the authentication and orders pieces of the integration.

Authenticating / Installing

During the registration phase, you will have been issued a clientId and clientSecret. These cannot be used to access the API directly, but will instead be used as a part of a standard OAuth2.0 Authorization Code Grant Flow.

A Zentail customer will enable your application, starting the OAuth authorization flow. Then you will complete the OAuth exchange and you will be automatically issued a token with the proper scopes that can be used for the Open API and will be properly associated with that particular seller. This means that each Zentail seller that sells on your channel will have a separate token that will need to be associated with their seller account on your channel.

For step-by-step details on the authorization flow see our guide here.

All of the steps provided below that involve making API calls should be executed separately for each seller.

Sending Sales orders

For this step, we will implement the process for sending orders that are placed by your customers. In Zentail terminology, these are referred to as Sales Orders.

In the sales channel system, you should identify which seller should fulfill the order, and use their corresponding Zentail API Token to make all calls below.

For this, we will primarily invoke the POST /salesOrder endpoint. The documentation there should provide all of the necessary info to make a successful call, but there are some special callouts below:

Integration ID

Since we are using a registered application, integrationID will not be required (in fact, it'll be ignored).

Order Status / Payment

If you are sending an order to Zentail for fulfillment, you should use either the PENDING or PENDING_PAYMENT status.

For orders that have not yet cleared payment verification, you can send the PENDING_PAYMENT status. In that status, no fulfillment action will be taken, but Zentail will reserve the inventory to fulfill this order for a short period of time.

If you used the PENDING_PAYMENT status, you will need to call the POST /salesOrder/markPaid/{orderNumber} endpoint for that order. Doing so will mark the order PENDING and from there, we will advance the order to the fulfillment process.

Commission

If it is relevant (and possible), you can provide the channel commission charged for this order in the resellerCommission field. This can be very helpful for your sellers so they can have a better picture of their overall profitability on your channel.

Retrieving shipment notifications

Once you have sent orders into Zentail for fulfillment, the next step will be to wait until it's shipped and then retrieve the shipment details.

Currently, there are 2 ways to do this which are each explained in detail below:

  1. Polling the GET /salesOrder endpoint, with the lastUpdatedTs and status filter (recommended)
  2. Polling the GET /salesOrder/{orderId} endpoint.

In either case, you will be looking for a few key things:

  1. The order status is SHIPPED (or PARTIALLY_SHIPPED, more on that below).
  2. The Package objects populated under the packages key on the order.

Each package contains basic package level information like carrier, tracking and shipment timestamp. There is also the products key which can be used to see which SKUs (and how many) are in each package.

For this approach, we will make a request to list all orders in a given status that have been updated on or after the given time. This is particularly useful since it allows us to target a specific set of orders and not need to rely on checking orders we don't care about or checking each order individually.

We recommend keeping a timestamp internal to each token indicating the last timestamp you received a response and querying our API with a time that slightly overlaps that time (maybe one minute before it). Then when you successfully proccess the results of that call, advance your internal timestamp to the time you made the initial request.

You can also add the status filter if you are particularly interested in orders that have shipped. For this, provide the value SHIPPED to the status param in each request.

Since this order data is so critical, we recommend polling at least once every 15 minutes and as fast as once every 2 minutes.

Polling individual orders

You may also use the individual order GET /salesOrder/{orderId} endpoint to check on each unshipped order one at a time. Procedurally, this is simpler but if you are sending a large volume of orders for a particular seller, this can be a bit unweildy and throttling can start to become an issue.

A Note on Partial Shipments

Zentail supports order in a partially shipped state. This indicates that some but not all of the units in the order have been shipped.

You can still process orders in this state, but note the contents of the packages array may change as the remaining items are shipped.

You can identify a partially shipped order by the status PARTIALLY_SHIPPED. Once all of the items are accounted for in shipments, the status will advance to SHIPPED.

Order Cancellations

Merchant Initiated

If an order is unfulfillable, the Zentail seller may need to cancel the order. This information can be obtained similarly to the shipment notifications by polling the GET /salesOrder endpoint. In this case, filter for the status CANCELLED.

We refer to this process as a Merchant Initiated Cancellation.

You will want to check the products array to see the cancelQuantity on each line item to confirm what part of the order is actually cancelled.

Customer Initiated

If, for some reason, an order needs to be cancelled by the customer the POST /salesOrder/cancel/{orderNumber} API can be used to communicate that to Zentail.

We refer to this process as a Customer Initiated Cancellation.

Please refer to the specification for details on calling that endpoint.

Returns / Refunds

Currently the Zentail APIs do not support returns, refunds or replacements. This means sellers will need to be able to manage these directly on your sales channel.

Getting Listing Data

The Zentail listings API will provide a custom, tailor-made payload for your sales channel.

A listing is comprised of a single SKU of set of SKUs related by a set of pivot attributes (think shirst with different sizes). Individual SKUs on a listing are referred to as variants.

The listings API provides several key pieces of data:

  1. Current inventory levels for each variant
  2. Current pricing for each variant
  3. High level meta-data for the listing as well as for each variant (title, description, etc...)
  4. Advanced listing data and images for the listing as well the variants. This includes things like Size, Color and any other attributes defined and mapped during the taxonomy mapping phase.

Each product a seller manages in Zentail may not result in a listing for your channel. In that case, those products will not be returned on this endpoint. Once a seller lists a product to your channel, it will start to appear as a listing. If they delist it after its been listed, we will continue to provide a listing in the API but it will have an inventory level of 0 and all of the listing data cleared out.

For more info you can also check out the listings API guide