Callbacks offer a mechanism to incorporate custom logic into different components of CPQ, such as line items, cart pages, and catalog pages, during runtime. For instance, you can apply custom pricing or validation to line items within the cart using Pricing Callback Classes and Validation Callback Classes respectively. Implementing callbacks involves utilizing interfaces tailored to each specific callback. It's essential to implement these interfaces in C# and configure your custom logic within the corresponding class using the interface's methods. Subsequently, after implementing the interface, you need to register the C# class on the platform to enable invocation of the callback class during runtime.

To Setup Callback using Custom Code on Platform Extensibility

To create a new custom code on Conga Platform, you must complete the following:

  • Insert a new custom code.
  • Register a new callback class.

To insert a new custom code

  1. Launch the extensibility swagger page.
  2. Invoke "Insert a new custom code" API as mentioned below.

    APIPOST api/extensibility/v1/customcode
    ParameterNA
    Request Payload

    Sample Code

    // "Name": " PricingBasePriceCallback.cs",
    // "FilePath": "",
    // "SourceCode": " using System;
    
    using System.Linq;
    using Conga.Revenue.Common.Callback.Models;
    using Conga.Platform.Extensibility.CustomCode.Library;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Conga.Revenue.Common.Callback;
    using Conga.Revenue.Common.Callback.Entities;
    using Conga.Revenue.Common.Callback.Messages;
    
    namespace APTestan
    {
    	/// <summary>
    	/// Pricing Callback
    	/// </summary>
    	public class PricingBasePriceCallback : CodeExtensibility, IPricingBasePriceCallback
    	{
    		public async Task AfterPricingBatchAsync(IBatchPriceRequest batchPriceRequest)
    		{
    			await Task.CompletedTask;
    		}
    
    		public async Task BeforePricingBatchAsync(IBatchPriceRequest batchPriceRequest)
    		{
    			var batchLineItems = batchPriceRequest.GetLineItems().SelectMany(x => x.GetChargeLines()).ToList();
    
    			foreach (var item in batchLineItems)
    			{
    
    				IPriceListItemModel priceListItemModel = item.GetPriceListItem();
    				IPriceListItem priceListItemEntity = priceListItemModel.GetEntity();
    				var entity = item.GetEntity();
    
    				if (priceListItemEntity.PriceType == "One Time")
    				{
    					entity.Quantity = 15;
    					entity.SetValue("CustomFieldTest_c", 50);
    				}
    				else
    				{
    					entity.Quantity = 10;
    					entity.SetValue("CustomFieldTest_c", 25);
    				}
    			}
    
    			await Task.CompletedTask;
    		}
    
    		public async Task OnPricingBatchAsync(IBatchPriceRequest batchPriceRequest)
    		{
    
    			var batchLineItems = batchPriceRequest.GetLineItems().SelectMany(x => x.GetChargeLines()).ToList();
    
    
    			await Task.CompletedTask;
    		}
    
    		public async Task OnProductOptionPriceAsync(IBatchPriceRequest batchPriceRequest, IDictionary<string, IProductOptionPrice> productOptionPrice)
    		{
    			var batchLineItems = batchPriceRequest.GetLineItems().SelectMany(x => x.GetChargeLines()).ToList();
    
    
    
    			await Task.CompletedTask;
    		}
    
    		public async Task OnPriceMatrixAsync(IBatchPriceRequest batchPriceRequest, IDictionary<string, IEnumerable<IPriceMatrixEntry>> priceMatrixEntries)
    		{
    			await Task.CompletedTask;
    		}
    
    		public async Task OnPriceRuleAsync(IBatchPriceRequest batchPriceRequest, IDictionary<string, IEnumerable<IPriceRuleEntry>> priceRuleEntries)
    		{
    			await Task.CompletedTask;
    		}
    
    		public async Task OnPipelinePriceRuleAsync(IBatchPriceRequest batchPriceRequest, IDictionary<string, IEnumerable<IPriceRuleEntry>> pipelinePriceRuleEntries)
    		{
    			await Task.CompletedTask;
    		}
    
    		public async Task OnPriceEscalatorAsync(IBatchPriceRequest batchPriceRequest, List<IPriceEscalator> priceEscalators)
    		{
    			await Task.CompletedTask;
    		}
    	}
    }
    
    
    CODE
    ExecuteClick Execute to execute the code.
    Response

    Success

To register a new callback

  • Invoke "Update callback contract mapping" API as mentioned below.

    APIPUT /api/extensibility/v1/callbacks
    ParameterNA
    Request Payload

    Sample Code

    [
    	{
    		"ModuleName": "Revenue",
    		"ContractName": "Conga.Revenue.Common.Callback.IPricingBasePriceCallback",
    		"ProjectName": "PricingBasePriceCallbackProject",
    		"ClassName": "APTestan.PricingBasePriceCallback"
    	}
    ]
    C#
    • ProjectName should be same as namespace within the custom code and name of the custom code.
    • ClassName is fully qualified name of the class from custom code.
    • When you pass empty values for ProjectName & ClassName fields, the system removes the specific callback.
    ExecuteClick Execute to execute the code.
    ResponseSuccess

Once the new callback is registered, it will be available in Conga Platform Administration > Custom Code.

In this section, the following Callbacks are described: