> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Personalized pricing

> Learn how to handle custom per-segment or per-buyer pricing in B2B ecommerce with Algolia.

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

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.

## Nested attributes as pricing tiers

If you have fewer than 100 pricing levels per product,
you can configure the price as a [nested attribute](/doc/guides/sending-and-managing-data/prepare-your-data/how-to/creating-and-using-nested-attributes) with one price per tier or customer group.

```json JSON icon=braces theme={"system"}
{
  "price": {
    "USD": {
      "default": 100,
      "group_0": 100,
      "group_1": 95,
      "group_2": 90
    }
  }
}
```

With this approach, you can adopt different [sorting](/doc/guides/managing-results/refine-results/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](/doc/guides/managing-results/refine-results/sorting/in-depth/replicas#standard-and-virtual-replicas).

<Note>
  You can create up to 20 virtual replicas per <Index />.
  To create more, contact the [Algolia support](https://support.algolia.com/hc/en-us/requests/new) 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.
</Note>

## 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.

<img src="https://mintcdn.com/algolia/u8QjGPGZbKOqOFEr/images/guides/solutions/b2b-personalized-pricing.svg?fit=max&auto=format&n=u8QjGPGZbKOqOFEr&q=85&s=d0516daa12568cc547ea08c7d2dfc2e9" width="750px" height="100%" alt="Load dynamic pricing information from your database and fetch the product information from Algolia" data-path="images/guides/solutions/b2b-personalized-pricing.svg" />

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.

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

In [InstantSearch](/doc/guides/building-search-ui/what-is-instantsearch/js), you can [customize the `hits` widget](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/js) to include additional information in the search results with the [`transformItems`](/doc/api-reference/widgets/hits/js#param-transform-items) function.

```js JavaScript icon=code theme={"system"}
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;
  },
});
```

## Retrieve 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.

```js JavaScript icon=code theme={"system"}
const searchClient = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');
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.

For a demo, see [Price lazy loading](https://codesandbox.io/p/sandbox/github/algolia/solutions/tree/master/price-lazy-loading).

<Note>
  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.
</Note>

## Combine 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.
