Tracking down Retail Transaction Service errors can be a bit of a challenge. In Support, for instance, we see the following message relatively often: “Cannot make a payment for this sales order, since the fulfillment warehouse is not specified.”
The “fulfillment warehouse” part of this message is usually a red herring. There are a couple of places you would usually look for more details: the POS logging (POSISLOG table in the POS database) and the logging of the Retail Transaction Service itself (configured in the “RetailTransactionService.exe.config” file). A third option is sometimes overlooked and can provide additional details.
[Note: see this article for information about logging all components of AX for Retail]
As a refresher, see this post for some technical information about how Retail Transaction Service fits into the AX for Retail architecture. The main takeaway is that the Transaction Service is really just a “middle man” that uses the AX .Net Business Connector to call business logic in AX.
The particular error shown above occurs when you make a payment on a sales order in the POS. This is done by calling the PaySalesOrder() method in the Retail Transaction Service which in turns calls the PosIsTransactionService::postOrderPayment() method in AX. If you were to look at this method in the AOT, there is quite a bit of logic involved, much of if native (non-Retail) code. Because of this, there are plenty of possible business errors that can occur.
Unfortunately, specific errors in X++ code are not sent back through Transaction Service to the POS. This is because calls to the Retail Transaction Service are usually handled as “all or nothing.” If the call succeeds, there is no error message. If it fails, an error message is shown with the most likely reason for failure. In the case of a sales order payment, “fulfillment warehouse is not specified” is that generic error message.
When an exception occurs in X++ code, the user is usually presented with an InfoBox. However, when an exception occurs in the same code when called through the .Net Business Connector, it gets sent to the Windows Application Log. Since the Retail Transaction Service uses the .Net Business Connector, you should look for these messages in the Windows Event Viewer on the Retail Transaction Service machine.
Note that if you have the LogLevel of the Retail Transaction Service set to Trace (3), you will likely get the same exception information in the Retail Transaction Service log file as well. But the Event Viewer is sometimes a quicker place to look.
Is the additional information very helpful? This is the exception that came from the Business Connector:
Microsoft Dynamics AX Business Connector Session 6.
An X++ exception has occurred.
Voucher ARP001239, date 1/13/2012, account 130100, amount currency -1,200.00, amount MST -1,200.00, alternative amount -867.68, currency USD, text Payment for order SO-101277
The transactions on voucher ARP001239 do not balance as per 1/13/2012. (Company currency: -1,200.00 – secondary currency: -867.68)
Posting has been canceled.
It is somewhat more helpful than “fulfillment warehouse not specified” but still doesn’t give us too much to go on. It does tell us that a voucher did not balance, which usually happens when ledger accounts have not been defined. In this situation we still had to debug the X++ code in PosIsTransactionService::postOrderPayment() to narrow down the issue (the PrePaymentLedgerAccount was not set up in the RBOParameters table) but sometimes we have seen a very obvious issue that we could quickly address.
Hopefully this article will help take a little mystery of how the Retail Transaction Service works. If you have suggestions for improving logging and troubleshooting this component, please send them our way.