How a service worker mediates optional payment data
Once a web-based payment app accepts a payment request and starts a transaction, its service worker becomes the communication hub between the merchant and the payment app. The Web-based Payment Handler API lets the payment app relay optional details — such as the selected payment method, shipping address, or shipping option — back to the merchant before the final payment response is sent. This article walks through those change events and how to handle the responses they trigger.
Notifying the merchant of a payment method change
A payment app can support multiple payment instruments, sometimes spanning different payment methods. For example, a wallet might hold two credit cards and one bank account, covering two distinct payment method brands. During a transaction, the customer picks one instrument to complete the purchase.
The payment app can notify the merchant of the selection ahead of the full payment response, which is useful when a merchant wants to apply method-specific promotions or otherwise adjust details. To do so, the service worker calls PaymentRequestEvent.changePaymentMethod(), passing the new payment method identifier. An optional second argument, a methodDetails object, can carry arbitrary details required for the merchant to handle the change.
On the merchant side, a paymentmethodchange event fires on the Payment Request API. The merchant updates the payment details and responds with a PaymentDetailsUpdate object. Back in the payment handler, the promise returned by PaymentRequestEvent.changePaymentMethod() resolves with a PaymentRequestDetailsUpdate object that the app can use to refresh its UI.
Shipping address changes
Payment apps can also supply a customer's shipping address as part of the transaction. This centralizes address collection with the payment app and gives merchants address data in the standard structure defined by the Payment Request API. Customers benefit by reusing saved address information across different merchants.
When the customer selects or edits an address in the payment app's UI, the app can send a "shipping address change" event from the service worker. The service worker calls PaymentRequestEvent.changeShippingAddress() with the new address object. Merchants can then:
- Check whether the address meets regional shipping restrictions.
- Adjust shipping options based on the destination region.
- Calculate new shipping costs and update the total price.
Note that the merchant receives a redacted address. The browser strips the organization, phone, recipient, and addressLine fields before raising the shippingaddresschange event in the merchant's DOM. This protects customer privacy while still giving the merchant enough geographic detail to determine shipping logistics.
The merchant handles the shippingaddresschange event by responding with an updated PaymentDetailsUpdate, and the promise from PaymentRequestEvent.changeShippingAddress() resolves with a PaymentRequestDetailsUpdate for the payment app to display.
When a shipping option changes
Shipping options — such as free, express, or international shipping — each carry their own cost, and the Payment Request API lets a payment app present those choices to the customer. The list of options defined by the merchant is passed to the payment app's service worker as a property of PaymentRequestEvent.
When the customer picks a different shipping option, the total price changes, so the merchant must be kept in the loop for later payment verification. The service worker calls PaymentRequestEvent.changeShippingOption() with the new option ID. The merchant receives a shippingoptionchange event, updates the total, and replies with a PaymentDetailsUpdate. As with the other change events, the promise resolves with a PaymentRequestDetailsUpdate that the payment app uses to update the UI.
Reflecting updated details and errors in the UI
All three change methods — .changePaymentMethod(), .changeShippingAddress(), and .changeShippingOption() — resolve with the same PaymentRequestDetailsUpdate shape. The payment app can use that result to update the displayed total and shipping options.
The merchant may return errors in the update for several reasons, including an unacceptable payment method, an unsupported shipping region, invalid address data, or a shipping option that isn't available for the chosen address. The update object exposes the problem through three properties:
error: A human-readable error string, which is the most direct text to show the customer.shippingAddressErrors: AnAddressErrorsobject with per-field error strings, useful if the payment app opens an address edit form and needs to flag specific invalid fields.paymentMethodErrors: A method-specific error object. The spec authors recommend keeping this a simple string, though merchants can provide structured errors.
The sample code for these patterns is available in the payment handler demo. To try the full flow: open the payment request demo, scroll to the bottom, click Add a payment button, enter https://paymenthandler-demo.glitch.me as the Payment Method Identifier, and press the Pay button.



