Pricing Management

General Summary

This document presents the pricing configuration and all its relation with other services on BEES platform, how it is related with others services, how it provides information for the next level services, and the importance of maintaining a good knowledge and understand about prices for the next steps.

This document is separated in three main topics, being them PRICING, DEALS and INTERESTS which are the three main parts of the price engine. The first session presents an overview of this functionality.

Prices Management

The Prices service provides information about prices, taxes and charges that are applied to a Product/SKU given a POC (Point of Connection/Consumption), such as base price, minimum price, promotional price, deposit, charges, taxes.

General Summary

Price represents a set of circumstances that apply when a price is calculated to a Product/SKU. For example, a customer orders a certain quantity of a product on a certain day. The variable factors here: the customer, the SKU, the order quantity, the date of when the order is being simulated. It also contains some attributes of the Taxes and Charges. For more details look up for the whole service in the links that will be shown later in this document.

Prices Placement

Load Limits

Regardless the BEES platform infrastructure robustness, it's necessary to limit the size of payload in 2MB per request, because of security and performance reasons (this limit is set by the application gateway). The number of entities could be greater if the payload is compressed. Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Prices

[PUT] /v2

yes

5K

Accounts

[PUT] /v2

yes

50k

If the payload limit size exceeds no error is returned.

Highlight Fields

Below are described which fields or attributes are important for a valid price:

Field

Description

VendorAccountId

Used to relate the account with the other services.

SKU (Stock Keeping Unit)

Used to identify product.

VendorItemId

Used to identify product. It can be equals to the SKU if the SKU is unique

BasePrice

Price of the product to calculate charges and taxes

MinimumPrice

Minimum price that should be payed for a product even with deals

PromotionalPrice

Product price that should be applied if its value is lower than BasePrice with deals

Deposit

Amount value of the returnable

QuantityPerPallet

Quantity of products that fits into a pallet

MeasureUnit

Type of the measure unit of the SKU

ValidFrom

Date identifying when this price will be valid. This field gives us the possibility to insert prices upfront, and from that date on this price will be the valid one

Charges

Additional fee paid for a specific service. Notice that this field represents charges that are exclusively linked to a product, and does not have any conditions to be applied
ChargeId - Charge id to identify the type of the charge
Base – Base value to be used instead of Product BasePrice to calculate charge
Type – Type of the charge to be calculated. It’s percentage (%) or amount ($)
Value - Value to calculate charge based on its type

Tax

Sum of money demanded by the Government
TaxId - Tax id that is used to indicate the name of the tax, also it’s referenced on TaxBaseInclusionId as tax over tax
Type - Type of the tax to be applied. It’s percentage or amount
Value – Value of the tax to be calculated above Product BasePrice
Base – Base value to be used to calculate tax instead of Product BasePrice
Hidden – Flag to indicate if tax will be displayed in the cart response
TaxBaseInclusionIds – Tax Id that indicated that tax should be calculated over another tax (compound tax)

It's important the price to have a valid set of information in order to further service work properly. Also, extra empties products need to be inserted into the prices structure with its basePrice (or deposit) value set.

Prices Data Details

  • ZTPM (Promotional Price): This structure was established to the (MX) Mexico zone migration, as a way to have a promotional price to a Item even when there is also a deal. The rule is that in the simulation pricing-engine will check which one of them gives the user the best benefit. To set how to calculate a promotional price, the structure below should be sent in the payload:

"promotionalPrice": {
"price": 10.19,
"externalId": "ZTPM"
}

PS: The promotional price will be applied ONLY if base price with Deals applied is greater than promotional price.

  • Tax over Tax: To set a tax over tax in case of compound tax the taxBaseInclusionIds should be provided where it says which of the taxes are depending on each other. It does not apply for a simple tax, only tax over taxes.

"taxes": [
{
"taxId": "IVA",
"type": "%",
"value": 16.5,
"taxBaseInclusionIds" : [
"IEPS"
]
},
{
"taxId": "IEPS",
"type": "%",
"value": 26.5,
}
]

Check that in this example above IVA is applied over IEPS.

  • Perception Tax: Was established to solve a tax problem in AR (Argentina) zone. Although it’s known as “perception tax”, it can be used with any tax that it’s conditional to a “orderSubTotal” value. To set a scaled tax, the condition of the minimum order value should be present. In case order hits the minimumValue, a tax will be applied.

"taxes": [
{
"taxId": "IVA",
"type": "%",
"value": 20.00,
"conditions": {
"orderSubTotal": {
"minimumValue": 2000.00
}
}
}
]

Note: in order to use this feature, the configuration “ignoreTaxesBasedOnCondition” must set to “True” for the Pricing Team in the application configuration.

It determines if the taxes must be applied based on the condition or not. Only applicable for /deals and /prices.

  • Hidden Tax: This flag will control if the tax appears in the cart response or not. It was established to the CO (Colombia) zone as a way to add a tax paid by ABI during the production process, but that needs to be transferred to the user total value without been displayed to him.

"taxes": [
{
"taxId": "IVA",
"type": "%",
"value": 20.00,
"hidden": true
}
]
  • Charges (Logistic Cost/Modeloramas): This field was established to solve a MX (Mexico) zone problem related to add a charge to a product, not depending on any condition. Check that pricing-engine has a charges-relay that is different from this structure, as charges in prices structure do not have conditions to be applied and are highly attached to the VendorItem. To set a logistic cost for each product separately in the cart, it’s necessary to send a charge structure called chargeId. Notice that any chargeId can be sent to pricing-engine, but the ones different to LOGISTIC_COST and MODELORAMAS needs to be mapped with the cart-service team and the front end, so it can be correctly displayed to the users.

"charges": [
{
"chargeId": "LOGISTIC_COST",
"type": "$",
"value": 2.00,
"base": 0
}
]

For most common required fields please access the required fields session. Apart those, the service has specific ones for each endpoint and they could be verified accessing the API documentation.

Prices Deletion

The prices deletion is a resource available in the price relay, it uses the same endpoint as the price but with the DELETE HTTP method. The request payload must contain the vendorAccounts and VendorItems for which the price must be removed.

Load Limits

Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Prices

[DELETE] /v2

yes

5K

Accounts

[DELETE] /v2

yes

50K

Deals Management

General Summary

Deals provides types of discount that is negotiated between the POCs and ABI informing quantity limit, availability, discount amount or discount percentage and conditions to apply the discounts or freegoods.

Deals represent a set of circumstances that apply discounts to a price or freegoods when is calculated to a Product/SKU. For example, a customer orders a certain quantity of a product on a certain day. The variable factors here: the customer, the SKU, the quantity, the deal, the conditions when the order is being simulated. For more details look up for the whole service in the links that will be shown later in this document.

Deals Placement

Load Limits

Regardless the BEES platform infrastructure robustness, it's necessary to limit the size of payload in 2MB per request, because of security and performance reasons (this limit is set by the application gateway). The number of entities could be greater if the payload is compressed. Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Deals

[PUT] /v2

yes

5K

Accounts

[PUT] /v2

yes

50K

If the payload limit size exceeds an error is returned.

Highlight Fields

Below are described which fields or attributes are important to have for a valid deal:

Field

Description

VendorAccountIds

Used to relate the accounts with the other services

Deals - vendorDealId

Deal identification

VendorPromotionId

ID of the promotion related to the Deal

AccumulationType

Type of accumulation (used by AR): ADD, COMPOSE, UNIQUE, HIGH, LOW - Optional

Priority

Priority of the deal to be applied - Optional

Level

Level of the deal to be applied - Optional

Budget

The budget for the customer (The discount of the customer cannot pass the deal budget - It is not saved into the PE database, Enforcement team handles this info) - Optional

Availability

Number of times a promotion can be applied - Optional

QuantityLimit

The limit number of the freegoods the customer is allowed to receive from this deal

Conditions

Set of rules combined that decides if deal is going to be applied or not.
PaymentMethod - The payment method the customer needs to choose to satisfy the condition.
SimulationDateTime - Date of the simulation to satisfy the condition.
DeliveryDate - Date of the delivery to satisfy the condition.
LineItem:
    - VendorItemIds - Used to identify list of products that the user needs to buy to meet the condition.
    - MinimumQuantity - The minimum quantity in the cart of these products to be eligible to receive the benefit.
    - SharedMinimumQuantity – A flag that indicates if the minimum quantity can be shared between the list of the VendorItemIds.
    - CrossDiscount – A flag that indicates if the discount can be applied to a different VendorItemId from the Condition in the Output.
MultipleLineItem:
Items
        - VendorItemIds – Used to identify list of products that the user needs to buy to meet the condition.
        - MinimumQuantity - The minimum quantity in the cart of these products to be eligible to receive the benefit.

Output

Type of benefit that will be applied if conditions are satisfied.
OrderTotalDiscount - Amount or percent given as benefit in the order level. Being them:
    - Type – Amount ($) or percent (%).
    - Discount – Value of the discount to be given
    - Proportion – Every X number (quantity) to acquire a discount. It doesn’t work if Fixed is set to true.
    - Fixed – Flag that indicates if the proportion will be applied. In case it’s false, the proportion should be greater than zero.
LineItemDiscount – Amount or percent given as benefit in the line item level (product). Being them:
    - VendorItemIds – List of products that gets the discount
    - Type - Amount ($) or percent (%)
    - Value - Value of the discount to be given.
    - MaxQuantity - The maximum quantity of VendorItemId that the discount can be applied
    - Proportion – Every X number (quantity) to acquire a discount. It doesn’t work if Fixed is set to true.
PalletDiscount - Discount given to POCs that are responsible to unload the truck during delivery. Being Them:
    - Discount – Value of the benefit.
    - Proportion - Every X number (quantity) to acquire a discount.
    - MeasureUnit – Measure unit of the beverages that fits in a pallet.
LineItemScaledDiscount – Scaled amount or percent given as benefit in the line item level (product). Follow the description of the field:
    - VendorItemIds – List of products that gets the discount.
    - Ranges:
        - From – The intial quantity that the deal might be applied.
        - To – The end quantity that the deal might be applied.
        - Type – Amount ($) or percent (%).
        - Value – Vale of the discount to be given.
        - MaxQuantity – The maximum quantity of VendorItemId that the discount can be applied. It's required on the latest range.
        - Proportion – Every X number to acquire a discount. It doesn’t work if Fixed is set to true.
        - Fixed – Flag that indicates if the proportion will be applied. In case it’s false, the proportion should be greater than zero.
FreeGoods - For this type of deal, the customer earns an item of the specific list if they achieve the minimum quantity of the combination.
    - Fixed – Flag that indicates if the proportion will be applied. In case it’s false, the proportion should be greater than zero.
    - Proportion - Every X number to acquire a discount. It doesn’t work if Fixed is set to true.
    - Items
        - VendorItemIds - List of selectable products that can be given as freegoods.
            - VendorItemId – Product identifier.
            - MeasureUnit - The measure of unit of the product for freegoods: Example: UNIT, 6PACK, 12PACK
            - Price – Value of te product.
        - Quantity – Quantity of the product in the freegoods.
    - Partial – Flag that indicates if the freegood can be partial redeemed.
ScaledFreeGoods - Scaled
    - Ranges
        - Index - Index of the scaled free good to be applied as discount.
        - Items
            - VendorItemIds – List of products
                - VendorItemId – Product identifier.
                - MeasureUnit - The measure of unit of the product for freegoods: Example: UNIT, 6PACK, 12PACK
                - Price – Value of te product.
            - Quantity - Quantity of the product in the freegoods.
        - Fixed - Flag that indicates if the proportion will be applied. In case it’s false, the proportion should be greater than zero.
        - Proportion - Every X number (quantity) to acquire a discount. It doesn’t work if Fixed is set to true.
        - Partial - Flag that indicates if the freegood can be partial redeemed.
    - MultipleLineItemDiscount:
        - Type – Type of the discount to be applied. Example: PROMOTIONAL_PRICE, PERCENT_OFF
        - Items
            - VendorItemId – Product identifier.
            - Value – Price of the product in the discount.
            - MaxQuantity – Maximum quantity of products that will be given the discount.

It's important the deals to have a valid set of information in order to further service work properly.

Deals application

VendorItemId Deal

A VendorItemId deal is based on a list of products and the minimum quantity in the cart for these products. In order to apply the deal, the customer should add in the cart one or more products from the deal rule list, and satisfy the minimum quantity. Price Engine can also limit the quantity of products that are eligible to discount.

Example:

Buy at least 10 units of CORONA, and get 10% off in these products.

Limit quantity, Buy at least 10 units of CORONA, and get 10% off in 50 units of this product.

{
"deals": [
{
"vendorDealId": "01",
"promotionId": "P01",
"conditions": {
"paymentMethod": "CASH",
"lineItem": {
"vendorItemIds": [
"CORONA"
],
"minimumQuantity": 10
}
},
"output": {
"lineItemDiscount": {
"vendorItemIds": [
"CORONA"
],
"type": "%",
"value": 10.0,
"maxQuantity": 50
}
}
}
]
}


Scaled VendorItemId Deal

A VendorItemId deal is based on a list of products and the minimum quantity in the cart for these products. For this discount, there is a list of ranges that can increase the discount based on the quantity of the products in the cart.

Example:

Range 01: Buy 01 to 10 units of BRAHMA and get 10% off for these products.

Range 02: Buy 11 to 20 units of BRAHMA, and get 15% off for these products.

Range 03: Buy 21 to 50 units of BRAHMA, and get 20% off for these products.

{
"deals": [
{
"vendorDealId": "01",
"promotionId": "P01",
"conditions": {
"paymentMethod": "CREDIT",
"lineItem": {
"vendorItemIds": [
"BRAHMA"
],
"sharedMinimumQuantity": false,
"crossDiscount": false
}
},
"output": {
"lineItemScaledDiscount": {
"vendorItemIds": [
"BRAHMA"
],
"ranges": [
{
"type": "%",
"value": 10,
"from": 1,
"to": 10,
"fixed": true
},
{
"type": "%",
"value": 15,
"from": 11,
"to": 20,
"fixed": true
},
{
"type": "%",
"value": 20,
"fixed": true,
"from": 21,
"maxQuantity": 30
}
]
}
}
}
]
}

IMPORTANT: The last range is always considered as unlimited. To limit the max items to apply the deals, it is necessary to add the attribute deals[].output.lineItemScaledDiscount.ranges[last].maxQuantity.

Cross Discount

A VendorItemId deal is based on a list of products and the minimum quantity in the cart for these products. In order to apply the deal, the customer should add in the cart one or more products from the deal rule list, and satisfy the minimum quantity. It also could have a different list of products from the conditions, and the benefit list. Price Engine can also limit the quantity of products that is eligible to discount. In practical terms, the customer can buy a list of products and receive the discount for other ones.

Example:

Buy at least 10 units of CORONA, and get 10% off in the BRAHMA

Limit quantity, Buy at least 10 units of CORONA, and get 10% off in the BRAHMA limit by 50 units of this product.

{
"deals": [
{
"vendorDealId": "01",
"promotionId": "P01",
"conditions": {
"paymentMethod": "CASH",
"lineItem": {
"vendorItemIds": [
"CORONA"
],
"minimumQuantity": 10
}
},
"output": {
"lineItemDiscount": {
"vendorItemIds": [
"BRAHMA"
],
"type": "%",
"value": 10.0,
"maxQuantity": 50
}
}
}
]
}

Shared Minimum Quantity

(`True or false) It will define if the minimum quantity can be shared between the list of the VendorItemIds .

If the flag is true, the minimum quantity condition is satisfied, so the discount will be applied

Example:

If I buy 10 units of BRAHMA or 5 units of BRAHMA and 5 units of CORONA I get 10% discount on BRAHMA and CORONA

{
"deals": [
{
"vendorDealId": "01",
"promotionId": "P01",
"conditions": {
"paymentMethod": "CASH",
"lineItem": {
"vendorItemIds": [
"CORONA",
"BRAHMA"
],
"minimumQuantity": 10,
"sharedMinimumQuantity": true
}
},
"output": {
"lineItemDiscount": {
"vendorItemIds": [
"BRAHMA",
"CORONA"
],
"type": "%",
"value": 10.0
}
}
}
]
}

Deals Deletion

The deals deletion is a resource available in the deals relay, it is accessed in the same endpoint as the deals, passing the json informing which accounts and deals are being needed to have the deals deletion done.

Load Limits

Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Deals

[DELETE] /v2

yes

5K

Interest Management

Interest has been renamed to Charges, you can find the Charges documentation below.

Charge Management

Charge, in finance and economics, is payment from a borrower or deposit-taking financial institution to a lender or depositor of an amount above repayment of the principal sum (that is, the amount borrowed), at a particular rate.

General Summary

Pricing-engine charge concept was first introduced by Brazil “boleto” (bank slip) feature, as a manner to add a charge that it’s not related to deals, products, or taxes data. Because of that, actually Charge component is today more similar to Charges, as we can have fees added to the simulation not belonging to financing institutions.

Charge Placement

Load Limits

Regardless the BEES platform infrastructure robustness, it's necessary to limit the size of payload in 2MB per request, because of security and performance reasons (this limit is set by the application gateway). The number of entities could be greater if the payload is compressed. Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Charges

PUT /v2

yes

50K

Charge application

Charge application allows to add a additional value (amount or pencertage) in the order or in the line item. There will be specific examples next in this document.

Loan Deduction

Loan in credit granted to the customer to consume products. The customer pays back their loan by having a percentage of their discount not applied. In MX this loan deduction is called Fomento.

To set the Loan deduction the structure below should be sent in the payload:

{
"vendorAccountIds": [
"1234567",
"4567123",
"789785"
],
"charges": [
{
"vendorChargeId": "CHARGE-01",
"type": "LOAN_DEDUCTION",
"conditions": {
"paymentMethod": "CASH"
},
"output": {
"scope": "LINE_ITEM",
"applyTo": "DISCOUNT_AMOUNT",
"type": "AMOUNT",
"value": 3.45,
"vendorItemIds": [
"SKU001",
"SKU002"
]
}
}
]
}

NOTE: The Loan deduction will only be applied if there is a discount amount.

Overprice

When the order match a specific condition, the customer will pay an additional fee on per vendorItemId basis with the structure below be sent in the payload.

{
"vendorAccountIds": [
"1234567",
"4567123",
"789785"
],
"charges": [
{
"vendorChargeId": "CHARGE-01",
"type": "OVERPRICE",
"conditions": {
"paymentMethod": "CREDIT"
},
"output": {
"scope": "LINE_ITEM",
"applyTo": "BASE_PRICE",
"type": "AMOUNT",
"value": 3.45,
"vendorItemIds": [
"SKU001",
"SKU002"
]
}
}
]
}

When the order match a specific condition, the customer will pay an additional fee on alcoholic products with the structure below be sent in the payload.

{
"vendorAccountIds": [
"1234567",
"4567123",
"789785"
],
"charges": [
{
"vendorChargeId": "CHARGE-01",
"type": "OVERPRICE",
"conditions": {
"paymentMethod": "CREDIT",
"productAttributes": {
"isAlcoholic": false
}
},
"output": {
"scope": "LINE_ITEM",
"applyTo": "BASE_PRICE",
"type": "PERCENT",
"value": 1.25
}
}
]
}

PS: Charge payment method should be the same of the simulation.

Boleto

In Brazil the customer can pay through something called boleto (bank slip), which means they may have 1, 7, or 14 additional days to pay after their order gets

delivered. Associated with that extra time there is an charge percentage in the order total.

To set a Boleto the structure below should be sent in the payload:

{
"accounts": [
"1234567"
],
"charges": [
{
"vendorChargeId": "CHARGE-01",
"type": "PAYMENT_MEHTOD_FEE",
"conditions": {
"orderTotal": {
"maximumValue": 5000.45
},
"paymentMethod": "BANK_SLIP",
"paymentTerms": [1,2,3,4,5,6,7,8,9,10]
},
"output": {
"scope": "ORDER",
"applyTo": "TOTAL",
"type": "PERCENT",
"value": 123.45
}
}
]
}

The overprice can also be scaled:

{
"accounts": [
"1234567",
"4567123",
"789785"
],
"charges": [
{
"vendorChargeId": "CHARGE-01",
"type": "PAYMENT_METHOD_FEE",
"conditions": {
"dependsOnChargeIds": [
"ID01",
"ID02"
],
"orderTotal": {
"maximumValue": 5000.45
},
"paymentMethod": "BANK_SLIP",
"scaledFrom": "ORDER_TOTAL",
"paymentTerms": [1,2,3,4,5,6,7,8,9,10]
},
"output": {
"scope": "ORDER",
"applyTo": "TOTAL",
"type": "PERCENT",
"ranges": [
{
"index": 1,
"from": 200,
"value": 3.45
},
{
"index": 2,
"from": 400,
"value": 1.98
}
]
}
}
]
}

Delivery Date Fee

“Regular” delivery dates are dates in which the user can order freely.

“Non-Regular” delivery dates are dates in which the user must pay a fee unless they hit a unique delivery “ORDER minimum” value.

To set a Delivery Date Fee, the structure below should be sent in the payload:

{
"vendorChargeId": "CHARGE-01",
"type": "DELIVERY_DATE_FEE",
"conditions": {
"alternativeDeliveryDate": true,
"paymentMethod": "CREDIT", // (OPTIONAL) BANK_SLIP, CREDIT, CASH
"orderTotal": {
"maximumValue": 123.45
}
},
"output": {
"scope": "ORDEM",
"applyTo": "TOTAL",
"type": "AMOUNT",
"value": 123.45
}
}

Charge Deletion

The charge deletion is a resource available in the cart calculation relay, it is accessed in the same endpoint as the charge, passing the json informing which accounts and charges are being needed to have the charge deletion done.

For this exclusion the payload should be passing the following data by the example bellow:

Load Limits

Check the limit per request below:

Entity

Endpoint

Compressed

Limit of entities

Charges

DELETE /v2

yes

50K

F.A.Q.

In this section you can find the frequently asked questions for our team.

What is the difference between deals and promotions?

Promotions is what the user will see in the app/web, it is the visual information of the promotion. Deals is the data that the system uses to define the discount when calculating the cart. It is possible to create deals without promotions that the user will see only when he goes to the cart. Although it is not possible to create a promotion without a deal related.

The date of the promotion need to be the same date of the deal?

  • The date of the promotion is the date that the promotion we appears to the user in the app/web

  • The date of the deal is what the system checks to determine whether the deal is applied

What is the difference between Deals Delivery Date and Simulation Date?

These attributes are checked to determine whether the deals is applied.

  • When a deal have the simulation date, the moment that the cart is calculated need to be between this period.

  • When a deal have the delivery date defined, the delivery date of the order need to be between this period.

  • A deal can have either both or one of these attributes.

When is applied the attribute promotionalPrice?

This field is not mandatory, and it's an option if you have a promotional price (linked to the product/sku, not to the deal). Today this field is used by Mexico, and we check between this promotional price field vs the deal discount itself, applying the best value. One important detail is that this promotional price discount is not shown as a promotion in the catalog (promotions page)

Why the deal is not been applied, even that it's correctly created?

Check if the "minimumPrice" is equal to the "basePrice" in Prices structure. If so, the deal is not applied because no discount is allowed as the minimum price is the same as the base price.