Introduction
Recently I worked on something very interesting related to a integration between MS Dynamics Nav and an external payment service provider. I had to use custom Cross Session Events to solve a problem which I think it’s worth sharing. So this why this post.
Basically, it is about doing some action in a NAV Session based on something else that happened on a different session that runs on a different server instance. We do this by implementing a custom Publisher and Listener (subscriber) pattern to bind the two sessions.
Process
First let me present the process of the integration.
We use LS Retail POS Solution for Microsoft Dynamics NAV and we develop a new payment method using a mobile app of a payment solution provider.
– Customer creates account to use this mobile app and they will have a User ID. (they also link a bank account to it).
– Customer arrives to the store at POS and requests to pay using this app.
– Employee of store scans the User Id (shown on the mobile app of customer), enters the payment amount and sends a payment request.
– Customer receives payment request on their phone and can Approve or Deny the transaction. (the payment provider checks also if bank account has sufficient funds and if not, it denies payment).
– Initial status of the payment request is ‘Pending’.
– After customer makes an action on the phone, the integration sends the new status to Dynamics Nav database via a web service that we exposed and registered(webhook). This calls a Codeunit which updates the Status from ‘Pending’ to ‘Accepted’ / ‘Denied’ / ‘Canceled’ based on customer action.
Here we have our problem: we need to show to the POS session that initiated the payment request a notification: Customer Approved or Denied and denied reason code etc. This way, employee knows that he can proceed with the processing of payment. Or even automatically create and complete the payment line at POS.
The problem is that the session used by the web service when we change the status knows nothing about the session that initially sent the payment request to the customer (at the POS).. They are 2 completely different sessions, running on 2 different service instances and we cannot send message from the “webservice session” to the “Pos session”..
Solution
Solution is to implement cross session events pattern.
1) At POS, employee asks customer for UserId barcode to scan it:
2) Employee enters payment amount:
3) Payment request is sent to customer. He receives notification on the phone:
– We now also start Listening to notifications received from other Sessions(record in table “Change Observer” is created).
4) At the POS, we create a loop for ‘x’ seconds (based on a setup) and show remaining seconds in a ScreenDisplay. Basically we wait for an action to happen on the mobile app and our session is now ‘bound’ to the mobile app session.
– If customer does not make an action until time expires, we automatically Cancel the payment request.
– If customer makes an action, the code that changes status of payment request is triggered via web services. Also, a record is created in table “Change Notification” with the message to be displayed at POS, the Status of Transaction, the Listener Session Id and Service Instance, Transaction Id etc.
In the loop at POS, we check every second for notifications in this table (for our Session Id and Service Instance) and when we find the one created via web service, we Show the message or process the payment at POS (based on setup) and break the loop. We now also, Stop Listening for notifications.
Code that waits a defined number of seconds and based on Customer action does something:
However, as you will see below, we still have another issue.
Another Problem
– We now have another problem: the notification is created in table “Change Notification”, but when we look for it from the POS Session, we find it only after 20-30 seconds after it was created.. Why is that?
– My assumption was that the FINDSET function looked for the record using the Cache: “In Microsoft Dynamics NAV, the data cache is shared by all users who are connected to the same Microsoft Dynamics NAV Server instance“.
– Because we inserted the record from another Server Instance (used by the Web service), it is not found in this Cache and notification was not displayed at the POS / payment was not automatically processed.
Solution
My solution was to use function SELECTLATESTVERSION to clear the cache and look for the most recent version of records in the database:
Hope you liked this post about Cross Session Events. Using custom publishers and listeners to bind different sessions in Microsoft Dynamics Nav / D365 Business Central can be useful.