We have an update on the payment ID discussions which have been increasing over the past weeks. The main point of discussion has been whether additional data should be included in the block payload - various options and opinions have been discussed in the New state block design topic.
The general stance from the Nano Foundation is that adding this additional, open data field to the block comes with trade-offs we think may not make it worth doing, some of these concerns are noted here. As an alternative, we have suggested a separate payment management setup, including a block and/or block hash handoff, which may provide the benefits needed without adding complexity to the protocol and ledger. Below are some details about how this might work for further discussion.
Each block already has a unique ID associated with it, which is the block hash, but when a typical transaction occurs with a merchant there is often only a one-way communication - the merchant telling the customer how much Nano to send and to what address. With this setup the merchant can't know for sure that a specific payment to the address was for a specific purchase - if the amounts conflict with another recent transaction it can become an issue.
To get around this most payment processors use a pool of unique accounts and assign one per expected purchase, then after validating payment they forward that on to a central wallet to manage. This is cumbersome and increases ledger size due to extra forwarding transactions.
The payment protocol approach is aiming to allow connecting a block published to the network with a specific payment expected by a merchant. It does so by standardizing the communication for sending the hash of the payment block or the fully signed block to the merchant for tracking purposes. Each of these approaches has benefits worth discussing.
Block hash and signed block handoff
In both handoff scenarios, the main component is a standard for a merchant to provide the wallet with a URL that accepts details of the payment to be made - we will call this the payment response URL. By providing the URL to the wallet the merchant can also include a unique payment ID as a parameter to include in the response, thus allowing direct ties between the block and the payment.
In the block hash approach, the response would include just the hash of the block prepared, not the block contents. The wallet would then publish the block contents to the network themselves, which the merchant can easily watch for confirmation on to complete the transaction on their side.
In the signed block handoff approach, the response would include the entire contents of the signed block, ready for the merchant to validate, connect with the payment on their end and publish to the network themselves. Here is a diagram outlining this process in more detail.
There are pros and cons to both methods, so including them both is likely useful. The block hash approach will likely be the preferred method when:
The customer wallet has an internet connection/ability to publish the block themselves
Has the ability to provide the necessary work with the block (or the merchant doesn't offer this option)
It is preferred because it doesn't rely on the merchant having to publish the block as the other approach requires, which removes the ability of the merchant to hold onto the signed block for malicious purposes. This malicious behavior only makes sense if the merchant believes they can deny providing the goods of the transaction while holding the block, and then subsequently publish the block to receive payment anyway. This scenario can be avoided by the wallet watching for the block being published to their node and providing a "cancel" option, which is essentially publishing another block themselves (change representative, without balance change, etc.) to prevent the merchant block from being allowed. This issue doesn't seem to be a high risk one, but is notable.
There are other situations where the signed block handoff would be necessary, primarily when:
The customer wallet doesn't have an internet connection so must use NFC or QR code scanning to communicate (e.g. in a busy stadium with poor cellular reception)
The customer doesn't have work ready for the block and the merchant offers to cover it
In these scenarios, the customer doesn't have a choice in letting the merchant publish the block on their behalf because they don't meet the necessary requirements to do so themselves (or perhaps the alternative is just too cumbersome, such as the merchant providing the work back to the user with an extra communication step).
Note that the ability for a receiver (merchant) to cover the work for a sender is possible, although requires on-demand work generation currently. Some potential changes being considered that would allow pre-computed work on the receiver side to cover sender work have been mentioned here.
What if the wallet used doesn't support these methods?
There is a generic fallback mechanism that can be used if the wallet doesn't support this protocol, and it likely is only needed in edge cases. If the merchant is expecting a payment of a specific amount and there is only one payment that arrives for that amount, then it is easy to associate those together. If there are conflicting payment amounts, then a small set of digits can be requested from the payment block so the merchant can choose the right block to associate with the payment. This is included in the diagram linked above.
Other payment standards
There are other payment protocols that attempt to standardize the communication between merchants and customers, most notably the W3C Payment Request API. The above process should be able to fit within a protocol such as this, as they are flexible enough to define a payment type with unique data fields to be passed along (including block hash, full block contents, etc.).
Prototype of payment process
Thanks to community developer Hector Chu, we now have a basic prototype of the signed block handoff process available. We are temporarily hosted the server side of the payment process but this is now down, keeping the below for future reference. This doesn't support QR code generation and scanning at this point, so some manual entry is required. But it does show how this process can work. Here is how to test:
Download the Gonano-gui v0.1.7 wallet from here: Release Gonano v0.1.7 · hectorchu/gonano-gui · GitHub
Setup an account on the wallet and deposit 0.00001 Nano there (NOTE: this was done on the main network to make it more accessible to the community; please manage your funds wisely)
The server side is now down so this can't be completed but leaving for reference
Click the Buy button next to either the Apple or Banana; note that a new entry appears at the top of the table with a unique payment ID
In the Gonano wallet, click Send and enter the following details:
Recipient = the wallet address at the top of the payment page
Amount = the amount for the item selected
Payment URL = right-click and copy the "Payment Link" on the payment page (this URL should contain the unique payment ID of the item you intend to buy)
Click OK and if everything was correct you should get a notification in the wallet and see the hash appear next to the proper item on the payment page
If you try sending the incorrect amount an error will appear in the wallet noting the issue and no payment will be made. As mentioned earlier this is a manual process that would be replaced with QR code scanning or NFC negotiation to make it seamless. By validating the payment details before publishing on the merchant side, this also avoids the complication of incorrect payments requiring refunds or additional top-up to complete.
Evaluating this option
All the details above were pulled together to generate discussion about whether this is a viable route for the Nano ecosystem. Given the separate protocol, this does require receivers of payments to run a service for managing these payment communications and wallets to support the process as well. However given the lightweight nature of the process, this is likely to be straight forward for Point of Sale backends and online checkout systems alike. And ultimately it helps wallets by eventually opening up an option for merchants to cover work they would otherwise have to do themselves.
There was consideration for including a payment protocol as part of the node itself, but that comes with drawbacks of additional complexity in the node, requiring additional ports opened on the node server and means setting up multiple instances of the payment services requires multiple nodes. The separation of concerns between the node and the payment protocol seems worthwhile.
We are interested in additional thoughts around this approach as it impacts the New state block design conversations as well as various services across the Nano network. We are especially looking forward to comments from developers of payment processors and wallets, so will be directly asking for their feedback in various channels. Thanks in advance for everyone's time, testing and consideration, we are excited to make some progress in this critical payments area.