🎉 Try the public beta of the new docs site at algolia.com/doc-beta! 🎉
Guides / Solutions / Ecommerce / B2B catalog management

In B2B ecommerce, conditions such as prices, discounts, or availability, are different for each buyer. When buyers search or browse, they should see the prices that apply to them. This guide focuses on pricing variations, but you can use the same methods also for other properties, such as minimum or maximum purchase volume or shipment options.

To handle flexible prices and other conditions, you can adopt these strategies:

  • Fixed prices and discounts. If you have one product catalog for all buyers, without variations per-buyer or per-segment, you can use regular B2C solutions with Algolia.

  • Pricing tiers. If you have customer segments with different pricing tiers, you can index the price for each segment as its own attribute. When buyers search, the prices of the segment they belong to are shown.

  • Custom prices per buyer. If each buyer account has its own pricing, you can update the pricing information dynamically. When buyers search for a product, retrieve the product price for that specific buyer from a database and display it in the search results.

  • Negotiable quotes. Allow your B2B buyers to request quotes and update the pricing information with the negotiated prices.

Using nested attributes for pricing tiers

If you have fewer than 100 pricing levels per product, you can configure the price as a nested attribute with one price per tier or customer group.

1
2
3
4
5
6
7
8
9
10
{
  "price": {
    "USD": {
      "default": 100,
      "group_0": 100,
      "group_1": 95,
      "group_2": 90
    }
  }
}

With this approach, you can adopt different sorting strategies. If your pricing has different discount levels based on a public price, you can sort by the public price, for example, price.USD.default. To sort by the per-segment prices, you can use virtual replicas.

You can create up to 20 virtual replicas per index (to create more, contact the Algolia support team). Having many attributes increases your index size and can slow down your search. If you have more than 100 pricing tiers or segments, it’s better to load the pricing information dynamically.

Lazy loading pricing information

If you have an extensive product catalog and many pricing levels, it’s better not to include all variations in the Algolia index. In this case, it’s best to update the pricing information dynamically. When buyers browse or search for products, you can retrieve the custom prices for that specific buyer from another database and show them in your search results.

Load dynamic pricing information from your database and fetch the product information from Algolia

To load the pricing information from another source outside of Algolia:

  1. When a buyer searches, your client-side app or website makes two API requests:

    • To your database with the prices
    • To Algolia with the product information

    Your database contains the pricing information for each buyer.

  2. When presenting the search results, the product information from Algolia is augmented with the pricing information from your database.

In InstantSearch, you can customize the hits widget to include additional information in the search results via the transformItems function.

1
2
3
4
5
6
7
8
9
10
11
12
instantsearch.widgets.hits({
  transformItems(items) {
    const productIDs = items.map((item) => item.objectID);
    // call an external API to get the pricing information
    const prices = getPrices(productIDs);
    items.forEach((item) => {
      item.price = prices[item.objectID];
    });

    return items;
  },
});

Retrieving the pricing information asynchronously

If you have a large product catalog, you can retrieve the pricing information asynchronously at the same time as doing the network request to Algolia.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const searchClient = algoliasearch('YourApplicationID', 'YourAPIKey');
const searchFn = searchClient.search.bind(searchClient);
searchClient.search = async (queries) => {
  const { results } = await searchFn(queries);

  // retrieve the pricing information from an external source
  const prices = await getPrices(results[0].hits.map((hit) => hit.objectID));

  return {
    results: results.map((result) => ({
      ...result,
      hits: result.hits.map((hit) => ({
        ...hit,
        price: prices[hit.objectID],
      })),
    })),
  };
};

Once this is done, you can use the pricing information for displaying, using the same method as in the previous section.

Since the per-customer prices aren’t in the Algolia index, you can’t use them for sorting or filtering. If your price variations are small enough, you could implement sorting by average price. With this approach, you need to call two APIs with every search request: the Algolia API for the product information and the external database for the dynamic pricing information.

Combining pricing attributes with lazy loading

You can combine both approaches. For example, you can include a per-segment price in the Algolia index and retrieve per-customer prices from an external database. This combined approach allows you to filter and sort by segment- or group-level prices while still showing up-to-date per-customer pricing at query time.

Did you find this page helpful?