Revalidation Callback provides you a mechanism to implement custom revalidations for products based on custom criteria. You can define custom criteria based on which the products are identified by CPQ for revalidation. The callback allows you to define a custom logic to be applied on the line item along with revalidation. You can also define a custom product version when the line item is created.

To use the Revalidation Callback you must create a custom Apex class that implements the Apttus_Config2.CustomClass.IRevalidationCallback interface and register the custom apex class with Revalidation Callback Class. You must write your custom logic in the custom apex class.

The following methods are available in the Apttus_Config2.CustomClass.IRevalidationCallback interface:

getRevalidations()Apttus_Config2.CustomClass.RevalidationResponse getRevalidations(Apttus_Config2.CustomClass.RevalidationRequest)

You can use this method to determine whether the line item requires revalidation based on a custom logic that you can define. This method is invoked when you reconfigure a save or finalized cart.

setRevalidations()void setRevalidations(Apttus_Config2.CustomClass.RevalidationRequest)

You can use this method write custom logic to apply on line items. This method is invoked when you click Apply Revalidation on the Revalidation pop-up.

setVersionNumber()void setVersionNumber(Id, List)You can use this method to set the version number field  of the line item with custom value based on custom logic you define. This method is invoked when you add line items to the cart.


You can use this callback to a scenario like:

  • You can have multiple versions for a single product record. This enables you to revalidate a specific version of the product as necessary.
    For example, for product record, you can set the version as X, Y, and any such value for the newly created line item of that product. You can determine which line item qualifies for revalidation and apply custom logic on the line items accordingly.
  • You can apply validation based custom fields other than the Product Version.
  • You can validate changes in pricing fields like List price of a given price list item.

The below-given code example checks if the quantity of line items is greater then 10 then triggers the revalidation on the cart, revalidates the line item and resets the quantity of the line items.

 *  Apttus Config & Pricing
 *  SampleRevalidationCallback
 *  @2019-2020 Apttus Inc. All rights reserved.
global with sharing class SampleRevalidationCallback implements Apttus_Config2.CustomClass.IRevalidationCallback {   
    private static String QUANTITY_TOO_HIGH = 'Quantity Too High';
     * Callback at the beginning of revalidation check.
     * use this method to get custom revalidations
     * @param request contains lineItemSO and validation info
     * @return map of revalidation category against list of line numbers
    global Apttus_Config2.CustomClass.RevalidationResponse getRevalidations(Apttus_Config2.CustomClass.RevalidationRequest request){
        Apttus_Config2.CustomClass.RevalidationResponse response = new Apttus_Config2.CustomClass.RevalidationResponse();
        Map<String, List<Apttus_Config2__LineItem__c>> lineItemSOsByRevalCategory = new Map<String, List<Apttus_Config2__LineItem__c>>();

        for (String revalCat : request.lineItemSOsByRevalCategory.keySet()) {
            lineItemSOsByRevalCategory.put(revalCat, request.lineItemSOsByRevalCategory.get(revalCat));
            for (Apttus_Config2__LineItem__c lineItemSO : request.lineItemSOsByRevalCategory.get(revalCat)) {
                response.isRevalidationNeeded = true;                

        response.lineItemSOsByRevalCategory = lineItemSOsByRevalCategory;
        response.isHardRevalidationNeeded = false;
        List<Apttus_Config2__LineItem__c> customQuantityLines = new List<Apttus_Config2__LineItem__c>();                          

        // Implementing list price change use case
        for (Apttus_Config2__LineItem__c lineItemSO : [select Id, Apttus_Config2__Quantity__c, Apttus_Config2__PriceListItemId__r.Apttus_Config2__ListPrice__c, Apttus_Config2__PrimaryLineNumber__c from Apttus_Config2__LineItem__c where Apttus_Config2__ConfigurationId__c = :request.cartId]) {
            if(lineItemSO.Apttus_Config2__Quantity__c > 10) {
        if (customQuantityLines.size() > 0) {
            response.lineItemSOsByRevalCategory.put(QUANTITY_TOO_HIGH, customQuantityLines);
            response.isRevalidationNeeded = true;
        return response;
     * Callback for applying revalidation         
     * @param  cartId Id of the cart to revalidate
     * @param  lineNumbers the list of line numbers to be validated
    global void setRevalidations(Apttus_Config2.CustomClass.RevalidationRequest request) {
        List<Apttus_Config2__LineItem__c> lineItemsSOsToUpdate = new List<Apttus_Config2__LineItem__c>();
        for (String revalCategory : request.lineItemSOsByRevalCategory.keySet()) {
            for (Apttus_Config2__LineItem__c lineItemSO : request.lineItemSOsByRevalCategory.get(revalCategory)) {               
                if (revalCategory == QUANTITY_TOO_HIGH) {
                    lineItemSO.Apttus_Config2__Quantity__c = 1.0;
                    lineItemSO.Apttus_Config2__PricingStatus__c = 'Pending';
        if (lineItemsSOsToUpdate.size() > 0) {
            update lineItemsSOsToUpdate;
     * Callback to set custom version number         
     * @param  cartId Id of the cart
     * @param  lineIntemSOs the list of line Item sobjects to set custom version
    global void setVersionNumber(ID cartId, List<Apttus_Config2__LineItem__c> lineItemSOs){
        /*for (Apttus_Config2__LineItem__c lineItemSO : lineItemSOs) {            
            lineItemSO.Apttus_Config2__ProductVersion__c = 33.0;