# apple_pay

> Whether the browser offers Apple Pay, the highest Apple Pay JS version it supports, and whether it says it can pay. No payment sheet is shown and no request is made.

Source: https://whiskerjs.com/signals/apple-pay/ (last updated 2026-10-26)

**apple_pay at a glance (from the library code, signalsVersion 9)**

| Field | Value |
| --- | --- |
| Component name | `apple_pay` |
| In the visitorId | yes |
| structuredId group | [browser (engine and build)](https://whiskerjs.com/docs/identifiers/#structuredid) |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | [signalsVersion 2](https://whiskerjs.com/whats-new/) |

> **In plain words:**
>
> Safari and other browsers built on Apple’s WebKit can offer Apple Pay to web pages. This signal records whether the browser offers it at all, which version of Apple’s web payment interface it supports, and whether it says it can make payments. It never starts a payment and never shows anything to the user. On browsers without Apple Pay it simply reports `none`.

## What it reads

- whether `window.ApplePaySession` exists and is a function;
- the highest version from 20 down to 1 that `ApplePaySession.supportsVersion(v)` accepts;
- the answer of `ApplePaySession.canMakePayments()`.

Nothing else: no merchant identifier, no card information, no session object.

## How the technique works

1. If `ApplePaySession` is not a function, the component reports `none` straight away.
2. Otherwise it calls `supportsVersion(20)`, then 19, and so on down to 1, and stops at the first version that returns true. If a call throws, the loop stops and the version found so far is kept (0 when none was found). When `supportsVersion` is missing, the version stays 0.
3. It calls `canMakePayments()` once. The result is written as `1` (true), `0` (false), `blocked` (the call threw) or `-` (the method does not exist).
4. The value is `version=<n>;can_pay=<x>`.

Neither call shows a payment sheet, and WhiskerJS never constructs an `ApplePaySession`, which is the step that would start a payment.

## Why it helps

Apple Pay JS versions follow the WebKit release and the operating system version, and `canMakePayments()` depends on the device (for example whether it has the hardware and settings for Apple Pay). Together they separate WebKit builds from each other and separate Apple-platform browsers from all others. On non-Apple browsers the value is the same `none` everywhere, so it adds nothing there; its value is on Apple devices.

## Stability

- The supported version changes when Safari or the operating system is updated, which also changes the visitorId and the `browser` part of the structuredId.
- `can_pay` can change if the user sets up or removes Apple Pay on the device. That is uncommon, but it does move the id.
- On non-Apple browsers it is stable: always `none`.

## Browser support and what blocks it

- **Safari on macOS and iOS**: `ApplePaySession` exists, so you see a version and a `can_pay` value. See [Safari on macOS](https://whiskerjs.com/browsers/safari-macos/) and [Safari and iOS browsers](https://whiskerjs.com/browsers/safari-ios/).
- **Other iOS browsers** run on WebKit too; whether they expose `ApplePaySession` depends on the browser and the iOS version, so expect either a version or `none`.
- **Chrome, Edge, Brave, Samsung Internet, Firefox** on other systems: `none`. See [Chrome on desktop](https://whiskerjs.com/browsers/chrome-desktop/) and [Firefox](https://whiskerjs.com/browsers/firefox/).
- `canMakePayments()` throws in insecure contexts and in some cross-origin frames; then `can_pay=blocked`.

## Privacy

The value says whether a device is set up for Apple Pay in general. It reveals no card, no account and no merchant relationship. WhiskerJS does not request a payment, does not show a sheet and makes no request. Like every device signal it can still help recognise a device, so it belongs in the notice your site gives users; see [Privacy](https://whiskerjs.com/docs/privacy/).

## How WhiskerJS handles noise and failures

| Status | ruleId | When |
| --- | --- | --- |
| `ok` |   | always when the collector runs: `none`, or `version=<n>;can_pay=<x>` |
| `excluded` | `caller_excluded` | you passed `apple_pay` in `collect({ exclude })` |
| `timed_out` | `timeout`, `aborted` | the inner timeout (1000 ms) or the overall budget ran out, or the abort signal fired |
| `blocked` | `threw`, `security_error` | an unexpected error outside the guarded calls |

Errors inside `supportsVersion` and `canMakePayments` are caught and turned into part of the value (`can_pay=blocked`, or a lower version), so they do not make the whole component fail. The value is short printable ASCII, so it is never hashed. No browser class excludes it.

## Example value

On the three headless test browsers run in a Linux container (Chromium, Firefox and WebKit), `apple_pay` was `{ status: 'ok', value: 'none', hashed: false }`: Linux WebKit builds have no Apple Pay. On a Mac or iPhone with Safari the value has the form `version=14;can_pay=1` (illustrative).

## Questions and answers

### Does apple_pay show a payment sheet or contact Apple?

No. WhiskerJS only checks that ApplePaySession exists and calls supportsVersion() and canMakePayments(), which answer locally. It never creates a session, so no sheet appears and no request is made.

### Why does my Chrome on Windows report none?

Outside Apple's WebKit there is no ApplePaySession, so the component reports the plain value none. That is an ok status, not a failure.

### What does can_pay=blocked mean?

canMakePayments() threw, which browsers do in contexts where Apple Pay is not allowed, such as insecure pages or some cross-origin frames. The value still joins the id as it is.

## Related pages

- [private_click](https://whiskerjs.com/signals/private-click/): Another WebKit-only signal in the browser group.
- [browser_class](https://whiskerjs.com/signals/browser-class/): How WhiskerJS classes Safari and every iOS browser.
- [Safari on macOS](https://whiskerjs.com/browsers/safari-macos/): What works and what is blocked in Safari.
- [Safari and every iOS browser](https://whiskerjs.com/browsers/safari-ios/): Why all iOS browsers look like Safari to WhiskerJS.
