Even though PayID is an incredibly simple protocol, some of the design decisions make it hard to host a PayID payload as a static file in a way that follows the protocol. Most of the problems stem from the use of headers, which a static JSON file cannot set. We should revisit those design decisions to see if we can iterate PayID to a place where it’s easy to use static files.
Currently, PayID Versioning happens at a few places:
A required request header of “PayID-Version: X.Y” specifying a version of PayID for the response payload. A required response header of “PayID-Version: A.B” specifying the version of PayID of the response. An optional (but recommended) header of “PayID-Server-Version: C.D” specifying the latest version of the PayID Protocol the server supports.
Add a new field in the response payload of “version”. This field can exist in a static file, or be set by a server. That allows us to evolve the PayID Protocol response payload in a way that is compatible with static files.
{
"payId": "alice$example.com",
"version": "1.1",
"addresses": [...]
}
In PayID 2.0, we would deprecate and remove the PayID-Version response header, and make this the only way to communicate PayID versions in a response.
If we still want the ability to advertise the latest version of the PayID Protocol the server knows how to respond with, we can move that to a “Web Host Metadata” JRD as described in RFC 6415, similar to using WebFinger for PayID Discovery. Whether or not we end up using Web Host Metadata, we can deprecate and remove the PayID-Server-Version response header.
Finally, a static JSON file won’t be able to do version negotiation. That is fine for the “simple” use case, but if we want a server that can do version negotiation, we need some way to do that. We could add new links to the WebFinger JRD that would allow a PayID server to serve up different versioned representations of the same PayID information. That lets us deprecate and remove the PayID-Version request header. If a server chooses not to implement the WebFinger JRD, it would be assumed that they are responding with PayID 2.0.
Currently, an Accept request header of the form “application/{paymentNetwork}-{environment}+json” is required, and the Content-Type response header is required to match the {paymentNetwork}-{environment} of the response.
A PayID request must now use only ‘Accept: “application/payid+json”’ The response should only set a Content-Type header of “application/json” or “application/payid+json” which are equivalent.
This will allow hosting static JSON files as valid PayIDs, and by deprecating the Accept headers entirely, we can just rely on the paymentNetwork and environment fields on an address payload, and the client can just filter the list of addresses to the desired subset.
Currently it is required for a PayID response to include a Cache-Control: no-store header.
Downgrade this from a MUST to a SHOULD in the spec, and remove the “no-store” requirement, perhaps explaining why you would want to use “no-store” (address rotation on every request).
CORS is particularly hard for PayID because we use custom request and response headers, which make CORS requests subject to a “preflight” check. By deprecating and eventually removing all the custom version headers, we can remove the “preflight” check and make PayIDs more accessible from the browser.
The only recommended CORS header now will be “Access-Control-Allow-Origin: *”, to allow PayID requests to come from the browser.
In PayID 1.0, the sender is setting their preference of payment network by using the Accept header, but there is no way for the recipient to indicate which network/currency they would most like to receive. We are eliminating the Accept header on the request, but since it is ultimately up to the sender which currency / payment network they send value with, they still have the capability to pick their preference.
By adding a “weight” field to each address, in PayID 2.0 it will now be possible for the recipient to set a preference for each address. The weight parameter will be a number from 0.0 to 1.0.
{
"paymentNetwork": "XRPL",
"environment": "MAINNET",
"weight": 1.0,
"addressDetailsType": "CryptoAddressDetails",
"addressDetails": {
"address": "rNsVR42JDDxVewSJrxwUaaTa41tsyMHmDa"
}
}
In PayID 1.0, there is a limitation of one address per network. In PayID 2.0, we can lift this restriction, because we will now have the weight field for the recipient to indicate address preference.
Multiple addresses pair really nicely with features that are out-of-scope for the PayID Protocol, but may be optionally implemented by any PayID Provider, such as PayID Aliases.
Yes. I'm open to that idea, but there are trade-offs, which is why
verifiedAddresses
is a separate field in the payload right now. For some languages (and as a developer) it's easier if all the items in an array have the same object shape. By splitting the two, it makes it easier to parse each individually.If we add a
weight
parameter in PayID 2.0, then having the same network/environment pairing in both fields becomes less of an issue (although you still do have to parse through both arrays).