This specification allows a web application to handle requests for payment on the end-user's behalf. The API also allows a web application to manage multiple payment methods for the user (e.g., multiple credit cards, proprietary payment methods, etc.). The API relies on a service worker to handle the request for payment, and affords a web application the ability to present a UI suitable for fulfilling a request for payment.

Use cases and requirements

The use cases for this specification:

As such, the requirements are that this specification can:

Usage examples

Registering to handle payments

The following example shows how a web application requests permission to handle payment requests from the end-user. It also shows how a web application can then start to manage payment methods on behalf of the end-user.


      

Handling a request for payment

The following shows how to process a request for payment via a service worker. In this example, the credit card information is dynamically generated.

        

Checking if the app can make a payment

The following shows how a web application can respond to a merchant's request to check if it can make an payment.


      

Model

To enable web applications to handle requests for payment, this specification defines the following:

If granted the "payment-request-handler" permission, the web application can manage payment methods (e.g., credit cards, communication with a proprietary payment provider, etc.) on behalf of the user. This is done by via the a PaymentMethodMap, which is a persistent data-store for payment methods.

Handling payment requests is done through an "onpaymentrequest" event associated with a service worker registration: when there is a payment request that matches a payment method supported by the web application (e.g., basic card), the service worker is notified via an event. More specifically, it defines how to register web applications with user agents, gives recommendations on how the user agents can present registration information to user, and the interaction between a payment handler and another that has made a request for payment using the Payment Request API.

Identity

For the purpose of handling payment requests, a web application is identified by its origin.

As origin's are not the most user-friendly way for end-users to recognize a web application, it is RECOMMENDED that web applications support the Web App Manifest specification ([[!appmanifest]]). The [[!appmanifest]] specification provides end-user friendly meta-data and icons that can help end-users identify a web application.

Permission

The "payment-request-handler" permission is the permission associated with the usage of this specification. It is a boolean feature.

Extensions to the ServiceWorkerRegistration interface

        partial interface ServiceWorkerRegistration {
          [SameObject] readonly attribute PaymentManager paymentManager;
        };
      

PaymentManager interface

        interface paymentManager {
          readonly attribute PaymentMethodMap paymentMethods;
          Promise<PermissionState> register();
          Promise<void> unregister();
        };
        

PaymentMethodMap interface

        [Exposed=(Window,Worker)]
        interface PaymentMethodMap {
          [NewObject] Promise<boolean> delete(DOMString methodKey);
          [NewObject] Promise<PaymentMethodDetails> get(DOMString methodKey);
          [NewObject] Promise<sequence<DOMString>> keys();
          [NewObject] Promise<boolean> has(DOMString methodKey);
          [NewObject] Promise<void> set(DOMString methodKey, PaymentMethodDetails details);
          // This doesn't exist yet in WebIDL I think - need to coordinate with
          // Domenic.
          // asyncIterator = { record<DOMString, PaymentMethodDetails>> }
        };
        

Extensions to PaymentRequest interface

        interface PaymentRequest : EventTarget {
          readonly attribute FrozenArray<PaymentMethod> supportedMethods;
          readonly attribute DOMString? paymentRequestID;
          readonly attribute PaymentItem total;
          readonly attribute DisplayItems displayItems;
          readonly attribute sequence<RequestedData> requestedFields;
          attribute EventHander onabort;
        };
      

PaymentMethodDetails dictionary

        dictionary PaymentMethodDetails {
          required DOMString name;
          required Sequence<DOMString> method;
          sequence <PaymentMethodIcon> icons;
        };
      

PaymentMethodIcon dictionary

        dictionary PaymentMethodIcon {
          USVString src;
          DOMString sizes;
          DOMString type;
        };
      
        partial interface ServiceWorkerGlobalScope {
          attribute EventHandler onpaymentrequest;
          attribute EventHandler oncanMakePayment;
        };
      

PaymentRequestDetails interface

      interface PaymentRequestDetails : EventTarget {
        readonly attribute DOMString? id;
        readonly attribute PaymentItem total;
        readonly attribute DisplayItems displayItems;
        readonly attribute FrozenArray<requestedFields> requestedFields;
        readonly attribute any data;
        attribute EventHander onabort;
      };
      

PaymentRequestEvent interface

        [Exposed=ServiceWorker,
        Constructor(DOMString type, optional PaymentRequestEventInit eventInitDict)]
        interface PaymentRequestEvent : ExtendableEvent {
          readonly attribute PaymentRequest requestData;
          readonly attribute USVString origin;
          Promise<WindowClient> openClientWindow(USVString url);
          void respondWith(Promise<PaymentResponse> paymentResponse);
        };
      

PaymentRequestEventInit interface

        dictionary PaymentRequestEventInit : EventInit {
          USVString origin = "";
        };
      

RequestedFields enum

        enum RequestedFields {
          "payerEmail",
          "payerName",
          "payerPhone",
          "shipping",
        };
      

Extensions to the PaymentResponse interface

        [Constructor(DOMString id, DOMString methodName, PaymentResponseInit details)]
        partial interface PaymentResponse {
          Promise<PaymentDetails> updateShippingAddress(ShippingAddress? newAddress);
          Promise<PaymentDetails> updateShippingOption(DOMString id);
          readonly attribute Promise<PaymentComplete> isComplete;
        };
      

CanMakePaymentEvent interface

        [Exposed=ServiceWorker,
        Constructor(DOMString type, optional CanMakePaymentEventInit eventInitDict)]
        interface CanMakePaymentEvent : ExtendableEvent {
          readonly attribute FrozenArray<PaymentMethod> methods;
          void canMakePayment(Promise<Boolean> result);
        };
      

CanMakePaymentEventInit dictionary

        dictionary CanMakePaymentEventInit : EventInit {
          required sequence<DOMString> paymentMethods;
        };
      

Dependencies

The following are defined in [[!SERVICE-WORKERS]]: