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.
  2. Invoke "Insert a new custom code" API as mentioned below.

    APIPOST api/extensibility/v1/customcode
    ParameterNA
    Request Payload


    // "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


    [
    	{
    		"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.

To Setup Callback using Custom Code on Platform UI

Authoring and registering callbacks is now supported through the Platform admin interface. You can access and manage custom code through the Platform UI. For step-by-step instructions on creating and using custom code and callbacks, see Managing Custom Code.


In this section, the following Callbacks are described: