Payment Method: Basic Card

W3C Working Draft

This version:
https://www.w3.org/TR/2019/WD-payment-method-basic-card-20190403/
Latest published version:
https://www.w3.org/TR/payment-method-basic-card/
Latest editor's draft:
https://w3c.github.io/payment-method-basic-card/
Test suite:
https://w3c-test.org/payment-method-basic-card/
Previous version:
https://www.w3.org/TR/2019/WD-payment-method-basic-card-20190330/
Editors:
Marcos Cáceres (Mozilla)
Domenic Denicola (Google)
Zach Koch (Google)
Roy McElmurry (Facebook)
Former editor:
Adrian Bateman (Microsoft Corporation)
Participate:
GitHub w3c/payment-method-basic-card
File a bug
Commit history
Pull requests

Abstract

This specification describes data structures and formats, and a simple processing model, to facilitate card-based payments on the Web. It is used by other specifications to facilitate monetary transactions with a "basic-card", such as credit, debit, or prepaid card.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This is a work in progress.

This document was published by the Web Payments Working Group as a Working Draft.

GitHub Issues are preferred for discussion of this specification.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. The group does not expect this document to become a W3C Recommendation. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

1. Introduction

This section is non-normative.

This specification defines the "basic-card" payment method for use, for instance, with the Payment Request API. With it, merchants can request the card details (card holder name, card number, etc.) from the end user as an alternative to collecting the same information through a form.

The basic card payment method provides information to merchant websites that can be used for multiple transactions over a potentially very long period of time, typically on the order of several years at a time. At the time of the development of this specification, it is commonplace for merchant sites to store this information long-term to reduce the friction of a user entering a credit card number for every future purchase.

The decision whether to retain credit card information for future transactions remains a matter of local policy for web sites; however, the introduction of a programmatic way to retrieve credit card information from a web browser affects some key factors that typically motivate storage of such information.

Because the web browser will retain credit card information, and make it available – subject to user approval – whenever a merchant needs it, the friction that merchants seek to avoid is reduced. This can also potentially reduce some liability considerations of storing information on a persistent basis, such as financial liability that can result from unauthorized access to the databases used to store credit card information.

Additionally, web sites that call the Payment Request API for each transaction avoid the friction that can result when users’ credit card numbers and/or expiration dates are updated. From a user’s perspective, this avoids the hassle of having to update a large number of merchant web sites any time they are issued a new card.

Finally, by letting the web browser determine user authentication information, the merchant site is relieved of the duty of ensuring that a time-local and sufficiently strong authentication has occurred. Additionally, payment handlers can make use of local affordances, such as biometrics and hardware tokens, to authenticate users in a way that is more convenient, more secure, and lower friction than web sites currently can.

2. Payment Method Identifier

The standardized payment method identifier (PMI) for this specification is "basic-card".

3. Model

A card is a physical or virtual payment instrument that has details and optionally is part of a network.

The details of a card are the primary account number (PAN) [ISO7812-1], card holder's name, security code (sometimes known as the CVV, CVC, CVN, CVE or CID), expiry month, expiry year, and optionally a billing address. These are represented as the members of the BasicCardResponse dictionary.

A card is identified as belonging to a network via its issuer identification number [ISO7812-1] (e.g., those belonging to Visa start with a "4"). In an API, each network is represented by a string from the Card Network Identifiers Approved for use with Payment Request API.

Note: Common issuer identification numbers (IIN)

A supported card is a card that when passed to the steps to check if an instrument is supported together with a list of networks returns true.

A payment handler's known networks are networks it supports. A payment handler MAY support zero or more networks from the Card Network Identifiers Approved for use with Payment Request API.

4. BasicCardRequest dictionary

dictionary BasicCardRequest {
  sequence<DOMString> supportedNetworks = [];
};

The BasicCardRequest dictionary contains the following members:

supportedNetworks
A sequence of identifiers for card networks that the merchant accepts, derived from the Card Network Identifiers Approved for use with Payment Request API. When the sequence is empty, it means that all networks are supported.

5. Interfacing with a payment request

5.1 Steps to check if a payment can be made

The steps to check if a payment can be made take a BasicCardRequest request as input. The steps return either true or false:

  1. Let cards be a list of cards associated with this payment handler.
  2. If cards is empty, return false.
  3. Let networks be an empty DOMString sequence.
  4. If request.supportedNetworks is present, append each item in request.supportedNetworks to networks.
  5. For each card in cards:
    1. Let isSupported be the result of running the steps to check if an instrument is supported, passing in card and networks.
    2. If isSupported is true, then return true.
  6. Return false.

5.2 Steps to check if an instrument is supported

The steps to check if an instrument is supported take as input a card card and a list of network networks. It returns true if the card is supported, false otherwise.

  1. If networks is empty, return true.
  2. If networks includes the card's network, return true. Otherwise, return false.

5.3 Steps to respond to a payment request

The steps to respond to a payment request are given by the following algorithm. The steps take PaymentRequest request as input. If the end user inputs or selects a card that meets the constraints of BasicCardRequest data the algorithm returns a card as a BasicCardResponse.

  1. Let networks be data.supportedNetworks, or an empty list if data.supportedNetworks is missing.
  2. Let card be a newly created BasicCardResponse dictionary.
  3. Set card.cardNumber to a user provided, or otherwise generated, string of digits of length between 10 to 19 items representing the primary account number.
  4. While the steps to check if an instrument is supported with card, networks returns false, ask the user to correct the card's details. Only when the card is a supported card, continue.
  5. If the card supports a card holder's name and the user chooses provide it, set card.cardholderName to the card holder's name.
  6. If the card supports a security code and the user chooses provide it, set card.cardSecurityCode to a three or more digit string.
  7. If the card supports an expiry month and the user chooses to provide it, set card.expiryMonth to two-digit string ranging from "01" to "12".
  8. If the card supports an expiry year and the user chooses provide it, set card.expiryYear to a four-digit string in the range "0000" to "9999".
  9. If request.[[options]]["requestBillingAddress"] is true, or, optionally, the user agent determines that payment is taking place in region where validation of billing addresses against an address verification system is the norm:
    1. Let redactList be at least « "addressLine", "organization", "phone", "recipient" ».
    2. Set card.billingAddress to the result of running the steps to create a PaymentAddress from user-provided input with redactList.
  10. Optionally, validate card's details to make sure they adhere to any additional network requirements and assist the user in fixing any issues encountered.

    Note: Validation of inputs

    The validation a user agent performs on the card's details is a quality of implementation detail and outside the scope of this specification. There is nevertheless an expectation that user agents will make a best effort to check that a card number is valid as per the Luhn algorithm [ISO7812-1], check the length is correct , check that the issuer identification number is correct for the selected network, check that the expiry date on the card hasn't lapsed, and so on.

  11. Return card.

5.4 Steps for when a user changes payment method

Note

When the end user explicitly switches from one card to another, these steps cause an event to fire in the Payment Request API. The algorithm presupposes that the user agent is only presenting supported cards to the end user, by having filtered out unsupported cards based on the initiating payment request's BasicCardRequest's supportedNetworks values.

The steps for when a user changes payment method are as follows. The steps take PaymentRequest request as input. To mitigate fingerprinting concerns, the user agent MUST NOT run these steps unless a user explicitly switches to a different card by performing some user action (e.g., by selecting a different card explicitly from a list of cards). For cards that are preselected by default by the user agent, any matching PaymentDetailsModifiers apply instead (without the need to run these steps).

  1. Let methodDetails be a newly created BasicCardChangeDetails dictionary.
  2. From the supported cards presented to the end user, let card be the card the user selects.
  3. If request.[[options]]["requestBillingAddress"] is true:
    1. Let redactList be at least « "addressLine", "organization", "phone", "recipient" ».

      Note: Privacy of recipient information

      The redactList optionally gives user agents the possibility to limit the amount of personal information about the recipient that the API shares with the merchant.

      For merchants, the resulting PaymentAddress object provides enough information to, for example, calculate tax, but, in most cases, not enough information to physically locate and uniquely identify the payer.

      Unfortunately, even with the redactList recipient anonymity cannot be assured. This is because in some countries postal codes are so fine-grained that they can uniquely identify a recipient.

    2. Set billingAddress to the result of running the steps to create a PaymentAddress from user-provided input with redactList
    3. Optionally, redact billingAddress.postalCode to make it more privacy preserving, but providing enough detail so that, for example, it can still be used to calculate tax.
  4. Set methodDetails.billingAddress to billingAddress.
  5. Run request's payment method changed algorithm with methodDetails and "basic-card".
  6. Let networkIdentifier be the network of the selected instrument.
  7. If updateWith() was called, apply the modifiers using request and networkIdentifier.

5.4.1 BasicCardChangeDetails dictionary

dictionary BasicCardChangeDetails {
  PaymentAddress? billingAddress = null;
};
billingAddress member
If the merchant requested the billing address, a redacted PaymentAddress that represents the billing address associated with the card. If the merchant does not request the billing address, it's null.

5.5 Selecting the payment handler

Note

In the case where a payment request is made with multiple applicable PaymentMethodDatas, this algorithm selects the last applicable [[serializedMethodData]] whose PMI is "basic-card". (i.e., "the last one wins").

Example 1: Last one wins
  const methodData = [
  // This one matches, but is ignored since one the follows also matches.
  {
    supportedMethods: "basic-card",
    data: {
      supportedNetworks: ["visa", "mastercard"],
    },
  },
  // ✅ This second one gets used!
  {
    supportedMethods: "basic-card",
    data: {
      supportedNetworks: ["visa"],
    },
  },
  // This one gets skipped, because it's not applicable to
  // basic card.
  {
    supportedMethods: "https://example.com/bobpay",
  },
];

// See above for which methodData gets picked.
await new PaymentRequest(methodData, details, options).show();

The steps for selecting the payment handler are given by the following algorithm. These steps run when a payment UI is first presented to the end-user, as a successful call to a PaymentRequest's show() method. The steps take a PaymentRequest request.

  1. Let restrictions be a newly created BasicCardRequest.
  2. For each pair (DOMString id / string data of request.[[serializedMethodData]] in reverse order:
    1. If id is not "basic-card", continue.
    2. Let object be result of JSON-parsing data
    3. If object is null, break.
    4. Otherwise, set restrictions be the result of converting object into a BasicCardRequest.
    5. Break.
  3. Apply restrictions's supportedNetworks member to constrain the card type inputs of the payment UI. When the sequence is empty, it means that all networks are supported.
  4. If a payment instrument is selected by default, apply the modifiers using request and passing the identifier for network of the selected instrument.

5.6 Applying the modifiers

The steps to apply the modifiers are given by the following algorithm. It takes a PaymentRequest request and a string networkIdentifier that identifies a network:

  1. Let index be the length of request.[[serializedModifierData]].
  2. Let restrictions be a newly created BasicCardRequest.
  3. For each pair (DOMString id / string data) of request[[serializedModifierData]] in reverse order:
    1. Decrement index by 1.
    2. If id is not "basic-card", continue.
    3. Let object be result of JSON-parsing data
    4. If object is null, break.
    5. Let bcRequest be the result of converting object to BasicCardRequest.
    6. If bcRequest's supportedNetworks is zero length, or supportedNetworks includes networkIdentifier
      1. Set restriction to bcRequest
      2. Break.
  4. Let modifier be the PaymentMethodModifier from request.[[details]].modifiers at index.
  5. If modifier.total is present, update the presented UI with the updated total.
  6. If modifier.additionalDisplayItems is present, update the presented UI with the additional display items.

6. BasicCardResponse dictionary

dictionary BasicCardResponse {
  required DOMString cardNumber;
  DOMString cardholderName = "";
  DOMString cardSecurityCode = "";
  DOMString expiryMonth = "";
  DOMString expiryYear = "";
  PaymentAddress? billingAddress = null;
};
cardholderName member
The card holder's name as it appears on the card.
cardNumber member
The primary account number for the card as a string of digits that ranges from 10 to 19 digits.
expiryMonth member
A two-digit string for the expiry month of the card in the range "01" to "12".
expiryYear member
A four-digit string for the expiry year of the card in the range "0000" to "9999".
cardSecurityCode member
A three or more digit string for the security code of the card.
billingAddress member
A PaymentAddress that represents the billing address associated with the card, or null.

7. BasicCardErrors dictionary

When retrying a request for payment, a developer can pass a BasicCardErrors dictionary for the value of the PaymentValidationErrors's paymentMethod member.

dictionary BasicCardErrors {
  DOMString cardNumber;
  DOMString cardholderName;
  DOMString cardSecurityCode;
  DOMString expiryMonth;
  DOMString expiryYear;
  AddressErrors billingAddress;
};
cardholderName member
Validation error for the card holder's name.
cardNumber member
Validation error for the primary account number for the card.
expiryMonth member
Validation error for the expiry month of the card.
expiryYear member
Validation error for the expiry year of the card.
cardSecurityCode member
Validation error for the security code of the card.
billingAddress member
A AddressErrors dictionary that represents validation errors with the billing address associated with the card.

8. Dependencies

This specification relies on WebIDL definitions defined in other specifications.

Payment Request API
The PaymentAddress interface, PaymentMethodData dictionary, PaymentMethodModifier dictionary, PaymentRequest interface, PaymentMethodChangeEvent interface and its methodDetails attribute, and the AddressErrors dictionary are defined in [payment-request].
WebIDL
The DOMString type is defined in [WebIDL].

9. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, and MUST NOT are to be interpreted as described in [RFC2119].

There is only one class of product that can claim conformance to this specification: a payment handler.

A conforming payment handler MUST:

10. Security and Privacy Considerations

This section is non-normative.

Due to differences in quality of implementation and the end user's ability to input data into unconstrained input fields, merchants are expected to revalidate all BasicCardResponse returned by APIs that make use of this specification.

In particular, merchants need to treat the values of any details with the same scrutiny that they would apply to a [HTML] input element, by, for example, sanitizing all the members of a BasicCardResponse before rendering them anywhere.

Depending on jurisdiction, users of this specification (implementers, merchants, payment processors, etc.) can be subject to Payment Card Industry Data Security Standard Compliance (PCI DSS) or other regulations. Discussion of those considerations are outside the scope of this document.

A. IDL Index

dictionary BasicCardRequest {
  sequence<DOMString> supportedNetworks = [];
};

dictionary BasicCardChangeDetails {
  PaymentAddress? billingAddress = null;
};

dictionary BasicCardResponse {
  required DOMString cardNumber;
  DOMString cardholderName = "";
  DOMString cardSecurityCode = "";
  DOMString expiryMonth = "";
  DOMString expiryYear = "";
  PaymentAddress? billingAddress = null;
};

dictionary BasicCardErrors {
  DOMString cardNumber;
  DOMString cardholderName;
  DOMString cardSecurityCode;
  DOMString expiryMonth;
  DOMString expiryYear;
  AddressErrors billingAddress;
};

B. References

B.1 Normative references

[card-network-ids]
Card Network Identifiers Approved for use with Payment Request API. W3C. URL: https://www.w3.org/Payments/card-network-ids
[ecma-262]
ECMAScript Language Specification. Ecma International. URL: https://tc39.github.io/ecma262/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[ISO7812-1]
Identification cards - Identification of issuers - Part 1: Numbering system. ISO/IEC 7812-1: Identification cards - Identification of issuers - Part 1. 1 January 2017. ISO 7812-1:2017. URL: https://www.iso.org/standard/70484.html
[payment-method-id]
Payment Method Identifiers. Marcos Caceres; Domenic Denicola; Zach Koch; Roy McElmurry; Adrian Bateman. W3C. 27 March 2019. W3C Candidate Recommendation. URL: https://www.w3.org/TR/payment-method-id/
[payment-request]
Payment Request API. Adrian Bateman; Zach Koch; Roy McElmurry; Domenic Denicola; Marcos Caceres. W3C. 30 August 2018. W3C Candidate Recommendation. URL: https://www.w3.org/TR/payment-request/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WebIDL]
Web IDL. Boris Zbarsky. W3C. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/

B.2 Informative references

[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/