> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overflow.co/llms.txt
> Use this file to discover all available pages before exploring further.

# onClick

> Fires before a wallet sheet opens, so you can gate on external state.

`onClick` fires when the shopper taps a wallet button, before the native payment sheet opens. Use it to validate external state (cart totals, inventory, contact details) and either let the sheet open or cancel.

Emitted by `applePay`, `googlePay`, and `checkout` (when a wallet tab inside Checkout is tapped). Every other element omits the key from its event map; subscribing on a non-wallet element is a TypeScript error and a runtime no-op (with a console warning).

For analytics or telemetry on non-wallet elements, use `onFocus`, `onBlur`, or `onChange`.

## Payload

Wallet elements:

```typescript theme={null}
type OverflowWalletClickEvent<T> = {
  elementType: T;              // 'applePay' | 'googlePay'
  preventDefault: () => void;
  resolve:        () => void;
  reject:         (reason?: unknown) => void;
};
```

Checkout:

```typescript theme={null}
type OverflowCheckoutClickEvent = {
  elementType:   'checkout';
  paymentMethod: 'applePay' | 'googlePay';
  preventDefault: () => void;
  resolve:        () => void;
  reject:         (reason?: unknown) => void;
};
```

## Control flow

The gate mirrors the DOM `preventDefault` convention:

* **No `preventDefault()` call**: the sheet opens immediately, in the same task as the click. Best for fire-and-forget telemetry.
* **`preventDefault()` then `resolve()`**: the sheet opens. Both calls can land synchronously, or `resolve()` can fire from a later microtask or promise (subject to the Apple Pay constraint below).
* **`preventDefault()` then `reject()`**: the sheet does not open. `onError` does not fire; a deliberate cancellation is not a failure. If you want UI feedback for the shopper, render it yourself.

Calling `resolve()` or `reject()` more than once is a no-op after the first decision. Calling either before `preventDefault()` is also a no-op.

## Example (Apple Pay standalone)

```javascript theme={null}
applePay.on('onClick', (event) => {
  event.preventDefault();
  if (cart.total <= 0) {
    event.reject();
    return;
  }
  event.resolve();
});
```

## Apple Pay synchronous constraint

Safari validates that the call that opens the Apple Pay sheet runs in the same synchronous task as the originating click. If `preventDefault()` is followed by an `await` (or any other deferred work) before `resolve()` lands, Safari invalidates the user gesture and the sheet fails to open. No error, no callback.

Apple Pay handlers that need to gate must do so synchronously: read pre-validated state from a local variable rather than awaiting a network call. Google Pay does not have this restriction.

This is a browser-level rule, not an SDK limitation.

## Handler throws

If your handler throws synchronously, the gate is treated as `reject(error)` and `onError` additionally fires with `code: 'unknown'`. This applies whether or not `preventDefault()` was called first, so a bug in your handler never silently opens the sheet.

## Checkout: branch on `paymentMethod`

When a wallet tab is tapped inside Checkout, the payload carries a `paymentMethod` discriminator so a single handler can branch:

```javascript theme={null}
checkout.on('onClick', (event) => {
  if (event.paymentMethod === 'applePay') {
    // Gate synchronously.
    event.preventDefault();
    if (cart.total <= 0) { event.reject(); return; }
    event.resolve();
  } else {
    // Google Pay: async gating is fine.
    event.preventDefault();
    reserveInventory().then((ok) => ok ? event.resolve() : event.reject());
  }
});
```

Card and bank inside Checkout are intentionally absent from the `paymentMethod` discriminator. Card submission flows through the internal submit button; bank has no programmatically blockable default action distinct from `submit()`. For pre-submit gating that applies to card or bank, run validation at the top of your `onSubmit` handler and return early.

## See also

* [`onExit`](/payment-elements/events/on-exit)
* [Wallets guide](/payment-elements/guides/wallets)
* [Apple Pay](/payment-elements/elements/payment-methods/wallets/apple-pay) · [Google Pay](/payment-elements/elements/payment-methods/wallets/google-pay)
