Community TeamVolo StaffVolo Marketing

Welcome to our first instalment of the Flight Engineering series. We'll be exploring the technical innovations and solutions Volo uses to create a powerful multichannel management platform, with lead Solution Architect Alaric Snell-Pym.

Integrating with sales channels is an essential part of what Volo does. We interface with eBay, Amazon, Walmart and others, sending listings to them and then processing orders that come back.

Customers want to list their products on multiple channels. So, we provide one central inventory, one order-processing system, and then interface all the channels into it.

The goal is to reduce the effort required to use each channel, so our customers can sell on more of them and reach more markets. We’re always trying to make selling online as easy as buying online, and that means making adoption of new channels simple.

To do this, we need to make our software use the seller API of each channel to communicate with it.

The Journey
In the early history of the product, we just supported eBay; when we added support for Amazon, it was hard-coded into the core of the product in the same way. But as it slowly became clear that the future held a wide range of channels, we knew we had to re-think that approach.

Adding channels to the product was complicating the codebase; a single software product with more and more features being added to it becomes harder to develop and test. We couldn't just keep adding more channels to it!

The solution is to break the system down into modules, with simple interfaces between the modules. This means that developers working on a module need only understand the interfaces that module uses, rather than the inner workings of the modules providing those interfaces, or any other parts of the system.

Speaking the Same Language
In our case, we clearly needed to provide a standard interface between the core of the system and each channel, in effect letting them talk a common language. The system can maintain a list of channels for each customer, and use that common language with each one to list products and process orders in a channel-agnostic manner. These "channel plugins" talk to the core with our common channel interface, and are responsible for translating it to each channel's native API.

We want to be able to update the channel plugins, and add new ones, without needing to do a whole release of our core product. So rather than making the channel plugins as Java classes deployed into the core, we've gone one step further: they are separate processes, and the common channel interface is a REST API that the plugin implements.

To add channels to a customer's account, we can just provide the URL of the plugin and the customer's API keys. This means we can let customers write their own plugins if they need to interface with bespoke sales channels such as their own ecommerce platforms, and let third parties write and sell their own Volo Origin channel integrations. We could even see ecommerce providers such as Magento provide their own Volo Origin integration module in future.

Working in this way makes it easier for us to add new features to the API. A channel that doesn't support the new features will return an error if we attempt to use them, because it doesn't understand the API call corresponding to the feature.

This means our platform can identify features that some channels don't provide and not offer that feature to users, while still offering the features that the channel does provide.

Staying Feature-rich
Using a common channel plugin API is a simple principle, but the details are complex. How do we define the common API so that it can express the widely varying capabilities of different channels?

It's easy to support lots of channels by only by providing a lowest common denominator feature set - basic listings, without variations or promotions, limited support for cancellations and refunds, and often without optional or category-specific product attributes.

However, our customers tend to come to us already selling on one or more channels. That means we must support all the features channels might have to offer in the channel plugin API.

In future posts, we will explore how we're approaching that problem and building an API that's easy to implement for simple channels, while still providing rich functionality to advance channels.