v149 · Web APIs · Payments

Allow payment handlers to report back internal errors

Payment handlers accessed via the Payment Request API can now return distinct errors: AbortError for user cancellation and OperationError for internal payment app failures. Merchants can finally distinguish "user said no" from "something broke" and route the user accordingly.

concepts

  1. Error Signal Tester

    Installs a same-origin payment handler and requests success, AbortError, OperationError, unsupported-method, and missing-activation outcomes on demand. Shows how PaymentRequest.show()'s promise resolves or rejects in real browser code.

  2. Smart Retry Flow

    A realistic checkout page that presents a payment sheet and reacts differently to user cancellation versus an internal app error, including basket persistence, a fresh-click fallback, fallback cancellation, and fallback failure handling.

  3. Live Checkout Flow

    Full end-to-end checkout: pick from six handler outcomes (success, user abort, card expired, insufficient funds, network error, unsupported method), click Pay, and watch the code trace show which actual browser result lands in the merchant catch block.

  4. Error Recovery Lab

    Five scenario tabs contrast AbortError, structured OperationError payloads, timeout back-off, field mapping, and a plain-message fallback for handlers that do not emit JSON.

  5. Error Log Replay

    Run the full promise chain for any payment scenario - success, abort, app crash, card expired, insufficient funds, network error, unsupported method, or missing activation - and inspect the resolved response or caught DOMException.

  6. Merchant Decision Tree

    A visual decision tree mapping every err.name value to the correct merchant UX action. Run an outcome to route the actual browser result to the recommended response — from polite cancellation to retry flow to fallback payment method.

why it shipped

The Payment Request API lets web apps delegate payment to a registered payment handler (a service worker or web app). Before Chrome 149, any failure — whether the user pressed Cancel or the payment app crashed internally — resulted in the same generic rejection. Merchant pages had no reliable signal to distinguish "user chose to cancel, respect that" from "the app hit a bug, retry with a different method." The new distinction uses standard DOMException names already defined in the Web IDL spec: AbortError for user-intentional cancellation and OperationError for internal failures. No new APIs, just precise use of existing ones.

references