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.
The use cases for this specification:
As such, the requirements are that this specification can:
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.
The following shows how to process a request for payment via a service worker. In this example, the credit card information is dynamically generated.
The following shows how a web application can respond to a merchant's request to check if it can make an payment.
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.
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.
The "payment-request-handler" permission is the permission associated with the usage of this specification. It is a boolean feature.
partial interface ServiceWorkerRegistration { [SameObject] readonly attribute PaymentManager paymentManager; };
interface paymentManager { readonly attribute PaymentMethodMap paymentMethods; Promise<PermissionState> register(); Promise<void> unregister(); };
[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>> } };
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; };
dictionary PaymentMethodDetails { required DOMString name; required Sequence<DOMString> method; sequence <PaymentMethodIcon> icons; };
dictionary PaymentMethodIcon { USVString src; DOMString sizes; DOMString type; };
partial interface ServiceWorkerGlobalScope { attribute EventHandler onpaymentrequest; attribute EventHandler oncanMakePayment; };
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; };
[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); };
dictionary PaymentRequestEventInit : EventInit { USVString origin = ""; };
enum RequestedFields { "payerEmail", "payerName", "payerPhone", "shipping", };
[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; };
[Exposed=ServiceWorker, Constructor(DOMString type, optional CanMakePaymentEventInit eventInitDict)] interface CanMakePaymentEvent : ExtendableEvent { readonly attribute FrozenArray<PaymentMethod> methods; void canMakePayment(Promise<Boolean> result); };
dictionary CanMakePaymentEventInit : EventInit { required sequence<DOMString> paymentMethods; };
The following are defined in [[!SERVICE-WORKERS]]:
ServiceWorkerRegistration