diff --git a/index.html b/index.html index 8ca237c5..fb013ee0 100644 --- a/index.html +++ b/index.html @@ -67,6 +67,7 @@ caniuse: "payment-request", lint: { "check-punctuation": true, + "wpt-tests-exist": true, }, doJsonLd: true, xref: "web-platform", @@ -112,53 +113,14 @@

Changes since last publication

- Substantive changes to the Payment Request API since the 9 July 2018 - version are as follows. The complete list of changes, including all - editorial changes, is viewable in the commit history. Key set of changes are viewable in the Changelog.

-
@@ -277,15 +239,10 @@

  • The |details|: The details of the transaction, as a 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 - card belonging to network X, it incurs a US$3.00 processing fee". -
  • -
  • The |options|: Optionally, a list of things as {{PaymentOptions}} - that the site needs to deliver the good or service (e.g., for physical - goods, the merchant will typically need a physical address to ship to. - For digital goods, an email will usually suffice). + optionally a list of goods or services being purchased. Additionally, + it can optionally include "modifiers" to how payments are made. For + example, "if you pay with a card belonging to network X, it incurs a + US$3.00 processing fee".
  • @@ -349,44 +306,20 @@

    label: "Value-Added Tax (VAT)", amount: { currency: "GBP", value: "5.00" }, }, + { + label: "Standard shipping", + amount: { currency: "GBP", value: "5.00" }, + }, ], total: { label: "Total due", // The total is GBP£65.00 here because we need to - // add shipping (below). The selected shipping - // costs GBP£5.00. + // add tax and shipping. amount: { currency: "GBP", value: "65.00" }, }, };

    -
    -

    - Adding shipping options -

    -

    - Here we see an example of how to add two shipping options to the - |details|. -

    -
    -          const shippingOptions = [
    -            {
    -              id: "standard",
    -              // Shipping by truck, 2 days
    -              label: "🚛  Envío por camión (2 dias)",
    -              amount: { currency: "EUR", value: "5.00" },
    -              selected: true,
    -            },
    -            {
    -              id: "drone",
    -              // Drone shipping, 2 hours
    -              label: "🚀 Drone Express (2 horas)",
    -              amount: { currency: "EUR", value: "25.00" }
    -            },
    -          ];
    -          Object.assign(details, { shippingOptions });
    -        
    -

    Conditional modifications to payment request @@ -421,30 +354,6 @@

    Object.assign(details, { modifiers });

    -
    -

    - Requesting specific information from the end user -

    -

    - Some financial transactions require a user to provide specific - information in order for a merchant to fulfill a purchase (e.g., the - user's shipping address, in case a physical good needs to be - shipped). To request this information, a merchant can pass a third - optional argument (|options|) to the {{PaymentRequest}} constructor - indicating what information they require. When the payment request is - shown, the user agent will request this information from the end user - and return it to the merchant when the user accepts the payment - request. -

    -
    -          const options = {
    -            requestPayerEmail: false,
    -            requestPayerName: true,
    -            requestPayerPhone: false,
    -            requestShipping: true,
    -          }
    -        
    -

    Constructing a PaymentRequest @@ -458,9 +367,6 @@

    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) { @@ -486,79 +392,6 @@

    doPaymentRequest();

    -
    -

    - Handling events and updating the payment request -

    -

    - 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 => {
    -            // selected shipping option
    -            const { shippingOption } = request;
    -            const newTotal = {
    -              currency: "USD",
    -              label: "Total due",
    -              value: calculateNewTotal(shippingOption),
    -            };
    -            ev.updateWith({ total: newTotal });
    -          };
    -          async function checkShipping(request) {
    -            try {
    -              const json = request.shippingAddress.toJSON();
    -
    -              await ensureCanShipTo(json);
    -              const { shippingOptions, total } = await calculateShipping(json);
    -
    -              return { shippingOptions, total };
    -            } catch (err) {
    -              return { error: `Sorry! we can't ship to your address.` };
    -            }
    -          }
    -        
    -
    -
    -

    - Fine-grained error reporting -

    -

    - A developer can use the - {{PaymentDetailsUpdate/shippingAddressErrors}} member of the - {{PaymentDetailsUpdate}} dictionary to indicate that there are - validation errors with specific attributes of a {{PaymentAddress}}. - The {{PaymentDetailsUpdate/shippingAddressErrors}} member is a - {{AddressErrors}} dictionary, whose members specifically demarcate - the fields of a physical address that are erroneous while also - providing helpful error messages to be displayed to the end user. -

    -
    -          request.onshippingaddresschange = ev => {
    -            ev.updateWith(validateAddress(request.shippingAddress));
    -          };
    -          function validateAddress(shippingAddress) {
    -            const error = "Can't ship to this address.";
    -            const shippingAddressErrors = {
    -              city: "FarmVille is not a real place.",
    -              postalCode: "Unknown postal code for your country.",
    -            };
    -            // Empty shippingOptions implies that we can't ship
    -            // to this address.
    -            const shippingOptions = [];
    -            return { error, shippingAddressErrors, shippingOptions };
    -          }
    -        
    -

    POSTing payment response back to a server @@ -625,8 +458,7 @@

    interface PaymentRequest : EventTarget { constructor( sequence<PaymentMethodData> methodData, - PaymentDetailsInit details, - optional PaymentOptions options = {} + PaymentDetailsInit details ); [NewObject] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise); @@ -636,12 +468,7 @@

    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; attribute EventHandler onpaymentmethodchange; }; @@ -656,12 +483,6 @@

    while the user is providing input (up to the point of user approval or denial of the payment request).

    -

    - The {{PaymentRequest/shippingAddress}}, - {{PaymentRequest/shippingOption}}, and - {{PaymentRequest/shippingType}} attributes are populated during - processing if the {{PaymentOptions/requestShipping}} member is set. -

    A |request|'s payment-relevant browsing context is that @@ -685,15 +506,14 @@

    The {{PaymentRequest}} is constructed using the supplied sequence of PaymentMethodData |methodData| including any payment - method specific {{PaymentMethodData/data}}, the - PaymentDetailsInit |details|, and the {{PaymentOptions}} - |options|. + method specific {{PaymentMethodData/data}}, and the + PaymentDetailsInit |details|.

    + "payment-request-constructor.https.sub.html, payment-request-insecure.http.html"> The PaymentRequest(|methodData|, - |details|, |options|) constructor MUST act as follows: + |details|) constructor MUST act as follows:

    1. If the current settings object's [=environment settings @@ -724,8 +544,8 @@

    2. For each |paymentMethod| of |methodData|:
      1. Run the steps - to validate a payment method identifier with + "payment-request-ctor-pmi-handling.https.sub.html">Run the + steps to validate a payment method identifier with |paymentMethod|.{{PaymentMethodData/supportedMethods}}. If it returns false, then throw a {{RangeError}} exception. Optionally, inform the developer that the payment method @@ -790,7 +610,7 @@

      2. Process the total:
        1. + "payment-request-ctor-currency-code-checks.https.sub.html"> Check and canonicalize total amount |details|.{{PaymentDetailsInit/total}}.{{PaymentItem/amount}}. Rethrow any exceptions. @@ -802,54 +622,12 @@

          |details|.{{PaymentDetailsBase/displayItems}}:
          1. + "payment-request-ctor-currency-code-checks.https.sub.html"> Check and canonicalize amount |item|.{{PaymentItem/amount}}. Rethrow any exceptions.

        2. -
        3. Let |selectedShippingOption| be null. -
        4. -
        5. If the {{PaymentOptions/requestShipping}} member of |options| is - present and set to true, process shipping options: -
            -
          1. Let |options:PaymentShippingOption| be an empty - sequence<{{PaymentShippingOption}}>. -
          2. -
          3. If the {{PaymentDetailsBase/shippingOptions}} member of - |details| is present, then: -
              -
            1. Let |seenIDs| be an empty set. -
            2. -
            3. For each |option:PaymentShippingOption| in - |details|.{{PaymentDetailsBase/shippingOptions}}: -
                -
              1. - Check and canonicalize amount - |item|.{{PaymentItem/amount}}. Rethrow any exceptions. -
              2. -
              3. If |seenIDs| contains - |option|.{{PaymentShippingOption/id}}, then throw a - {{TypeError}}. Optionally, inform the developer that - shipping option IDs must be unique. -
              4. -
              5. Otherwise, append - |option|.{{PaymentShippingOption/id}} to |seenIDs|. -
              6. -
              7. If |option|.{{PaymentShippingOption/selected}} is - true, then set |selectedShippingOption| to - |option|.{{PaymentShippingOption/id}}. -
              8. -
              -
            4. -
            -
          4. -
          5. Set |details|.{{PaymentDetailsBase/shippingOptions}} to - |options|. -
          6. -
          -
        6. Let |serializedModifierData| be an empty list.
        7. Process payment details modifiers: @@ -869,7 +647,7 @@

          |modifier| is present, then:
          1. + "payment-request-ctor-currency-code-checks.https.sub.html"> Check and canonicalize total amount |modifier|.{{PaymentDetailsModifier/total}}.{{PaymentItem/amount}}. Rethrow any exceptions. @@ -882,7 +660,7 @@

            |modifier|.{{PaymentDetailsModifier/additionalDisplayItems}}:
            1. + "payment-request-ctor-currency-code-checks.https.sub.html"> Check and canonicalize amount |item|.{{PaymentItem/amount}}. Rethrow any exceptions. @@ -916,8 +694,6 @@

            2. Set |request|.{{PaymentRequest/[[handler]]}} to `null`.
            3. -
            4. Set |request|.{{PaymentRequest/[[options]]}} to |options|. -
            5. Set |request|.{{PaymentRequest/[[state]]}} to "[=PaymentRequest/created=]".
            6. @@ -933,17 +709,6 @@

            7. Set |request|.{{PaymentRequest/[[response]]}} to null.
            8. -
            9. Set the value of |request|'s {{PaymentRequest/shippingOption}} - attribute to |selectedShippingOption|. -
            10. -
            11. Set the value of the {{PaymentRequest/shippingAddress}} attribute - on |request| to null. -
            12. -
            13. If |options|.{{PaymentOptions/requestShipping}} is set to true, - then set the value of the {{PaymentRequest/shippingType}} attribute - on |request| to |options|.{{PaymentOptions/shippingType}}. Otherwise, - set it to null. -
            14. Return |request|.
            @@ -1155,9 +920,8 @@

          2. -
          3. - If |detailsPromise| was passed, then: +
          4. If + |detailsPromise| was passed, then:
            1. Run the update a PaymentRequest's details algorithm with |detailsPromise|, |request|, and null. @@ -1391,69 +1155,11 @@

              make payment algorithm.

    -
    -

    - shippingAddress attribute -

    -

    - A {{PaymentRequest}}'s {{PaymentRequest/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 {{PaymentRequest/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 - [=PaymentRequest.PaymentRequest()|construction=] (see - {{PaymentOptions}}'s {{PaymentOptions/shippingType}} member). -

    -
    -
    -

    - onshippingaddresschange attribute -

    -

    - A {{PaymentRequest}}'s {{PaymentRequest/onshippingaddresschange}} - attribute is an {{EventHandler}} for a {{PaymentRequestUpdateEvent}} - named shippingaddresschange. -

    -
    -
    -

    - shippingOption attribute -

    -

    - A {{PaymentRequest}}'s {{PaymentRequest/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 {{PaymentRequest/onshippingoptionchange}} - attribute is an {{EventHandler}} for a {{PaymentRequestUpdateEvent}} - named shippingoptionchange. -

    -

    onpaymentmethodchange attribute

    -

    +

    A {{PaymentRequest}}'s {{PaymentRequest/onpaymentmethodchange}} attribute is an {{EventHandler}} for a {{PaymentMethodChangeEvent}} named "paymentmethodchange". @@ -1516,15 +1222,6 @@

    {{PaymentRequest/[[serializedModifierData]]}} internal slot. - - - [[\options]] - - - The {{PaymentOptions}} supplied to the constructor. - - [[\state]] @@ -1822,7 +1519,6 @@

             dictionary PaymentDetailsBase {
               sequence<PaymentItem> displayItems;
    -          sequence<PaymentShippingOption> shippingOptions;
               sequence<PaymentDetailsModifier> modifiers;
             };
             
    @@ -1839,41 +1535,6 @@

    {{PaymentDetailsInit/total}} amount is the sum of these items. -
    - shippingOptions member -
    -
    -

    - A sequence containing the different shipping options for the user - to choose from. -

    -

    - If an item in the sequence has the - {{PaymentShippingOption/selected}} member set to true, then this - is the shipping option that will be used by default and - {{PaymentRequest/shippingOption}} will be set to the - {{PaymentShippingOption/id}} of this option without running the - shipping option changed algorithm. If more than one item - in the sequence has {{PaymentShippingOption/selected}} set to - true, then the user agent selects the last one in the - sequence. -

    -

    - The {{PaymentDetailsBase/shippingOptions}} member is only used if - the {{PaymentRequest}} was constructed with {{PaymentOptions}} - and {{PaymentOptions/requestShipping}} set to true. -

    - -
    modifiers member
    @@ -1937,10 +1598,7 @@

               dictionary PaymentDetailsUpdate : PaymentDetailsBase {
    -            DOMString error;
                 PaymentItem total;
    -            AddressErrors shippingAddressErrors;
    -            PayerErrors payerErrors;
                 object paymentMethodErrors;
               };
             
    @@ -1954,21 +1612,6 @@

    {{PaymentDetailsUpdate}} dictionary:

    -
    - error member -
    -
    - A human-readable string that explains why goods cannot be shipped - to the chosen shipping address, or any other reason why no shipping - options are available. When the payment request is updated using - {{PaymentRequestUpdateEvent/updateWith()}}, the - {{PaymentDetailsUpdate}} can contain a message in the - {{PaymentDetailsUpdate/error}} member that will be displayed to the - user if the {{PaymentDetailsUpdate}} indicates that there are no - valid {{PaymentDetailsBase/shippingOptions}} (and the - {{PaymentRequest}} was constructed with the - {{PaymentOptions/requestShipping}} option set to true). -
    total member
    @@ -1981,19 +1624,6 @@

    is a negative number.

    -
    - shippingAddressErrors member -
    -
    - Represents validation errors with the shipping address that is - associated with the potential event target. -
    -
    - payerErrors member -
    -
    - Validation errors related to the payer details. -
    paymentMethodErrors member
    @@ -2072,131 +1702,6 @@

    -
    -

    - PaymentShippingType enum -

    -
    -        enum PaymentShippingType {
    -          "shipping",
    -          "delivery",
    -          "pickup"
    -        };
    -      
    -
    -
    - "shipping" -
    -
    - This is the default and refers to the address being collected as the - destination for shipping. -
    -
    - "delivery" -
    -
    - This refers to the address being collected as the destination for - delivery. This is commonly faster than shipping. For example, it - might be used for food delivery. -
    -
    - "pickup" -
    -
    - This refers to the address being collected as part of a service - pickup. For example, this could be the address for laundry pickup. -
    -
    -
    -
    -

    - PaymentOptions dictionary -

    -
    -        dictionary PaymentOptions {
    -          boolean requestPayerName = false;
    -          boolean requestBillingAddress = 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. -

    -
    -
    - requestBillingAddress member -
    -
    - A boolean that indicates whether the user agent SHOULD collect - and return the billing address associated with a payment - method (e.g., the billing address associated with a credit card). - Typically, the user agent will return the billing address as part of - the {{PaymentMethodChangeEvent}}'s - {{PaymentMethodChangeEvent/methodDetails}}. A merchant can use this - information to, for example, calculate tax in certain jurisdictions - and update the displayed total. See below for privacy considerations - regarding exposing user information. -
    -
    - requestPayerName member -
    -
    - A boolean that indicates whether the user agent SHOULD collect - and return the payer's name as part of the payment request. For - example, this would be set to true to allow a merchant to make a - booking in the payer's name. -
    -
    - requestPayerEmail member -
    -
    - A boolean that indicates whether the user agent SHOULD collect - and return the payer's email address as part of the payment request. - For example, this would be set to true to allow a merchant to email a - receipt. -
    -
    - requestPayerPhone member -
    -
    - A boolean that indicates whether the user agent SHOULD collect - and return the payer's phone number as part of the payment request. - For example, this would be set to true to allow a merchant to phone a - customer with a billing enquiry. -
    -
    - requestShipping member -
    -
    - A boolean that indicates whether the user agent SHOULD collect - and return a shipping address as part of the payment request. For - example, this would be set to true when physical goods need to be - shipped by the merchant to the user. This would be set to false for - the purchase of digital goods. -
    -
    - shippingType member -
    -
    - A {{PaymentShippingType}} enum value. Some transactions require an - address for delivery but the term "shipping" isn't appropriate. For - example, "pizza delivery" not "pizza shipping" and "laundry pickup" - not "laundry shipping". If {{PaymentOptions/requestShipping}} is set - to true, then the {{PaymentOptions/shippingType}} member can - influence the way the user agent presents the user interface - for gathering the shipping address. -

    - The {{PaymentOptions/shippingType}} member only affects the user - interface for the payment request. -

    -
    -
    -

    PaymentItem dictionary @@ -2240,831 +1745,38 @@

    -
    +

    - Physical addresses + PaymentComplete enum

    -

    - A physical address is composed of the following parts. -

    -
    -
    - Country -
    -
    - The country corresponding to the address. -
    -
    - Address line -
    -
    - 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. -
    -
    - Dependent locality -
    -
    - The dependent locality or sublocality within a city. For example, - neighborhoods, boroughs, districts, or UK dependent localities. -
    -
    - Postal code -
    -
    - The postal code or ZIP code, also known as PIN code in India. -
    +
    +        enum PaymentComplete {
    +          "fail",
    +          "success",
    +          "unknown"
    +        };
    +      
    +
    - Sorting code + "fail"
    - The sorting code system, such as the CEDEX system used in France. + Indicates that processing of the payment failed. The user + agent MAY display UI indicating failure.
    - Organization + "success"
    - The organization, firm, company, or institution at the address. + Indicates the payment was successfully processed. The user + agent MAY display UI indicating success.
    - Recipient + "unknown"
    - The name of the recipient or contact person at the address. -
    -
    - Phone number -
    -
    - The phone number of the recipient or contact person at the address. -
    -
    -
    -

    - PaymentAddress interface -

    -
    -          [SecureContext, Exposed=(Window)]
    -          interface PaymentAddress {
    -            [Default] object toJSON();
    -            readonly attribute DOMString city;
    -            readonly attribute DOMString country;
    -            readonly attribute DOMString dependentLocality;
    -            readonly attribute DOMString organization;
    -            readonly attribute DOMString phone;
    -            readonly attribute DOMString postalCode;
    -            readonly attribute DOMString recipient;
    -            readonly attribute DOMString region;
    -            readonly attribute DOMString sortingCode;
    -            readonly attribute FrozenArray<DOMString> addressLine;
    -          };
    -        
    -

    - The {{PaymentAddress}} interface represents a physical - address. -

    - -
    -

    - Internal constructor -

    -

    - The steps to internally construct a - `PaymentAddress` with an optional {{AddressInit}} - |details:AddressInit| are given by the following algorithm: -

    -
      -
    1. Let |address:PaymentAddress| be a new instance of - {{PaymentAddress}}. -
    2. -
    3. Set |address|.{{PaymentAddress/[[addressLine]]}} to the empty - frozen array, and all other [=PaymentAddress slots|internal slots=] - to the empty string. -
    4. -
    5. If |details| was not passed, return |address|. -
    6. -
    7. If |details|.{{AddressInit/country}} is present and not the - empty string: -
        -
      1. Set |country| the result of strip leading and trailing - ASCII whitespace from |details|.{{AddressInit/country}} and - performing ASCII uppercase. -
      2. -
      3. If |country| is not a valid [[ISO3166-1]] alpha-2 code, - throw a {{RangeError}} exception. -
      4. -
      5. Set |address|.{{PaymentAddress/[[country]]}} to |country|. -
      6. -
      -
    8. -
    9. Let |cleanAddressLines:list| be an empty list. -
    10. -
    11. If |details|.{{AddressInit/addressLine}} is present, then for - each |item| in |details|.{{AddressInit/addressLine}}: -
        -
      1. - Strip leading and trailing ASCII whitespace from - |item| and append the result into |cleanAddressLines|. -
      2. -
      -
    12. -
    13. Set |address|.{{PaymentAddress/[[addressLine]]}} to a new - frozen array created from |cleanAddressLines|. -
    14. -
    15. If |details|.{{AddressInit/region}} is present, strip - leading and trailing ASCII whitespace from - |details|.{{AddressInit/region}} and set - |address|.{{PaymentAddress/[[region]]}} to the result. -
    16. -
    17. If |details|.{{AddressInit/city}} is present, strip leading - and trailing ASCII whitespace from - |details|.{{AddressInit/city}} and set - |address|.{{PaymentAddress/[[city]]}} to the result. -
    18. -
    19. If |details|.{{AddressInit/dependentLocality}} is present, - strip leading and trailing ASCII whitespace from - |details|.{{AddressInit/dependentLocality}} and set - |address|.{{PaymentAddress/[[dependentLocality]]}} to the result. -
    20. -
    21. If |details|.{{AddressInit/postalCode}} is present, strip - leading and trailing ASCII whitespace from - |details|.{{AddressInit/postalCode}} and set - |address|.{{PaymentAddress/[[postalCode]]}} to the result. -
    22. -
    23. If |details|.{{AddressInit/sortingCode}} is present, strip - leading and trailing ASCII whitespace from - |details|.{{AddressInit/sortingCode}} and set - |address|.{{PaymentAddress/[[sortingCode]]}} to the result. -
    24. -
    25. If |details|.{{AddressInit/organization}} is present, strip - leading and trailing ASCII whitespace from - |details|.{{AddressInit/organization}} and set - |address|.{{PaymentAddress/[[organization]]}} to the result. -
    26. -
    27. If |details|.{{AddressInit/recipient}} is present, strip - leading and trailing ASCII whitespace from - |details|.{{AddressInit/recipient}} and set - |address|.{{PaymentAddress/[[recipient]]}} to the result. -
    28. -
    29. If |details|.{{AddressInit/phone}} is present, strip leading - and trailing ASCII whitespace from - |details|.{{AddressInit/phone}} and set - |address|.{{PaymentAddress/[[phone]]}} to the result. -
    30. -
    31. Return |address|. -
    32. -
    -
    -
    -

    - country attribute -

    -

    - Represents the country of the address. When getting, returns - the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[country]]}} internal slot. -

    -
    -
    -

    - addressLine attribute -

    -

    - Represents the address line of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[addressLine]]}} internal slot. -

    -
    -
    -

    - region attribute -

    -

    - Represents the region of the address. When getting, returns - the value of the {{PaymentAddress}}'s {{PaymentAddress/[[region]]}} - internal slot. -

    -
    -
    -

    - city attribute -

    -

    - Represents the city of the address. When getting, returns - the value of the {{PaymentAddress}}'s {{PaymentAddress/[[city]]}} - internal slot. -

    -
    -
    -

    - dependentLocality attribute -

    -

    - Represents the dependent locality of the address. When - getting, returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[dependentLocality]]}} internal slot. -

    -
    -
    -

    - postalCode attribute -

    -

    - Represents the postal code of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[postalCode]]}} internal slot. -

    -
    -
    -

    - sortingCode attribute -

    -

    - Represents the sorting code of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[sortingCode]]}} internal slot. -

    -
    -
    -

    - organization attribute -

    -

    - Represents the organization of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[organization]]}} internal slot. -

    -
    -
    -

    - recipient attribute -

    -

    - Represents the recipient of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[recipient]]}} internal slot. -

    -
    -
    -

    - phone attribute -

    -

    - Represents the phone number of the address. When getting, - returns the value of the {{PaymentAddress}}'s - {{PaymentAddress/[[phone]]}} internal slot. -

    -
    -
    -

    - Internal - slots -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Internal slot - - Description (non-normative) -
    - [[\country]] - - A country as an [[ISO3166-1]] alpha-2 code stored in its - canonical uppercase form or the empty string. For example, - "JP". -
    - [[\addressLine]] - - A frozen array, possibly of zero length, representing an - address line. -
    - [[\region]] - - A region as a country subdivision name or the - empty string, such as "Victoria", representing the state of - Victoria in Australia. -
    - [[\city]] - - A city or the empty string. -
    - [[\dependentLocality]] - - A dependent locality or the empty string. -
    - [[\postalCode]] - - A postal code or the empty string. -
    - [[\sortingCode]] - - A sorting code or the empty string. -
    - [[\organization]] - - An organization or the empty string. -
    - [[\recipient]] - - A recipient or the empty string. -
    - [[\phone]] - - A phone number or the empty string. -
    -
    -
    -
    -

    - AddressInit dictionary -

    -
    -          dictionary AddressInit {
    -            DOMString country = "";
    -            sequence<DOMString> addressLine = [];
    -            DOMString region = "";
    -            DOMString city = "";
    -            DOMString dependentLocality = "";
    -            DOMString postalCode = "";
    -            DOMString sortingCode = "";
    -            DOMString organization = "";
    -            DOMString recipient = "";
    -            DOMString phone = "";
    -          };
    -        
    -

    - An {{AddressInit}} is passed when - [=PaymentAddress.PaymentAddress()|constructing=] a - {{PaymentAddress}}. Its members are as follows. -

    -
    -
    - country member -
    -
    - An country, represented as a [[ISO3166-1]] country code. -
    -
    - addressLine member -
    -
    - An address line, represented as a sequence. -
    -
    - region member -
    -
    - A region. -
    -
    - city member -
    -
    - A city. -
    -
    - dependentLocality member -
    -
    - A dependent locality. -
    -
    - postalCode member -
    -
    - A postal code. -
    -
    - sortingCode member -
    -
    - A sorting code. -
    -
    - organization member -
    -
    - An organization. -
    -
    - recipient member -
    -
    - A recipient. Under certain circumstances, this member may - contain multiline information. For example, it might contain "care - of" information. -
    -
    - phone member -
    -
    - A phone number, optionally structured to adhere to - [[E.164]]. -
    -
    -
    -
    -

    - AddressErrors dictionary -

    -
    -          dictionary AddressErrors {
    -            DOMString addressLine;
    -            DOMString city;
    -            DOMString country;
    -            DOMString dependentLocality;
    -            DOMString organization;
    -            DOMString phone;
    -            DOMString postalCode;
    -            DOMString recipient;
    -            DOMString region;
    -            DOMString sortingCode;
    -          };
    -        
    -

    - The members of the {{AddressErrors}} dictionary represent validation - errors with specific parts of a physical address. Each - dictionary member has a dual function: firstly, its presence denotes - that a particular part of an address is suffering from a validation - error. Secondly, the string value allows the developer to describe - the validation error (and possibly how the end user can fix the - error). -

    -

    - Developers need to be aware that users might not have the ability to - fix certain parts of an address. As such, they need to be mindful not - to ask the user to fix things they might not have control over. -

    -
    -
    - addressLine member -
    -
    - Denotes that the address line has a validation error. In the - user agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/addressLine}} - attribute's value. -
    -
    - city member -
    -
    - Denotes that the city has a validation error. In the user - agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/city}} - attribute's value. -
    -
    - country member -
    -
    - Denotes that the country has a validation error. In the user - agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/country}} - attribute's value. -
    -
    - dependentLocality member -
    -
    - Denotes that the dependent locality has a validation error. - In the user agent's UI, this member corresponds to the input field - that provided the {{PaymentAddress}}'s - {{PaymentAddress/dependentLocality}} attribute's value. -
    -
    - organization member -
    -
    - Denotes that the organization has a validation error. In the - user agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/organization}} - attribute's value. -
    -
    - phone member -
    -
    - Denotes that the phone number has a validation error. In the - user agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/phone}} - attribute's value. -
    -
    - postalCode member -
    -
    - Denotes that the postal code has a validation error. In the - user agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/postalCode}} - attribute's value. -
    -
    - recipient member -
    -
    - Denotes that the recipient has a validation error. In the - user agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/addressLine}} - attribute's value. -
    -
    - region member -
    -
    - Denotes that the region has a validation error. In the user - agent's UI, this member corresponds to the input field that - provided the {{PaymentAddress}}'s {{PaymentAddress/region}} - attribute's value. -
    -
    - sortingCode member -
    -
    - The sorting code has a validation error. In the user agent's - UI, this member corresponds to the input field that provided the - {{PaymentAddress}}'s {{PaymentAddress/sortingCode}} attribute's - value. -
    -
    -
    -
    -

    - Creating a `PaymentAddress` from user-provided input -

    -

    - The steps to create a `PaymentAddress` from - user-provided input are given by the following algorithm. The - algorithm takes a list |redactList|. -

    -
    -

    - 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 shipping costs, but, - in most cases, not enough information to physically locate and - uniquely identify the recipient. -

    -

    - 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. -

    -
    -
      -
    1. Let |details:AddressInit| be a newly created {{AddressInit}} - dictionary. -
    2. -
    3. If "addressLine" is not in |redactList|, set - |details|.{{AddressInit/addressLine}} to the result of splitting the - user-provided address line into a list. - -
    4. -
    5. If "country" is not in |redactList|, set - |details|.{{AddressInit/country}} to the user-provided country as an - upper case [[ISO3166-1]] alpha-2 code. -
    6. -
    7. If "phone" is not in |redactList|, set - |details|.{{AddressInit/phone}} to the user-provided phone number. - -
    8. -
    9. If "city" is not in |redactList|, set - |details|.{{AddressInit/city}} to the user-provided city, or to the - empty string if none was provided. -
    10. -
    11. If "dependentLocality" is not in |redactList|, set | - details|.{{AddressInit/dependentLocality}} to the user-provided - dependent locality. -
    12. -
    13. If "organization" is not in |redactList|, set - |details|.{{AddressInit/organization}} to the user-provided recipient - organization. -
    14. -
    15. If "postalCode" is not in |redactList|, set - |details|.{{AddressInit/postalCode}} to the user-provided postal - code. Optionally, redact part of - |details|.{{AddressInit/postalCode}}. -
      -

      - Postal codes in certain countries can be so specific as - to uniquely identify an individual. This being a privacy - concern, some user agents only return the part of a postal code - that they deem sufficient for a merchant to calculate shipping - costs. This varies across countries and regions, and so the - choice to redact part, or all, of the postal code is left to - the discretion of implementers in the interest of protecting - users' privacy. -

      -
      -
    16. -
    17. If "recipient" is not in |redactList|, set - |details|.{{AddressInit/recipient}} to the user-provided recipient of - the transaction. -
    18. -
    19. -

      - If "region" is not in |redactList|: -

      -

      - In some countries (e.g., Belgium) it is uncommon for users to - include a region as part of a physical address - (even if all the regions of a country are part of [[ISO3166-2]]). - As such, when the user agent knows that the user is inputting the - address for a particular country, it might not provide a field - for the user to input a region. In such cases, the user - agent returns an empty string for both {{PaymentAddress}}'s - {{PaymentAddress/region}} attribute - but the address can still - serve its intended purpose (e.g., be valid for shipping or - billing purposes). -

      -
        -
      1. Set |details|.{{AddressInit/region}} to the user-provided - region. -
      2. -
      -
    20. -
    21. If "sortingCode" is not in |redactList|, set - |details|.{{AddressInit/sortingCode}} to the user-provided sorting - code. -
    22. -
    23. [=PaymentAddress.PaymentAddress()|Internally construct a new - `PaymentAddress`=] with |details| and return the result. -
    24. -
    -
    -
    -
    -

    - 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 - {{PaymentRequestUpdateEvent/updateWith()}} method in response to a - change event. -

    -
    -
    - id member -
    -
    - A string identifier used to reference this {{PaymentShippingOption}}. - It MUST be unique for a given {{PaymentRequest}}. -
    -
    - label member -
    -
    - A human-readable string description of the item. The user - agent SHOULD use this string to display the shipping option to - the user. -
    -
    - amount member -
    -
    - A {{PaymentCurrencyAmount}} containing the monetary amount for the - item. -
    -
    - selected member -
    -
    - A boolean. When true, it indicates that this is the default selected - {{PaymentShippingOption}} in a sequence. User agents SHOULD - display this option by default in the user interface. -
    -
    -
    -
    -

    - PaymentComplete enum -

    -
    -        enum PaymentComplete {
    -          "fail",
    -          "success",
    -          "unknown"
    -        };
    -      
    -
    -
    - "fail" -
    -
    - Indicates that processing of the payment failed. The user - agent MAY display UI indicating failure. -
    -
    - "success" -
    -
    - Indicates the payment was successfully processed. The user - agent MAY display UI indicating success. -
    -
    - "unknown" -
    -
    - The developer did not indicate success or failure and the user - agent SHOULD NOT display UI indicating success or failure. + The developer did not indicate success or failure and the user + agent SHOULD NOT display UI indicating success or failure.
    @@ -3080,18 +1792,11 @@

    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; [NewObject] Promise<undefined> complete(optional PaymentComplete result = "unknown"); [NewObject] Promise<undefined> retry(optional PaymentValidationErrors errorFields = {}); - - attribute EventHandler onpayerdetailchange; };

    @@ -3131,7 +1836,7 @@

    during {{PaymentResponse/retry()}}.

    -

    +

    The retry(|errorFields:PaymentValidationErrors|) method MUST act as follows:

    @@ -3167,35 +1872,6 @@

  • If |errorFields:PaymentValidationErrors| was passed:
      -
    1. Optionally, show a warning in the developer console if any of - the following are true: -
        -
      1. - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestPayerName}} - is false, and - |errorFields|.{{PaymentValidationErrors/payer}}.{{PayerErrors/name}} - is present. -
      2. -
      3. - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestPayerEmail}} - is false, and - |errorFields|.{{PaymentValidationErrors/payer}}.{{PayerErrors/email}} - is present. -
      4. -
      5. - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestPayerPhone}} - is false, and - |errorFields|.{{PaymentValidationErrors/payer}}.{{PayerErrors/phone}} - is present. -
      6. -
      7. - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestShipping}} - is false, and - |errorFields|.{{PaymentValidationErrors/shippingAddress}} is - present. -
      8. -
      -
    2. If @@ -3271,26 +1947,11 @@

                   dictionary PaymentValidationErrors {
      -              PayerErrors payer;
      -              AddressErrors shippingAddress;
                     DOMString error;
                     object paymentMethod;
                   };
                 
      -
      - payer member -
      -
      - Validation errors related to the payer details. -
      -
      - shippingAddress member -
      -
      - Represents validation errors with the {{PaymentResponse}}'s - {{PaymentResponse/shippingAddress}}. -
      error member
      @@ -3313,63 +1974,6 @@

  • -
    -

    - PayerErrors dictionary -

    -
    -          dictionary PayerErrors {
    -            DOMString email;
    -            DOMString name;
    -            DOMString phone;
    -          };
    -          
    -

    - The {{PayerErrors}} is used to represent validation errors with one - or more payer details. -

    -

    - Payer details are any of the payer's name, payer's phone - number, and payer's email. -

    -
    -
    - email member -
    -
    - Denotes that the payer's email suffers from a validation error. - In the user agent's UI, this member corresponds to the input - field that provided the {{PaymentResponse}}'s - {{PaymentResponse/payerEmail}} attribute's value. -
    -
    - name member -
    -
    - Denotes that the payer's name suffers from a validation error. In - the user agent's UI, this member corresponds to the input field - that provided the {{PaymentResponse}}'s - {{PaymentResponse/payerName}} attribute's value. -
    -
    - phone member -
    -
    - Denotes that the payer's phone number suffers from a validation - error. In the user agent's UI, this member corresponds to the - input field that provided the {{PaymentResponse}}'s - {{PaymentResponse/payerPhone}} attribute's value. -
    -
    -
    -            const payer = {
    -              email: "The domain is invalid.",
    -              phone: "Unknown country code.",
    -              name: "Not in database.",
    -            };
    -            await response.retry({ payer });
    -          
    -

    @@ -3408,66 +2012,6 @@

    -
    -

    - shippingAddress attribute -

    -

    - If the {{PaymentOptions/requestShipping}} member was set to true in - the {{PaymentOptions}} passed to the {{PaymentRequest}} constructor, - then {{PaymentRequest/shippingAddress}} will be the full and final - shipping address chosen by the user. -

    -
    -
    -

    - shippingOption attribute -

    -

    - If the {{PaymentOptions/requestShipping}} member was set to true in - the {{PaymentOptions}} passed to the {{PaymentRequest}} constructor, - then {{PaymentRequest/shippingOption}} will be the - {{PaymentShippingOption/id}} attribute of the selected shipping - option. -

    -
    -
    -

    - payerName attribute -

    -

    - If the {{PaymentOptions/requestPayerName}} member was set to true in - the {{PaymentOptions}} passed to the {{PaymentRequest}} constructor, - then {{PaymentResponse/payerName}} will be the name provided by the - user. -

    -
    -
    -

    - payerEmail attribute -

    -

    - If the {{PaymentOptions/requestPayerEmail}} member was set to true in - the {{PaymentOptions}} passed to the {{PaymentRequest}} constructor, - then {{PaymentResponse/payerEmail}} will be the email address chosen - by the user. -

    -
    -
    -

    - payerPhone attribute -

    -

    - If the {{PaymentOptions/requestPayerPhone}} member was set to true in - the {{PaymentOptions}} passed to the {{PaymentRequest}} constructor, - then {{PaymentResponse/payerPhone}} will be the phone number chosen - by the user. -

    -

    requestId attribute @@ -3553,14 +2097,6 @@

    -
    -

    - onpayerdetailchange attribute -

    -

    - Allows a developer to handle "payerdetailchange" events. -

    -

    Internal Slots @@ -3654,49 +2190,6 @@

    Target - - - shippingaddresschange - - - {{PaymentRequestUpdateEvent}} - - - The user provides a new shipping address. - - - {{PaymentRequest}} - - - - - shippingoptionchange - - - {{PaymentRequestUpdateEvent}} - - - The user chooses a new shipping option. - - - {{PaymentRequest}} - - - - - payerdetailchange - - - {{PaymentRequestUpdateEvent}} - - - The user changes the payer name, the payer email, or the payer - phone (see payer detail changed algorithm). - - - {{PaymentResponse}} - - paymentmethodchange @@ -3828,50 +2321,13 @@

    changes made by the end user through the UI), developers need to immediately call {{PaymentRequestUpdateEvent/updateWith()}}.

    -
    -              // ❌ Bad - this won't work!
    -              request.onshippingaddresschange = async ev => {
    -                // await goes to next tick, and updateWith()
    -                // was not called.
    -                const details = await getNewDetails(oldDetails);
    -                // 💥 So it's now too late! updateWith()
    -                // throws "InvalidStateError".
    -                ev.updateWith(details);
    -              };
    -
    -              // ✅ Good - UI will wait.
    -              request.onshippingaddresschange = ev => {
    -                // Calling updateWith() with a promise is ok 👍
    -                const promiseForNewDetails = getNewDetails(oldDetails);
    -                ev.updateWith(promiseForNewDetails);
    -              };
    -            

    Additionally, {{PaymentRequestUpdateEvent/[[waitForUpdate]]}} prevents reuse of {{PaymentRequestUpdateEvent}}.

    -
    -              // ❌ Bad - calling updateWith() twice doesn't work!
    -              request.addEventListener("shippingaddresschange", ev => {
    -                ev.updateWith(details); // this is ok.
    -                // 💥 [[waitForUpdate]] is true, throws "InvalidStateError".
    -                ev.updateWith(otherDetails);
    -              });
    -
    -              // ❌ Bad - this won't work either!
    -              request.addEventListener("shippingaddresschange", async ev => {
    -                const p = Promise.resolve({ ...details });
    -                ev.updateWith(p);
    -                await p;
    -                // 💥 Only one call to updateWith() is allowed,
    -                // so the following throws "InvalidStateError"
    -                ev.updateWith({ ...newDetails });
    -              });
    -            

    + "PaymentRequestUpdateEvent/updatewith-method.https.html"> The {{PaymentRequestUpdateEvent/updateWith()}} with |detailsPromise:Promise| method MUST act as follows:

    @@ -4019,88 +2475,6 @@

    -
    -

    - Shipping address changed algorithm -

    -

    - The shipping address changed algorithm runs when the user - provides a new shipping address. It MUST run the following steps: -

    -
      -
    1. Let |request:PaymentRequest| be the {{PaymentRequest}} object - that the user is interacting with. -
    2. -
    3. - Queue a task on the user interaction task source to - run the following steps: -
        -
      1. -
        -

        - The |redactList| limits 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 - shipping costs, but, in most cases, not enough information - to physically locate and uniquely identify the recipient. -

        -

        - 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. -
      3. Let |redactList:list| be the empty list. Set |redactList| to - « "organization", "phone", "recipient", "addressLine" ». -
      4. -
      5. Let |address:PaymentAddress| be the result of running the - steps to create a `PaymentAddress` from user-provided - input with |redactList|. -
      6. -
      7. Set |request|.{{PaymentRequest/shippingAddress}} to - |address|. -
      8. -
      9. Run the PaymentRequest updated algorithm with - |request| and "shippingaddresschange". -
      10. -
      -
    4. -
    -
    -
    -

    - Shipping option changed algorithm -

    -

    - The shipping option changed algorithm runs when the user - chooses a new shipping option. It MUST run the following steps: -

    -
      -
    1. Let |request:PaymentRequest| be the {{PaymentRequest}} object - that the user is interacting with. -
    2. -
    3. - Queue a task on the user interaction task source to - run the following steps: -
        -
      1. Set the {{PaymentRequest/shippingOption}} attribute on - |request| to the id string of the - {{PaymentShippingOption}} provided by the user. -
      2. -
      3. Run the PaymentRequest updated algorithm with - |request| and "shippingoptionchange". -
      4. -
      -
    4. -
    -

    Payment method changed algorithm @@ -4114,15 +2488,6 @@

    method identifier of the payment handler the user is interacting with.

    -

    - When the user selects or changes a payment method (e.g., a credit - card), the {{PaymentMethodChangeEvent}} includes redacted billing - address information for the purpose of performing tax calculations. - Redacted attributes include, but are not limited to, address - line, dependent locality, organization, phone - number, and recipient. -

    1. Let |request:PaymentRequest| be the {{PaymentRequest}} object that the user is interacting with. @@ -4153,7 +2518,7 @@

      PaymentRequest updated algorithm

      -

      +

      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 @@ -4184,85 +2549,11 @@

    -
    -

    - Payer detail changed algorithm -

    -

    - The user agent MUST run the payer detail changed algorithm - when the user changes the |payer name|, or the |payer email|, or the - |payer phone| in the user interface: -

    -
      -
    1. Let |request:PaymentRequest| be the {{PaymentRequest}} object - that the user is interacting with. -
    2. -
    3. If |request|.{{PaymentRequest/[[response]]}} is null, return. -
    4. -
    5. Let |response:PaymentResponse| be - |request|.{{PaymentRequest/[[response]]}}. -
    6. -
    7. - Queue a task on the user interaction task source to - run the following steps: -
        -
      1. Assert: |request|.{{PaymentRequest/[[updating]]}} is false. -
      2. -
      3. Assert: |request|.{{PaymentRequest/[[state]]}} is - "[=PaymentRequest/interactive=]". -
      4. -
      5. Let |options:PaymentOptions| be - |request|.{{PaymentRequest/[[options]]}}. -
      6. -
      7. If |payer name| changed and - |options|.{{PaymentOptions/requestPayerName}} is true: -
          -
        1. Set |response|.{{PaymentResponse/payerName}} attribute to - |payer name|. -
        2. -
        -
      8. -
      9. If |payer email| changed and - |options|.{{PaymentOptions/requestPayerEmail}} is true: -
          -
        1. Set |response|.{{PaymentResponse/payerEmail}} to |payer - email|. -
        2. -
        -
      10. -
      11. If |payer phone| changed and - |options|.{{PaymentOptions/requestPayerPhone}} is true: -
          -
        1. Set |response|.{{PaymentResponse/payerPhone}} to |payer - phone|. -
        2. -
        -
      12. -
      13. Let |event:PaymentRequestUpdateEvent| be the result of - creating an event using {{PaymentRequestUpdateEvent}}. -
      14. -
      15. Initialize |event|'s {{Event/type}} attribute to - "payerdetailchange". -
      16. -
      17. - Dispatch |event| at |response|. -
      18. -
      19. If |event|.{{PaymentRequestUpdateEvent/[[waitForUpdate]]}} is - true, disable any part of the user interface that could cause - another change to the payer details to be fired. -
      20. -
      21. Otherwise, set - |event|.{{PaymentRequestUpdateEvent/[[waitForUpdate]]}} to true. -
      22. -
      -
    8. -
    -

    User accepts the payment request algorithm

    -

    +

    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 @@ -4282,13 +2573,6 @@

    take no further action. The user agent user interface SHOULD ensure that this never occurs. -
  • If the {{PaymentOptions/requestShipping}} value of - |request|.{{PaymentRequest/[[options]]}} is true, then if the - {{PaymentRequest/shippingAddress}} attribute of |request| is null or - if the {{PaymentRequest/shippingOption}} attribute of |request| is - null, then terminate this algorithm and take no further action. The - user agent SHOULD ensure that this never occurs. -
  • Let |isRetry:boolean| be true if |request|.{{PaymentRequest/[[response]]}} is not null, false otherwise. @@ -4323,50 +2607,6 @@

    to an object resulting from running the |handler|'s steps to respond to a payment request.

  • -
  • If the {{PaymentOptions/requestShipping}} value of - |request|.{{PaymentRequest/[[options]]}} is false, then set the - {{PaymentResponse/shippingAddress}} attribute value of |response| to - null. Otherwise: -
      -
    1. Let |redactList:list| be the empty list. -
    2. -
    3. Let |shippingAddress:PaymentAddress| be the result of - create a `PaymentAddress` from user-provided input with - |redactList|. -
    4. -
    5. Set the {{PaymentResponse/shippingAddress}} attribute value - of |response| to |shippingAddress|. -
    6. -
    7. Set the {{PaymentResponse/shippingAddress}} attribute value - of |request| to |shippingAddress|. -
    8. -
    -
  • -
  • If the {{PaymentOptions/requestShipping}} value of - |request|.{{PaymentRequest/[[options]]}} is true, then set the - {{PaymentResponse/shippingOption}} attribute of |response| to the - value of the {{PaymentResponse/shippingOption}} attribute of - |request|. Otherwise, set it to null. -
  • -
  • If the {{PaymentOptions/requestPayerName}} value of - |request|.{{PaymentRequest/[[options]]}} is true, then set the - {{PaymentResponse/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. -
  • -
  • If the {{PaymentOptions/requestPayerEmail}} value of - |request|.{{PaymentRequest/[[options]]}} is true, then set the - {{PaymentResponse/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. -
  • -
  • If the {{PaymentOptions/requestPayerPhone}} value of - |request|.{{PaymentRequest/[[options]]}} is true, then set the - {{PaymentResponse/payerPhone}} attribute of |response| to the payer's - phone number provided by the user, or to null if none was provided. - When setting the {{PaymentResponse/payerPhone}} value, the user agent - SHOULD format the phone number to adhere to [[E.164]]. -
  • Set |request|.{{PaymentRequest/[[state]]}} to "[=PaymentRequest/closed=]".
  • @@ -4478,11 +2718,6 @@

  • Let |serializedModifierData| be an empty list.
  • -
  • Let |selectedShippingOption| be null. -
  • -
  • Let |shippingOptions| be an empty - sequence<{{PaymentShippingOption}}>. -
  • Validate and canonicalize the details:
    1. If the {{PaymentDetailsUpdate/total}} member of |details| @@ -4508,41 +2743,6 @@

  • -
  • If the {{PaymentDetailsBase/shippingOptions}} member of - |details| is present, and - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestShipping}} - is true, then: -
      -
    1. Let |seenIDs| be an empty set. -
    2. -
    3. For each |option| in - |details|.{{PaymentDetailsBase/shippingOptions}}: -
        -
      1. - Check and canonicalize amount - |option|.{{PaymentShippingOption/amount}}. If an - exception is thrown, then abort the update - with |request| and that exception. -
      2. -
      3. - If |seenIDs|[|option|.{{PaymentShippingOption/id}] - exists, then abort the update with |request| - and a {{TypeError}}. -
      4. -
      5. Append |option|.{{PaymentShippingOption/id}} to - |seenIDs|. -
      6. -
      7. Append |option| to |shippingOptions|. -
      8. -
      9. If |option|.{{PaymentShippingOption/selected}} is - true, then set |selectedShippingOption| to - |option|.{{PaymentShippingOption/id}}. -
      10. -
      -
    4. -
    -
  • If the {{PaymentDetailsBase/modifiers}} member of |details| is present, then:
      @@ -4554,9 +2754,7 @@

    1. For each {{PaymentDetailsModifier}} |modifier| in |modifiers|:
        -
      1. - Run the steps to validate a payment method +
      2. Run the steps to validate a payment method identifier with |modifier|.{{PaymentDetailsModifier/supportedMethods}}. If it returns false, then abort the update @@ -4645,21 +2843,6 @@

    2. -
    3. If the {{PaymentDetailsBase/shippingOptions}} member of - |details| is present, and - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestShipping}} - is true, then: -
        -
      1. Set - |request|.{{PaymentRequest/[[details]]}}.{{PaymentDetailsBase/shippingOptions}} - to |shippingOptions|. -
      2. -
      3. Set the value of |request|'s - {{PaymentRequest/shippingOption}} attribute to - |selectedShippingOption|. -
      4. -
      -
    4. If the {{PaymentDetailsBase/modifiers}} member of |details| is present, then:
        @@ -4673,50 +2856,6 @@

    5. -
    6. -

      - If - |request|.{{PaymentRequest/[[options]]}}.{{PaymentOptions/requestShipping}} - is true, and - |request|.{{PaymentRequest/[[details]]}}.{{PaymentDetailsBase/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 - {{PaymentRequest/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 - {{PaymentDetailsUpdate/error}} member of |details|, if it - is present, to give more information about why there are - no valid shipping options for that address. -

      -

      - Further, if - |details|["{{PaymentDetailsUpdate/shippingAddressErrors}}"] - member is present, the user agent SHOULD display an error - specifically for each erroneous field of the shipping - address. This is done by matching each present member of - the {{AddressErrors}} to a corresponding input field in - the shown user interface. -

      -

      - Similarly, if |details|["{{payerErrors}}"] member is - present and |request|.{{PaymentRequest/[[options]]}}'s - {{PaymentOptions/requestPayerName}}, - {{PaymentOptions/requestPayerEmail}}, or - {{PaymentOptions/requestPayerPhone}} is true, then - display an error specifically for each erroneous field. -

      -

      - Likewise, if - |details|.{{PaymentDetailsUpdate/paymentMethodErrors}} is - present, then display errors specifically for each - erroneous input field for the particular payment method. -

      -
  • @@ -4909,7 +3048,7 @@

    The user agent MUST NOT share information about the user with - a developer (e.g., the shipping address) without user consent. + a developer without user consent.

    In particular, the {{PaymentMethodData}}'s {{PaymentMethodData/data}} @@ -4944,22 +3083,8 @@

    data shared via the {{PaymentMethodChangeEvent}}'s {{PaymentMethodChangeEvent/methodDetails}} attribute. Requirements and approaches for minimizing shared data are likely to vary by - payment method and might include: + payment method.

    -

    Where sharing of privacy-sensitive information might not be obvious to users (e.g., when [=payment handler/payment method changed @@ -5011,9 +3136,7 @@

    For the user-facing aspects of Payment Request API, implementations integrate with platform accessibility APIs via form controls and other - input modalities. Furthermore, to increase the intelligibility of - total, shipping addresses, and contact information, implementations - format data according to system conventions. + input modalities.

    @@ -5067,7 +3190,7 @@

    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