Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ZIP 321] Specify payment request URIs #347

Closed
daira opened this issue Apr 27, 2017 · 15 comments · Fixed by #395
Closed

[ZIP 321] Specify payment request URIs #347

daira opened this issue Apr 27, 2017 · 15 comments · Fixed by #395

Comments

@daira
Copy link
Collaborator

daira commented Apr 27, 2017

Issue by nathan-at-least
Monday Nov 21, 2016 at 21:18 UTC
Originally opened as #94


A payment request is an opaque string which specifies details of a requested payment, such as recipient, amount, perhaps some details of the memo field contents, perhaps some UX prescriptions.

Originally posted as zcash/zcash#1877, here's that description quoted:

The intent of this specification is to streamline usability for common use cases of payments between users and vendors or perhaps user-to-user.

Note: I'm wary of 'early specification' before we have solid real life use cases. More input from third parties such as wallet makers and 'service vendors' (eg: exchanges, shopping cart providers, etc…) is important.

The basic idea is to introduce a new entity called a Payment Request. This is an encoded blob that's distinct from addresses or any other encoded entity. A vendor wishing to receive payment generates this, and a wallet consumes it, then does some user interaction to execute it. An important sticking point is wallet user authentication of the request.

We should start simple and keep it simple and concrete to known real-world use cases.

A Usage Story:

Here is a UX that I believe has good request authentication:

The user is on a website and expresses the desire to purchase an item, such as by clicking a checkout button after reviewing an order.
That page displays a QR code along with an order number which is high-entropy / unguessable.
The user scans the QR code with their wallet.
The wallet describes the payment amount, the order number, and a description of the items.
The user accepts/cancels the payment request.

Design Principles (Based off of the Story):

Notice two forms of user authentication here:

The wallet only displays the request in response to a user explicitly scanning a QR code, so the user learns to trust the request based on their assessment of the QR code's origin. For example, if a QR code appears in a forum post from a user, the hope is that a user realizes that the user or the website could have generated that request.
The website displays and order number, and so does the wallet, (and importantly) the order number cannot be guessed/spoofed.

Notice forms of 'authentication' that are problematic and potentially dangerous do not exist in this example:

The wallet doesn't display the domain name of the site. (Indeed, the site might be some distributed system like OpenBazaar which doesn't have domain names, or the QR code could be a request from a user on a forum without the explicit coordination of the website hosting that forum.)
There is no other form of indication of the source of the request other than the order number and the 'innate source' of the QR code display and scanning process.
There are no third-party attestations as to the origin of the request such as certificate authority systems or decentralized naming systems.
The data encoded by the QR code is opaque to the user (actually never directly seen) and should not be used by them to authenticate the request.

Notice that this story requires wallets to meet usability requirements, so if the specification we adopt supports this kind of story it would encompass both data formats as well as usability requirements (eg: the wallet must not display a request due to an 'ambiently triggered event' such as a website javascript calling a showRequest() call at its discretion, and must only show a request in response to an explicit user-authenticatable action such as scanning a QR code or pasting in a request blob).

Note, this is distinct from [#2310] although they interact.

@jasondavies
Copy link

jasondavies commented Aug 8, 2017

One possible way to encode a payment request, {z-addr, memo}, is to extend BIP21 to include a "memo" parameter, i.e. zcash:<z-addr>?memo=<memo>. This can then be displayed using a QR code. The encoding of the memo field itself would need specifying: it could simply be encoded using RFC 3986 percent-encoding, or alternatively it could be hex-encoded.

Note that BIP21-style Zcash addresses (both t- and z-addrs) are already in use "in the wild", e.g. the Wikileaks donation links (both the hyperlinks and the QR codes), but of course without use of a "memo" parameter (I haven't seen this used anywhere yet).

@daira daira changed the title ZIP: Specify 'payment request v0'. [ZIP 321] Specify 'payment request v0'. Nov 13, 2018
@daira daira changed the title [ZIP 321] Specify 'payment request v0'. [ZIP 321] Specify payment request URIs Nov 13, 2018
@daira
Copy link
Collaborator Author

daira commented Nov 13, 2018

I've renamed this to "Specify payment request URIs" and assigned a ZIP number derived from BIP 21. Note that:

  • this is a narrowing of scope relative to the original description;
  • URIs have a standard QR code format, and so this is effectively also standardizing the QR code for a payment request as that format.

If there is an objection to either of these effects, speak up!

@tromer
Copy link
Contributor

tromer commented May 3, 2019

The payment request encoding may need to contain different information if the payment will be done using a secure channel instead of a recipient z-address (discussed in zcash/zcash#2432).

It would be nice to have a single encoding that supports both use cases.

@tromer
Copy link
Contributor

tromer commented Jun 2, 2019

Re https://github.com/zcash/zcash/issues/2319#issuecomment-321063481:
The Zcash Foundation grants platform also uses BIP21-style zcash:t3...?amount=... payment request URIs.

@tromer
Copy link
Contributor

tromer commented Jun 2, 2019

Do we want support for these URIs in zcashd RPC?

Perhaps:
zcash-cli z_sendmany "t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd" '[{"request": "zcash:ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf?amount=5.0&memo=squeamish+ossifrage"}]'

Or should the parsing be left to higher-level software?

What do other coins do (e.g., Bitcoin for BIP21)?

@tromer
Copy link
Contributor

tromer commented Jun 10, 2019

The just-funded Zcash Foundation grant for Zcash Point-Of-Sale will also use the zcash:saplingpaymentaddress?amount=0.12345678&memo=ordernumber format (according to its discussion comments).

@daira daira transferred this issue from zcash/zcash Apr 20, 2020
@r3ld3v r3ld3v added this to the Core Sprint 2020-31 milestone Jul 28, 2020
@r3ld3v r3ld3v removed this from the Core Sprint 2020-33 milestone Aug 27, 2020
@nuttycom nuttycom self-assigned this Sep 9, 2020
@r3ld3v r3ld3v added this to the Core Sprint 2020-37 milestone Sep 10, 2020
@zancas
Copy link
Contributor

zancas commented Oct 6, 2020

One possible way to encode a payment request, {z-addr, memo}, is to extend BIP21 to include a "memo" parameter, i.e. zcash:<z-addr>?memo=<memo>. This can then be displayed using a QR code. The encoding of the memo field itself would need specifying: it could simply be encoded using RFC 3986 percent-encoding, or alternatively it could be hex-encoded.

Note that BIP21-style Zcash addresses (both t- and z-addrs) are already in use "in the wild", e.g. the Wikileaks donation links (both the hyperlinks and the QR codes), but of course without use of a "memo" parameter (I haven't seen this used anywhere yet).

I'd like to agitate for calling it anything other than memo since that overloads the term with the memo field.

@nuttycom
Copy link
Contributor

nuttycom commented Oct 7, 2020

I'd like to agitate for calling it anything other than memo since that overloads the term with the memo field.

The precise intent of this is exactly that the contents of the "memo" parameter be inserted into the "memo" field of the shielded output in the generated transaction. This is so that the vendor can ensure that the purchaser includes an order ID in the memo field, for example. So it's not overloaded at all.

@AArnott
Copy link
Contributor

AArnott commented Aug 17, 2023

The ZIP doesn't include any sample use of the req- prefix, so I wonder: is the req- prefix considered part of the parameter name, or just an optional prefix that can be prepended to any already defined parameter?
For example, should my parsing implementation consider req-amount to be an alias of the amount parameter?

@nuttycom
Copy link
Contributor

nuttycom commented Aug 17, 2023

@AArnott At present, there are no required parameters specified. You'll notice that the reqparam production is defined in the "forward compatibility" section. The reqparam production was added to allow for future changes to the specification without explicit versioning; instead, if a parameter is added in the future where an existing parser might misinterpret the payment request and produce the wrong result, compliant parsers will produce an error instead. What this means is that your parser should look for variables having the req- prefix, but if it encounters any at all (since none have yet been specified) your parser should report an error.

As an example of a potential future change that might necessitate the introduction of a req- parameter, once ZSA functionality is active on the network it might make sense to introduce a req-currency parameter that can specify the currency in which the payment recipient wishes to be paid. A parser that does not understand the req-currency parameter will be unable to correctly interpret the payment request, and should therefore return an error.

@AArnott
Copy link
Contributor

AArnott commented Aug 17, 2023

Thanks. I think there is an opportunity for using it more. For example req-memo could indicate that the memo field must be copied into the payment screen, and perhaps locked so the user cannot change it.
But I guess such a thing will need a follow-up ZIP.

@nuttycom
Copy link
Contributor

Thanks. I think there is an opportunity for using it more. For example req-memo could indicate that the memo field must be copied into the payment screen, and perhaps locked so the user cannot change it. But I guess such a thing will need a follow-up ZIP.

The ZIP 321 specification is a living document, so changes and additions to it can be proposed via the ordinary pull-request process; zips PRs are reviewed and eventually approved or rejected by the ZIP editors.

@AArnott
Copy link
Contributor

AArnott commented Aug 17, 2023

Oh! I thought once ZIPs were ratified they couldn't be substantially changed. I do have an active PR that changes this ZIP and a few others, but it's just typo fixes.

@nuttycom
Copy link
Contributor

Oh! I thought once ZIPs were ratified they couldn't be substantially changed. I do have an active PR that changes this ZIP and a few others, but it's just typo fixes.

It varies a bit by ZIP, based upon the character of the ZIP itself, but updating ZIPs is pretty common; for example, if you look at the "NU5 ZIPs" section at https://zips.z.cash/ you'll see a number of ZIPs were updated in order to facilitate NU5 deployment.

@nuttycom
Copy link
Contributor

Speaking of which, @daira I think that ZIP 321 should probably be transitioned from Proposed to Active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants