Broadleaf Microservices
  • v1.0.0-latest-prod

Pricing Provider

Overview

Provider for interfacing with a Pricing Engine that can supply merchandise pricing for the contents of a cart. The default implementation facilitates HTTP requests against the Pricing Services endpoints. The Pricing Engine should provide retail, sale, contract, etc. prices.

Default Implementation Details

The default implementation, ExternalPricingProvider, handles building out the DTOs and pricing contexts the Broadleaf Pricing Engine requires. Each CartItem can be converted into a PriceableTarget. This process is delegated to CartItemPricingUtils, which also handles mapping the PriceInfo that the Pricing Engine returns back onto the corresponding cart items.

Request Details

A PriceableTarget is a DTO representing any kind of entity that can be priced. It includes

  • the ID,

  • the type (e.g., SKU, PRICING_KEY),

  • the quantity to help identify placement within quantity-based pricing tiers (e.g. buy in bulk to get a discounted price),

  • a map representing the priceable fields of the entity (e.g., basePrice → $10.99, salePrice → $9.99, cost → 1.99),

  • a reference to the marketplace vendor to help identify the target for applicable pricing,

  • and a map of arbitrary attributes that the pricing engine can target such as the entity’s name, categories it belongs to, etc.

These targets are included in the pricing request in the X-Price-Info-Context header as well as

  • the IDs of any prefetched price lists,

  • whether to include the PriceTypeDetails mentioned above in the response

Pricing requests can also include additional context in the X-Price-Context header such as

  • the locale,

  • currency,

  • users,

  • web request attributes like user agent or URL on the frontend being viewed

Request Payload

Example Pricing Request
{
  "priceableTargets": [
    {
      "targetId": "HS-HHS-20", // (1)
      "targetType": "SKU", // (2)
      "targetQuantity": 1, // (3)
      "priceableFields": { // (4)
        "standardPrice": {
          "amount": 8,
          "currency": "USD"
        },
        "basePrice": {
          "amount": 8.99,
          "currency": "USD"
        }
      },
      "attributes": {} // (5)
    },
    {
      "targetId": "HS-GG-20", // (1)
      "targetType": "SKU", // (2)
      "targetQuantity": 2, // (3)
      "priceableFields": { // (4)
        "standardPrice": {
          "amount": 12,
          "currency": "USD"
        },
        "basePrice": {
          "amount": 11.99,
          "currency": "USD"
        },
        "salePrice": {
          "amount": 9.99,
          "currency": "USD"
        },
        "contractPrice": {
          "amount": 7.5,
          "currency": "USD"
        }
      },
      "attributes": {} // (5)
    }
  ],
  "priceLists": [], // (6)
  "skipDetails": false // (7)
}
  1. The target ID, this is the identifier of the entity being priced. Typically, this is either the SKU or pricing key.

  2. The target type, this declares how the entity is being identified. This is set to SKU or PRICING_KEY, see CartPricingTargetType.

  3. The quantity of the target entity, this informs the pricing service of when price data tiers may apply during best price calculations.

  4. Optional details for priceable fields on the cart item, each of these entries are keyed by their type and contain the best price based on their type and currency. Possible pricing types include standardPrice, basePrice, salePrice, etc.; to see all the out-of-box priceable types, see PricingFields.

  5. Additional attributes that are passed to the pricing service.

  6. Optional list of prefetched PriceListRef details to price against.

  7. Flag that determines whether or not to return the PriceTypeDetails on the PriceInfos response. These details breakdown the best prices per pricing type and include details for all the potential pricelists of that type.

Response Details

The result of a request to the Pricing Engine is a list of PriceInfos, which are then mapped back onto their respective cart items. A PriceInfo represents the pricing information for a target. This includes

  • The target itself

  • The best overall price chosen for it

  • The type of the best price (whether base/retail, sale, contract)

  • The ID of the price list that provided the price (if any)

  • A map of all candidate prices by type of price. This includes a similar structure called a PriceTypeDetail that has the best price for that type (e.g., sale price) as well as a map of all candidate sale prices.

Response Payload

Example Pricing Response
[
  {
    "target": { // (1)
      "targetId": "HS-HHS-20",
      "targetType": "SKU",
      "targetQuantity": 1,
      "priceableFields": {
        "standardPrice": {
          "amount": 8,
          "currency": "USD"
        },
        "basePrice": {
          "amount": 8.99,
          "currency": "USD"
        }
      },
      "attributes": {}
    },
    "price": {  // (2)
      "amount": 8,
      "currency": "USD"
    },
    "priceType": "standardPrice", // (3)
    "priceListId": "01H82FNQ6RAZ410VSH2FSC04CQ", // (4)
    "priceTypeDetails": { // (5)
      "standardPrice": { // (5a)
        "type": "standardPrice",
        "bestPrice": {
          "amount": 8,
          "currency": "USD"
        },
        "priceListId": "01H82FNQ6RAZ410VSH2FSC04CQ",
        "priceDetails": {
          "01H82FNQ6RAZ410VSH2FSC04CQ": {  // (6)
            "price": {
              "amount": 8,
              "currency": "USD"
            },
            "priceList": {
              "id": "01H82FNQ6RAZ410VSH2FSC04CQ",
              "type": "STANDARD",
              "name": "Standard US pricing",
              "currency": "USD"
            },
            "priceType": "standardPrice",
            "priceDataTierList": []
          }
        }
      },
      "basePrice": { // (5b)
        "type": "basePrice",
        "bestPrice": {
          "amount": 8.99,
          "currency": "USD"
        },
        "priceDetails": {}
      }
    }
  },
  {
    "target": {
      "targetId": "HS-GG-20",
      "targetType": "SKU",
      "targetQuantity": 2,
      "priceableFields": {
        "standardPrice": {
          "amount": 12,
          "currency": "USD"
        },
        "salePrice": {
          "amount": 9.99,
          "currency": "USD"
        },
        "contractPrice": {
          "amount": 7.5,
          "currency": "USD"
        },
        "basePrice": {
          "amount": 11.99,
          "currency": "USD"
        }
      },
      "attributes": {}
    },
    "price": {
      "amount": 7.5,
      "currency": "USD"
    },
    "priceType": "contractPrice",
    "priceListId": "01H82FKVNC4FJ106HJN1WW1HQ1",
    "priceTypeDetails": {
      "salePrice": {
        "type": "salePrice",
        "bestPrice": {
          "amount": 9.99,
          "currency": "USD"
        },
        "priceListId": "hc_base_sales",
        "priceDetails": {
          "hc_base_sales": {
            "price": {
              "amount": 9.99,
              "currency": "USD"
            },
            "priceList": {
              "id": "hc_base_sales",
              "type": "SALE",
              "name": "Base Running Sales",
              "priority": 200,
              "currency": "USD"
            },
            "priceType": "salePrice",
            "priceDataTierList": [
              {
                "minQuantity": 4,
                "price": {
                  "amount": 6,
                  "currency": "USD"
                }
              }
            ]
          },
          "01H8203221T3XD1152RD441F3J": {
            "price": {
              "amount": 8,
              "currency": "USD"
            },
            "priceList": {
              "id": "01H8203221T3XD1152RD441F3J",
              "type": "SALE",
              "name": "New Sale Prices",
              "currency": "USD"
            },
            "priceType": "salePrice",
            "priceDataTierList": []
          }
        }
      },
      "contractPrice": {
        "type": "contractPrice",
        "bestPrice": {
          "amount": 7.5,
          "currency": "USD"
        },
        "priceListId": "01H82FKVNC4FJ106HJN1WW1HQ1",
        "priceDetails": {
          "01H82FKVNC4FJ106HJN1WW1HQ1": {
            "price": {
              "amount": 7.5,
              "currency": "USD"
            },
            "priceList": {
              "id": "01H82FKVNC4FJ106HJN1WW1HQ1",
              "type": "CONTRACT",
              "name": "Contract Pricing",
              "currency": "USD"
            },
            "priceType": "contractPrice",
            "priceDataTierList": []
          }
        }
      },
      "standardPrice": {
        "type": "standardPrice",
        "bestPrice": {
          "amount": 12,
          "currency": "USD"
        },
        "priceListId": "01H82FNQ6RAZ410VSH2FSC04CQ",
        "priceDetails": {
          "01H82FNQ6RAZ410VSH2FSC04CQ": {
            "price": {
              "amount": 12,
              "currency": "USD"
            },
            "priceList": {
              "id": "01H82FNQ6RAZ410VSH2FSC04CQ",
              "type": "STANDARD",
              "name": "Standard US pricing",
              "currency": "USD"
            },
            "priceType": "standardPrice",
            "priceDataTierList": []
          }
        }
      },
      "basePrice": {
        "type": "basePrice",
        "bestPrice": {
          "amount": 11.99,
          "currency": "USD"
        },
        "priceDetails": {}
      }
    }
  }
]
  1. The target that requested this pricing operation. These were included in the PriceInfoContext request to the pricing service.

  2. The best overall price for the target.

  3. The best price’s type, see PricingFields for potential pricing types.

  4. The pricelist ID of the best price, if any. If the best price was the price information from the catalog entity and not a pricelist, this would field would be returned as null.

  5. The price type details, which contain the information around the best price per price type. Each entry is keyed by the price type and contains the best price & pricelist details if associated to a pricelist.

    1. This example is a PriceTypeDetail for a standard pricelist and so it’s keyed by its price type, standardPrice. It also contains the best price and the ID of the standard pricelist, as well as the pricelist PriceDetails as seen in (6).

    2. This example is a PriceTypeDetail for the basePrice that is stored on the entity catalog information. Since this price is from the catalog data and not a pricelist, there is no pricelist ID and no price details included on the response.

  6. This entry is an example of a PriceDetail and is keyed by the pricelists’s ID. It contains the price that was provided by the pricelist, information about the pricelist (name, type, etc.), the pricing type, and any pricing tiers for the pricelist.

Configuration

ExternalPricingProperties defines the properties for configuring the ExternalPricingProvider. These include

  • broadleaf.cartoperation.pricingprovider.url: The base url of the Pricing Engine

  • broadleaf.cartoperation.pricingprovider.priceInfosUri The context path for retrieving PriceInfos for the cart This is appended to the url property.

Examples of building request from properties
UriComponentsBuilder.fromHttpUrl(properties.getUrl())
        .path(properties.getPriceInfosUri())
        .toUriString())