Every time the in-app cart is modified (e.g., by adding or removing a product), the backend calculates the price of the shopping basket and returns it to the client app.
The following data flow shows where the pricing process takes place in the customer journey:
As a further step, the Pricing section can be represented as follows:
If you need to configure an external pricing system to return the correct pricing, the “Basket evaluation” option should be activated in the DataHub settings. This way, a request will sent to the external system every time a shopping basket price is calculated.
If a shopping journey includes redeemable items such as coupons, deposit slips, or vouchers, these are locked with the purchaseEvaluation flag in the /evaluate call. If the user cancels the checkout (due to a session timeout, or a user action), a call to /cancelPurchase unlocks those items.
Evaluates the gross prices (before any promotions are applied) for a shopping basket by communicating with an external pricing system. The request includes scanned product data and loyalty information. The response returns calculated prices for each item and aggregated totals per tax rate.
For price reductions, we recommend using the positions.promotions field so that the promotion.title is displayed in the cart, and informs the shopper about it. However, it is also possible to simply send the updated prices along with the positions.singleStrikePrice per position.
When purchaseEvaluation is set to true, the result is considered final and used for the actual transaction (payment).
Validation rules that apply during evaluation:
The order and number of basket positions in the response must exactly match those in the request.
The sum of all individual item totals must equal the overall basket total if the receipt generation is handled by shopreme (See info note below).
The pricing system must not alter the quantity of each position.
Response error codes: Please communicate what error codes the price engine can return and what they mean, so that the shopreme backend can send the correct translated error messages to the client apps.
Receipt generation: If shopreme needs to generate receipts, the checkbox for “Receipt” should be disabled in the “Fiscalization & receipting” section, in the API connector settings.
Evaluation examples
Below are examples of the client request, the server response, and what the customer would see in the Scan & Go app. This can help you visualize what value in the response corresponds to what piece of the UI in the client app.
Basic evaluation example
A basic example of a valid request for one regular product, without discounts or any special requirements.
Basic evaluation example (including unit handling)
Unit handling is very similar to the basic case above. The shopreme system sends a salesUnitPerPiece field in the request, indicating the packaging size regardless of the actual quantity bought. For example, a six-pack of a drink will have a salesUnitPerPiece of 6. The system to calculate the price is supposed to either look up a special price for a six-pack or multiply the quantity with the salesUnitPerPiece, in case a single bottle has the same price regardless of the packaging.
Example of a promotion that reduces the price of one product position. The external pricing system adds the promotion without any coupon or voucher. This usually reflects general price reductions for all customers without any activation process.
Example of a promotion that reduces the price for all positions in the shopping basket. A promotion can affect several or all product positions. This is usually for promotions that target the entire purchase or a product range.
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":720}],"totalPrice":720,"error":null,"purchaseEvaluationReferences":null}
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":720}],"totalPrice":720,"error":null,"purchaseEvaluationReferences":null}
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":720}],"totalPrice":720,"error":null,"purchaseEvaluationReferences":null}
Result in the customer app
Promotion (Mixed: position and basket level)
In this case, the cart contains a promotion on a basket level (general for all products added to the shopping cart) and on position level (specific for one product).
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"4324321321","title":"Test Promotion 0.5€ on every drink","basketLevelDiscount":false,"grossReductionValue":100,"externalPromotionInformation":null},{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":620}],"totalPrice":620,"error":null,"purchaseEvaluationReferences":null}
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"4324321321","title":"Test Promotion 0.5€ on every drink","basketLevelDiscount":false,"grossReductionValue":100,"externalPromotionInformation":null},{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":620}],"totalPrice":620,"error":null,"purchaseEvaluationReferences":null}
{"positions":[{"productNumber":"1234","error":null,"quantity":2,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":400,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"4324321321","title":"Test Promotion 0.5€ on every drink","basketLevelDiscount":false,"grossReductionValue":100,"externalPromotionInformation":null},{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":40,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-000001","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]},{"productNumber":"00-34567","error":null,"quantity":1,"singleStrikePrice":null,"totalStrikePrice":null,"singlePrice":200,"totalPrice":200,"totalTax":null,"taxRate":1900,"promotions":[{"promotionId":"12341234","title":"10 % on everything","basketLevelDiscount":true,"grossReductionValue":20,"externalPromotionInformation":null}],"supplementalCosts":[]}],"totals":[{"taxRate":1900,"value":620}],"totalPrice":620,"error":null,"purchaseEvaluationReferences":null}
Result in the customer app
Coupon/voucher example
A coupon or voucher can be added to the shopping basket, either manually (users scan it) or automatically, through a condition configured in the shopreme middleware.
In both cases, a unique ID (either gathered from the barcode or the configuration in the middleware) is added to the voucher array.
If this coupon or voucher is valid, the external pricing system may add a promotion to the response in the promotion field.
For shopreme, there is no direct connection between coupons in the request and promotions in the response; therefore, shopreme (and the customer) cannot show a direct link between those two entities.
An invalid coupon will only return no promotion by the external pricing service.
This example shows how the external pricing system can add deposit information to a specific product. This is necessary if shopreme did not receive information about the deposit during the product import. Please note that, at this point, shopreme will not give information about the deposit product on the corresponding request.
Example of a product that contains semantic information in the barcode (in this case, weight information). The originally-scanned barcode is sent in the request. There is no manipulation of the barcode, such as splitting its content into weight, price, or PLU fields.
The external pricing system may use this barcode information to calculate the price for this position.
Barcodes with such encoded semantic information need to be configured in the shopreme Middleware (for instance, by using a unique prefix). If you need to use such barcode types, please don’t hesitate to contact your shopreme integration consultant.
Example of a final evaluation before the payment is processed. The external pricing system can lock coupons/vouchers from the request, so they cannot be used a second time. The vouchers or coupons should be redeemed when the external system receives the /liveClearing request or unlocked when a /cancelPurchase request is received.
In this example, the external system returns a new transactionId that will overwrite the original transactionId (which was generated by shopreme) from the request. In all further requests, the new transactionId will be used.
Additionally, the external pricing system returns a pspTransactionId. This ID will be used by shopreme to set the unique ID of the transaction for the payment service provider. If the external system does not provide it, the transactionId will be used.
If a shopper cancels the payment transaction, this call notifies the external pricing system that a transaction was canceled. This call includes the transactionId and is mainly used to unlock redeemables (e.g., coupons, vouchers, deposit slips) that were previously locked with the final evaluation call.
This request is only sent if an /evaluate request with the field "purchaseEvaluation" = true was previously sent. (The purchaseEvaluation flag indicates that this was the final evaluation before payment).
The external pricing system identifies the /evaluate request by matching the corresponding transactionId.
This request is sent in the following cases:
The customer manually canceled the payment
The payment failed
After a configured timeout period.
ℹ️ Note: This endpoint is only applicable for online payment. For “Pay-at-Cash-Register” transactions, the client app cannot cancel the purchase anymore once the transaction has been handed over to the POS (cash register). Cancellations at the physical cash register are not reported via this endpoint.
If the response code is not successful (200), the clearing request is repeatedly resent after a configurable time interval.