Override POS request handler
This article explains how to override POS request handler. We've introduced an extension pattern for overriding the POS business logic. If you have a scenario where you want to modify/add some business logic to the core POS business flow, then you can follow this pattern.
For example, when you sell a serial item, POS will display a dialog box where you can enter the serial number for that item after the scan. If you want to automate the serial number process by entering the serial number through code, then you can override this serial number request handler and use custom business logic. Most of the business logic in POS is implemented in request handler, however, you can override the relevant request handler and return the response according to your business flow.
Note
Not all request handler logic is exposed for customization. If you want to customize any business logic and if that request handler is not overridable, then create a support ticket or log a request in the LCS extensibility tool.
POS request handler logic exposed for overriding
This list is based on Microsoft Dynamics 365 Finance - Version 7.3.5.
In each monthly update we will be adding additional extension points, so check the Pos.api.d.ts file in the Retail SDK for the full list.
Cart extension handlers
Request name | Description |
---|---|
AddTenderLineToCartClientRequestHandler | This handler is executed when you add tender (payment) line to cart. |
GetKeyedInPriceClientRequestHandler | This handler is executed when you add an item that has a configuration key in price during sale. |
GetPickupDateClientRequestHandler | Executed when you select a pickup date during a customer order. |
GetShippingDateClientRequestHandler | Executed when you select a shipping date during a customer order. |
ShowChangeDueClientRequestHandler | Executed when the change due dialog box is shown at the end of transaction. |
GetReceiptEmailAddressClientRequestHandler | Executed when you get a receipt email address. |
DepositOverrideOperationRequestHandler | Executed when you override a deposit. |
GetShippingChargeClientRequestHandler | Executed when get shipping charge workflow initiated during customer order flow. |
GetKeyedInPriceClientRequestHandler | Executed when the key in product price dialog box is shown. |
Payment extension handler
Request name | Description |
---|---|
GetGiftCardByIdServiceRequestHandler | This handler is executed when you receive the gift card ID. |
GetPaymentCardTypeByBinRangeClientRequestHandler | This handler is executed when POS gets the card type, such as Visa or Master Card. This is based on the HQ configuration during the card tender line processing. |
Peripherals request handler
Request name | Description |
---|---|
CardPaymentAuthorizePaymentRequestHandler | Executed when a card payment is authorized. |
CardPaymentCapturePaymentRequestHandler | Executed when a card payment is captured. |
CardPaymentExecuteTaskRequestHandler | Used to execute any custom task. This handler is mainly for extensions for custom functionality with payment connector, which is not supported. |
CardPaymentRefundPaymentRequestHandler | Executed when a card payment is refunded. |
CardPaymentVoidPaymentRequestHandler | Executed when a card payment is voided. |
CardPaymentBeginTransactionRequestHandler | Executed when a card payment is initiated. |
CardPaymentEndTransactionRequestHandler | Executed when a card payment is ended. |
CardPaymentEnquireGiftCardBalancePeripheralRequestHandler | Executed when a gift card balance inquiry is made. |
PaymentTerminalAuthorizePaymentActivityRequestHandler | Executed when a card payment is authorized using a payment. terminal/device. |
PaymentTerminalAuthorizePaymentRequestHandler | Executed when a card payment is authorized using a payment. terminal/device. |
PaymentTerminalEnquireGiftCardBalancePeripheralRequestHandler | Executed when a gift card balance inquiry is made using a payment. terminal/device. |
PaymentTerminalExecuteTaskRequestHandler | Used to execute any custom task. This handler is mainly for extensions for custom functionality with payment terminal/device, which is not supported. |
PaymentTerminalRefundPaymentRequestHandler | Executed when a card payment is refunded using a payment terminal/device. |
PaymentTerminalUpdateLinesRequestHandler | Executed when POS sends line item details to a payment device for display purposes. |
PaymentTerminalVoidPaymentRequestHandler | Executed when a card payment is voided using a payment terminal/device. |
PaymentTerminalBeginTransactionRequestHandler | Executed when a card payment is initiated using a payment terminal/device. |
PaymentTerminalCancelOperationRequestHandler | Executed when a card payment is canceled using a payment terminal/device. |
PaymentTerminalEndTransactionRequestHandler | Executed when a card payment is ended using a payment terminal/device. |
CashDrawerOpenRequestHandler | Executed when a cash drawer open request is initiated by POS. |
PaymentTerminalActivateGiftCardPeripheralRequestHandler | Executed when activate gift card request is initiated by POS. |
PaymentTerminalAddBalanceToGiftCardPeripheralRequestHandler | Executed when add balance to gift card request is initiated by POS. |
Scan request handler
Request name | Description |
---|---|
GetScanResultClientRequestHandler | Executed when you scan or key in a POS transaction screen Numpad. |
Store fulfillment request handler
Request name | Description |
---|---|
PrintPackingSlipClientRequestHandler | Executed when you print a packing slip from the store fulfillment view. |
MarkAsPickedServiceRequestHandler | Executed when you mark a sales line as picked from the store fulfillment view. |
Store operations request handler
Request name | Description |
---|---|
CreateTenderRemovalTransactionClientRequestHandler | Executed when you do a tender removal operation in POS. |
CreateFloatEntryTransactionClientRequestHandler | Executed when you do a float entry operation in POS. |
SelectZipCodeInfoClientRequestHandler | Executed when you key in zip code in address add/edit view in POS. |
CreateStartingAmountTransactionClientRequestHandler | Executed when you do a start amount declaration in POS. |
LoyaltyCardPointsBalanceOperationRequestHandler | Executed when you do a loyalty card balance operation in POS. |
GetReportParametersClientRequestHandler | Executed when you use a report parameter. If your POS report needs an input parameter this dialog will be executed to capture the parameters. |
GetPickingAndReceivingOrdersClientRequestHandler | Executed when orders fetched for picking and receiving processing. |
GetStartingAmountClientRequestHandler | Executed when you do a start amount declaration in POS (before navigating to the view). |
Tender counting request handler
Request name | Description |
---|---|
CreateSafeDropTransactionClientRequestHandler | Executed when you do a safe drop operation in POS. |
GetTenderDetailsClientRequestHandler | Executed when you get tender declaration details in POS. |
CreateBankDropTransactionClientRequestHandler | Executed when you do a bank drop operation in POS. |
CreateTenderDeclarationTransactionClientRequestHandler | Executed when you do a tender declaration operation in POS. |
GetCountedTenderDetailAmountClientRequestHandler | Executed when you do a tendercount detail in POS. |
CreateBankDropTransactionClientRequestHandler | Executed when you do a bank drop operation in POS. |
Sales orders request handlers
Request name | Description |
---|---|
GetGiftReceiptsClientRequestHandler | Executed when you print a gift receipt in POS. |
SelectCustomerOrderTypeClientRequestHandler | Executed when you get a dialog box with options to choose between customer order or quote. |
GetCancellationChargeClientRequestHandler | Executed when you get a dialog box to enter the cancellation shipping charge during the customer order workflow. |
How to override a handler in POS
If you want to override any of the above POS request handler logic, you to need to use the following steps:
Create a new class and extend it from the corresponding handler class. For example, if you are overriding GetSerialNumberClientRequestHandler, then extend your class from GetSerialNumberClientRequestHandler.
Implement the executeAsync method.
Either call the default handler or do your custom logic inside the executeAsync method and return the response.
Step by step instructions
The following example shows how to override the GetSerialNumberClientRequestHandler to automate the serial number entry in POS. By default, POS will display a dialog box to enter the serial number if the item is configured to ask for serial number. We want to avoid showing this dialog box and enter serial number through code.
Open Visual Studio 2015 in administrator mode.
Open ModernPOS solution from …\RetailSDK\POS.
Under the POS.Extensions project, create a new folder called POSRequestHandlerExtension.
Under the POSRequestHandlerExtension folder, create new folder called Handlers.
In the Handlers folder, add a new .ts (typescript) file and name it GetSerialNumberClientRequestHandlerExt.ts.
Add the following import statement to import the relevant entities and context in the GetSerialNumberClientRequestHandlerExt.ts file.
import { GetSerialNumberClientRequestHandler } from "PosApi/Extend/RequestHandlers/ProductsRequestHandlers"; import { GetSerialNumberClientRequest, GetSerialNumberClientResponse } from "PosApi/Consume/Products"; import { ClientEntities } from "PosApi/Entities";
In the GetSerialNumberClientRequestHandlerExt.ts file, create a new class called GetSerialNumberClientRequestHandlerExtend and extend it from GetSerialNumberClientRequestHandler.
export default class GetSerialNumberClientRequestHandlerExt extends GetSerialNumberClientRequestHandler { }
Implement the executeAsync method inside the GetSerialNumberClientRequestHandlerExt class. In the executeAsync method, you can write your custom logic and return the response or call the default handler. When POS sells the serial item, it will look for executeAsync to execute the logic for the serial number, however because we are overriding it, POS will now execute this overridden executeAsync method instead of the standard method.
Sample implementation of how to override the executeAsync method
public executeAsync(request: GetSerialNumberClientRequest<GetSerialNumberClientResponse>): Promise<ClientEntities.ICancelableDataResult<GetSerialNumberClientResponse>> { // User could implement new business logic here to process the serial number. // The following example sets serial number "112233" for product 82001. if (request.product.ItemId === "82001") { let response: GetSerialNumberClientResponse = new GetSerialNumberClientResponse("112233"); return Promise.resolve(<ClientEntities.ICancelableDataResult<GetSerialNumberClientResponse>>{ canceled: false, data: response }); } // If you don’t want to execute custom logic on some conditions, and you just want to call the standard logic, you can call the default request, as shown below. return this.defaultExecuteAsync(request); }
Full sample code:
import { GetSerialNumberClientRequestHandler } from "PosApi/Extend/RequestHandlers/ProductsRequestHandlers"; import { GetSerialNumberClientRequest, GetSerialNumberClientResponse } from "PosApi/Consume/Products"; import { ClientEntities } from "PosApi/Entities"; /** * Override request handler class for getting serial number request. */ export default class GetSerialNumberClientRequestHandlerExt extends GetSerialNumberClientRequestHandler { /** * Executes the request handler asynchronously. * @param {GetSerialNumberClientRequest<GetSerialNumberClientResponse>} request The request containing the response. * @return {Promise<ICancelableDataResult<GetSerialNumberClientResponse>>} The cancelable promise containing the response. */ public executeAsync(request: GetSerialNumberClientRequest<GetSerialNumberClientResponse>): Promise<ClientEntities.ICancelableDataResult<GetSerialNumberClientResponse>> { // User could implement new business logic here to process the serial number. // The following example sets serial number "112233" for product 82001. if (request.product.ItemId === "82001") { let response: GetSerialNumberClientResponse = new GetSerialNumberClientResponse("112233"); return Promise.resolve(<ClientEntities.ICancelableDataResult<GetSerialNumberClientResponse>>{ canceled: false, data: response }); } return this.defaultExecuteAsync(request); } }
Create a new json file under the POSRequestHandlerExtension folder. Name it manifest.json.
In the manifest.json file, copy and paste the following code. Be sure to delete the default generated code before copying this code.
{ "$schema": "../manifestSchema.json", "name": "Pos_Extensibility_Samples", "publisher": "Microsoft", "version": "7.3.5.0", "minimumPosVersion": "7.3.5.0", "components": { "extend": { "requestHandlers": [ { "modulePath": "Handlers/GetSerialNumberClientRequestHandlerExt" } ] } } }
Open the extensions.json file under the POS.Extensions project. Update it with POSRequestHandlerExtension samples, so that POS during runtime will include this extension.
{ "extensionPackages": [ { "baseUrl": "SampleExtensions2" }, { "baseUrl": " SampleExtensions" }, { "baseUrl": "POSRequestHandlerExtension" } ] }
Note
The extension.json file should always contain two extensions folder names, so be sure to keep the SampleExtensions folder name or your custom extension folder name. For production, don’t use the sample extensions. You should add your own extension folders and remove all the samples.
Open the tsconfig.json file to comment out the extension package folders from the exclude list. POS will use this file to include or exclude the extension for compilation. By default, the list contains all the excluded extensions list. If you want to compile any extension part of the POS, then you need to add the extension folder name and comment the extension from the extension list, as shown below.
"exclude": [ // "SampleExtensions", //"SampleExtensions2", //"POSRequestHandlerExtension" ],
Compile and rebuild the project.
How to test your extension
Press F5 and deploy the POS to test your customization.
After POS launches, sign in to POS and add a serial item to a transaction.
Place a break point in the extension code. When you add the serial item you should be able to debug the extension code.