Copyright © 2017 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
This specification standardizes an API to allow merchants (i.e. web sites selling physical or digital goods) to utilize one or more payment methods with minimal integration. User agents (e.g., browsers) facilitate the payment flow between merchant and user.
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/.
The working group maintains a list of all bug reports that the group has not yet addressed. Pull requests with proposed specification text for outstanding issues are strongly encouraged.
The deadline for comments for Candidate Recommendation is 31 October 2017.
If you wish to make comments regarding this document, please raise them as GitHub issues. Only send comments by email if you are unable to raise issues on GitHub (see links below). All comments are welcome.
The working group will demonstrate implementation experience by producing an implementation report. The report will show two or more independent implementations passing each mandatory test in the test suite (i.e., each test the corresponds to a MUST requirement of the specification).
There has been no change in dependencies on other workings groups during the development of this specification.
This document was published by the Web Payments Working Group as a Candidate Recommendation. This document is intended to become a W3C Recommendation. W3C publishes a Candidate Recommendation to indicate that the document is believed to be stable and to encourage implementation by the developer community. This Candidate Recommendation is expected to advance to Proposed Recommendation no earlier than 31 October 2017.
Please see the Working Group's implementation report.
Publication as a Candidate Recommendation 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 5 February 2004 W3C Patent Policy. 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 2017 W3C Process Document.
As this specification enters the Candidate Recommendation phase of the W3C standardization process, the working group has identified the following feature(s) as being "at risk" of being removed from the specification. The working group seeks input from implementers, developers, and the general public on whether these features should remain in the specification. If no compelling use cases are received, or if there is limited interest from implementers, these features will be removed from the specification before proceeding along the W3C Recommendation track.
currencySystem (see
                    issue
            490).
                This section is non-normative.
This specification describes an API that allows user agents (e.g., browsers) to act as an intermediary between three parties in a transaction:
The details of how to fulfill a payment request for a given payment method are handled by payment handlers. In this specification, these details are left up to the user agent, but future specifications may expand on the processing model in more detail.
This API also enables web sites to take advantage of more secure payment schemes (e.g., tokenization and system-level authentication) that are not possible with standard JavaScript libraries. This has the potential to reduce liability for the merchant and helps protect sensitive user information.
This section is non-normative.
            In order to use the API, the developer needs to provide and keep track of a number of key pieces of information. These bits of information are passed to the PaymentRequest            constructor as arguments, and subsequently used to update the payment request being displayed to the user. Namely, these bits of information are:
        
PaymentMethodDatas that represents the payment methods                that the site supports (e.g., "we support card-based payments, but only Visa and MasterCard credit cards.").
            PaymentDetailsInit dictionary. This includes total cost, and optionally a list of goods or services being purchased, for physical goods, and shipping
                options. Additionally, it can optionally include "modifiers" to how payments are made. For example, "if you pay with a credit card of type X, it incurs a US$3.00 processing fee".
            PaymentOptions that the site needs to deliver the good or service (e.g., for physical goods, the merchant will typically need an physical address to
                ship to. For digital goods, an email will usually suffice).
            
            Once a PaymentRequest is constructed, it's presented to the end user via the show()            method. The show() returns a promise that, once the user confirms request for payment, results in a
            PaymentResponse.
        
methodData argument
            
                The methodData sequence contains PaymentMethodData dictionaries containing the payment method identifiers for the
                payment methods that the web site accepts and any associated
                payment method specific data.
            
const methodData = [
  {
    supportedMethods: "basic-card",
    data: {
      supportedNetworks: ["visa", "mastercard"],
      supportedTypes: ["debit", "credit"],
    },
  },
  {
    supportedMethods: "https://example.com/bobpay",
    data: {
      merchantIdentifier: "XXXX",
      bobPaySpecificField: true,
    },
  },
];
            details argument
            The details contains information about the transaction that the user is being asked to complete, such as the line items in an order.
const details = {
  id: "super-store-order-123-12312",
  displayItems: [
    {
      label: "Sub-total",
      amount: { currency: "USD", value: "55.00" },
    },
    {
      label: "Sales Tax",
      amount: { currency: "USD", value: "5.00" },
    },
  ],
  total: {
    label: "Total due",
    amount: { currency: "USD", value: "65.00" },
  },
};
            Here we see an example of how to add two shipping options to the details.
const shippingOptions = [
  {
    id: "standard",
    label: "🚛 Ground Shipping (2 days)",
    amount: { currency: "USD", value: "5.00" },
    selected: true,
  },
  {
    id: "drone",
    label: "🚀 Drone Express (2 hours)",
    amount: { currency: "USD", value: "25.00" }
  },
];
Object.assign(details, { shippingOptions });
                Here we see how to add a processing fee for using a credit card. Notice that it requires recalculating the total.
// Credit card incurs a $3.00 processing fee.
const creditCardFee = {
  label: "Credit card processing fee",
  amount: { currency: "USD", value: "3.00" },
};
// Modifiers apply when the user chooses to pay with
// a credit card.
const modifiers = [
  {
    additionalDisplayItems: [creditCardFee],
    supportedMethods: "basic-card",
    total: {
      label: "Total due",
      amount: { currency: "USD", value: "68.00" },
    },
    data: {
      supportedTypes: "credit",
    },
  },
];
Object.assign(details, { modifiers });
                options argument
            The options dictionary contains information the developer needs from the user to perform the payment (e.g., the payer's name and shipping address).
const options = {
  requestPayerEmail: false,
  requestPayerName: true,
  requestPayerPhone: false,
  requestShipping: true,
}
            PaymentRequest
            
                Having gathered all the prerequisite bits of information, we can now construct a PaymentRequest and request that the browser present it to the user:
            
async function doPaymentRequest() {
  try {
    const request = new PaymentRequest(methodData, details, options);
    // See below for a detailed example of handling these events
    request.onshippingaddresschange = ev => ev.updateWith(details);
    request.onshippingoptionchange = ev => ev.updateWith(details);
    const response = await request.show();
    await validateResponse(response);
  } catch (err) {
    // AbortError, SecurityError
    console.error(err);
  }
}
async function validateResponse(response) {
  try {
    if (await checkAllValuesAreGood(response)) {
      await response.complete("success");
    } else {
      await response.complete("fail");
    }
  } catch (err) {
    // Something went wrong...
    await response.complete("fail");
  }
}
doPaymentRequest();
            Prior to the user accepting to make payment, the site is given an opportunity to update the payment request in response to user input. This can include, for example, providing additional shipping options (or modifying their cost), removing items that cannot ship to a particular address, etc.
const request = new PaymentRequest(methodData, details, options);
// Async update to details
request.onshippingaddresschange = ev => {
  ev.updateWith(checkShipping(request));
};
// Sync update to the total
request.onshippingoptionchange = ev => {
  const shippingOption = shippingOptions.find(
    option => option.id === request.id
  );
  const newTotal = {
    currency: "USD",
    label: "Total due",
    value: calculateNewTotal(shippingOption),
  };
  ev.updateWith({ ...details, total: newTotal });
};
async function checkShipping(request) {
  try {
    const json = request.shippingAddress.toJSON();
    await ensureCanShipTo(json);
    const { shippingOptions, total } = await calculateShipping(json);
    return { ...details, shippingOptions, total };
  } catch (err) {
    return { ...details, error: `Sorry! we can't ship to your address.` };
  }
}
            
                It's expected that data in a PaymentResponse will be POSTed back to a server for processing. To make this as easy as possible,
                PaymentResponse provides a toJSON() method that
                serializes the object directly into JSON. This makes it trivial to POST the resulting JSON back to a server using the Fetch API:
            
async function doPaymentRequest() {
  const payRequest = new PaymentRequest(methodData, details, options);
  const payResponse = await payRequest.show();
  let result = "";
  try {
    const httpResponse = await fetch("/process-payment", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: payResponse.toJSON(),
    });
    result = httpResponse.ok ? "success" : "fail";
  } catch (err) {
    console.error(err);
    result = "fail";
  }
  await payResponse.complete(result);
}
doPaymentRequest();
            PaymentRequest interface
        [Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options),
 SecureContext,
 Exposed=Window]
interface PaymentRequest : EventTarget {
    Promise<PaymentResponse> show();
    Promise<void>            abort();
    Promise<boolean>         canMakePayment();
    readonly attribute DOMString            id;
    readonly attribute PaymentAddress?      shippingAddress;
    readonly attribute DOMString?           shippingOption;
    readonly attribute PaymentShippingType? shippingType;
             attribute EventHandler         onshippingaddresschange;
             attribute EventHandler         onshippingoptionchange;
};
        
                    A developer creates a PaymentRequest to make a payment request. This is typically associated with the user initiating a payment process (e.g.,
                    by activating a "Buy," "Purchase," or "Checkout" button on a web site, selecting a "Power Up" in an interactive game, or paying at a kiosk in a parking structure). The
                    PaymentRequest allows developers to exchange information with the user agent                    while the user is providing input (up to the point of user approval or denial of the payment request).
                
                    The shippingAddress, shippingOption,
                    and
                    shippingType attributes are populated during processing if the
                    requestShipping member is set.
                
            Because the simultaneous display of multiple PaymentRequest user interfaces might confuse the user, this specification limits the
            user agent to displaying one at a time via the show() method. This is ensured
            by a payment request is showing boolean.
        
                The PaymentRequest is constructed using the supplied
                methodData list including any payment method specific data,
                the payment
                details, and the payment options.
            
                The PaymentRequest(methodData,
          details, options) constructor MUST act as follows:
            
allowpaymentrequest, then throw                    a "
                    SecurityError" DOMException.
                TypeError,
                            optionally informing the developer that at least one payment method is required.
                        supportedMethods. If it returns false,
                                    then throw a RangeError exception and terminate this algorithm. Optionally, inform
                                    the developer that the payment method identifier is invalid.
                                data member of paymentMethod is missing, let
                                    serializedData be null. Otherwise, let
                                    serializedData be the result of
                                    JSON-serializing
                                    paymentMethod.data into a string. Rethrow any exceptions.
                                supportedMethods,
                                    serializedData) to
                                    serializedMethodData.
                                total.amount.
                            Rethrow any exceptions.
                        displayItems member of details is present, then for each item in
                    details.displayItems:
                    amount. Rethrow any exceptions.
                        requestShipping member of 
            options is present and set to true, process shipping options:
                    sequence<PaymentShippingOption>.
                        shippingOptions member of details is present, then:
                            shippingOptions.
                                amount. Rethrow any exceptions.
                                        id, then throw a
                                            TypeError. Optionally, inform the developer that shipping option IDs must
                                            be unique.
                                        id to
                                            seenIDs.
                                        shippingOptions to 
                options.
                        sequence<PaymentDetailsModifier>.
                        modifiers member of details is present, then:
                            modifiers.
                                total member of 
                        modifier is present, then:
                                            total.amount. Rethrow any exceptions.
                                                additionalDisplayItems member
                                            of modifier is present, then for each
                                            item of modifier.additionalDisplayItems:
                                            amount. Rethrow any exceptions.
                                                data member of
                                            modifier is missing, let
                                            serializedData be null. Otherwise, let
                                            serializedData be the result of
                                            JSON-serializing modifier.data into a string. Rethrow any exceptions.
                                        
                        data member of modifier, if it is present.
                                        modifiers to
                            modifiers.
                        PaymentRequest.
                shippingOption attribute to 
            selectedShippingOption.
                
            shippingAddress attribute on request to null.
                requestShipping is set to true, then set the value of the shippingType attribute on
                    request to options.shippingType. Otherwise, set it to null.
                id attribute
            
                When getting, the id attribute returns this
                PaymentRequest's [[details]].id.
            
show() method
            
                        The show() method is called when a developer wants to begin user interaction for the payment request. The show() method returns a Promise that will be resolved when the user
            accepts the payment request. Some kind of user interface will be presented to the user to facilitate the payment request after the show() method
                        returns.
                    
                        It is not possible to show multiple PaymentRequests at the same time within one user agent.
                        If a PaymentRequest is already showing, calling show()                        —from any Web site— will return a promise rejected with an "AbortError"
                        DOMException.
                    
                The show() method MUST act as follows:
            
PaymentRequest object on which the method is called.
                AbortError" DOMException.
                
                        Optionally, if the user agent wishes to disallow the call to show()                        to protect the user, then return a promise rejected with a "SecurityError" DOMException.
                        For example, the user agent may require the call to be
                        triggered by user activation, or may limit the rate at which a page can call show(), as described in the privacy considerations section.
                    
                            During the Candidate Recommendation phase, implementations are expected to experiment in this area. Developers using this API should investigate and anticipate such experiments and understand under what circumstances a "
                            SecurityError"
                                DOMException might occur. If interoperable behavior emerges amongst user agents, then that behavior will be standardized
                                here before progressing the specification along the
                                W3C Recommendation Track.
                        
InvalidStateError" 
            DOMException.
                AbortError" DOMException.
                Optionally:
AbortError"
                            DOMException.
                        This allows the user agent to act as if the user had immediately aborted the payment request, at its discretion. For example, in "private browsing" modes or similar, user agents might take advantage of this step.
NotSupportedError"
                    DOMException, and set the user agent's payment
          request is showing boolean to false.
                Otherwise, present a user interface to allow the user to interact with the handlers. The user agent SHOULD prioritize the preference of the user when presenting payment methods.
For the payment handler selected by the end-user, the user agent MUST pass the converted second element in the paymentMethod tuple. Optionally, the user agent SHOULD send the appropriate data from request to the user-selected payment handler in order to guide the user through the payment process. This includes the various attributes and internal slots of request (some MAY be excluded for privacy reasons where appropriate).
The acceptPromise will later be resolved or rejected by either the user accepts the payment request algorithm or the user aborts the payment request algorithm, which are triggered through interaction with the user interface.
                        If document stops being fully active while the user interface is being shown, or no longer is by the time this step is reached, then the user interface
                        SHOULD be hidden, and
                        acceptPromise SHOULD be rejected with an "
                        AbortError" DOMException.
                    
abort() method
            
                        The abort() method is called if a developer wishes to tell the user agent                        to abort the payment request and to tear down any user interface that might be shown. The
                        abort() can only be called after the show()                        method has been called (see states) and before this instance's [[acceptPromise]]                        has been resolved. For example, developers might choose to do this if the goods they are selling are only available for a limited amount of time. If the user does not accept the payment request within the allowed time period, then
                        the request will be aborted.
                    
                        A user agent might not always be able to abort a request. For example, if the user agent                        has delegated responsibility for the request to another app. In this situation, abort() will reject the returned Promise.
                    
See also the algorithm when the user aborts the payment request.
                The abort() method MUST act as follows:
            
PaymentRequest object on which the method is called.
                InvalidStateError"
                    DOMException.
                InvalidStateError"
                            DOMException and abort these steps.
                        AbortError" DOMException.
                        canMakePayment() method
            
                    The canMakePayment() method can be used by the developer to determine if the PaymentRequest object can be used to make a payment, before they call show(). It returns a Promise that will be fulfilled with true if the user agent supports any of the desired payment methods supplied to the
                    PaymentRequest constructor, and false if none are supported. If the method is called too often, the user agent might instead return a promise rejected
                    with a "NotAllowedError"
                    DOMException, at its discretion.
                
                The canMakePayment() method MUST act as follows:
            
PaymentRequest object on which the method was called.
                InvalidStateError" 
            DOMException.
                NotAllowedError"
                    DOMException.
                    
                            This allows user agents to apply heuristics to detect and prevent abuse of the canMakePayment() method for fingerprinting
                            purposes, such as creating PaymentRequest objects with a variety of supported payment methods                            and calling
                            canMakePayment() on them one after the other. For example, a user agent may restrict the number of successful calls that
                            can be made based on the top-level browsing context or the time period in which those calls were made.
                        
supportedMethods is a supported payment method identifier (including its
                            payment method specific capabilities), resolve
                            promise with true, and abort this algorithm.
                        shippingAddress attribute
            
                A PaymentRequest's shippingAddress attribute
                is populated when the user provides a shipping address. It is null by default. When a user provides a shipping address, the shipping
          address changed algorithm runs.
            
shippingType attribute
            
                A PaymentRequest's shippingType attribute is the
                type of shipping used to fulfill the transaction. Its value is either a
                PaymentShippingType enum value, or null if none is provided by the developer during construction (see
                PaymentOptions's shippingType                member).
            
onshippingaddresschange attribute
            
                A PaymentRequest's onshippingaddresschange                attribute is an EventHandler for a PaymentRequestUpdateEvent                named
                shippingaddresschange.
            
shippingOption attribute
            
                A PaymentRequest's shippingOption attribute
                is populated when the user chooses a shipping option. It is null by default. When a user chooses a shipping option, the shipping
          option changed algorithm runs.
            
onshippingoptionchange attribute
            
                A PaymentRequest's onshippingoptionchange                attribute is an EventHandler for a PaymentRequestUpdateEvent                named
                shippingoptionchange.
            
                Instances of PaymentRequest are created with the internal slots in the following table:
            
| Internal Slot | Description (non-normative) | 
|---|---|
| [[serializedMethodData]] | The methodDatasupplied to the constructor, but represented as tuples containing supported methods and a string or null for data (instead of the original object form). | 
| [[serializedModifierData]] | A list containing the serialized string form of each datamember for each corresponding
                            item in the sequence
                            [[details]].modifier, or null if no
                            such member was present. | 
| [[details]] | The current PaymentDetailsBasefor the payment request initially supplied to the constructor and then updated with calls to updateWith(). Note that alldatamembers ofPaymentDetailsModifierinstances contained in themodifiersmember will be removed, as they are instead stored in serialized form in the [[serializedModifierData]] internal slot. | 
| [[options]] | The PaymentOptionssupplied to the constructor. | 
| [[state]] | The current state of the payment request, which transitions from: 
 The state transitions are illustrated in the figure below: show()method changes the
                  state to "interactive". From there, theabort()method or any other error can send the
                  state to "closed"; similarly, the user
                  accepts the payment request algorithm and user aborts
                  the payment request algorithm will change the
                  state to "closed". | 
| [[updating]] | true is there is a pending updateWith() call to update the payment request and false otherwise. | 
| [[acceptPromise]] | The pending Promise created during show that will be resolved if the user accepts the payment request. | 
PaymentMethodData dictionary
        dictionary PaymentMethodData {
    required DOMString supportedMethods;
             object    data;
};
        
            A PaymentMethodData dictionary is used to indicate a set of supported payment methods            and any associated payment
        method specific data for those methods.
        
supportedMethods member
        data member
        
                The value of supportedMethods was changed from array to string, but the name was left as a plural to maintain compatibility with existing content on the Web.
            
PaymentCurrencyAmount dictionary
        dictionary PaymentCurrencyAmount {
    required DOMString currency;
    required DOMString value;
    // Note: currencySystem is "at risk" of being removed!
             DOMString currencySystem = "urn:iso:std:iso:4217";
};
        
            A PaymentCurrencyAmount dictionary is used to supply monetary amounts.
        
currency member
        
                    A string containing a currency identifier. The value of
                    currency can be any string that is valid within the currency system indicated by currencySystem.
                
When using [ISO4217], all well-formed 3-letter alphabetic codes are allowed (i.e., the numeric codes are not supported). Their canonical form is upper case. However, the set of combinations of currency code for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, a user agent SHOULD use U+00A4 (¤) for formatting.
value member
        The following example shows how to represent US$55.00.
{
  "currency": "USD",
  "value" : "55.00"
}
        A JavaScript string is a valid decimal monetary value if it consists of the following code points in the given order: [INFRA]
^-?[0-9]+(\.[0-9]+)?$
                To check and canonicalize amount given a
                PaymentCurrencyAmount amount, run the following steps:
            
currencySystem is not "
                    urn:iso:std:iso:4217", terminate this algorithm.
                currency                    as the argument.
                RangeError exception and terminate this algorithm, optionally informing the developer that the
                    currency is invalid.
                value is not a valid decimal
          monetary value, throw a TypeError, optionally informing the developer that the currency is invalid.
                currency to the result of
                    ASCII uppercasing
                    amount.currency.
                
                To check and canonicalize total given a
                PaymentCurrencyAmount total, run the following steps:
            
currencySystem is not "
                    urn:iso:std:iso:4217", terminate this algorithm.
                TypeError                    optionally informing the developer that a total can't be a negative number.
                PaymentDetailsBase dictionary
            dictionary PaymentDetailsBase {
    sequence<PaymentItem>            displayItems;
    sequence<PaymentShippingOption>  shippingOptions;
    sequence<PaymentDetailsModifier> modifiers;
};
            displayItems member
          PaymentItem dictionaries contains line items for the payment request that the user agent                    MAY display. For example, it might include details of products or breakdown of tax and shipping. It is optional to provide this information.
                    shippingOptions member
          A sequence containing the different shipping options for the user to choose from.
                        If an item in the sequence has the selected member set to true, then this is the shipping
                        option that will be used by default and
                        shippingOption will be set to the id of this option without running the shipping option changed
              algorithm. Authors SHOULD NOT set selected to
                        true on more than one item. If more than one item in the sequence has
                        selected set to true, then the user agent                        selects the last one in the sequence.
                    
                        The shippingOptions member is only used if the
                        PaymentRequest was constructed with PaymentOptions
                        requestShipping set to true.
                    
modifiers member
          PaymentDetailsModifier dictionaries that contains modifiers for particular payment method identifiers. For example, it allows
                    you to adjust the total amount based on payment method.
                PaymentDetailsInit dictionary
            dictionary PaymentDetailsInit : PaymentDetailsBase {
             DOMString   id;
    required PaymentItem total;
};
            
                In addition to the members inherited from the
                PaymentDetailsBase dictionary, the following members are part of the PaymentDetailsInit                dictionary:
            
id member
          total member
          PaymentItem containing a non-negative total amount for the payment request.
                    PaymentDetailsUpdate dictionary
            dictionary PaymentDetailsUpdate : PaymentDetailsBase {
    DOMString   error;
    PaymentItem total;
};
            
                The PaymentDetailsUpdate dictionary is used to update the payment request using updateWith().
            
                In addition to the members inherited from the
                PaymentDetailsBase dictionary, the following members are part of the PaymentDetailsUpdate                dictionary:
            
error member
          PaymentDetailsUpdate can contain a message in the
                    error member that will be displayed to the user, if the
                    PaymentDetailsUpdate indicates that there are no valid
                    shippingOptions (and the PaymentRequest                    was constructed with the requestShipping option set to true). This can be used to explain
                    why goods cannot be shipped to the chosen shipping address, or any other reason why no shipping options are available.
                total member
          PaymentItem contains the non-negative amount.
                    
                            Algorithms in this specification that accept a
                            PaymentDetailsUpdate dictionary will throw if the
                            total.amount.
                            value is a negative number.
                        
PaymentDetailsModifier dictionary
        dictionary PaymentDetailsModifier {
    required DOMString             supportedMethods;
             PaymentItem           total;
             sequence<PaymentItem> additionalDisplayItems;
             object                data;
};
        
            The PaymentDetailsModifier dictionary provides details that modify the PaymentDetailsBase            based on a payment method
        identifier. It contains the following members:
        
supportedMethods member
        PaymentDetailsModifier only apply if the user selects this
                payment method.
            total member
        PaymentItem value that overrides the total                member in the
                PaymentDetailsInit dictionary for the payment method
          identifiers of the supportedMethods member.
            additionalDisplayItems member
        PaymentItem dictionaries provides additional display items that are appended to the displayItems member in the
                PaymentDetailsBase dictionary for the payment method
          identifiers in the supportedMethods member. This member is commonly used to add a discount or surcharge line item indicating
                the reason for the different total amount for the selected
                payment method that the user agent MAY display.
                
                        It is the developer's responsibility to verify that the
                        total amount is the sum of the displayItems and the
                        additionalDisplayItems.
                    
data member
        PaymentShippingType enum
        enum PaymentShippingType {
    "shipping",
    "delivery",
    "pickup"
};
        shipping"
        delivery"
        pickup"
        PaymentOptions dictionary
        dictionary PaymentOptions {
    boolean             requestPayerName = false;
    boolean             requestPayerEmail = false;
    boolean             requestPayerPhone = false;
    boolean             requestShipping = false;
    PaymentShippingType shippingType = "shipping";
};
        
                The PaymentOptions dictionary is passed to the
                PaymentRequest constructor and provides information about the options desired for the payment request.
            
requestPayerName member
        requestPayerEmail member
        requestPayerPhone member
        requestShipping member
        shippingType member
        requestShipping is set to true, then the shippingType member can influence the way the user
          agent presents the user interface for gathering the shipping address.
                
                    The shippingType member only affects the user interface for the payment request.
                
PaymentItem dictionary
        dictionary PaymentItem {
    required DOMString             label;
    required PaymentCurrencyAmount amount;
             boolean               pending = false;
};
        
            A sequence of one or more PaymentItem dictionaries is included in the PaymentDetailsBase            dictionary to indicate what the payment request is for and the value asked for.
        
label member
        amount member
        PaymentCurrencyAmount containing the monetary amount for the item.
            pending member
        amount member is not final. This is commonly used to show items such as shipping or tax amounts that
                depend upon selection of shipping address or shipping option. User agents MAY indicate pending fields in the user interface for
                the payment request.
            PaymentAddress interface
        [SecureContext,
 Exposed=Window]
interface PaymentAddress {
    [Default] object toJSON();
    readonly attribute DOMString              country;
    readonly attribute FrozenArray<DOMString> addressLine;
    readonly attribute DOMString              region;
    readonly attribute DOMString              city;
    readonly attribute DOMString              dependentLocality;
    readonly attribute DOMString              postalCode;
    readonly attribute DOMString              sortingCode;
    readonly attribute DOMString              languageCode;
    readonly attribute DOMString              organization;
    readonly attribute DOMString              recipient;
    readonly attribute DOMString              phone;
};
        toJSON() method
            When called, runs [WEBIDL]'s default toJSON operation.
country attribute
            
                When getting, returns the value of the PaymentAddress's
                [[country]] internal slot.
            
addressLine attribute
            
                When getting, returns the value of the PaymentAddress's
                [[addressLine]] internal slot.
            
region attribute
            
                When getting, returns the value of the PaymentAddress's
                [[region]] internal slot.
            
city attribute
            
                When getting, returns the value of the PaymentAddress's
                [[city]] internal slot.
            
dependentLocality attribute
            
                When getting, returns the value of the PaymentAddress's
                [[dependentLocality]] internal slot.
            
postalCode attribute
            
                When getting, returns the value of the PaymentAddress's
                [[postalCode]] internal slot.
            
sortingCode attribute
            
                When getting, returns the value of the PaymentAddress's
                [[sortingCode]] internal slot.
            
languageCode attribute
            
                When getting, returns the value of the PaymentAddress's
                [[languageCode]] internal slot.
            
organization attribute
            
                When getting, returns the value of the PaymentAddress's
                [[organization]] internal slot.
            
recipient attribute
            
                When getting, returns the value of the PaymentAddress's
                [[recipient]] internal slot.
            
phone attribute
            
                When getting, returns the value of the PaymentAddress's
                [[phone]] internal slot.
            
| Internal slot | Description (non-normative) | 
|---|---|
| [[country]] | An [ISO3166] alpha-2 code. The canonical form is upper case. For example, "JP". | 
| [[addressLine]] | The most specific part of the address. It can include, for example, a street name, a house number, apartment number, a rural delivery route, descriptive instructions, or a post office box number. | 
| [[region]] | The top level administrative subdivision of the country. For example, this can be a state, a province, an oblast, or a prefecture. | 
| [[city]] | The city/town portion of the address. | 
| [[dependentLocality]] | The dependent locality or sublocality within a city. For example, used for neighborhoods, boroughs, districts, or UK dependent localities. | 
| [[postalCode]] | The postal code or ZIP code, also known as PIN code in India. | 
| [[sortingCode]] | The sorting code as used in, for example, France. | 
| [[languageCode]] | The [BCP47] language tag for the address, in canonical form. It's used to determine the field separators and the order of fields when formatting the address for display. | 
| [[organization]] | The organization, firm, company, or institution at this address. | 
| [[recipient]] | The name of the recipient or contact person. This member may, under certain circumstances, contain multiline information. For example, it might contain "care of" information. | 
| [[phone]] | The phone number of the recipient or contact person. | 
PaymentShippingOption dictionary
        dictionary PaymentShippingOption {
    required DOMString             id;
    required DOMString             label;
    required PaymentCurrencyAmount amount;
             boolean               selected = false;
};
        
            The PaymentShippingOption dictionary has members describing a shipping option. Developers can provide the user with one or more shipping options
            by calling the updateWith() method in response to a change event.
        
id member
        PaymentShippingOption. It MUST be unique for a given
                PaymentRequest.
            label member
        amount member
        PaymentCurrencyAmount containing the monetary amount for the item.
            selected member
        PaymentShippingOption in a sequence. User agents SHOULD display this option by default in the user interface.
            PaymentComplete enum
        enum PaymentComplete {
    "fail",
    "success",
    "unknown"
};
        fail"
        success"
        unknown"
        PaymentResponse interface
        [SecureContext,
 Exposed=Window]
interface PaymentResponse {
    [Default] object        toJSON();
    readonly attribute DOMString       requestId;
    readonly attribute DOMString       methodName;
    readonly attribute object          details;
    readonly attribute PaymentAddress? shippingAddress;
    readonly attribute DOMString?      shippingOption;
    readonly attribute DOMString?      payerName;
    readonly attribute DOMString?      payerEmail;
    readonly attribute DOMString?      payerPhone;
    Promise<void> complete(optional PaymentComplete result = "unknown");
};
        
                A PaymentResponse is returned when a user has selected a payment method and approved a payment request.
            
toJSON() method
            When called, runs [WEBIDL]'s default toJSON operation.
methodName attribute
            The payment method identifier for the payment method that the user selected to fulfill the transaction.
details attribute
            An object or dictionary generated by a payment method that a merchant can use to process or validate a transaction (depending on the payment method).
shippingAddress attribute
            
                If the requestShipping member was set to true in the PaymentOptions passed to the
                PaymentRequest constructor, then shippingAddress                will be the full and final shipping address chosen by the user.
            
shippingOption attribute
            
                If the requestShipping member was set to true in the PaymentOptions passed to the
                PaymentRequest constructor, then shippingOption                will be the
                id attribute of the selected shipping option.
            
payerName attribute
            
                If the requestPayerName member was set to true in the PaymentOptions passed to the
                PaymentRequest constructor, then payerName                will be the name provided by the user.
            
payerEmail attribute
            
                If the requestPayerEmail member was set to true in the PaymentOptions passed to the
                PaymentRequest constructor, then payerEmail                will be the email address chosen by the user.
            
payerPhone attribute
            
                If the requestPayerPhone member was set to true in the PaymentOptions passed to the
                PaymentRequest constructor, then payerPhone                will be the phone number chosen by the user.
            
requestId attribute
            
                The corresponding payment request id that spawned this payment response.
            
complete() method
            
                    The complete() method is called after the user has accepted the payment request and the [[acceptPromise]] has been resolved. Calling the complete() method tells the user
          agent that the payment interaction is over (and SHOULD cause any remaining user interface to be closed).
                
                After the payment request has been accepted and the
                PaymentResponse returned to the caller but before the caller calls complete()                the payment request user interface remains in a pending state. At this point the user interface ought not offer a cancel command because acceptance of the payment request has been returned. However, if something goes wrong and the developer
                never calls complete() then the user interface is blocked.
            
                For this reason, implementations MAY impose a timeout for developers to call complete(). If the timeout
                expires then the implementation will behave as if complete() was called with no arguments.
            
The complete(result) method MUST act as follows:
InvalidStateError"
                    DOMException.
                
                Instances of PaymentResponse are created with the internal slots in the following table:
            
| Internal Slot | Description (non-normative) | 
|---|---|
| [[completeCalled]] | true if the complete method has been called and false otherwise. | 
PaymentRequest and iframe elements
        This section is non-normative.
            To indicate that a cross-origin iframe is allowed to invoke the payment request API, the allowpaymentrequest attribute can be specified on the iframe            element.
        
This section is non-normative.
| Event name | Interface | Dispatched when… | 
|---|---|---|
| shippingaddresschange | PaymentRequestUpdateEvent | The user provides a new shipping address. | 
| shippingoptionchange | PaymentRequestUpdateEvent | The user chooses a new shipping option. | 
PaymentRequestUpdateEvent interface
            [Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict),
 SecureContext,
 Exposed=Window]
interface PaymentRequestUpdateEvent : Event {
    void updateWith(Promise<PaymentDetailsUpdate> detailsPromise);
};
            
                The PaymentRequestUpdateEvent enables developers to update the details of the payment request in response to a user interaction.
            
                The PaymentRequestUpdateEvent constructor MUST set the internal slot [[waitForUpdate]] to false.
            
updateWith() method
                The updateWith(detailsPromise) method MUST act as follows:
PaymentRequestUpdateEvent instance.
                    isTrusted attribute is false, then then throw                        a "InvalidStateError" DOMException.
                    InvalidStateError" DOMException.
                    target attribute.
                    InvalidStateError" DOMException.
                    InvalidStateError" DOMException.
                    Return from the method and perform the remaining steps in parallel.
The remaining steps are conditional on the detailsPromise settling. If detailsPromise never settles then the payment request is blocked. Users SHOULD always be able to cancel a payment request. Implementations MAY choose to implement a timeout for pending updates if detailsPromise doesn't settle in a reasonable amount of time. If an implementation chooses to implement a timeout, they must execute the steps listed below in the "upon rejection" path. Such a timeout is a fatal error for the payment request.
AbortError"
                                DOMException.
                            PaymentDetailsUpdate dictionary. If this throws                                an exception, abort the update with the thrown exception.
                            sequence<PaymentShippingOption>.
                            total member of details is present, then:
                                        total.amount. If an exception is thrown, then abort the update with that exception.
                                            displayItems member of details is present, then for each item in
                                        details.displayItems:
                                        amount. If an exception is thrown, then abort the update with that exception.
                                            shippingOptions member of
                                        details is present, and
                                        request.[[options]].requestShipping is true, then:
                                        shippingOptions.
                                            amount. If an exception is thrown, then
                                                        abort the update with that exception.
                                                    id, then abort
                            the update with a TypeError.
                                                    id to seenIDs.
                                                    modifiers member of details is present, then:
                                        modifiers.
                                            PaymentDetailsModifier
                                                modifier in modifiers:
                                                supportedMethods.
                                                        If it returns false, then abort the update with a RangeError                                                        exception. Optional, inform the developer that the payment method identifier is invalid.
                                                    total member of
                                                        modifier is present, then:
                                                        total.amount. If an exception is thrown, then abort the
                                  update with that exception.
                                                            additionalDisplayItems member of
                                                        modifier is present, then for each
                                                        PaymentItem item in
                                                        modifier.additionalDisplayItems:
                                                        amount. If an exception is thrown, then abort the
                                  update with that exception.
                                                            data member of
                                                        modifier is missing, let
                                                        serializedData be null. Otherwise, let
                                                        serializedData be the result of
                                                        JSON-serializing
                                                        modifier.data into a string. If JSON-serializing throws an exception, then abort the update with that exception.
                                                    data member of
                                                        modifier, if it is present.
                                                    PaymentRequest using the new details:
                                total member of details is present, then:
                                        total to details.total.
                                            displayItems member of details is present, then:
                                        displayItems                                                to details.displayItems.
                                            shippingOptions member of
                                        details is present, and
                                        request.[[options]].requestShipping is true, then:
                                        shippingOptions                                                to shippingOptions.
                                            shippingOption attribute to
                                                selectedShippingOption.
                                            modifiers member of details is present, then:
                                        modifiers                                                to details.modifiers.
                                            requestShipping is true, and
                                        request.[[details]].shippingOptions                                        is empty, then the developer has signified that there are no valid shipping options for the currently-chosen shipping address (given by request's shippingAddress). In this case, the user agent SHOULD display an error indicating this, and MAY                                        indicate that the currently-chosen shipping address is invalid in some way. The user agent
                                        SHOULD use the error member of
                                        details, if it is present, to give more information about why there are no valid shipping options for that address.
                                    If any of the above steps say to abort the update with an exception exception, then:
                            Aborting the update is performed when there is a fatal error updating the payment request, such as the supplied detailsPromise                            rejecting, or its fulfillment value containing invalid data. This would potentially leave the payment request in an inconsistent state since the developer hasn't successfully handled the change event. Consequently, the PaymentRequest moves to a "
                            closed" state. The error is signaled to the developer through the rejection of the [[acceptPromise]],
                            i.e., the promise returned by show().
                        
User agents might show an error message to the user when this occurs.
                    Instances of PaymentRequestUpdateEvent are created with the internal slots in the following table:
                
| Internal Slot | Description (non-normative) | 
|---|---|
| [[waitForUpdate]] | A boolean indicating whether an updateWith()-initiated update is currently in progress. | 
PaymentRequestUpdateEventInit dictionary
                dictionary PaymentRequestUpdateEventInit : EventInit {
};
                
            When the internal slot [[state]] of a PaymentRequest object is set to "
            interactive", the user agent will trigger the following algorithms based on user interaction.
        
The shipping address changed algorithm runs when the user provides a new shipping address. It MUST run the following steps:
PaymentRequest object that the user is interacting with.
                shippingaddresschange".
                PaymentAddress.
                        country                            as an upper case [ISO3166] alpha-2 code, or to the empty string if none was provided.
                        Implementers are currently figuring out how to derive the languageCode's value in an interoperable manner.
During the CR phase of standardization, implementers will report back on implementation experience, possibly using Unicode CLDR to derive the languageCode. Please see comments
                                    of this GitHub issue for followup, or join the discussion.
shippingAddress attribute on
                            request to address.
                        The shipping option changed algorithm runs when the user chooses a new shipping option. It MUST run the following steps:
PaymentRequest object that the user is interacting with.
                shippingoptionchange".
                shippingOption attribute on
                            request to the id string of the
                            PaymentShippingOption provided by the user.
                        
                The PaymentRequest updated algorithm is run by other algorithms above to fire an event                to indicate that a user has made a change to a PaymentRequest called request with an event name of name:
            
PaymentRequestUpdateEvent.
                type attribute to name.
                The user accepts the payment request algorithm runs when the user accepts the payment request and confirms that they want to pay. It MUST queue a task on the user interaction task source to perform the following steps:
PaymentRequest object that the user is interacting with.
                requestShipping value of
                    request.[[options]] is true, then if the
                    shippingAddress attribute of request is null or if the shippingOption attribute of 
            request is null, then terminate this algorithm and take no further action. The user agent SHOULD ensure that this never occurs.
                PaymentResponse.
                requestId attribute value of response to the value of
                    request.[[details]].id.
                methodName attribute value of response to the payment method
          identifier for the payment method that the user selected to accept the payment.
                details attribute value of response to an object containing the
                    payment method specific object that will be used by the merchant to process or validate the transaction. The format of this response will be defined for each
                    payment method.
                requestShipping value of
                    request.[[options]] is true, then set the
                    shippingAddress attribute of response to the value of the shippingAddress attribute of
                    request. Otherwise, set it to null.
                requestShipping value of
                    request.[[options]] is true, then set the
                    shippingOption attribute of response to the value of the shippingOption attribute of 
            request. Otherwise, set it to null.
                requestPayerName value of 
            request.[[options]] is true, then set the payerName                    attribute of
                    response to the payer's name provided by the user, or to null if none was provided. Otherwise, set it to null.
                requestPayerEmail value of
                    request.[[options]] is true, then set the
                    payerEmail attribute of
                    response to the payer's email address provided by the user, or to null if none was provided. Otherwise, set it to null.
                requestPayerPhone value of
                    request.[[options]] is true, then set the
                    payerPhone attribute of
                    response to the payer's phone number provided by the user, or to null if none was provided. When setting the payerPhone                    value, the user agent
                    SHOULD format the phone number to adhere to [E.164]. Otherwise, set it to null.
                The user aborts the payment request algorithm runs when the user aborts the payment request through the currently interactive user interface. It MUST queue a task on the user interaction task source to perform the following steps:
PaymentRequest object that the user is interacting with.
                AbortError"
                    DOMException.
                This section is non-normative.
This section is non-normative.
                The PaymentRequest API does not directly support encryption of data fields. Individual payment methods                may choose to include support for encrypted data but it is not mandatory that all
                payment methods support this.
            
                For security reasons, a user agent can limit matching (in
                show() and canMakePayment()) to
                payment handlers
                    from the same origin as a URL
                    payment method identifier. User agents can also use information provided by a payment method                    owner to match
                    payment handlers from other origins.
            
The user agent MUST NOT share information about the user with a developer (e.g., the shipping address) without user consent.
Developers might try to call the payment request API repeatedly with only one payment method identifier to try to determine what payment methods a user agent has installed. There are legitimate scenarios for calling repeatedly (for example, to control the flow of payment method selection). The fact that a successful match to a payment method causes a user interface to be displayed mitigates the disclosure risk. Implementations MAY require a user action to initiate a payment request or they MAY rate limit the calls to the API to prevent too many repeated calls.
This specification relies on several other underlying specifications.
EventHandler,
                queue a
          task, user interaction
          task source, top-level browsing
          context, current settings
          object, allowed to use,
                triggered by
          user activation, in parallel, the
                iframe element, and the allowpaymentrequest                attribute.
            
          RangeError, TypeError, and JSON.stringify                are defined by [ECMASCRIPT].
                
                    The term JSON-serialize applied to a given object means to run the algorithm specified by the original value of the JSON.stringify                    function on the supplied object, passing the supplied object as the sole argument, and return the resulting string. This can throw an exception.
                
Event interface, The EventInit                dictionary, and the terms fire an event,
                dispatch flag,
                stop propagation
          flag, isTrusted attribute, and
                stop immediate
          propagation flag are defined by [DOM].
            When this specification says to throw an error, the user agent must throw an error as described in [WEBIDL]. When this occurs in a sub-algorithm, this results in termination of execution of the sub-algorithm and all ancestor algorithms until one is reached that explicitly describes procedures for catching exceptions.
The algorithm for converting an ECMAScript value to a dictionary is defined by [WEBIDL].
                    DOMException and the following DOMException                    types from [WEBIDL] are used: "
                    AbortError", "
                    InvalidStateError", "
                    NotAllowedError", "
                    NotSupportedError", and "
                    SecurityError".
                
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, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT are to be interpreted as described in [RFC2119].
There is only one class of product that can claim conformance to this specification: a user agent.
Although this specification is primarily targeted at web browsers, it is feasible that other software could also implement this specification in a conforming manner.
User agents MAY implement algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms.
            User agents MAY impose implementation-specific limits on otherwise unconstrained inputs, e.g., to prevent denial of service attacks, to guard against running out of memory, or to work around platform-specific
            limitations. When an input exceeds implementation-specific limit, the user agent MUST throw, or, in the context of a promise, reject with, a TypeError            optionally informing the developer of how a particular input exceeded an implementation-specific limit.
        
[Constructor(sequence<PaymentMethodData> methodData,PaymentDetailsInitdetails, optionalPaymentOptionsoptions), SecureContext, Exposed=Window] interfacePaymentRequest: EventTarget { Promise<PaymentResponse> show(); Promise<void> abort(); Promise<boolean> canMakePayment(); readonly attribute DOMStringid; readonly attributePaymentAddress?shippingAddress; readonly attribute DOMString?shippingOption; readonly attributePaymentShippingType?shippingType; attribute EventHandleronshippingaddresschange; attribute EventHandleronshippingoptionchange; }; dictionaryPaymentMethodData{ required DOMStringsupportedMethods; objectdata; }; dictionaryPaymentCurrencyAmount{ required DOMStringcurrency; required DOMStringvalue; // Note: currencySystem is "at risk" of being removed! DOMStringcurrencySystem= "urn:iso:std:iso:4217"; }; dictionaryPaymentDetailsBase{ sequence<PaymentItem>displayItems; sequence<PaymentShippingOption>shippingOptions; sequence<PaymentDetailsModifier>modifiers; }; dictionaryPaymentDetailsInit:PaymentDetailsBase{ DOMStringid; requiredPaymentItemtotal; }; dictionaryPaymentDetailsUpdate:PaymentDetailsBase{ DOMStringerror;PaymentItemtotal; }; dictionaryPaymentDetailsModifier{ required DOMStringsupportedMethods;PaymentItemtotal; sequence<PaymentItem>additionalDisplayItems; objectdata; }; enumPaymentShippingType{ "shipping", "delivery", "pickup" }; dictionaryPaymentOptions{ booleanrequestPayerName= false; booleanrequestPayerEmail= false; booleanrequestPayerPhone= false; booleanrequestShipping= false;PaymentShippingTypeshippingType= "shipping"; }; dictionaryPaymentItem{ required DOMStringlabel; requiredPaymentCurrencyAmountamount; booleanpending= false; }; [SecureContext, Exposed=Window] interfacePaymentAddress{ [Default] object toJSON(); readonly attribute DOMStringcountry; readonly attribute FrozenArray<DOMString>addressLine; readonly attribute DOMStringregion; readonly attribute DOMStringcity; readonly attribute DOMStringdependentLocality; readonly attribute DOMStringpostalCode; readonly attribute DOMStringsortingCode; readonly attribute DOMStringlanguageCode; readonly attribute DOMStringorganization; readonly attribute DOMStringrecipient; readonly attribute DOMStringphone; }; dictionaryPaymentShippingOption{ required DOMStringid; required DOMStringlabel; requiredPaymentCurrencyAmountamount; booleanselected= false; }; enumPaymentComplete{ "fail", "success", "unknown" }; [SecureContext, Exposed=Window] interfacePaymentResponse{ [Default] object toJSON(); readonly attribute DOMStringrequestId; readonly attribute DOMStringmethodName; readonly attribute objectdetails; readonly attributePaymentAddress?shippingAddress; readonly attribute DOMString?shippingOption; readonly attribute DOMString?payerName; readonly attribute DOMString?payerEmail; readonly attribute DOMString?payerPhone; Promise<void> complete(optionalPaymentCompleteresult = "unknown"); }; [Constructor(DOMString type, optionalPaymentRequestUpdateEventIniteventInitDict), SecureContext, Exposed=Window] interfacePaymentRequestUpdateEvent:Event{ void updateWith(Promise<PaymentDetailsUpdate> detailsPromise); }; dictionaryPaymentRequestUpdateEventInit:EventInit{ };
This specification was derived from a report published previously by the Web Platform Incubator Community Group.