Payment Method Manifest

Living Document,

Issue Tracking:
GitHub
Editors:
Dapeng Liu (Alibaba)
Domenic Denicola (Google)
Zach Koch (Google)

Abstract

This specification defines the machine-readable manifest file, known as a payment method manifest, describing how a payment method participates in the Web Payments ecosystem, and how such files are to be used.

Status of this document

This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.

1. Introduction

This section and its sub-sections are non-normative.

1.1. Use cases

This specification intends to address the following use cases:

This is accomplished via the requirement that every payment method whose identifier is a URL will provide a payment method manifest file in JSON format containing two key pieces of information:

1.2. Accessing the manifest

The resource identified by the payment method identifier URL does not directly contain the machine-readable payment method manifest. It is often a generic URL (such as "https://alicepay.com/") which is more suitable for human-readable content. Instead, a HTTP Link header is used to direct user agents seeking out the payment method manifest toward another location. [RFC5988]

For an example payment method AlicePay, with payment method identifier "https://alicepay.com/", a user agent might issue a request to that payment method identifier URL as follows:

HEAD / HTTP/2
Host: alicepay.com
User-Agent: Mellblomenator/9000

The server would then respond:

HTTP/2 204
Link: </pay/payment-manifest.json>; rel="payment-method-manifest"

1.3. Example manifest file

Continuing our example from §1.2 Accessing the manifest, the AlicePay payment method could provide the following payment method manifest file at https://alicepay.com/pay/payment-manifest.json:

{
  "default_applications": ["https://alicepay.com/pay/app/webappmanifest.json"],
  "supported_origins": [
    "https://bobpay.xyz",
    "https://alicepay.friendsofalice.example"
  ]
}

This indicates that, if the user agent does not have a payment app for AlicePay installed, it can locate one by consulting the web app manifest at "https://alicepay.com/pay/app/webappmanifest.json".

It also indicates that, apart from this default payment app, AlicePay also allows payment apps hosted at the two indicated origins to be used for AlicePay. This means that if the user agent ever encounters payment apps hosted at those origins claiming support for AlicePay, it can allow them to act as payment apps for the AlicePay payment method.

The manifest file could also omit the "supported_origins" key, if no third-party payment apps are supported for the payment method in question, or it could use the value "*" instead of an array of origins, to indicate that any third party is allowed to support the payment method.

2. Manifest format

A valid payment method manifest file is a UTF-8 encoded file containing contents parseable as a JSON object. The resulting JSON object must contain at most two items, with the possible keys "default_applications" and "supported_origins".

The value of the default_applications key, if present, must be a non-empty JSON array. Each item in the array must be an absolute-URL string such that the resulting parsed URL's scheme is "https".

The value of the supported_origins key, if present, must be either the string "*", or a non-empty JSON array. In the latter case, each item in the array must be an absolute-URL string that represents an HTTPS origin. Formally, the string must be equal to the serialization of the resulting parsed URL's origin.

Web developers must ensure that all of their payment method manifests are valid.

As with all conformance requirements on the contents of files, these are web-developer facing, and not implementer-facing. The exact processing model (given in §3 Processing model) governs how implementers process all payment method manifest files, including invalid ones.

The following payment method manifest is not valid, but the currently-specified processing model algorithms will still accept it:
{
  "default_applications": ["https://alicepay.com/pay/app/webappmanifest.json"],
  "created_by": "Alice",
  "created_in": "Wonderland"
}

This could change in the future, for example if the processing model later expands to define a meaning for a new standard "created_by" key that requires it to be an object instead of a string. To avoid situations like this, web developers are best served by ensuring validity of their payment method manifests, and thus avoiding any unpleasant surprises.

3. Processing model

3.1. Ingesting payment method manifests

A user agent is expected to receive, from various sources, a list of payment method identifiers. A notable source is as the first parameter to the PaymentRequest(methodData, details, options) constructor, but other sources are possible, in a user-agent specific manner.

A user agent could scan locally-installed payment apps on the device to see which payment methods they support.

A user agent could have built-in support for certain payment methods as a result of out-of-band arrangements.

Given such a list of payment method identifiers identifiers, the user agent may at any time run the following steps, to ingest payment method manifests:

  1. Fetch payment method manifests, given identifiers, and wait for this to asynchronously complete with manifestsMap. If the result is failure, return.

  2. For each identifiermanifest of manifestsMap:

    1. Let parsed be the result of validating and parsing manifest. If this returns failure, continue.

    2. For each url in parsed’s default applications:

      1. Fetch the web app manifest at url, and wait for it to asynchronously complete with webAppManifestString. If the result is failure, continue.

      2. Let webAppManifest be the result of running the steps for processing a web app manifest given webAppManifestString.

        The steps for processing a web app manifest are very forgiving and will return empty objects or objects missing crucial fields instead of failing. User agents will need to separately validate the processed web app manifest to ensure it contains enough data for their purposes in the next step.

      3. In a user-agent-specific way, use the resulting processed web app manifest webAppManifest to install any applicable payment apps for the payment method identified by identifier.

        In the future, the plan is for there to be a user-agent-independent way to use the resulting processed web app manifest, by consulting its serviceworker field and using that to install a web-based payment app conforming to the Payment Handler API specification. [PAYMENT-HANDLER]

    3. Associate the supported origins to identifier so that the user agent can use it in the future to determine what third-party payment apps can be displayed for the payment method identified by identifier.

3.2. Fetching payment method manifests

To fetch payment method manifests, given a list of JavaScript strings supportedMethods, perform the following steps. This algorithm will asynchronously complete with a map (possibly empty) from URLs to byte sequences, mapping payment method identifiers to the contents of the corresponding manifest.

  1. Let identifierURLs be an empty list.

  2. For each string of supportedMethods:

    1. Let identifierURL be the result of basic URL parsing string. If the result is failure, continue.

    2. If identifierURL’s scheme is not "https", continue.

    3. Append identifierURL to identifierURLs.

  3. Let manifestsMap be an empty map.

  4. For each identifierURL of identifierURLs:

    1. Let identifierRequest be a new request whose method is `HEAD`, url is identifierURL, client is null, credentials mode is "omit", and redirect mode is "error".

    2. Fetch identifierRequest. To process response with the response identifierResponse:

      1. If identifierResponse is a network error or identifierResponse’s status is not an ok status, continue.

      2. Let linkHeaders be the result of extracting header list values given `Link` and identifierResponse’s header list.

      3. Let manifestURLString be null.

      4. For each linkHeader of linkHeaders:

        1. Parse linkHeader according to the link-value production. If it cannot be parsed, continue. [RFC5988]

        2. If the parsed header contains a parameter whose name is an ASCII case-insensitive match for the string "rel" and whose value is an ASCII case-insensitive match for the string "payment-method-manifest", then set manifestURLString to the string given by the URI-Reference production in the parsed header, and break.

      5. If manifestURLString is not null, then:

        1. Let manifestURL be the result of basic URL parsing manifestURLString with base URL given by identifierResponse’s url. If the result is failure, continue.

        2. If manifestURL’s scheme is not "https", continue.

        3. Let manifestRequest be a new request whose url is manifestURL, client is null, credentials mode is "omit", and redirect mode is "error".

        4. Fetch manifestRequest. To process response end-of-body with the response manifestResponse:

          1. If manifestResponse is a network error or manifestResponse’s status is not an ok status, continue.

          2. Let body be manifestResponse’s body.

          3. If body is null, continue.

          4. Let reader be the result of getting a reader from body.

          5. Let promise be the result of reading all bytes from body with reader.

          6. Upon fulfillment of promise with a byte sequence bytes, set manifestsMap[identifierURL] to bytes.

  5. Once all ongoing fetch algorithms initiated by the above steps are complete, including the specified process response and process response end-of-body steps, asynchronously complete this algorithm with manifestsMap.

3.3. Validating and parsing payment method manifests

A parsed payment method manifest is a struct containing two fields:

default applications

An ordered set of URLs, possibly empty

supported origins

Either the string "*", or an ordered set of origins

To validate and parse a byte sequence bytes purporting to contain a payment method manifest, perform the following steps. The result will either be a parsed payment method manifest, or failure.

  1. Let parsed be the result of parsing JSON from bytes given bytes, in a user-agent defined JavaScript realm. If this throws an exception, return failure.

  2. If Type(parsed) is not Object, return failure.

  3. Let defaultApps be an empty ordered set.

  4. Let defaultAppsValue be Get(parsed, "default_applications").

  5. If defaultAppsValue is not undefined:

    1. If IsArray(defaultAppsValue) is false, return failure.

    2. Let defaultAppsList be CreateListFromArrayLike(defaultAppsValue, « String »). If this throws an exception, return failure.

    3. If the size of defaultAppsList is 0, return failure.

    4. For each defaultAppString in defaultAppsList:

      1. Let defaultAppURL be the result of basic URL parsing defaultAppString. If the result is failure, return failure.

      2. If defaultAppURL’s scheme is not "https", return failure.

      3. Append defaultAppURL to defaultApps.

  6. Let supportedOrigins be an empty ordered set.

  7. Let supportedOriginsValue be Get(parsed, "supported_origins").

  8. If supportedOriginsValue is "*", set supportedOrigins to "*".

  9. Otherwise, if supportedOriginsValue is not undefined:

    1. If IsArray(supportedOriginsValue) is false, return failure.

    2. Let supportedOriginsList be CreateListFromArrayLike(supportedOriginsValue, « String »). If this throws an exception, return failure.

    3. If the size of supportedOriginsList is 0, return failure.

    4. For each supportedOriginString in supportedOriginsList:

      1. Let supportedOriginURL be the result of basic URL parsing supportedOriginString. If the result is failure, return failure.

      2. If supportedOriginURL’s scheme is not "https", return failure.

      3. If supportedOriginURL’s username or password are not the empty string, return failure.

      4. If supportedOriginURL’s path's size is not 0, return failure.

      5. If supportedOriginURL’s query or fragment are not null, return failure.

      6. Append supportedOriginURL’s origin to supportedOrigins.

  10. Return a new parsed payment method manifest with default applications given by defaultApps and supported origins given by supportedOrigins.

Empty arrays for "default_applications" or "supported_origins" will cause parsing to fail. That is, this is not a valid payment method manifest, and will be rejected by the above algorithm:
{
  "default_applications": ["https://alicepay.com/pay/app/webappmanifest.json"],
  "supported_origins": []
}

3.4. Fetching web app manifests

Because the determination of payment apps happens independent of any embedding HTML document, the procedure for obtaining a web app manifest that gives information about a default payment app is different from the usual steps for obtaining a web app manifest.

To fetch the web app manifest for a default payment app, given a URL url, perform the following steps. This algorithm will asynchronously complete with either a scalar value string or failure.

  1. Let request be a new request whose url is url, client is null, credentials mode is "omit", and redirect mode is "error".

  2. Fetch request. To process response end-of-body with the response response:

    1. If response is a network error or response’s status is not an ok status, asynchronously complete this algorithm with failure.

    1. Let body be response’s body.

    2. If body is null, asynchronously complete this algorithm with failure.

    3. Let reader be the result of getting a reader from body.

    4. Let promise be the result of reading all bytes from body with reader.

    5. Upon fulfillment of promise with a byte sequence bytes, asynchronously complete this algorithm with the result of UTF-8 decoding bytes.

    6. Upon rejection of promise, asynchronously complete this algorithm with failure.

4. Security and privacy considerations

w3c/payment-method-manifest/1Should these fetches have a client? (impacts CSP, CORS, ...)
w3c/payment-method-manifest/7Privacy considerations of retrieving a payment method manifest
w3c/payment-method-manifest/11Matching payment apps and security in a world of payment method manifests

5. IANA considerations

This registration is for community review and will be submitted to the IESG for review, approval, and registration with IANA.

Relation name

payment-method-manifest

Description

Links to a payment method manifest, which describes a specific payment method within the Web Payments ecosystem.

Reference

https://w3c.github.io/payment-method-manifest/

Notes

See §3.2 Fetching payment method manifests for the specific manner in which such links are expected to be fetched, and §3.1 Ingesting payment method manifests for the larger context in which they are used.

Acknowledgments

§3 Processing model is based heavily on algorithms originally outlined by Rouslan Solomakhin.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[APPMANIFEST]
Marcos Caceres; et al. Web App Manifest. URL: https://w3c.github.io/manifest/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PAYMENT-METHOD-ID]
Adrian Bateman; et al. Payment Method Identifiers. URL: https://w3c.github.io/payment-method-id/
[PAYMENT-REQUEST]
Adrian Bateman; et al. Payment Request API. URL: https://w3c.github.io/payment-request/
[PROMISES-GUIDE]
Domenic Denicola. Writing Promise-Using Specifications. 16 February 2016. Finding of the W3C TAG. URL: https://www.w3.org/2001/tag/doc/promises-guide
[RFC5988]
M. Nottingham. Web Linking. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/

Informative References

[PAYMENT-HANDLER]
Adrian Hope-Bailie; et al. Payment Handler API. URL: https://w3c.github.io/payment-handler/