Friday, October 8, 2021

Implementing B2B Solutions with Commercetools

Sergey Chmelev, Senior Solutions Architect

Commercetools is a well-established cloud-based headless E-Commerce platform. Retailers admire its performance, scalability and high availability, while the developers enjoy thoroughly documented features and APIs, as well as an extensive open-source community support. Historically designed with the focus on B2C features, this powerful MACH platform has started getting lots of traction in the B2B world as well.

1. Architecture

Commercetools makes every effort to make sure your storefront infrastructure and implementation are as lightweight as possible. You typical Commercetools B2C implementation could be as simple as this:

Note that the whole storefront can be run as a client-side application. Commercetools takes care of proper authentication, authorization, and data scope for each API call. Once authenticated as a customer, the /me/* endpoint would return data int the context of the current user only – my orders, my lists, my carts, my profile… This eliminates need for any layer between the client-side code and Commercetools instance.

Things change when it comes to B2B, where the customer is not a user but an organization. The /me/* endpoint would be useless since users within the same customer organization would share access to carts, order history, lists, and other org-wide data. What you need is an extra data access layer that would implement organization-scoped /me/* endpoints while having elevated permissions to access Commercetools data. It can be a middleware, microservice, or even server-side code for your storefront web application:

Here our custom web service exposes /myorg/orders endpoint to the Storefront application. It calls Commercetools client API with permissions to query all orders and retrieves order history for the currently logged in user’s organization only. Of course, you’re responsible for properly securing your custom web service.

While this simplified view gives a general idea on handling the B2B data in the Commercetools-based implementations, there’s more than one way to model the B2B entities and corresponding flows.

Let’s take a look how some of the most important B2B functionality (B2B customers, customer-specific catalogs, and customer-specific pricing) can be implemented within the Commercetools platform.

2. B2B Customers

As you might have already guessed, there’s no out of box support for business customers or customer organizations. The existing Customer entity is tailored to B2C scenarios, where a customer = user. There’s also no quick and straightforward way to declare an organization as a customer with multiple user accounts and roles associated with it. There are quite a few options to consider.

2.1 Stores Approach

It might sound a bit counter-intuitive, but just think about it – there’s already an out of box method of grouping the customer accounts, and even their carts. In many B2B scenarios you are not going to use Stores for their intended purpose anyway, as there’s no real need for physical retail locations and/or brand stores. So, for every B2B customer organization you can create a new Store and assign customer users to it using the out of box Merchant Center and APIs. You even get the benefit of automatically sorting out orders by customer so that your business users could quickly see orders by B2B customer without you writing a single line of code. The biggest downside of the Stores approach is Commercetools limit of 100 (recently decreased from 500) stores per project (aka Commercetools instance). So, if your implementation is to handle more than 100 B2B customer organizations, this option is not going to work.

2.2 Channels Approach

The Channel is another pre-existing Commercetools entity type that can be used to model B2B customer organizations. While there’s no out of box way to directly associate customer users to channels, it is relatively easy to do by adding a Channel reference type to Customer entity. In fact, it can be done via the Merchant Center without writing any code. The real benefit to this approach comes when you need to have B2B customer-specific product availability and pricing as Commercetools supports such functionality for channels out of box. The major problem with the Channel approach is once again the soft limit of 100 (recently decreased from 500) channels per project.

2.3 Custom Objects Approach

Commercetools allows creation of arbitrary JSON-formatted data which can be stored within the platform and retrieved using the Commercetools APIs. Custom Objects can be utilized to represent organizations, or even organization structures which can be referenced by the standard objects, like Customer, Store, Product, etc. This kind of a flexibility comes with a cost though: developers would be responsible for implementing the Merchant Center custom applications to let the business users manage custom objects and their relationships. Unlike the standard Commercetools types, custom objects data integrity and consistency would have to be provided by the middleware or custom services. Finally, the custom objects in Commercetools have very limited query functionality, so retrieving organizations by something like state or city might end up being very complex.

2.4 External System Approach

This approach is similar to the custom objects, but the business organization data is stored and managed in an external system. This can be as simple as just database or as complex as CRM or ERP. While providing considerably better data modeling and management capabilities, this type of implementation is not cheap, and pushes the eCommerce solution boundaries far beyond the Commercetools platform. The External System approach is ideal for the large-scale B2B implementations.

3. Customer-specific Catalogs

Ability to provide a different set of products to each business customer is a firm requirement in almost every B2B eCommerce implementation. A Commercetools project does not have a concept of multiple catalogs, so developers have to get a bit creative here.

3.1 Categories Approach

Using categories is the most natural way to simulate multiple catalogs within the single one. Just create a top-level category for each B2B customer and put related categories and products under it! Of course, you’d have to be careful with implementation of your queries to make sure each B2B customer is limited to their top-level category when querying and searching for products. There’s also a soft limit for total number of categories in a Commercetools catalog: 10,000. That means even if you don’t have any subcategories in your B2B catalog, you would be limited to 10K B2B customers per project. This number would quickly drop if your catalog does have subcategories. Remember, that unlike products, categories in Commercetools catalog can have one parent category only, so you cannot “reuse” the same subcategory under different top-level categories. If your B2B catalog has 99 categories, you would be limited to 10,000/(99 subcategories + 1 top category) = 100 B2B customers with this approach.

3.2 Channels Approach

Modeling the B2B customer organizations against the Commercetools supply channels comes with built-in ability to assign SKUs to specific customers. You would even get a management UI in Merchant Center (in the Inventory tab of the product variant management screen). Now the customer-specific product query becomes simple: just retrieve products assigned to specific channel. Of course, this is not the intended use of supply channels within Commercetools, and the soft cap on the number of channels is once again a limiting factor. However, if your particular use case does not involve multiple inventory sources, and number of B2B customers is less than 100, this might be the fastest way to get B2B functionality within Commercetools.

3.3 External System Approach

Large and scalable B2B implementations would be better off relying on an external system to keep the customer-specific product availability association. A typical approach is a custom database managed via a Merchant Center custom application, and indexed by an enterprise search engine, which in turn provides customer-specific products to storefronts. This may sound costly to implement, but the benefits are evident.

4. Customer-specific Pricing

The customer-specific pricing is another absolute requirement for pretty much every B2B implementation. Unfortunately, this is where the current Commercetools capabilities are very limited.

4.1 Channels Approach

Since the product prices in Commercetools can be specified by the supply channel, assigning such channel to each B2B customer automatically eliminates the need to implement new pricing system, an API to expose it, and UI to manage price assignments. Everything would be taken care of except for the soft limit of 100 channels (hence 100 B2B customers). A viable choice for smaller B2B implementations.

4.2 Customer Groups Approach

Customer group is another way to slice pricing for a product in Commercetools. Creating a group per B2B customer provides benefits similar to the Channels approach – management UI, and available API to query. A Commercetools project has a limit of 1000 customer groups, and this might appear as a better alternative than 100 channels. However, a product variant in Commercetools has a soft limit of 100 prices assigned, so a 1000 customer groups does not really make much difference, unless each B2B customer has access to a relatively small part of the whole catalog.

4.3 External System Approach

Most Commercetools B2B solutions would have to rely on external implementations for price management. The good news is that many B2B service providers already do have a price management system, be it ERP or dedicated price administration software. However, not only the pricing information has to be properly exposed to the storefronts (via indexing engine and custom APIs), but also Commercetools API Extensions have to be implemented for the carts/orders/payments entities in order to make the Commercetools aware of the external product pricing that cannot be modelled or even stored within its own data models.

...And Some More

We went through the typical obstacles in Commercetools B2B implementations. Of course, depending on the business specifics, there could be more required functionality that is not currently native to Commercetools, such as product quotes, reservations, invoicing, support for MTO (made to order) and ATP (available to promise), etc. However, many B2B eCommerce platforms would require extensive customizations for mentioned features anyway. That said there are numerous B2B use cases where Commercetools is a very suitable solution. That’s why about 30% of the current Commercetools deployments are in B2B area.