├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── dist
├── README.txt
└── spec
│ ├── payid-discovery.html
│ ├── payid-discovery.txt
│ ├── payid-discovery.xml
│ ├── payid-easy-checkout.html
│ ├── payid-easy-checkout.txt
│ ├── payid-easy-checkout.xml
│ ├── payid-protocol.html
│ ├── payid-protocol.txt
│ ├── payid-protocol.xml
│ ├── payid-uri.html
│ ├── payid-uri.txt
│ ├── payid-uri.xml
│ ├── self-sov-verifiable-payid-protocol.html
│ ├── self-sov-verifiable-payid-protocol.txt
│ ├── self-sov-verifiable-payid-protocol.xml
│ ├── verifiable-payid-protocol.html
│ ├── verifiable-payid-protocol.txt
│ └── verifiable-payid-protocol.xml
├── java
├── README.md
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── payid
│ │ ├── AbstractPayId.java
│ │ └── PayId.java
│ └── test
│ ├── java
│ └── org
│ │ └── payid
│ │ ├── PayIdInvalidValuesTest.java
│ │ ├── PayIdPublicSuffixesTest.java
│ │ └── PayIdValidValuesTest.java
│ └── resources
│ └── org
│ └── payid
│ └── valid-payids.json
├── package-lock.json
├── package.json
└── src
└── spec
├── payid-discovery.md
├── payid-easy-checkout.md
├── payid-protocol.md
├── payid-uri.md
├── self-sov-verifiable-payid-protocol.md
└── verifiable-payid-protocol.md
/.gitignore:
--------------------------------------------------------------------------------
1 | **/node_modules/
2 | **/.DS_Store
3 | **/.idea
4 | **/target
5 | **/*.iml
6 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | // Add new RFC proposals to this list:
3 | const rfcs = [
4 | "src/spec/payid-uri.md",
5 | "src/spec/payid-discovery.md",
6 | "src/spec/payid-protocol.md",
7 | "src/spec/verifiable-payid-protocol.md",
8 | "src/spec/payid-easy-checkout.md",
9 | "src/spec/self-sov-verifiable-payid-protocol.md"
10 | ]
11 |
12 | // Project configuration.
13 | grunt.initConfig({
14 | pkg: grunt.file.readJSON("package.json"),
15 |
16 | // The command that generates specs
17 | kramdown_rfc2629: {
18 | options: {
19 | outputs: ["text", "html"],
20 | outputDir: "dist/spec",
21 | removeXML: false
22 | },
23 | your_target: {
24 | src: rfcs,
25 | }
26 | },
27 |
28 | // The "watch" command which will watch specs for file changes,
29 | // and automatically regenerate the RFC outputs.
30 | watch: {
31 | scripts: {
32 | files: rfcs,
33 | tasks: ["kramdown_rfc2629"],
34 | options: {
35 | spawn: false
36 | }
37 | }
38 | },
39 |
40 | });
41 |
42 | grunt.loadNpmTasks("grunt-contrib-watch");
43 | grunt.loadNpmTasks("grunt-kramdown-rfc2629");
44 | };
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2020 Ripple Labs Inc.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PayID
2 |
3 | ## Specs
4 |
5 | - [You can find the full list of RFCs here](https://github.com/payid-org/rfcs/tree/master/dist/spec)
6 |
7 | ### List of RFCs
8 |
9 | #### PayID Core
10 | - [PayID Whitepaper](https://payid.org/whitepaper.pdf)
11 | - [The 'payid' URI Scheme](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-uri.txt)
12 | - [PayID Discovery](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-discovery.txt)
13 | - [PayID Protocol](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-protocol.txt)
14 |
15 | #### Verifiable PayID
16 | - [Verifiable PayID Protocol](https://github.com/payid-org/rfcs/blob/master/dist/spec/verifiable-payid-protocol.txt)
17 | - [Self-Sovereign Verifiable PayID](https://github.com/payid-org/rfcs/blob/master/dist/spec/self-sov-verifiable-payid-protocol.txt)
18 |
19 | #### PayID Commerce
20 | - [PayID Easy Checkout](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-easy-checkout.txt)
21 |
22 | The source code for each spec is in [src/spec](https://github.com/payid-org/rfcs/tree/master/src/spec).
23 |
24 | ## Implementations
25 |
26 | Known implementations of PayID and PayID Discovery:
27 |
28 | - [TypeScript](https://github.com/payid-org/payid)
29 | - Java: TBD.
30 | - Swift: TBD.
31 |
32 | If you would like to update this list, please feel free to open a pull request against this repository.
33 |
34 | ## Generating the Spec
35 |
36 | From the root directory of the repo run:
37 |
38 | ```sh
39 | # Install IETF RFC tools
40 | gem install kramdown-rfc2629
41 | pip3 install xml2rfc
42 |
43 | # Install PayID RFC dependencies
44 | npm install
45 |
46 | # Generate the spec
47 | npm run spec
48 | ```
49 |
50 | This generates the RFC output files in the `dist` folder using [kramdown-rfc2629](https://github.com/cabo/kramdown-rfc2629/), [xml2rfc](http://xml2rfc.ietf.org/) and [Grunt](http://gruntjs.com/) with the [Grunt kramdown_rfc2629 task](https://github.com/hildjj/grunt-kramdown-rfc2629/)
51 |
52 | To watch edits to RFC source files and auto-generate output when changes are saved run `npm run watch`.
53 |
54 | ## Authoring a new RFC
55 |
56 | First, write a Pull Request that adds the markdown file for the spec in the [src/spec](https://github.com/payid-org/rfcs/tree/master/src/spec) folder.
57 |
58 | Then, add that file to the [Gruntfile](https://github.com/payid-org/rfcs/tree/master/Gruntfile.js) list of RFCs. That way the spec output can be generated for your proposal.
59 | ## Legal
60 |
61 | **This code is not authorised for download in Australia. Any persons located in Australia are expressly prohibited from downloading, using, reproducing or distributing the code.** This code is not owned by, or associated with, NPP Australia Limited, and has no sponsorship, affiliation or other connection with the “Pay ID” service operated by NPP Australia Limited in Australia.
62 |
--------------------------------------------------------------------------------
/dist/README.txt:
--------------------------------------------------------------------------------
1 | Placeholder for generated files.
2 |
--------------------------------------------------------------------------------
/dist/spec/payid-discovery.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Network Working Group D. Fuelling
6 | Internet-Draft Ripple
7 | Intended status: Standards Track July 17, 2020
8 | Expires: January 18, 2021
9 |
10 |
11 | PayID Discovery
12 | draft-fuelling-payid-discovery-01
13 |
14 | Abstract
15 |
16 | This specification defines the PayID Discovery protocol, which can be
17 | used to discover information about a 'payid' URI using standard HTTP
18 | methods.
19 |
20 | The primary use-case of this protocol is to define how to transform a
21 | PayID URI into a URL that can be used with other protocols.
22 |
23 | Feedback
24 |
25 | This specification is a draft proposal, and is part of the PayID
26 | Protocol [1] initiative. Feedback related to this document should be
27 | sent in the form of a Github issue at: https://github.com/payid-
28 | org/rfcs/issues.
29 |
30 | Status of This Memo
31 |
32 | This Internet-Draft is submitted in full conformance with the
33 | provisions of BCP 78 and BCP 79.
34 |
35 | Internet-Drafts are working documents of the Internet Engineering
36 | Task Force (IETF). Note that other groups may also distribute
37 | working documents as Internet-Drafts. The list of current Internet-
38 | Drafts is at https://datatracker.ietf.org/drafts/current/.
39 |
40 | Internet-Drafts are draft documents valid for a maximum of six months
41 | and may be updated, replaced, or obsoleted by other documents at any
42 | time. It is inappropriate to use Internet-Drafts as reference
43 | material or to cite them other than as "work in progress."
44 |
45 | This Internet-Draft will expire on January 18, 2021.
46 |
47 | Copyright Notice
48 |
49 | Copyright (c) 2020 IETF Trust and the persons identified as the
50 | document authors. All rights reserved.
51 |
52 |
53 |
54 |
55 |
56 | Fuelling Expires January 18, 2021 [Page 1]
57 |
58 | Internet-Draft PayID Discovery July 2020
59 |
60 |
61 | This document is subject to BCP 78 and the IETF Trust's Legal
62 | Provisions Relating to IETF Documents
63 | (https://trustee.ietf.org/license-info) in effect on the date of
64 | publication of this document. Please review these documents
65 | carefully, as they describe your rights and restrictions with respect
66 | to this document. Code Components extracted from this document must
67 | include Simplified BSD License text as described in Section 4.e of
68 | the Trust Legal Provisions and are provided without warranty as
69 | described in the Simplified BSD License.
70 |
71 | Table of Contents
72 |
73 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
74 | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4
75 | 3. Example Usage . . . . . . . . . . . . . . . . . . . . . . . . 4
76 | 3.1. PayID Discovery by a Wallet . . . . . . . . . . . . . . . 4
77 | 3.2. PayID Discovery with Default Template . . . . . . . . . . 5
78 | 4. PayID Discovery Protocol . . . . . . . . . . . . . . . . . . 5
79 | 4.1. Interactive Mode . . . . . . . . . . . . . . . . . . . . 6
80 | 4.1.1. Step 1: Assemble PayID Discovery URL . . . . . . . . 7
81 | 4.1.2. Step 2: Query PayID Discovery URL . . . . . . . . . . 8
82 | 4.1.3. Step 3: Parse PayID Metadata . . . . . . . . . . . . 8
83 | 4.1.4. Step 4: Assemble PayID URL . . . . . . . . . . . . . 8
84 | 4.2. Fallback Mode . . . . . . . . . . . . . . . . . . . . . . 10
85 | 4.2.1. Fallback Assembly Flow . . . . . . . . . . . . . . . 10
86 | 5. PayID Discovery JRDs . . . . . . . . . . . . . . . . . . . . 10
87 | 5.1. JRD for PayID Discovery URL . . . . . . . . . . . . . . . 11
88 | 5.2. JRD for PayID URI Template . . . . . . . . . . . . . . . 11
89 | 6. Security Considerations . . . . . . . . . . . . . . . . . . . 11
90 | 6.1. Hosted PayID Discovery Services . . . . . . . . . . . . . 12
91 | 6.2. Cross-Origin Resource Sharing (CORS) . . . . . . . . . . 12
92 | 6.3. Access Control . . . . . . . . . . . . . . . . . . . . . 12
93 | 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12
94 | 7.1. New Link Relation Types . . . . . . . . . . . . . . . . . 12
95 | 7.1.1. PayID Discovery URL . . . . . . . . . . . . . . . . . 12
96 | 7.1.2. PayID Discovery URI Template . . . . . . . . . . . . 12
97 | 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 13
98 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 13
99 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 13
100 | 9.2. Informative References . . . . . . . . . . . . . . . . . 14
101 | 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 14
102 | Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 14
103 |
104 | 1. Introduction
105 |
106 | PayID Discovery is used to transform a PayID URI [PAYID-URI] into a
107 | URL (defined below as a PayID Discovery URL) that can then be used by
108 |
109 |
110 |
111 |
112 | Fuelling Expires January 18, 2021 [Page 2]
113 |
114 | Internet-Draft PayID Discovery July 2020
115 |
116 |
117 | higher-order protocols to discover metadata about a PayID-enabled
118 | service provider.
119 |
120 | This document specifies two modes of PayID discovery: one using
121 | Webfinger [RFC7033] to resolve a corresponding PayID Discovery URL
122 | from a PayID using an interactive protocol. The second mode uses a
123 | manual mechanism to assemble a PayID Discovery URL from a PayID by-
124 | hand.
125 |
126 | In 'interactive' mode, a PayID can be presented to a Webfinger-
127 | enabled service endpoint that supports PayID Discovery. The resource
128 | returns a Webfinger-compliant JavaScript Object Notation (JSON)
129 | [RFC4627] object that can be used to perform PayID Discovery as
130 | defined in section 4.1 of this document.
131 |
132 | As an alternative, "manual" mode MAY be used to decompose a PayID
133 | into a URL, without any intermediate server interaction by simply
134 | transposing portions of a PayID URI into a URL format. This
135 | procedure is defined in section 4.2 of this document.
136 |
137 | It should be noted that "manual" mode does not allow divergence
138 | between the string characters in a PayID URI and any corresponding
139 | PayID URL. Interactive mode, on the other hand, does allow such
140 | divergence, and is thus more powerful. For example, in manual mode,
141 | the PayID 'alice$example.com' MUST always map to the URL
142 | 'https://example.com/alice', whereas in interactive mode that same
143 | PayID URI can map to any arbitrary URL structure determined by the
144 | service provider, such as 'https://example.com/users/alice'.
145 |
146 | Information returned via PayID Discovery might be used for direct
147 | human consumption (e.g., looking up someone's Bitcoin address), or it
148 | might be used by systems to help carry out some operation (e.g.,
149 | facilitating, with additional security mechanisms, protocols to
150 | support compliance or other legal requirements necessary to
151 | facilitate a payment).
152 |
153 | The information returned via this protocol is intended to be static
154 | in nature. As such, PayID Discovery is not intended to be used to
155 | return dynamic information like a payment account balance or the
156 | current status of a payment account.
157 |
158 | PayID Discovery is designed to be used across many applications. Use
159 | of PayID Discovery is illustrated in the examples in Section 3 and
160 | described more formally in Section 4.
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | Fuelling Expires January 18, 2021 [Page 3]
169 |
170 | Internet-Draft PayID Discovery July 2020
171 |
172 |
173 | 2. Terminology
174 |
175 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
176 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
177 | "OPTIONAL" in this document are to be interpreted as described in
178 | [RFC2119].
179 |
180 | 3. Example Usage
181 |
182 | This section shows sample uses of PayID Discovery in several
183 | hypothetical scenarios.
184 |
185 | 3.1. PayID Discovery by a Wallet
186 |
187 | Imagine Alice wishes to send a friend some XRP from a web-based
188 | wallet provider that Alice has an account on. Alice would log-in to
189 | the wallet provider and enter Bob's PayID (say,
190 | "bob$receiver.example.com") into the wallet UI to start the payment.
191 |
192 | The Wallet application would first perform a WebFinger query looking
193 | for the PayID Discovery service provider, like this:
194 |
195 | GET /.well-known/webfinger?
196 | resource=payid%3Abob%24receiver.example.com
197 | HTTP/1.1
198 | Host: receiver.example.com
199 |
200 | The server might respond like this:
201 |
202 | HTTP/1.1 200 OK
203 | Access-Control-Allow-Origin: *
204 | Content-Type: application/jrd+json
205 |
206 | {
207 | "subject" : "payid:bob$receiver.example.com",
208 | "links" :
209 | [
210 | {
211 | "rel": "https://payid.org/ns/payid-uri-template/1.0",
212 | "template": "https://receiver.example.com/users/{acctpart}"
213 | }
214 | ]
215 | }
216 |
217 | Alice's wallet then uses the URL template found in the "template"
218 | property to assemble the specified PayId URL,
219 | "https://receiver.example.com/users/bob".
220 |
221 |
222 |
223 |
224 | Fuelling Expires January 18, 2021 [Page 4]
225 |
226 | Internet-Draft PayID Discovery July 2020
227 |
228 |
229 | Per [RFC7033], Webfinger requests can be filtered by using a "rel"
230 | parameter in the Webfinger request. Because support for the "rel"
231 | parameter is not required nor guaranteed, the client must not assume
232 | the "links" array will contain only the link relations related to
233 | PayID Discovery.
234 |
235 | 3.2. PayID Discovery with Default Template
236 |
237 | Imagine Alice, as in the example above, wants to send a friend some
238 | XRP from a web-based wallet provider that Alice has an account on.
239 | However, in this example, let's assume that the PayID Alice is
240 | wanting to pay doesn't support "interactive" PayID discovery (i.e.,
241 | the receiver's server doesn't support Webfinger).
242 |
243 | Alice would log-in to her wallet provider and enter Bob's PayID (say
244 | "bob$receiver.example.com") to make a payment.
245 |
246 | The Wallet application would first attempt a WebFinger query as in
247 | the example above, like this:
248 |
249 | GET /.well-known/webfinger?
250 | resource=payid%3Abob%24receiver.example.com&
251 | HTTP/1.1
252 | Host: receiver.example.com
253 |
254 | However, in this case the "receiver.example.com" server doesn't
255 | support "interactive" PayID Discovery, so the server responds like
256 | this:
257 |
258 | HTTP/1.1 404 NOT FOUND
259 |
260 | Because Alice's Wallet can utilize "manual" PayID Discovery, the
261 | wallet software merely transforms "bob$receiever.example.com" into
262 | the URL "https://receiver.example.com/bob". Alice's wallet then uses
263 | that URL to continue making a PayID payment.
264 |
265 | It should be noted that "manual" mode does not allow the PayID URI to
266 | diverge from the underlying URL returned via PayID Discovery.
267 | Because of this, "interactive" PayID Discovery is generally
268 | preferred.
269 |
270 | 4. PayID Discovery Protocol
271 |
272 | The PayID Discovery protocol is used to request information about an
273 | entity identified by a PayID URI.
274 |
275 | When successful, PayID Discovery always yields a PayID URL, which is
276 | a URI as defined by [RFC3986] using the 'https' scheme defined in
277 |
278 |
279 |
280 | Fuelling Expires January 18, 2021 [Page 5]
281 |
282 | Internet-Draft PayID Discovery July 2020
283 |
284 |
285 | section 2.7.2 [RFC7230]. A PayID URL can be used for any purposes
286 | outside the scope of this document.
287 |
288 | PayID Discovery is performed using one of two modes: "interactive" or
289 | "manual." Clients MUST attempt "interactive" mode first. If that
290 | mode fails to yield a PayID URL, then "manual" mode MAY be used as an
291 | alternative discovery mechanism.
292 |
293 | 4.1. Interactive Mode
294 |
295 | Interactive PayID Discovery is broken up into a series of steps, each
296 | of which is defined in more detail below. The following is a visual
297 | representation of the protocol flow:
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 | Fuelling Expires January 18, 2021 [Page 6]
337 |
338 | Internet-Draft PayID Discovery July 2020
339 |
340 |
341 | +--------------------------+
342 | | PayID URI |
343 | | alice$example.com |
344 | +--------------------------+
345 | |
346 | v
347 | +--------------------------+
348 | | Assemble |
349 | | PayID Discovery URL |
350 | +--------------------------+
351 | |
352 | v
353 | +--------------------------+
354 | | Query |
355 | +-----| PayID Discovery URL |-----+
356 | | +--------------------------+ |
357 | | Success
358 | | |
359 | | v
360 | | +---------------------------+
361 | Failure | Parse PayID Metadata |
362 | | +---------------------------+
363 | | |
364 | | v
365 | | +---------------------------+
366 | | | Select PayID URI Template |
367 | | +---------------------------+
368 | | |
369 | v v
370 | +--------------------------+ +---------------------------+
371 | | Manual PayID Discovery | | Assemble PayID URL |
372 | +--------------------------+ +---------------------------+
373 | | |
374 | +---------------------+----------------+
375 | |
376 | v
377 | +---------------------------+
378 | | PayID URL |
379 | | https://example.com/alice |
380 | +---------------------------+
381 |
382 | 4.1.1. Step 1: Assemble PayID Discovery URL
383 |
384 | PayID Discovery utilizes the Webfinger [RFC7033] specification in a
385 | narrowly defined profile.
386 |
387 |
388 |
389 |
390 |
391 |
392 | Fuelling Expires January 18, 2021 [Page 7]
393 |
394 | Internet-Draft PayID Discovery July 2020
395 |
396 |
397 | This document defines a PayID Discovery URL as being a Webfinger
398 | resource URI where the specified resource value is a valid PayID URI
399 | [PAYID-URI].
400 |
401 | For example, the PayID Discovery URL for alice$example.com is
402 |
403 | https://example.com/.well-known/webfinger?
404 | resource=payid%3Aalice%24example.com
405 |
406 | 4.1.2. Step 2: Query PayID Discovery URL
407 |
408 | A Webfinger query MUST be performed against the PayID Discovery URL,
409 | as described in section 4.2 of Webfinger.
410 |
411 | In response, the WebFinger resource returns a JSON Resource
412 | Descriptor (JRD) as the resource representation to convey information
413 | about the requested PayID.
414 |
415 | If the Webfinger endpoint returns a non-200 HTTP response status
416 | code, then interactive PayID Discovery is considered to have failed.
417 | Clients MAY attempt to assemble a PayID URL using "manual" mode as
418 | defined in section 4.2.1 of this document.
419 |
420 | 4.1.3. Step 3: Parse PayID Metadata
421 |
422 | If the PayID Discovery server returns a valid response, the response
423 | will contain one or more of the JRDs defined in section 5 of this
424 | document.
425 |
426 | If any of the JRDs contain a 'rel' value that represents a PayID URL
427 | Template, then that template value MUST be used in the next protocol
428 | step.
429 |
430 | Failing the above, if the 'rel' value of any JRDs represents a PayID
431 | Discovery URL, then that URL MUST be used in step 2 above, repeated
432 | recursively if needed, until a valid PayID URI Template is obtained.
433 | That URI Template value MUST be used in the next protocol step.
434 |
435 | 4.1.4. Step 4: Assemble PayID URL
436 |
437 | A PayID URL is constructed by applying the PayID URI to the PayID URI
438 | Template string obtained in the step above. The PayID URI template
439 | MAY contain a URI string without any variables to represent a host-
440 | level PayID URL that is identical for every PayID URI on a particular
441 | host.
442 |
443 | For example, a PayID Discovery endpoint that only supports a single
444 | account might use a URI template string with no variables, like this:
445 |
446 |
447 |
448 | Fuelling Expires January 18, 2021 [Page 8]
449 |
450 | Internet-Draft PayID Discovery July 2020
451 |
452 |
453 | {
454 | "rel": "https://payid.org/ns/payid-uri-template/1.0",
455 | "template": "https://example.com/alice"
456 | }
457 |
458 | The result of this step is the PayID URL. Once obtained, PayID
459 | Discovery is considered to have completed successfully.
460 |
461 | 4.1.4.1. Template Syntax
462 |
463 | This specification defines a simple template syntax for PayID URI
464 | transformation. A template is a string containing brace-enclosed
465 | ("{}") variable names marking the parts of the string that are to be
466 | substituted by the corresponding variable values.
467 |
468 | This specification defines a one variable - "acctpart" - which
469 | corresponds to the 'acctpart' of a PayID URI as defined in
470 | [PAYID-URI].
471 |
472 | When substituting the 'acctpart' value into a URI 'path' as defined
473 | by [RFC3986], values MUST NOT be percent or otherwise encoded because
474 | the 'acctpart' value of a PayID URI always conforms to the character
475 | set allowed by paths in [RFC3986].
476 |
477 | However, before substituting template variables into a URI 'query'
478 | part, values MUST be encoded using UTF-8, and any character other
479 | than unreserved (as defined by [RFC3986]) MUST be percent-encoded per
480 | [RFC3986].
481 |
482 | Protocols MAY define additional variables and syntax rules, but MUST
483 | NOT change the meaning of the 'acctpart' variable. If a client is
484 | unable to successfully process a template (e.g., unknown variable
485 | names, unknown or incompatible syntax), the JRD SHOULD be ignored.
486 |
487 | The template syntax ABNF is as follows:
488 |
489 | uri-char = ( reserved / unreserved / pct-encoded )
490 | var-char = ALPHA / DIGIT / "." / "_"
491 | var-name = %x61.63.63.74.70.61.72.74 / ( 1*var-char ) ; "acctpart" or
492 | other names
493 | variable = "{" var-name "}"
494 | PAYID-URI-Template = *( uri-char / variable )
495 |
496 | For example:
497 |
498 | Input: alice$example.org
499 | Template: https://example.org/{acctpart}
500 | Output: https://example.org/alice
501 |
502 |
503 |
504 | Fuelling Expires January 18, 2021 [Page 9]
505 |
506 | Internet-Draft PayID Discovery July 2020
507 |
508 |
509 | 4.2. Fallback Mode
510 |
511 | If "Interactive" mode is not supported or otherwise fails to yield a
512 | PayID URL, then a PayID URL MAY be assembled manually using the
513 | following predefined ruleset:
514 |
515 | 1. Decompose the PayID URI into its component parts, per
516 | [PAYID-URI], capturing the 'acctpart' and 'host' values.
517 |
518 | 2. Using the 'acctpart' and 'host', assemble a URL by substituting
519 | each value into the following string using no special encoding or
520 | other character adjustments: "https://{host}/{acctpart}".
521 |
522 | For example:
523 |
524 | Input: bob.primary$example.org
525 | Output: https://example.org/bob.primary
526 |
527 | The resulting URL is a PayID URL.
528 |
529 | 4.2.1. Fallback Assembly Flow
530 |
531 | The following is a visual representation of the Fallback Assembly
532 | protocol flow:
533 |
534 | +--------------------------+
535 | | PayID URI |
536 | | alice$example.com |
537 | +--------------------------+
538 | |
539 | v
540 | +--------------------------+
541 | |Manual PayID URL Assembly |
542 | +--------------------------+
543 | |
544 | v
545 | +---------------------------+
546 | | PayID URL |
547 | | https://example.com/alice |
548 | +---------------------------+
549 |
550 | 5. PayID Discovery JRDs
551 |
552 | This document defines two JRDs that conform to section 4.4 of the
553 | Webfinger RFC.
554 |
555 |
556 |
557 |
558 |
559 |
560 | Fuelling Expires January 18, 2021 [Page 10]
561 |
562 | Internet-Draft PayID Discovery July 2020
563 |
564 |
565 | 5.1. JRD for PayID Discovery URL
566 |
567 | This type of JRD can be used to represent a URL that is a PayID
568 | Discovery URL. This is useful for delegating PayID Discovery to
569 | another service endpoint:
570 |
571 | o 'rel': "https://payid.org/ns/payid-discovery-url/1.0"
572 |
573 | o 'href': A PayID Discovery URL that clients can dereference to
574 | perform interactive PayID Discovery.
575 |
576 | The following is an example of a JRD that indicates a PayID Discovery
577 | URL:
578 |
579 | {
580 | "rel": "https://payid.org/ns/payid-discovery-url/1.0",
581 | "href": "https://delegate.example.com/.well-known/webfinger?resource=
582 | payid%3Aalice%24example.com"
583 | }
584 |
585 | 5.2. JRD for PayID URI Template
586 |
587 | This type of JRD can be used to represent a URL that is a PayID URL
588 | Template.
589 |
590 | o 'rel': "https://payid.org/ns/payid-uri-template/1.0"
591 |
592 | o 'template': A PayID URI Template
593 |
594 | The following is an example of a JRD that indicates a PayID URI
595 | Template:
596 |
597 | {
598 | "rel": "https://payid.org/ns/payid-uri-template/1.0",
599 | "template": "https://example.com/{acctpart}"
600 | }
601 |
602 | 6. Security Considerations
603 |
604 | Various security considerations should be taken into account for
605 | PayID Discovery.
606 |
607 | Among other resource, consult section 9 of [RFC7033] and section 7 of
608 | [RFC3986] for important security considerations involved in PayID
609 | Discovery.
610 |
611 |
612 |
613 |
614 |
615 |
616 | Fuelling Expires January 18, 2021 [Page 11]
617 |
618 | Internet-Draft PayID Discovery July 2020
619 |
620 |
621 | 6.1. Hosted PayID Discovery Services
622 |
623 | As with most services provided on the Internet, it is possible for a
624 | domain owner to utilize "hosted" WebFinger services. Consult section
625 | 7 of [RFC7033] for considerations that could apply to both "manual"
626 | and "interactive" PayID Discovery when hosted by a third-party.
627 |
628 | 6.2. Cross-Origin Resource Sharing (CORS)
629 |
630 | PayID Discovery resources might not be accessible from a web browser
631 | due to "Same-Origin" policies. See section 5 of [RFC7033] for CORS
632 | considerations that apply to both "manual" and "interactive" PayID
633 | Discovery modes.
634 |
635 | 6.3. Access Control
636 |
637 | As with all web resources, access to the PayID Discovery resource
638 | could require authentication. See section 6 of [RFC7033] for Access
639 | Control considerations that could apply to both "manual" and
640 | "interactive" PayID Discovery modes.
641 |
642 | 7. IANA Considerations
643 |
644 | 7.1. New Link Relation Types
645 |
646 | This document defines the following Link relation types per
647 | [RFC7033]. See section 3 for examples of each type of Link.
648 |
649 | 7.1.1. PayID Discovery URL
650 |
651 | o Relation Type ('rel'): "https://payid.org/ns/payid-discovery-
652 | url/1.0"
653 |
654 | o Media Type: "application/jrd+json"
655 |
656 | o Description: PayID Discovery URL, version 1.0
657 |
658 | 7.1.2. PayID Discovery URI Template
659 |
660 | o Relation Type ('rel'): "https://payid.org/ns/payid-uri-
661 | template/1.0"
662 |
663 | o Media Type: "application/jrd+json"
664 |
665 | o Description: PayID Discovery URI Template, version 1.0
666 |
667 |
668 |
669 |
670 |
671 |
672 | Fuelling Expires January 18, 2021 [Page 12]
673 |
674 | Internet-Draft PayID Discovery July 2020
675 |
676 |
677 | 8. Acknowledgments
678 |
679 | This document was heavily influenced by, and builds upon, Webfinger
680 | [RFC7033] (adapted for a payments use-case) as well as the supporting
681 | RFCs that it relies upon and that influenced it, especially [RFC5988]
682 | and [RFC6415]. The author would like to acknowledge the
683 | contributions of everyone who worked on those and any related
684 | specifications.
685 |
686 | In addition, the author would like to acknowledge everyone who
687 | provided feedback and use-cases for this derivative specification.
688 |
689 | 9. References
690 |
691 | 9.1. Normative References
692 |
693 | [PAYID-URI]
694 | Fuelling, D., "The 'payid' URI Scheme", n.d.,
695 | .
696 |
697 | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
698 | Requirement Levels", BCP 14, RFC 2119,
699 | DOI 10.17487/RFC2119, March 1997,
700 | .
701 |
702 | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
703 | Resource Identifier (URI): Generic Syntax", STD 66,
704 | RFC 3986, DOI 10.17487/RFC3986, January 2005,
705 | .
706 |
707 | [RFC4627] Crockford, D., "The application/json Media Type for
708 | JavaScript Object Notation (JSON)", RFC 4627,
709 | DOI 10.17487/RFC4627, July 2006,
710 | .
711 |
712 | [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.,
713 | and D. Orchard, "URI Template", RFC 6570,
714 | DOI 10.17487/RFC6570, March 2012,
715 | .
716 |
717 | [RFC7033] Jones, P., Salgueiro, G., Jones, M., and J. Smarr,
718 | "WebFinger", RFC 7033, DOI 10.17487/RFC7033, September
719 | 2013, .
720 |
721 | [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
722 | Protocol (HTTP/1.1): Message Syntax and Routing",
723 | RFC 7230, DOI 10.17487/RFC7230, June 2014,
724 | .
725 |
726 |
727 |
728 | Fuelling Expires January 18, 2021 [Page 13]
729 |
730 | Internet-Draft PayID Discovery July 2020
731 |
732 |
733 | 9.2. Informative References
734 |
735 | [RFC5988] Nottingham, M., "Web Linking", RFC 5988,
736 | DOI 10.17487/RFC5988, October 2010,
737 | .
738 |
739 | [RFC6415] Hammer-Lahav, E., Ed. and B. Cook, "Web Host Metadata",
740 | RFC 6415, DOI 10.17487/RFC6415, October 2011,
741 | .
742 |
743 | 9.3. URIs
744 |
745 | [1] https://payid.org/
746 |
747 | Author's Address
748 |
749 | David Fuelling
750 | Ripple
751 | 315 Montgomery Street
752 | San Francisco, CA 94104
753 | US
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 | Fuelling Expires January 18, 2021 [Page 14]
785 |
--------------------------------------------------------------------------------
/dist/spec/payid-easy-checkout.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Network Working Group N. Kramer
6 | Internet-Draft D. Fuelling
7 | Intended status: Standards Track I. Simpson
8 | Expires: February 7, 2021 Ripple
9 | August 06, 2020
10 |
11 |
12 | Draft 1 - PayID Easy Checkout Protocol
13 | payid-easy-checkout-protocol
14 |
15 | Abstract
16 |
17 | This specification formalizes how a payment recipient, such as a
18 | merchant or a non-profit, can automatically initiate a payment from a
19 | sender using only the sender's PayID.
20 |
21 | Feedback
22 |
23 | This specification is a draft proposal, and is part of the PayID
24 | Protocol [1] initiative. Feedback related to this document should be
25 | sent in the form of a Github issue at: https://github.com/payid-
26 | org/rfcs/issues.
27 |
28 | Status of This Memo
29 |
30 | This Internet-Draft is submitted in full conformance with the
31 | provisions of BCP 78 and BCP 79.
32 |
33 | Internet-Drafts are working documents of the Internet Engineering
34 | Task Force (IETF). Note that other groups may also distribute
35 | working documents as Internet-Drafts. The list of current Internet-
36 | Drafts is at https://datatracker.ietf.org/drafts/current/.
37 |
38 | Internet-Drafts are draft documents valid for a maximum of six months
39 | and may be updated, replaced, or obsoleted by other documents at any
40 | time. It is inappropriate to use Internet-Drafts as reference
41 | material or to cite them other than as "work in progress."
42 |
43 | This Internet-Draft will expire on February 7, 2021.
44 |
45 | Copyright Notice
46 |
47 | Copyright (c) 2020 IETF Trust and the persons identified as the
48 | document authors. All rights reserved.
49 |
50 | This document is subject to BCP 78 and the IETF Trust's Legal
51 | Provisions Relating to IETF Documents
52 | (https://trustee.ietf.org/license-info) in effect on the date of
53 |
54 |
55 |
56 | Kramer, et al. Expires February 7, 2021 [Page 1]
57 |
58 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
59 |
60 |
61 | publication of this document. Please review these documents
62 | carefully, as they describe your rights and restrictions with respect
63 | to this document. Code Components extracted from this document must
64 | include Simplified BSD License text as described in Section 4.e of
65 | the Trust Legal Provisions and are provided without warranty as
66 | described in the Simplified BSD License.
67 |
68 | Table of Contents
69 |
70 | 1. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 2
71 | 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
72 | 3. PayID Easy Checkout Protocol . . . . . . . . . . . . . . . . 3
73 | 3.1. PayID Easy Checkout Discovery . . . . . . . . . . . . . . 4
74 | 3.1.1. Step 1: Assemble PayID Easy Checkout Discovery URL . 4
75 | 3.1.2. Step 2: Query PayID Easy Checkout Discovery URL . . . 4
76 | 3.1.3. Step 3: Parse PayID Easy Checkout Metadata . . . . . 4
77 | 3.2. PayID Easy Checkout URL Assembly . . . . . . . . . . . . 5
78 | 3.2.1. PayID Easy Checkout URL Query Parameters . . . . . . 5
79 | 4. PayID Easy Checkout JRDs . . . . . . . . . . . . . . . . . . 6
80 | 5. Security Considerations . . . . . . . . . . . . . . . . . . . 7
81 | 5.1. PayID Easy Checkout Redirection URI Manipulation . . . . 7
82 | 5.2. Access Control . . . . . . . . . . . . . . . . . . . . . 7
83 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8
84 | 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 8
85 | 8. Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . 8
86 | 8.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . 8
87 | 8.1.1. Design Goals . . . . . . . . . . . . . . . . . . . . 8
88 | 8.2. Example Usage . . . . . . . . . . . . . . . . . . . . . . 9
89 | 8.2.1. PayID Easy Checkout Initiation . . . . . . . . . . . 9
90 | 8.2.2. PayID Easy Checkout Wallet Discovery . . . . . . . . 9
91 | 8.2.3. Assemble PayID Easy Checkout URL with Query
92 | Parameters . . . . . . . . . . . . . . . . . . . . . 10
93 | 8.2.4. Redirect Sender to Their Wallet . . . . . . . . . . . 11
94 | 8.2.5. Sender Confirms Payment . . . . . . . . . . . . . . . 11
95 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 11
96 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 11
97 | 9.2. Informative References . . . . . . . . . . . . . . . . . 12
98 | 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 12
99 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 13
100 |
101 | 1. Terminology
102 |
103 | This protocol can be referred to as the "PayID Easy Checkout
104 | Protocol". It uses the following terminology:
105 |
106 | o PayID Easy Checkout Client: A client that assembles a PayID Easy
107 | Checkout URL using information obtained from PayID Discovery
108 | Server via [PAYID-DISCOVERY].
109 |
110 |
111 |
112 | Kramer, et al. Expires February 7, 2021 [Page 2]
113 |
114 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
115 |
116 |
117 | o PayID Discovery Server: An endpoint that returns a PayID Discovery
118 | JRD conforming to [PAYID-DISCOVERY].
119 |
120 | o Recipient: An individual or entity receiving a payment (e.g.,
121 | e-commerce merchant, charity).
122 |
123 | o Sender: An individual or entity originating a payment to a
124 | "recipient".
125 |
126 | o Wallet: A device or application that holds funds (may be a non-
127 | custodial wallet).
128 |
129 | o PayID Easy Checkout URL: A URL that is the result of this
130 | protocol; can be used to redirect a client to a wallet
131 | corresponding to a particular PayID as defined in [PAYID-URI].
132 |
133 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
134 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
135 | "OPTIONAL" in this document are to be interpreted as described in
136 | [RFC2119] and [RFC9174][].
137 |
138 | 2. Introduction
139 |
140 | The PayID Easy Checkout Protocol allows a recipient (e.g., an online
141 | merchant or a charity) to request a payment from a sender using only
142 | the sender's PayID [PAYID-URI]. Implementations of this protocol
143 | require little to no server-side engineering effort, while creating a
144 | seamless and uniform user experience for senders.
145 |
146 | The main focus of the protocol is on PayID Easy Checkout Discovery,
147 | which defines how a PayID Easy Checkout Client can retrieve a PayID
148 | Easy Checkout URL and use it to initiate a payment to the merchant.
149 |
150 | Though the Section 8 of this specification provides an example usage
151 | of this protocol using Web Redirects, supplemental RFCs are needed to
152 | define any different ways in which a PayID client can utilize a PayID
153 | Easy Checkout URL.
154 |
155 | 3. PayID Easy Checkout Protocol
156 |
157 | The PayID Easy Checkout Protocol can be used to initiate an end-to-
158 | end checkout flow between a payment recipient, such as an online
159 | merchant, and a sender.
160 |
161 | The protocol is comprised of two parts:
162 |
163 | 1. PayID Easy Checkout Discovery
164 |
165 |
166 |
167 |
168 | Kramer, et al. Expires February 7, 2021 [Page 3]
169 |
170 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
171 |
172 |
173 | 2. PayID Easy Checkout URL Assembly
174 |
175 | 3.1. PayID Easy Checkout Discovery
176 |
177 | PayID Easy Checkout Discovery extends [PAYID-DISCOVERY] by defining a
178 | new link relation in the PayID metadata JRD returned by a PayID
179 | Discovery query. This link relation, defined in the JRD (Section 4)
180 | section of this specification, includes the URL on the sender's
181 | wallet that can be used to initiate a payment.
182 |
183 | Recipients who wish to initiate an Easy Checkout flow MUST first
184 | query the sender's PayID Discovery Server to obtain a PayID Easy
185 | Checkout URL. Therefore, PayID Discovery Servers that wish to enable
186 | PayID Easy Checkout MUST include an Easy Checkout JRD Link in all
187 | PayID Easy Checkout Discovery responses.
188 |
189 | Recipients SHOULD implement fallback measures to complete a checkout
190 | flow if a sender's wallet does not support PayID Easy Checkout.
191 |
192 | The following steps describe how a PayID Easy Checkout Client can
193 | query a PayID Discovery Server to obtain a PayID Easy Checkout URL.
194 |
195 | 3.1.1. Step 1: Assemble PayID Easy Checkout Discovery URL
196 |
197 | The process of assembling a PayID Discovery URL is defined in section
198 | 4.1.1 of [PAYID-DISCOVERY].
199 |
200 | 3.1.2. Step 2: Query PayID Easy Checkout Discovery URL
201 |
202 | The process of querying the PayID Discovery URL is defined in section
203 | 4.1.2 of [PAYID-DISCOVERY].
204 |
205 | Clients SHOULD implement fallback measures to complete checkout if
206 | the PayID Easy Checkout Discovery query fails.
207 |
208 | 3.1.3. Step 3: Parse PayID Easy Checkout Metadata
209 |
210 | If PayID Easy Checkout is supported, a PayID Discovery server MUST
211 | respond to discovery requests with an HTTP status code of "200" and a
212 | JSON payload containing a JRD with an Easy Checkout link relation.
213 |
214 | For example, a PayID Discovery Server might respond to a PayID
215 | Discovery query with the following payload:
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 | Kramer, et al. Expires February 7, 2021 [Page 4]
225 |
226 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
227 |
228 |
229 | {
230 | "subject": "payid:alice$wallet.com",
231 | "links": [
232 | {
233 | "rel" : "https://payid.org/ns/payid-easy-checkout-uri/1.0",
234 | "href": "https://wallet.com/checkout"
235 | }
236 | ]
237 | }
238 |
239 | A PayID Easy Checkout client MUST parse this response to find the
240 | PayID Easy Checkout Link. If the JRD returned from the PayID
241 | Discovery query does not contain a PayID Easy Checkout Link in its
242 | 'links' collection, PayID Easy Checkout is considered to have failed.
243 |
244 | However, if a PayID Easy Checkout URL can been obtained from the
245 | PayID Easy Checkout Link, PayID Easy Checkout Discovery is considered
246 | to be complete.
247 |
248 | 3.2. PayID Easy Checkout URL Assembly
249 |
250 | A PayID Easy Checkout URL represents the resource on a wallet that
251 | can be used by a sender to complete a payment. However, before
252 | directing a sender to their wallet, the recipient MUST append all of
253 | the query parameters defined in the following section
254 | (Section 3.2.1).
255 |
256 | Once a PayID Easy Checkout URL is assembled, PayID Easy Checkout is
257 | considered to be complete.
258 |
259 | 3.2.1. PayID Easy Checkout URL Query Parameters
260 |
261 | This specification defines several query parameter names and
262 | corresponding datatypes which MUST be added to the PayID Easy
263 | Checkout URL before redirecting a sender to their wallet. The PayID
264 | Easy Checkout URL SHOULD be parsed by the wallet in order to retrieve
265 | any values set by the recipient. It is RECOMMENDED that wallets use
266 | these values to pre-populate a payment transaction.
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | Kramer, et al. Expires February 7, 2021 [Page 5]
281 |
282 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
283 |
284 |
285 | +----------------+---------+----------------------------------------+
286 | | Name | Type | Description |
287 | +----------------+---------+----------------------------------------+
288 | | amount | integer | The amount that should be sent by the |
289 | | | | sender to the recipient. |
290 | | | | |
291 | | receiverPayId | string | The [PAYID-URI] of the receiver. |
292 | | | | |
293 | | assetCode | string | The currency code that denominates the |
294 | | | | amount as defined in [PAYID-PROTOCOL]. |
295 | | | | |
296 | | assetScale | short | Defines how many units make up one |
297 | | | | regular unit of the assetCode. |
298 | | | | |
299 | | paymentNetwork | string | The payment network, as defined in |
300 | | | | [PAYID-PROTOCOL], that the sender |
301 | | | | should use to send a payment. |
302 | | | | |
303 | | nextUrl | HTTP | A URL that the sender's wallet can |
304 | | | Url | navigate a sender to after the sender |
305 | | | string | completes a payment. |
306 | +----------------+---------+----------------------------------------+
307 |
308 | When adding values into a URI 'query' part as defined by [RFC3986],
309 | values with characters outside the character set allowed by query
310 | parameters in [RFC3986] MUST be percent or otherwise encoded.
311 |
312 | Protocols MAY define additional query parameter names and syntax
313 | rules, but MUST NOT change the meaning of the variables specified in
314 | this document.
315 |
316 | For example:
317 |
318 | Input: alice$wallet.com
319 | amount=10
320 | receiverPayId=pay$merchant.com
321 | assetCode=XRP
322 | assetScale=6
323 | network=XRPL
324 | nextUrl=https://merchant.com/thankyou
325 | PayID Easy Checkout URL: https://wallet.com/checkout
326 | Output: https://wallet.com/checkout?amount=100000&receiverPayId=payid%2Apay%24merchant.com&assetCode=XRP&assetScale=6&paymentNetwork=XRPL&nextUrl=https%3A%2F%2Fmerchant.com%2Fthankyou
327 |
328 | 4. PayID Easy Checkout JRDs
329 |
330 | This section defines the PayID Easy Checkout Link Relation, which
331 | conforms to section 4.4 of Webfinger [RFC7033].
332 |
333 |
334 |
335 |
336 | Kramer, et al. Expires February 7, 2021 [Page 6]
337 |
338 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
339 |
340 |
341 | The Link MUST include the Link Relation Type defined in PayID Easy
342 | Checkout URL (Section 6) in the object's 'rel' field. The Link MUST
343 | also include a PayID Easy Checkout URL in the 'href' field of the
344 | link.
345 |
346 | * 'rel': `https://payid.org/ns/payid-easy-checkout-uri/1.0`
347 | * 'href': {A PayID Easy Checkout URL}
348 |
349 | The following is an example of a PayID Easy Checkout Link:
350 |
351 | {
352 | "rel": "https://payid.org/ns/payid-easy-checkout-uri/1.0",
353 | "href": "https://wallet.com/checkout"
354 | }
355 |
356 | 5. Security Considerations
357 |
358 | Various security considerations should be taken into account for
359 | PayID Easy Checkout.
360 |
361 | The security considerations for PayID Easy Checkout Discovery are
362 | discussed in section 6 of [PAYID-DISCOVERY].
363 |
364 | 5.1. PayID Easy Checkout Redirection URI Manipulation
365 |
366 | When a sender uses the resource located at the PayID Easy Checkout
367 | URL, an attacker could manipulate the data encoded in the URL to
368 | trick the sender into sending a payment to a different PayID than was
369 | originally requested, or manipulate other parts of PayID Easy
370 | Checkout data to trick the sender.
371 |
372 | Additionally, if an attacker gains access to the merchant
373 | application, an attacker could replace the PayID Easy Checkout URL to
374 | execute a phishing or other attack.
375 |
376 | 5.2. Access Control
377 |
378 | As with all web resources, access to the PayID Discovery resource
379 | could require authentication. See section 6 of [RFC7033] for Access
380 | Control considerations.
381 |
382 | Furthermore, it is RECOMMENDED that PayID Discovery Servers only
383 | expose PayID Easy Checkout URLs which resolve to a protected resource
384 | (e.g., by logging into a wallet) before allowing access.
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 | Kramer, et al. Expires February 7, 2021 [Page 7]
393 |
394 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
395 |
396 |
397 | 6. IANA Considerations
398 |
399 | ## New Link Relation Types This document defines the following Link
400 | relation type per [RFC7033]. See section 3 for examples of each type
401 | of Link.
402 |
403 | ### PayID Easy Checkout URL
404 |
405 | * Relation Type ('rel'): `https://payid.org/ns/payid-easy-checkout-uri/1.0`
406 | * Media Type: `application/jrd+json`
407 | * Description: PayID Easy Checkout URL, version 1.0
408 |
409 | 7. Acknowledgments
410 |
411 | 8. Appendix
412 |
413 | 8.1. Motivation
414 |
415 | The PayID Easy Checkout Protocol aims to enable a consistent user
416 | experience for senders paying for goods or services by standardizing
417 | the interaction between merchants/non-profits and customer/donor
418 | wallets. Given the ability to assign arbitrary metadata to a PayID
419 | as defined in [PAYID-DISCOVERY], there is an opportunity to
420 | standardize the set of interactions between merchant and sender,
421 | specifically the process by which a merchant directs a sender to
422 | their digital wallet to complete a payment. The intention of this
423 | protocol is to enable an improved paying experience by reducing the
424 | number of steps a sender must take to complete a transaction.
425 |
426 | PayID Easy Checkout also limits the engineering effort needed to
427 | implement the protocol. Clients wishing to adopt this pattern should
428 | only need to implement UI-level changes in order to make the flow
429 | function as intended, which may aid in expanding overall adoption,
430 | further enhancing the protocol's user experience benefits.
431 |
432 | 8.1.1. Design Goals
433 |
434 | 8.1.1.1. Minimal effort for the Sender
435 |
436 | In order for a sender to checkout using the PayID Easy Checkout
437 | protocol, the sender only needs to provide a merchant with their
438 | PayID Easy Checkout enabled PayID.
439 |
440 | 8.1.1.2. No New Server-Side Software
441 |
442 | Apart from a PayID Discovery compliant PayID Discovery Server, The
443 | PayID Easy Checkout Protocol does not require server-side software to
444 | be run by either the sender or merchant for a payment. The PayID
445 |
446 |
447 |
448 | Kramer, et al. Expires February 7, 2021 [Page 8]
449 |
450 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
451 |
452 |
453 | Discovery Server is capable of providing details of where to send the
454 | sender via the PayID Discovery Protocol. Assuming the wallet used by
455 | the sender has implemented support in their UI for the PayID Easy
456 | Checkout Protocol, the sender can be redirected to their wallet to
457 | complete their transaction.
458 |
459 | 8.2. Example Usage
460 |
461 | This section shows a non-normative example of PayID Easy Checkout
462 | between a hypothetical merchant (recipient) and sender. The merchant
463 | accepts payments using the PayID pay$merchant.example.com, and the
464 | sender controls the PayID alice$wallet.example.com.
465 |
466 | 8.2.1. PayID Easy Checkout Initiation
467 |
468 | In this example, the sender might place some items in an online
469 | shopping cart on the merchant's web-site, then choose to checkout.
470 | The merchant would then render a form asking for the sender's PayID,
471 | as well as a "Checkout with PayID" button. Once the sender inputs
472 | their PayID "alice$wallet.example.com" and clicks the "Checkout with
473 | PayID" button, the merchant begins the PayID Easy Checkout flow.
474 |
475 | 8.2.2. PayID Easy Checkout Wallet Discovery
476 |
477 | The merchant UI would first assemble the PayID Easy Checkout URL as
478 | defined in PayID Easy Checkout Discovery (Section 3.1), yielding the
479 | URL "https://wallet.example.com/.well-known/
480 | webfinger?resource=payid%3Aalice%24wallet.example.com". The merchant
481 | UI would then query the assembled URL (Section 3.1.2).
482 |
483 | The HTTP request in this example would look like this:
484 |
485 | GET /.well-known/webfinger?resource=payid%3Aalice%24wallet.example.com
486 | Host: wallet.example.com
487 |
488 | If the sender's PayID Discovery Server has enabled PayID Easy
489 | Checkout in their wallet, the server would respond with something
490 | like this:
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 | Kramer, et al. Expires February 7, 2021 [Page 9]
505 |
506 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
507 |
508 |
509 | HTTP/1.1 200 OK
510 | Access-Control-Allow-Origin: *
511 | Content-Type: application/jrd+json
512 |
513 | {
514 | "subject" : "payid:alice$wallet.example.com",
515 | "links" :
516 | [
517 | {
518 | "rel": "https://payid.org/ns/payid-easy-checkout-uri/1.0",
519 | "template": "https://wallet.example.com/checkout"
520 | }
521 | ]
522 | }
523 |
524 | 8.2.3. Assemble PayID Easy Checkout URL with Query Parameters
525 |
526 | The merchant UI would parse the PayID Discovery response and iterate
527 | over the 'links' collection to find the link with the Relation Type
528 | of "https://payid.org/ns/payid-easy-checkout-uri/1.0". The merchant
529 | UI would then add all of the query parameters defined in PayID Easy
530 | Checkout URL Query Parameters (Section 3.2.1) to the URL included in
531 | the JRD Link. One query parameter of note is the "nextUrl"
532 | parameter, which allows the merchant to supply a redirect or callback
533 | URL for the sender's wallet to call once the sender has confirmed the
534 | payment. In this example, the merchant would like to display a
535 | "Thank You" page, and replaces "{nextUrl}" with
536 | "https://merchant.com/thankyou".
537 |
538 | 8.2.3.1. Correlating a Payment to an Invoice
539 |
540 | Merchants and non-profits will often need to correlate discrete
541 | layer-1 payments to an invoice or transaction entity in the
542 | merchants' native systems. The merchant in this example may have an
543 | invoice tracking system, on which an invoice gets created for the
544 | goods that the sender is buying, for example an invoice with a unique
545 | identifier of "1045464". A common practice for correlating layer-1
546 | payments to a specific transaction or invoice is to accept payments
547 | on a different layer-1 address for each invoice so that the merchant
548 | can listen for payments into that address and correlate the payment
549 | to the invoice. However, because the PayID Easy Checkout URL only
550 | provides the receiver's PayID, there is currently no way to associate
551 | the address that is given to the sender to the invoice.
552 |
553 | In order to accomplish this, a merchant could provide a unique PayID
554 | associated with an invoice, for example a PayID containing the
555 | invoice identifier, for each PayID Easy Checkout transaction. In
556 | this example, the merchant would first associate a payment address
557 |
558 |
559 |
560 | Kramer, et al. Expires February 7, 2021 [Page 10]
561 |
562 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
563 |
564 |
565 | with the invoice ID, and would then redirect the sender to their
566 | wallet with the "receiverPayId" query parameter set to "pay-
567 | 1045464$merchant.com". When the merchant PayID Server receives a
568 | query for the address associated with that PayID, they could return
569 | the previously stored payment address. When the merchant receives a
570 | payment to that address, they can then associate the layer 1 payment
571 | with the invoice.
572 |
573 | 8.2.4. Redirect Sender to Their Wallet
574 |
575 | Once the merchant UI populates the required query parameters in the
576 | URL template, the merchant UI redirects the sender to the Redirect
577 | URL so that the sender can confirm the payment.
578 |
579 | 8.2.5. Sender Confirms Payment
580 |
581 | After the sender clicks the "Pay with PayID" button the merchant's
582 | UI, and the merchant performs the previous steps, the sender will be
583 | redirected to the Redirect URL, which is a front end resource of the
584 | wallet. The wallet UI can read the query parameters from the
585 | Redirect URL and render a confirmation page or modal with all of the
586 | required fields pre-populated.
587 |
588 | Once the sender confirms the payment, the wallet would perform a
589 | PayID address lookup on the "receiverPayId" query parameter to get
590 | the payment address of the merchant and submit a transaction to the
591 | underlying ledger or payment system. The merchant can then redirect
592 | the user back to the URL specified in the "nextUrl" query parameter,
593 | which will display the "Thank You" page of the merchant.
594 |
595 | 9. References
596 |
597 | 9.1. Normative References
598 |
599 | [PAYID-DISCOVERY]
600 | Fuelling, D., "PayID Discovery", n.d..
601 |
602 | [PAYID-PROTOCOL]
603 | Schwartz, D., "PayID Protocol", n.d..
604 |
605 | [PAYID-URI]
606 | Fuelling, D., "The 'payid' URI Scheme", n.d.,
607 | .
608 |
609 | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
610 | Requirement Levels", BCP 14, RFC 2119,
611 | DOI 10.17487/RFC2119, March 1997,
612 | .
613 |
614 |
615 |
616 | Kramer, et al. Expires February 7, 2021 [Page 11]
617 |
618 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
619 |
620 |
621 | [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818,
622 | DOI 10.17487/RFC2818, May 2000,
623 | .
624 |
625 | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
626 | Resource Identifier (URI): Generic Syntax", STD 66,
627 | RFC 3986, DOI 10.17487/RFC3986, January 2005,
628 | .
629 |
630 | [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265,
631 | DOI 10.17487/RFC6265, April 2011,
632 | .
633 |
634 | [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.,
635 | and D. Orchard, "URI Template", RFC 6570,
636 | DOI 10.17487/RFC6570, March 2012,
637 | .
638 |
639 | [RFC7033] Jones, P., Salgueiro, G., Jones, M., and J. Smarr,
640 | "WebFinger", RFC 7033, DOI 10.17487/RFC7033, September
641 | 2013, .
642 |
643 | [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
644 | Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
645 | DOI 10.17487/RFC7231, June 2014,
646 | .
647 |
648 | [RFC7413] Cheng, Y., Chu, J., Radhakrishnan, S., and A. Jain, "TCP
649 | Fast Open", RFC 7413, DOI 10.17487/RFC7413, December 2014,
650 | .
651 |
652 | [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
653 | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
654 | .
655 |
656 | 9.2. Informative References
657 |
658 | [RFC5988] Nottingham, M., "Web Linking", RFC 5988,
659 | DOI 10.17487/RFC5988, October 2010,
660 | .
661 |
662 | 9.3. URIs
663 |
664 | [1] https://payid.org/
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 | Kramer, et al. Expires February 7, 2021 [Page 12]
673 |
674 | Internet-Draft Draft 1 - PayID Easy Checkout Protocol August 2020
675 |
676 |
677 | Authors' Addresses
678 |
679 | Noah Kramer
680 | Ripple
681 | 315 Montgomery Street
682 | San Francisco, CA 94104
683 | US
684 |
685 | Phone: -----------------
686 | Email: nkramer@ripple.com
687 | URI: https://www.ripple.com
688 |
689 |
690 | David Fuelling
691 | Ripple
692 | 315 Montgomery Street
693 | San Francisco, CA 94104
694 | US
695 |
696 | Phone: -----------------
697 | Email: fuelling@ripple.com
698 | URI: https://www.ripple.com
699 |
700 |
701 | Ian Simpson
702 | Ripple
703 | 315 Montgomery Street
704 | San Francisco, CA 94104
705 | US
706 |
707 | Phone: -----------------
708 | Email: isimpson@ripple.com
709 | URI: https://www.ripple.com
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 | Kramer, et al. Expires February 7, 2021 [Page 13]
729 |
--------------------------------------------------------------------------------
/dist/spec/payid-uri.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Network Working Group D. Fuelling
6 | Internet-Draft Ripple
7 | Intended status: Standards Track July 17, 2020
8 | Expires: January 18, 2021
9 |
10 |
11 | The 'payid' URI Scheme
12 | draft-fuelling-payid-uri-01
13 |
14 | Abstract
15 |
16 | This specification defines the 'payid' Uniform Resource Identifier
17 | (URI) scheme as a way to identify a payment account at a service
18 | provider.
19 |
20 | Feedback
21 |
22 | This specification is a draft proposal, and is part of the PayID
23 | Protocol [1] initiative. Feedback related to this document should be
24 | sent in the form of a Github issue at: https://github.com/payid-
25 | org/rfcs/issues.
26 |
27 | Status of This Memo
28 |
29 | This Internet-Draft is submitted in full conformance with the
30 | provisions of BCP 78 and BCP 79.
31 |
32 | Internet-Drafts are working documents of the Internet Engineering
33 | Task Force (IETF). Note that other groups may also distribute
34 | working documents as Internet-Drafts. The list of current Internet-
35 | Drafts is at https://datatracker.ietf.org/drafts/current/.
36 |
37 | Internet-Drafts are draft documents valid for a maximum of six months
38 | and may be updated, replaced, or obsoleted by other documents at any
39 | time. It is inappropriate to use Internet-Drafts as reference
40 | material or to cite them other than as "work in progress."
41 |
42 | This Internet-Draft will expire on January 18, 2021.
43 |
44 | Copyright Notice
45 |
46 | Copyright (c) 2020 IETF Trust and the persons identified as the
47 | document authors. All rights reserved.
48 |
49 | This document is subject to BCP 78 and the IETF Trust's Legal
50 | Provisions Relating to IETF Documents
51 | (https://trustee.ietf.org/license-info) in effect on the date of
52 | publication of this document. Please review these documents
53 |
54 |
55 |
56 | Fuelling Expires January 18, 2021 [Page 1]
57 |
58 | Internet-Draft The 'payid' URI Scheme July 2020
59 |
60 |
61 | carefully, as they describe your rights and restrictions with respect
62 | to this document. Code Components extracted from this document must
63 | include Simplified BSD License text as described in Section 4.e of
64 | the Trust Legal Provisions and are provided without warranty as
65 | described in the Simplified BSD License.
66 |
67 | Table of Contents
68 |
69 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
70 | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3
71 | 3. Definition . . . . . . . . . . . . . . . . . . . . . . . . . 3
72 | 4. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 3
73 | 5. Security Concerns . . . . . . . . . . . . . . . . . . . . . . 4
74 | 6. Internationalization Concerns . . . . . . . . . . . . . . . . 5
75 | 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 5
76 | 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 6
77 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 6
78 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 6
79 | 9.2. Informative References . . . . . . . . . . . . . . . . . 7
80 | 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 8
81 | Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 8
82 |
83 | 1. Introduction
84 |
85 | Various Uniform Resource Identifier (URI) schemes can be used to
86 | identify a user account at a service provider. However, no standard
87 | identifier exists to identify a user's _payment_ account at a service
88 | provider.
89 |
90 | While popular URIs could be re-used as payment account identifiers,
91 | these identifiers are insufficient because they are typically
92 | recognized as supporting functionality unique to those schemes. For
93 | example, the 'mailto' scheme [RFC6068] is broadly deployed for
94 | messaging. Re-using this identifier for payments would likely cause
95 | confusion because one desirable quality of a payment account
96 | identifier is that it expressly does not support messaging, in order
97 | to avoid spam and/or other security concerns such as phishing
98 | attacks.
99 |
100 | Deploying payment protocols on top of identifiers that are commonly
101 | employed for other use-cases would likely be a mis-use of those
102 | identifiers, and could also cause confusion for end-users, among
103 | other problems.
104 |
105 | Instead, the 'payid' scheme defines an identifier that is intended to
106 | identify accounts for payment use-cases only.
107 |
108 |
109 |
110 |
111 |
112 | Fuelling Expires January 18, 2021 [Page 2]
113 |
114 | Internet-Draft The 'payid' URI Scheme July 2020
115 |
116 |
117 | 2. Terminology
118 |
119 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
120 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
121 | "OPTIONAL" in this document are to be interpreted as described in
122 | [RFC2119].
123 |
124 | 3. Definition
125 |
126 | The syntax of the 'payid' URI scheme is defined in Section 7 of this
127 | document.
128 |
129 | A 'payid' URI identifies a payment account hosted at a service
130 | provider, and is designed for payment account identification rather
131 | than interaction, as discussed in section 1.2.2 of [RFC3986].
132 |
133 | A 'payid' URI is constructed by taking a user's payment account
134 | identifier at a service provider and using that value as the
135 | 'acctpart'. The 'host' portion is then set to the DNS domain name of
136 | the service provider that provides the 'payid'.
137 |
138 | To compare two 'payid' URIs, case normalization and percent-encoding
139 | normalization (as specified in sections 6.2.2.1 and 6.2.2.2 of
140 | [RFC3986]) MUST be employed before performing any comparison.
141 |
142 | In addition, a 'payid' is case-insensitive and therefore should be
143 | normalized to lowercase. For example, the URI
144 | "PAYID:aLICE$www.EXAMPLE.com" is equivalent to
145 | "payid:alice$www.example.com".
146 |
147 | Note that both the 'acctpart' and 'host' components of a 'payid' may
148 | contain one or more dollar-sign characters. However, because a
149 | 'host' SHOULD also be a valid DNS domain, that portion of a 'payid'
150 | will generally not include a dollar-sign. Therefore, applications
151 | SHOULD always search for the last dollar-sign when attempting to
152 | parse a 'payid' URI into its two component parts.
153 |
154 | 4. Examples
155 |
156 | As an example, a user with an account name of "apollo" at a wallet
157 | service "wallet.example.com" can be identified by a URI using the
158 | 'payid' scheme via the following construction:
159 |
160 | 'payid:apollo$wallet.example.com'
161 |
162 | One possible PayID scenario is for an account to be registered with a
163 | payment service provider using an identifier that is associated with
164 | some other service provider. For example, a user with the email
165 |
166 |
167 |
168 | Fuelling Expires January 18, 2021 [Page 3]
169 |
170 | Internet-Draft The 'payid' URI Scheme July 2020
171 |
172 |
173 | address "alice@example.net" might register with a wallet website
174 | whose domain name is "wallet.example.com". In order to facilitate
175 | payments to/from Alice, the wallet service provider might offer Alice
176 | a PayID using Alice's email address (though using an email address as
177 | a PayID is not recommended). In order to use Alice's email address
178 | as the 'acctpart' of the 'payid' URI, no percent-encoding is
179 | necessary because the 'acctpart' portion of a PayID allows for at-
180 | signs. Thus, the provisioned 'payid' URI for Alice would be
181 | "payid:alice@example.net$shoppingsite.example".
182 |
183 | Another possible scenario is where a payment service provider (e.g.,
184 | a digital wallet) provides its users with PayIDs that are associated
185 | with the PayIDs of another service provider. For example, a user
186 | with the PayID "alice$bank.example.net" might register with a wallet
187 | website whose domain name is "wallet.example.net". In order to use
188 | the bank's PayID as the acctpart of the wallet's 'payid' URI, no
189 | percent-encoding is necessary because the 'acctpart' portion of a
190 | PayID allows for dollar-signs. Therefore, the resulting 'payid' URI
191 | would be "payid:alice$bank.example$wallet.example".
192 |
193 | The following example URIs illustrate several variations of PayIDs
194 | and their common syntax components:
195 |
196 | payid:alice$example.net
197 |
198 | payid:john.doe$example.net
199 |
200 | payid:jane-doe$example.net
201 |
202 | 5. Security Concerns
203 |
204 | The 'payid' URI scheme defined in this document does not directly
205 | enable interaction with a user's payment account and therefore does
206 | not present any direct security concerns.
207 |
208 | However, a 'payid' URI indicates existence of a payment account, so
209 | care should be taken to properly secure any payment account
210 | interactions allowed by a service provider.
211 |
212 | In addition, service providers and users should consider whether an
213 | attacker might be able to derive or infer other identifiers
214 | correlating to the user of any particular PayID. For example,
215 | replacing the "$" character in a PayID with an "@" sign SHOULD NOT
216 | yield a 'mailto' URI, when possible. In addition, care should be
217 | taken when the 'acctpart' of a PayID corresponds to a user's email
218 | address (in part or in whole) as this might allow an attacker to
219 | execute phishing attacks or send spam messages.
220 |
221 |
222 |
223 |
224 | Fuelling Expires January 18, 2021 [Page 4]
225 |
226 | Internet-Draft The 'payid' URI Scheme July 2020
227 |
228 |
229 | Due to the use of percent-encoding in 'payid' URIs, implementers
230 | SHOULD disallow percent-encoded characters or sequences that would
231 | result in "space", "null", "control", or other characters that are
232 | otherwise forbidden.
233 |
234 | 6. Internationalization Concerns
235 |
236 | As specified in [RFC3986], the 'payid' URI scheme allows any
237 | character from the Unicode repertoire [UNICODE] encoded as UTF-8
238 | [RFC3629] and then percent-encoded into valid ASCII [RFC0020].
239 | Before applying any percent-encoding, an application MUST ensure the
240 | following about the string that is used as input to the URI-
241 | construction process:
242 |
243 | o The 'acctpart' consists only of Unicode code points that conform
244 | to the PRECIS IdentifierClass specified in [RFC8264].
245 |
246 | o The 'host' consists only of Unicode code points that conform to
247 | the rules specified in [RFC5892].
248 |
249 | o Internationalized domain name (IDN) labels are encoded as A-labels
250 | [RFC5890].
251 |
252 | 7. IANA Considerations
253 |
254 | In accordance with [RFC7595], this section provides the information
255 | needed to register the 'payid' URI scheme.
256 |
257 | *URI Scheme Name*: payid
258 |
259 | *Status*: permanent
260 |
261 | *URI Scheme Syntax*: The 'payid' URI syntax is defined here in
262 | Augmented Backus-Naur Form (ABNF) per [RFC5234], borrowing the 'host'
263 | and 'path' rules from [RFC3986]:
264 |
265 | payidURI = "payid" ":" acctpart "$" host
266 | acctpart = path
267 |
268 | Note that additional rules limit the characters that can be percent-
269 | encoded in a 'payid' URI. See "Encoding Considerations" below for
270 | more details.
271 |
272 | *URI Scheme Semantics*: The 'payid' URI scheme identifies payment
273 | accounts hosted at payment service providers. It is used only for
274 | identification, not interaction.
275 |
276 | *Encoding Considerations*: See Section 6 of this document.
277 |
278 |
279 |
280 | Fuelling Expires January 18, 2021 [Page 5]
281 |
282 | Internet-Draft The 'payid' URI Scheme July 2020
283 |
284 |
285 | *Applications/Protocols That Use This URI Scheme Name*: The following
286 | protocols utilize this URI scheme:
287 |
288 | - [PAYID-DISCOVERY][],
289 | - [PAYID-PROTOCOL][],
290 | - [VERIFIABLE-PAYID][].
291 |
292 | *Interoperability Considerations*: n/a.
293 |
294 | *Security Considerations*: See Section 6 of this document.
295 |
296 | *Contact*: rfcs@payid.org
297 |
298 | *Author/Change Controller*: TBD.
299 |
300 | *References*: None.
301 |
302 | 8. Acknowledgements
303 |
304 | This document was adapted from and heavily influenced by [RFC7565],
305 | modifying it (in some cases only slightly) for a payments use-case.
306 | The author would like to acknowledge the contributions of everyone
307 | who worked on that and related specifications.
308 |
309 | In addition, the author would like to acknowledge everyone who
310 | provided feedback and use-cases for this derivative specification.
311 |
312 | 9. References
313 |
314 | 9.1. Normative References
315 |
316 | [PAYID-DISCOVERY]
317 | Fuelling, D., "The PayID Discovery Protocol", n.d.,
318 | .
319 |
320 | [PAYID-PROTOCOL]
321 | Malhotra, A. and D. Schwartz, "PayID Protocol", n.d.,
322 | .
323 |
324 | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
325 | Requirement Levels", BCP 14, RFC 2119,
326 | DOI 10.17487/RFC2119, March 1997,
327 | .
328 |
329 | [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
330 | 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
331 | 2003, .
332 |
333 |
334 |
335 |
336 | Fuelling Expires January 18, 2021 [Page 6]
337 |
338 | Internet-Draft The 'payid' URI Scheme July 2020
339 |
340 |
341 | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
342 | Resource Identifier (URI): Generic Syntax", STD 66,
343 | RFC 3986, DOI 10.17487/RFC3986, January 2005,
344 | .
345 |
346 | [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
347 | Specifications: ABNF", STD 68, RFC 5234,
348 | DOI 10.17487/RFC5234, January 2008,
349 | .
350 |
351 | [RFC5890] Klensin, J., "Internationalized Domain Names for
352 | Applications (IDNA): Definitions and Document Framework",
353 | RFC 5890, DOI 10.17487/RFC5890, August 2010,
354 | .
355 |
356 | [RFC5892] Faltstrom, P., Ed., "The Unicode Code Points and
357 | Internationalized Domain Names for Applications (IDNA)",
358 | RFC 5892, DOI 10.17487/RFC5892, August 2010,
359 | .
360 |
361 | [RFC8264] Saint-Andre, P. and M. Blanchet, "PRECIS Framework:
362 | Preparation, Enforcement, and Comparison of
363 | Internationalized Strings in Application Protocols",
364 | RFC 8264, DOI 10.17487/RFC8264, October 2017,
365 | .
366 |
367 | [UNICODE] Consortium, T. U., "The Unicode Standard", n.d.,
368 | .
369 |
370 | [VERIFIABLE-PAYID]
371 | Malhotra, A. and D. Schwartz, "Verifiable PayID Protocol",
372 | n.d., .
373 |
374 | 9.2. Informative References
375 |
376 | [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80,
377 | RFC 20, DOI 10.17487/RFC0020, October 1969,
378 | .
379 |
380 | [RFC5988] Nottingham, M., "Web Linking", RFC 5988,
381 | DOI 10.17487/RFC5988, October 2010,
382 | .
383 |
384 | [RFC6068] Duerst, M., Masinter, L., and J. Zawinski, "The 'mailto'
385 | URI Scheme", RFC 6068, DOI 10.17487/RFC6068, October 2010,
386 | .
387 |
388 |
389 |
390 |
391 |
392 | Fuelling Expires January 18, 2021 [Page 7]
393 |
394 | Internet-Draft The 'payid' URI Scheme July 2020
395 |
396 |
397 | [RFC7033] Jones, P., Salgueiro, G., Jones, M., and J. Smarr,
398 | "WebFinger", RFC 7033, DOI 10.17487/RFC7033, September
399 | 2013, .
400 |
401 | [RFC7565] Saint-Andre, P., "The 'acct' URI Scheme", RFC 7565,
402 | DOI 10.17487/RFC7565, May 2015,
403 | .
404 |
405 | [RFC7595] Thaler, D., Ed., Hansen, T., and T. Hardie, "Guidelines
406 | and Registration Procedures for URI Schemes", BCP 35,
407 | RFC 7595, DOI 10.17487/RFC7595, June 2015,
408 | .
409 |
410 | 9.3. URIs
411 |
412 | [1] https://payid.org/
413 |
414 | Author's Address
415 |
416 | David Fuelling
417 | Ripple
418 | 315 Montgomery Street
419 | San Francisco, CA 94104
420 | US
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 | Fuelling Expires January 18, 2021 [Page 8]
449 |
--------------------------------------------------------------------------------
/dist/spec/payid-uri.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ]>
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | The 'payid' URI Scheme
30 |
31 |
32 | Ripple
33 |
34 |
35 | 315 Montgomery Street
36 | San Francisco
37 | CA
38 | 94104
39 | US
40 |
41 |
42 |
43 |
44 |
45 |
46 | security
47 |
48 |
49 |
50 |
51 |
52 |
53 | This specification defines the 'payid' Uniform Resource Identifier (URI)
54 | scheme as a way to identify a payment account at a service provider.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | This specification is a draft proposal, and is part of the
65 | PayID Protocol initiative. Feedback related to this
66 | document should be sent in the form of a Github issue at:
67 | https://github.com/payid-org/rfcs/issues.
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | Various Uniform Resource Identifier (URI) schemes can be used to
80 | identify a user account at a service provider. However, no standard
81 | identifier exists to identify a user's payment account at a service
82 | provider.
83 |
84 | While popular URIs could be re-used as payment account identifiers,
85 | these identifiers are insufficient because they are typically recognized
86 | as supporting functionality unique to those schemes. For example, the
87 | 'mailto' scheme is broadly deployed for messaging. Re-using
88 | this identifier for payments would likely cause confusion because one
89 | desirable quality of a payment account identifier is that it expressly
90 | does not support messaging, in order to avoid spam and/or other security
91 | concerns such as phishing attacks.
92 |
93 | Deploying payment protocols on top of identifiers that are commonly
94 | employed for other use-cases would likely be a mis-use of those
95 | identifiers, and could also cause confusion for end-users, among other
96 | problems.
97 |
98 | Instead, the 'payid' scheme defines an identifier that is intended to
99 | identify accounts for payment use-cases only.
100 |
101 |
102 |
103 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
104 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
105 | "OPTIONAL" in this document are to be interpreted as described in
106 | .
107 |
108 |
109 |
110 | The syntax of the 'payid' URI scheme is defined in Section 7 of this
111 | document.
112 |
113 | A 'payid' URI identifies a payment account hosted at a service provider,
114 | and is designed for payment account identification rather than
115 | interaction, as discussed in section 1.2.2 of .
116 |
117 | A 'payid' URI is constructed by taking a user's payment account identifier
118 | at a service provider and using that value as the 'acctpart'. The 'host'
119 | portion is then set to the DNS domain name of the service provider that
120 | provides the 'payid'.
121 |
122 | To compare two 'payid' URIs, case normalization and percent-encoding
123 | normalization (as specified in sections 6.2.2.1 and 6.2.2.2 of
124 | ) MUST be employed before performing any comparison.
125 |
126 | In addition, a 'payid' is case-insensitive and therefore should be
127 | normalized to lowercase. For example, the URI
128 | "PAYID:aLICE$www.EXAMPLE.com" is equivalent to
129 | "payid:alice$www.example.com".
130 |
131 | Note that both the 'acctpart' and 'host' components of a 'payid' may
132 | contain one or more dollar-sign characters. However, because a 'host'
133 | SHOULD also be a valid DNS domain, that portion of a 'payid' will
134 | generally not include a dollar-sign. Therefore, applications SHOULD
135 | always search for the last dollar-sign when attempting to parse a 'payid'
136 | URI into its two component parts.
137 |
138 |
139 |
140 | As an example, a user with an account name of "apollo" at a wallet
141 | service "wallet.example.com" can be identified by a URI using the 'payid'
142 | scheme via the following construction:
143 |
144 |
147 |
148 | One possible PayID scenario is for an account to be registered with a
149 | payment service provider using an identifier that is associated with some
150 | other service provider. For example, a user with the email address
151 | "alice@example.net" might register with a wallet website whose domain
152 | name is "wallet.example.com". In order to facilitate payments to/from
153 | Alice, the wallet service provider might offer Alice a PayID using Alice's
154 | email address (though using an email address as a PayID is not
155 | recommended). In order to use Alice's email address as the 'acctpart' of
156 | the 'payid' URI, no percent-encoding is necessary because the 'acctpart'
157 | portion of a PayID allows for at-signs. Thus, the provisioned 'payid' URI
158 | for Alice would be "payid:alice@example.net$shoppingsite.example".
159 |
160 | Another possible scenario is where a payment service provider (e.g., a
161 | digital wallet) provides its users with PayIDs that are associated with
162 | the PayIDs of another service provider. For example, a user with the
163 | PayID "alice$bank.example.net" might register with a wallet website whose
164 | domain name is "wallet.example.net". In order to use the bank's PayID
165 | as the acctpart of the wallet's 'payid' URI, no percent-encoding is
166 | necessary because the 'acctpart' portion of a PayID allows for
167 | dollar-signs. Therefore, the resulting 'payid' URI would be
168 | "payid:alice$bank.example$wallet.example".
169 |
170 | The following example URIs illustrate several variations of PayIDs and
171 | their common syntax components:
172 |
173 |
180 |
181 |
182 |
183 | The 'payid' URI scheme defined in this document does not directly enable
184 | interaction with a user's payment account and therefore does not present
185 | any direct security concerns.
186 |
187 | However, a 'payid' URI indicates existence of a payment account, so
188 | care should be taken to properly secure any payment account interactions
189 | allowed by a service provider.
190 |
191 | In addition, service providers and users should consider whether an
192 | attacker might be able to derive or infer other identifiers correlating
193 | to the user of any particular PayID. For example, replacing the $
194 | character in a PayID with an @ sign SHOULD NOT yield a 'mailto' URI,
195 | when possible. In addition, care should be taken when the 'acctpart' of
196 | a PayID corresponds to a user's email address (in part or in whole) as this
197 | might allow an attacker to execute phishing attacks or send spam messages.
198 |
199 | Due to the use of percent-encoding in 'payid' URIs, implementers SHOULD
200 | disallow percent-encoded characters or sequences that would result in
201 | "space", "null", "control", or other characters that are otherwise
202 | forbidden.
203 |
204 |
205 |
206 | As specified in , the 'payid' URI scheme allows any character
207 | from the Unicode repertoire encoded as UTF-8 and
208 | then percent-encoded into valid ASCII . Before applying any
209 | percent-encoding, an application MUST ensure the following about the
210 | string that is used as input to the URI-construction process:
211 |
212 |
213 | The 'acctpart' consists only of Unicode code points that conform to
214 | the PRECIS IdentifierClass specified in .
215 | The 'host' consists only of Unicode code points that conform to the
216 | rules specified in .
217 | Internationalized domain name (IDN) labels are encoded as A-labels
218 | .
219 |
220 |
221 |
222 |
223 | In accordance with , this section provides the information
224 | needed to register the 'payid' URI scheme.
225 |
226 | URI Scheme Name: payid
227 |
228 | Status: permanent
229 |
230 | URI Scheme Syntax: The 'payid' URI syntax is defined here in Augmented
231 | Backus-Naur Form (ABNF) per , borrowing the 'host' and 'path'
232 | rules from :
233 |
234 |
238 |
239 | Note that additional rules limit the characters that can be
240 | percent-encoded in a 'payid' URI. See "Encoding Considerations" below for
241 | more details.
242 |
243 | URI Scheme Semantics: The 'payid' URI scheme identifies payment
244 | accounts hosted at payment service providers. It is used only for
245 | identification, not interaction.
246 |
247 | Encoding Considerations: See Section 6 of this document.
248 |
249 | Applications/Protocols That Use This URI Scheme Name: The following
250 | protocols utilize this URI scheme:
251 |
252 |
257 |
258 | Interoperability Considerations: n/a.
259 |
260 | Security Considerations: See Section 6 of this document.
261 |
262 | Contact: rfcs@payid.org
263 |
264 | Author/Change Controller: TBD.
265 |
266 | References: None.
267 |
268 |
269 |
270 | This document was adapted from and heavily influenced by ,
271 | modifying it (in some cases only slightly) for a payments use-case. The
272 | author would like to acknowledge the contributions of everyone who worked
273 | on that and related specifications.
274 |
275 | In addition, the author would like to acknowledge everyone who provided
276 | feedback and use-cases for this derivative specification.
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 | &RFC2119;
288 | &RFC3629;
289 | &RFC3986;
290 | &RFC5234;
291 | &RFC5890;
292 | &RFC5892;
293 | &RFC8264;
294 |
295 |
296 | The PayID Discovery Protocol
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 | PayID Protocol
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 | Verifiable PayID Protocol
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 | The Unicode Standard
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 | &RFC0020;
343 | &RFC5988;
344 | &RFC6068;
345 | &RFC7033;
346 | &RFC7565;
347 | &RFC7595;
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
443 |
444 |
445 |
446 |
--------------------------------------------------------------------------------
/java/README.md:
--------------------------------------------------------------------------------
1 | # PayID Java Test Harness
2 | This folder contains a Java implementation of a PayID, in addition to a
3 | test harness that validates the JSON test vectors.
4 |
5 | NOTE that the PayID code in this project will eventually be moved to xpring4j
6 | , but the test-harness and test-vectors will continue to live in this RFC.
7 |
8 | ## Running Tests
9 | 1. Install [Maven](https://maven.apache.org/) and a [JDK](https://www.oracle.com/java/technologies/javase-downloads.html).
10 | 1. Execute this command: `mvn clean install` in the folder holding this
11 | README file.
12 |
--------------------------------------------------------------------------------
/java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | PayID :: Core
8 | Core libraries for PayID.
9 | org.payid
10 | payid-core
11 | HEAD-SNAPSHOT
12 | jar
13 |
14 | https://github.com/xpring-eng/rfcs/java
15 | 2017
16 |
17 |
18 |
19 | The Apache Software License, Version 2.0
20 | http://www.apache.org/licenses/LICENSE-2.0.txt
21 | repo
22 |
23 |
24 |
25 |
26 | 1.8
27 | 1.8
28 | UTF-8
29 | UTF-8
30 | UTF-8
31 | 2.10.3
32 | 4.2.0
33 |
34 |
35 |
36 |
37 | com.fasterxml.jackson.core
38 | jackson-databind
39 |
40 |
41 | com.google.guava
42 | guava
43 |
44 |
45 | junit
46 | junit
47 | test
48 |
49 |
50 | org.immutables
51 | value
52 | provided
53 |
54 |
55 | org.assertj
56 | assertj-core
57 | test
58 |
59 |
60 | com.squareup.okhttp3
61 | okhttp
62 | test
63 |
64 |
65 |
66 |
67 |
68 | com.fasterxml.jackson.core
69 | jackson-databind
70 | ${jackson.version}
71 |
72 |
73 | com.google.guava
74 | guava
75 | 28.1-android
76 |
77 |
78 | junit
79 | junit
80 | 4.12
81 | test
82 |
83 |
84 | org.immutables
85 | value
86 | 2.8.3
87 | provided
88 |
89 |
90 | org.assertj
91 | assertj-core
92 | 3.13.2
93 | test
94 |
95 |
96 | com.squareup.okhttp3
97 | okhttp
98 | ${okhttp.version}
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/java/src/main/java/org/payid/AbstractPayId.java:
--------------------------------------------------------------------------------
1 | package org.payid;
2 |
3 | import static java.lang.String.format;
4 |
5 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
7 | import com.google.common.base.Preconditions;
8 | import org.immutables.value.Value;
9 | import org.immutables.value.Value.Check;
10 |
11 | import java.util.regex.Matcher;
12 | import java.util.regex.Pattern;
13 |
14 | /**
15 | * An abstract implementation of {@link PayId} for use by Immutables.
16 | */
17 | @Value.Immutable
18 | @JsonSerialize(as = ImmutablePayId.class)
19 | @JsonDeserialize(as = ImmutablePayId.class)
20 | abstract class AbstractPayId implements PayId {
21 |
22 | private static final String ALPHA = "a-zA-Z";
23 | private static final String DIGIT = "0-9";
24 | private static final String UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~";
25 | private static final String SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=";
26 | private static final String PERCENT = "\\%";
27 |
28 | // Note: These regex's don't enforce any ordering or format for things like IP address, etc. They merely define
29 | // allowed characters in a PayID. A PayID must be dereferenced in order to determine if it's a valid host
30 | // per RFC-3986.
31 |
32 | // ACCOUNT (allowed-chars)
33 | private static final String ALLOWED_ACCOUNT_CHARS = UNRESERVED + SUB_DELIMS + PERCENT + ":@/";
34 | private static final String ALLOWED_ACCOUNT_CHARS_REGEX = "^([" + ALLOWED_ACCOUNT_CHARS + "]+)*$";
35 |
36 | // HOST (allowed-chars)
37 | // IP-literal / IPv4address / reg-name
38 | private static final String HEX_DIGITS = "[[:xdigit:]]";
39 | private static final String IPV4_ADDRESS = DIGIT + "."; // Hex is already allowed via IP_LITERAL
40 | private static final String IPV6_ADDRESS = ":\\." + HEX_DIGITS;
41 | // reg-name syntax allows percent-encoded octets in order to represent non-ASCII registered names in a uniform way
42 | // that is independent of the underlying name resolution technology
43 | private static final String REG_NAME = UNRESERVED + PERCENT + SUB_DELIMS;
44 |
45 | // IPVFUTURE and IP_LITERAL are not accounted for.
46 | private static final String ALLOWED_HOST_CHARS = IPV4_ADDRESS + IPV6_ADDRESS + REG_NAME;
47 | private static final String ALLOWED_HOST_CHARS_REGEX = "^([" + ALLOWED_HOST_CHARS + "]+)*$";
48 |
49 | // Regex
50 | private static final Pattern ACCOUNT_PATTERN = Pattern.compile(ALLOWED_ACCOUNT_CHARS_REGEX);
51 | private static final Pattern HOST_PATTERN = Pattern.compile(ALLOWED_HOST_CHARS_REGEX);
52 |
53 | // For upper-casing HEX
54 | private static final Pattern PERCENT_ENCODED_PATTERN = Pattern.compile("(%[0-9a-fA-F][0-9a-fA-F])");
55 |
56 | /**
57 | * For a String {@code input}, find any lower-cased percent-encoded values (e.g., %3a) and upper-case them (e.g., %3A)
58 | * in order to conform to the rules of RFC-3986.
59 | *
60 | * @param input A {@link String} that might have percent-encoded triplets.
61 | *
62 | * @return A {@link String} with any percent-encoded triplets normalized to upper-case form.
63 | *
64 | * @see "https://tools.ietf.org/html/rfc3986#section-6.2.2.1"
65 | */
66 | static String upperCasePercentEncoded(String input) {
67 | // Upper-case any percent-encoded triplets (e.g., `%3a` -> `%3A`).
68 | final Matcher matcher = PERCENT_ENCODED_PATTERN.matcher(input);
69 |
70 | final StringBuffer result = new StringBuffer();
71 | while (matcher.find()) {
72 | matcher.appendReplacement(result, matcher.group().toUpperCase());
73 | }
74 | matcher.appendTail(result);
75 |
76 | String returnable = result.toString();
77 | return returnable;
78 | }
79 |
80 | /**
81 | * Validate a PayID per the rules defined in the PayID RFC.
82 | *
83 | * @return A normalized and valid {@link AbstractPayId}.
84 | */
85 | @Check
86 | AbstractPayId validate() {
87 |
88 | // Verify Account
89 | Preconditions.checkArgument(
90 | ACCOUNT_PATTERN.matcher(this.account()).matches(),
91 | format("PayID 'account' for `%s` has an invalid value.", this.toString())
92 | );
93 |
94 | // Verify Host
95 | Preconditions.checkArgument(HOST_PATTERN.matcher(this.host()).matches(),
96 | format("PayID 'host' for `%s` has an invalid value.", this.toString()));
97 |
98 | return this;
99 | }
100 |
101 | @Override
102 | public String toString() {
103 | return PAYID_SCHEME + account() + "$" + host();
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/java/src/main/java/org/payid/PayId.java:
--------------------------------------------------------------------------------
1 | package org.payid;
2 |
3 | import static java.lang.String.format;
4 | import static org.payid.AbstractPayId.upperCasePercentEncoded;
5 |
6 | import com.google.common.base.Preconditions;
7 | import org.immutables.value.Value.Default;
8 |
9 | import java.util.Locale;
10 | import java.util.Objects;
11 |
12 | /**
13 | * A standardized identifier for payment accounts.
14 | *
15 | * @see "https://github.com/xpring-eng/rfcs/blob/master/TBD.md"
16 | */
17 | public interface PayId {
18 |
19 | String PAYID_SCHEME = "payid:";
20 |
21 | static ImmutablePayId.Builder builder() {
22 | return ImmutablePayId.builder();
23 | }
24 |
25 | /**
26 | *
Parses a PayId URI string into a @{code PayId}, applying normalization rules defined in the PayID RFC.
27 | *
28 | *
Normalization includes the following:
29 | *
30 | *
31 | *
Lower-case the scheme, if present.
32 | *
Lower-case the accountpart
33 | *
Lower-case the host
34 | *
For any hex-encoded String, upper-case the Hexadecimal letters (e.g., 'f' -> 'F')
35 | *
36 | *
37 | * @param value text of a complete PayID.
38 | *
39 | * @return A valid {@link PayId}.
40 | *
41 | * @throws NullPointerException if {@code value} is null.
42 | * @throws IllegalArgumentException if {@code value} cannot be properly parsed or has invalid characters per the PayID
43 | * RFC.
44 | */
45 | static PayId of(String value) {
46 | Objects.requireNonNull(value, "PayID must not be null");
47 | if (value.toLowerCase(Locale.ENGLISH).startsWith(PAYID_SCHEME)) {
48 | value = value.substring(6);
49 | } else {
50 | throw new IllegalArgumentException(format("PayID `%s` must start with the 'payid:' scheme", value));
51 | }
52 |
53 | if (!value.contains("$")) {
54 | throw new IllegalArgumentException(format("PayID `%s` must contain a $", value));
55 | } else {
56 | Preconditions
57 | .checkArgument(value.length() > 6, format("PayID `%s` must specify a valid account and host", value));
58 | }
59 |
60 | int lastDollar = value.lastIndexOf("$");
61 | String account = value.substring(0, lastDollar);
62 | String host = value.substring(lastDollar + 1);
63 |
64 | // NOTE: This implementation purposefully does not percent-encode any invalid characters because we don't want to
65 | // be too proscriptive around which encoding scheme should be used. Thus, it is assumed that only valid characters
66 | // are initially supplied to a PayID, and that software encodes properly to the PayID-allowed character set before
67 | // contruction.
68 |
69 | // NORMALIZATION: Capitalization
70 | account = account.toLowerCase(Locale.ENGLISH);
71 | host = host.toLowerCase(Locale.ENGLISH);
72 |
73 | // NORMALIZATION: Percent-encoding
74 | account = upperCasePercentEncoded(account);
75 | host = upperCasePercentEncoded(host);
76 |
77 | final ImmutablePayId.Builder builder = builder();
78 | if (account.length() > 0) {
79 | builder.account(account);
80 | }
81 |
82 | builder.host(host);
83 |
84 | return builder.build();
85 | }
86 |
87 | /**
88 | * A payment account identifier defined in the `payid-uri` RFC.
89 | *
90 | * @return A {@link String} containing the 'path' portion of this PayId.
91 | */
92 | @Default
93 | default String account() {
94 | return "";
95 | }
96 |
97 | /**
98 | * A host as defined defined in the `payid-uri` RFC.
99 | *
100 | * @return A {@link String} containing the 'host' portion of this PayId.
101 | */
102 | String host();
103 | }
104 |
--------------------------------------------------------------------------------
/java/src/test/java/org/payid/PayIdInvalidValuesTest.java:
--------------------------------------------------------------------------------
1 | package org.payid;
2 |
3 | import org.junit.Rule;
4 | import org.junit.Test;
5 | import org.junit.rules.ExpectedException;
6 | import org.junit.runner.RunWith;
7 | import org.junit.runners.Parameterized;
8 | import org.junit.runners.Parameterized.Parameters;
9 |
10 | import java.util.Arrays;
11 | import java.util.Collection;
12 | import java.util.Objects;
13 |
14 | /**
15 | * Unit tests for {@link PayId}.
16 | */
17 | @RunWith(Parameterized.class)
18 | public class PayIdInvalidValuesTest {
19 |
20 | @Rule
21 | public ExpectedException expectedException = ExpectedException.none();
22 |
23 | private String sourcepayid;
24 | private Class exceptionClassToExpect;
25 | private String exceptionMessageToExpect;
26 |
27 | public PayIdInvalidValuesTest(
28 | final String sourcepayid, final Class exceptionToExpect, final String exceptionMessageToExpect
29 | ) {
30 | this.sourcepayid = sourcepayid;
31 | this.exceptionClassToExpect = Objects.requireNonNull(exceptionToExpect);
32 | this.exceptionMessageToExpect = exceptionMessageToExpect;
33 | }
34 |
35 | /**
36 | * The data for this test...
37 | */
38 | @Parameters
39 | public static Collection