Basket Validation

Basket validation ensures that certain conditions are met before performing an operation on a basket.

The following basket items are checked:

  • The user is eligible for the offers contained in the basket.

  • The offers in the basket are effective.

  • The price list entries that were used to create the basket are still effective.

Basket validation is enabled or disabled by passing the validatebasket query parameter. The default value is true. To turn off the basket validation, pass false as the value for the query parameter.

The basket operations that supports basket validation are shown here:

Basket OperationDescription
Add offer to a basketThe effectivity and eligibility of the bundle offer is checked. If the offer is eligible and effective, the add-to-basket will proceed.
Add new offer to an existing basketThe existing basket is validated. Only when the basket is valid, any add or update operations are allowed.
Update an existing basketThe existing basket is validated. Only when the basket is valid, any add or update operations are allowed.
Get basket detailsThe basket details are validated. Depending on the validation result, the response will be modified.
Delete offer from an existing basketThe delete operation is performed first, and the validation is preformed on the remaining offers in the basket.
Create cart using a basketThe basket is validated. Only if the validation is successful will cart creation be allowed.

The fields in the table below are checked when performing effectivity checking:

AttributesFields
For productsIsActive, IsOrderable, SellingStartDate, SellingEndDate, EndOfLifeDate
For promotionsIsActive, IsOrderable, EffectiveFrom, EffectiveUntil
For price list entriesIsActive, EffectiveFrom, EffectiveUntil, CalculatedEffectiveDate (based on applied TimePlan and TimePolicy)

Adding assets to the basket after the SellingEndDate is not supported due to implementation limitations.

Important

Example 1: Validation when adding a new offer to a basket 

When adding an offer (either a product or promotion) to the basket (either an empty basket or an existing valid basket), the eligibility and effectivity of the offer that is being added is checked. Only when the offer is eligible and effective will the basket be created. For invalid offers, depending on the reason, the different responses are shown below.

Example: An ineligible offer is added for anonymous users.

1Request URL
2/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket
3
4Request Body
5{"offer":"DTHOffer","basketAction":"AddWithNoConfig"}
6
7Condition
8The product, DTHOffer, has a rule applied. The rule is valid for Account SLA=Silver. The default value for rule dimension is Bronze.
9
10Response
11{"success":false,"result":{"BasketValidationResult":{"IneligibleOffers":["DTHOffer"]}},"errorCode":"422","error":"One or more offers are ineligible."}

Response:

validation1

Example: An ineligible offer is added for logged-in users.

1Request URL
2/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket?context={"accountId":"<<AccountId With SLA not as Silver>>"}&isloggedin=true
3
4Request Body
5{"offer":"DTHOffer","basketAction":"AddWithNoConfig"}
6
7Condition
8The product, DTHOffer, has a rule applied. The is valid for Account SLA = Silver. The default value for rule dimension is Bronze
9
10Response
11{"success":false,"result":{"BasketValidationResult":{"IneligibleOffers":{"DTHOffer":"The SLA of Account should be SILVER"}}},"errorCode":"422","error":"One or more offers are ineligible."}

Response:

Validation2

Example: The offer being added is not effective.

1Request URL
2/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket
3
4Request Body
5{"offer":"SportsPack","basketAction":"AddWithNoConfig"}
6
7Condition
8The SellingEndDate of the offer SportsPack has expired
9
10Response
11{"success":false,"result":{"BasketValidationResult":{"InvalidOffers":{"SportsPack":["SellingEndDate"]}}},"errorCode":"422","error":"The offer being added to the basket is ineffective"}

Response

Validation3

Example: The product being added to the basket does not have a valid price list entry.

1Request URL
2/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket
3
4Request Body
5{"offer":"EntertainmentPack","basketAction":"AddWithNoConfig"}
6
7Condition
8There are no valid PLEs on the offer EntertainmentPack 
9
10Response
11{"success":false,"errorCode":"INVOKE-500","error":"No valid price list entry found for product EntertainmentPack"}

Response:

Validation4

Example 2: Validation while running a basket operation on an invalid basket 

An existing basket might have one or more ineligible offers in it. This may be because the basket was created in an older version of the product (pre-Fall ‘20) or the basket was created with validatebasket query parameter set to false. For this example, assume that the basket was created with a bundle named DTHOffer, and DTHOffer is eligible only if the account SLA is Silver. Also, the default value of the SLA is Bronze. Below is the basket structure:

Example: Validation while performing basket operation on an invalid basket having ineligible offer(s)

1{
2  "totalSize": 1,
3  "records": [
4    {
5      "displaySequence": -1,
6      "Id": {
7        "value": "8026g000003qmNjAAI",
8        "previousValue": null,
9        "originalValue": null,
10        "messages": [],
11        "label": "Order Product ID",
12        "hidden": false,
13        "fieldName": "Id",
14        "editable": false,
15        "dataType": "ID",
16        "alternateValues": null,
17        "actions": {}
18      },
19      "Pricebook2Id": "01s6g000008qDnSAAU",
20      "Product2Id": "01t6g000003yHyWAAU",
21      "ProductCode": "DTHOffer",
22      "UnitPrice": {
23        "value": 0,
24        "previousValue": null,
25        "originalValue": null,
26        "messages": [],
27        "label": "Unit Price",
28        "hidden": true,
29        "fieldName": "UnitPrice",
30        "editable": false,
31        "dataType": "CURRENCY",
32        "alternateValues": null,
33        "actions": {}
34      },
35      "Name": "DTHOffer",
36      "IsActive": true,
37      "dc_108__RecurringPrice__c": 25,
38      "Product2": {
39        "attributes": {
40          "type": "Product2",
41          "url": "/services/data/v49.0/sobjects/Product2/01t6g000003yHyWAAU"
42        },
43        "Id": "01t6g000003yHyWAAU",
44        "Name": "DTHOffer",
45        "dc_108__IsConfigurable__c": false,
46        "dc_108__GlobalGroupKey__c": "eeed75c1-d269-c274-796d-0babcbf4d6fb",
47        "dc_108__Type__c": "None",
48        "dc_108__SubType__c": "None",
49        "RecordTypeId": "0126g000001MCLdAAO",
50        "dc_108__JSONAttribute__c": null
51      },
52      "CurrencyCode": "USD",
53      "productId": "01t6g000003yHyWAAU",
54      "defaultQuantity": 1,
55      "minQuantity": 0,
56      "maxQuantity": 99999,
57      "groupMinQuantity": 0,
58      "groupMaxQuantity": 99999,
59      "sequenceNumber": 1,
60      "productChildItemDefinition": {
61        "attributes": {
62          "type": "dc_108__ProductChildItem__c"
63        },
64*** and so on ***

For the above basket, a subsequent basket operation will return one of the following responses:

  • Anonymous user:

    1Operation
    2Add Promotion to existing Basket
    3
    4Condition
    5The basket was created by an anonymous user and the next basket operation is also being performed by an anonymous user.
    6
    7Request URL/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket/273ea5445b7b80ab40b566baab089e41
    8
    9Request Body
    10{"basketAction":"AddWithNoConfig","offer":"10%OffDTH"}
    11
    12Response
    13{
    14  "success": false,
    15  "cartContextKey": "273ea5445b7b80ab40b566baab089e41",
    16  "result": {
    17    "BasketValidationResult": {
    18      "isBasketValid": false,
    19      "basketValidationMessage": "One or more offers are ineligible.",
    20      "IneligibleOffers": [
    21        "DTHOffer"
    22      ]
    23    },
    24    "totals": {
    25      "EffectiveOneTimeTotal__c": 200,
    26      "EffectiveRecurringTotal__c": 25
    27    },
    28    "records": [
    29      {
    30        "actions": {
    31          "deleteFromBasketAction": {
    32            "rest": {
    33              "params": {
    34                "basketAction": "deleteFromBasket",
    35                "lineItemKey": "eb4ba8910c60a25ae4d4dda7a1b60c64",
    36                "bundleContextKey": "eb4ba8910c60a25ae4d4dda7a1b60c64"
    37              },
    38              "link": "/v3/catalogs/DTHCatalog/basket/273ea5445b7b80ab40b566baab089e41?contextKey=9d6af941cb9c06b0a31d0e6be2dddf17",
    39              "method": "deleteFromBasketAction"
    40            }
    41          },
    42          "updateBasketAction": {
    43            "rest": {
    44              "params": {
    45                "basketAction": "updateBasket",
    46                "lineItemKey": "eb4ba8910c60a25ae4d4dda7a1b60c64",
    47                "bundleContextKey": "eb4ba8910c60a25ae4d4dda7a1b60c64"
    48              },
    49              "link": "/v3/catalogs/DTHCatalog/basket/273ea5445b7b80ab40b566baab089e41?contextKey=9d6af941cb9c06b0a31d0e6be2dddf17",
    50              "method": "updateBasketAction"
    51            }
    52          }
    53        },
    54(truncated for brevity)

    Result:

    Validation5

  • Logged-in user, case 1:

    1Operation
    2Add Promotion to existing Basket
    3
    4Condition
    5The basket was created by a logged in user with account id <<AccountId1>> having SLA as Bronze and the next basket operation is also being performed by the same user without any change to the account shape.
    6
    7Request URL/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket/f4f58e16f583e8843ab5cc7c101b864e?context={"accountId":"AccountId1"}&isloggedin=true
    8
    9Request Body
    10{"basketAction":"AddWithNoConfig","offer":"10%OffDTH"}

    Result:

    Validation6

  • Logged-in user, case 2

    1Operation
    2Add Promotion to existing Basket
    3
    4Conditions - the response will be similar for both the cases mentioned below
    5
    6Condition 1 - The basket was created by logged in user with account id <<AccountId1>> having SLA as Bronze and the next basket operation is being performed by same user but the account SLA has changed to Silver
    7Condition 2 - The basket was created by logged in user with account id <<AccountId1>> having SLA as Bronze and the next basket operation is being performed by different user with account id <<AccountId2>> with account SLA Silver
    8
    9Request URL/services/apexrest/dc_108/v3/catalogs/DTHCatalog/basket/f4f58e16f583e8843ab5cc7c101b864e?context={"accountId":"AccountId2"}&isloggedin=true
    10
    11Request Parameter
    12{"basketAction":"AddWithNoConfig","offer":"10%OffDTH"}

    Result:

    Validation7

Validation while performing a basket operation on an invalid basket having eligible but ineffective offer(s) 

After some time interval, the offers in the basket are eligible but,For offer SportsPack,

  • The SellingEndDate and EndOfLifeDate are ineffective.

  • The Effective Until Date of the OT PLE,50$OTCharge, used, is now ineffective

Once the basket is ineffective, further basket operations (except getBasket) return a response similar to the response shown below.

Response

Understanding the response structure 

When an invalid basket is found during basket validation, the response will contain an extra node named BasketValidationResult. In the node, the details about why the basket is invalid are available. The InvalidOffers node contains:

  • InvalidPLEs - This node contains the details of all the ineffective price list entries for all of the invalid offers in the basket.

  • InvalidProducts - This node contains the details of the products that are invalid, with the name of the fields indicating which product is invalid.

  • InvalidPromotions - This node contains the details of the promotion(s) that are invalid, with the name of the fields indicating which the promotion is invalid.

If basket validation fails, the errorCode in the response will be 422 with an appropriate error message.

When a getBasket operation is performed, an extra nextAction node is available in the response. This node contains details about how to correct the basket. See the examples for more information.

Basket validation limitations 

  • For add-to-basket operations, validation is performed only when basketAction is set to AddWithNoConfig.

  • Price list entry validation is only for price list entries that were used to create the basket. If an offer has more than one price list entry but was not used, then the validation will not be performed for those price list entries.

  • Price list entry validation is performed only if the basket was created with active PricingInterface implementation as PricingPlanService.

  • Basket validation does not support the price list entry validation if the pricing is done using a custom implementation for PricingInterface; for example, if the prices were picked from a Matrix.

  • For price list entry validation, there must be an entry in the CachedAPIResponse__c SObject of Type=pleOfferMap and cacheKey=<<CartContextKey>> must be available. If the basket was created using a version earlier than Fall ‘20, the pleOfferMap will not be available for that basket; therefore the PLE validation for that basket will be skipped.

  • Basket validation does not apply to the effectivity of the CatalogProductRelationship.

  • When adding a new offer to either an empty or existing basket, validation is performed only for the root offer; that is, only for the offer passed in the post body of the API call. Validations are not done for child products or auto-add relationship products.

  • Effectivity checking for new offers is supported starting in Fall ‘20f. If offer details were generated in an earlier version, the effectivity check for the offer being added to the basket will not occur.

  • The eligibility check for the offers in the basket is done only for the offers present in the catalog passed in the input. If there are offers from different catalogs, they will not be checked for eligibility.