- From: Marcos Cáceres <notifications@github.com>
- Date: Mon, 02 Mar 2026 03:17:59 -0800
- To: w3c/payment-request <payment-request@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/payment-request/pull/1050/c3983746014@github.com>
marcoscaceres left a comment (w3c/payment-request#1050)
Alternative, building on @stephenmcgruer proposal:
https://github.com/w3c/payment-request/pull/1050/commits/236c39b6a6aa579c130b8b8b9e4c780536212cca
PayPal's SDK exposes `onError` and `onCancel` callbacks to merchants. Currently, the Payment Request API returns `AbortError` for both user cancellation AND payment handler errors, forcing PayPal to parse `error.message` strings that vary by browser version.
## Proposed Solution
Use the existing WebIDL `OperationError` DOMException type to distinguish payment handler errors from user cancellation (`AbortError`).
## Two `OperationError` Cases
### Case 1: OS-Level Error
When the operating system kills the payment UI (e.g., memory pressure when user switches apps):
```
User opens payment sheet → Switches to another app →
OS kills payment UI for memory → OperationError
```
This is **not** user cancellation - the user didn't intentionally close the sheet.
### Case 2: Payment Handler Internal Error
When the payment handler encounters an error during processing:
```
User selects PayPal → PayPal server returns 500 →
PayPal handler signals error → OperationError
```
This is **not** user cancellation - the payment failed due to a technical issue.
## Backwards Compatibility
**Self-healing approach:**
1. PayPal continues using message-based detection for old browsers
2. New browsers will throw `OperationError` instead of `AbortError`
3. PayPal can add `error.name === "OperationError"` check
4. Code naturally works in both old and new browsers:
```javascript
function handlePaymentError(error) {
// New path: check error type first
if (error.name === "OperationError") {
this.onError(error);
return;
}
// Legacy path: message-based detection for old browsers
if (error.name === "AbortError") {
const cancelMessages = [
"Request cancelled",
"User closed the Payment Request UI."
];
if (cancelMessages.some(m => error.message?.includes(m))) {
this.onCancel();
} else {
this.onError(error);
}
}
}
```
--
Reply to this email directly or view it on GitHub:
https://github.com/w3c/payment-request/pull/1050#issuecomment-3983746014
You are receiving this because you are subscribed to this thread.
Message ID: <w3c/payment-request/pull/1050/c3983746014@github.com>
Received on Monday, 2 March 2026 11:18:03 UTC