@paydock/client-sdk 1.144.1-beta → 1.147.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +551 -32
  2. package/bundles/index.cjs +2683 -599
  3. package/bundles/index.cjs.d.ts +322 -21
  4. package/bundles/index.mjs +2683 -600
  5. package/bundles/index.mjs.d.ts +322 -21
  6. package/bundles/types/api/api-base.d.ts +6 -0
  7. package/bundles/types/api/api-base.d.ts.map +1 -1
  8. package/bundles/types/api/api-charge-internal.d.ts +1 -5
  9. package/bundles/types/api/api-charge-internal.d.ts.map +1 -1
  10. package/bundles/types/canvas-3ds/canvas-3ds-event-map.d.ts +50 -0
  11. package/bundles/types/canvas-3ds/canvas-3ds-event-map.d.ts.map +1 -1
  12. package/bundles/types/canvas-3ds/canvas-3ds.d.ts +7 -5
  13. package/bundles/types/canvas-3ds/canvas-3ds.d.ts.map +1 -1
  14. package/bundles/types/canvas-3ds/index.d.ts +1 -1
  15. package/bundles/types/canvas-3ds/index.d.ts.map +1 -1
  16. package/bundles/types/canvas-3ds/services/gpayments-service.d.ts +117 -2
  17. package/bundles/types/canvas-3ds/services/gpayments-service.d.ts.map +1 -1
  18. package/bundles/types/canvas-3ds/services/standalone3ds-service.d.ts +6 -0
  19. package/bundles/types/canvas-3ds/services/standalone3ds-service.d.ts.map +1 -1
  20. package/bundles/types/components/iframe-event.d.ts +4 -3
  21. package/bundles/types/components/iframe-event.d.ts.map +1 -1
  22. package/bundles/types/components/iframe.d.ts +5 -0
  23. package/bundles/types/components/iframe.d.ts.map +1 -1
  24. package/bundles/types/components/param.d.ts +19 -0
  25. package/bundles/types/components/param.d.ts.map +1 -1
  26. package/bundles/types/helper/browser.d.ts.map +1 -1
  27. package/bundles/types/helper/element-id.d.ts +3 -1
  28. package/bundles/types/helper/element-id.d.ts.map +1 -1
  29. package/bundles/types/helper/uuid.d.ts.map +1 -1
  30. package/bundles/types/index-cba.d.ts +1 -1
  31. package/bundles/types/index-cba.d.ts.map +1 -1
  32. package/bundles/types/index.d.ts +2 -2
  33. package/bundles/types/index.d.ts.map +1 -1
  34. package/bundles/types/open-wallets/apple-pay-open-wallet-button.d.ts +41 -0
  35. package/bundles/types/open-wallets/apple-pay-open-wallet-button.d.ts.map +1 -1
  36. package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts +10 -0
  37. package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts.map +1 -1
  38. package/bundles/types/open-wallets/base/service-config-cache.d.ts +23 -0
  39. package/bundles/types/open-wallets/base/service-config-cache.d.ts.map +1 -0
  40. package/bundles/types/open-wallets/google-pay-open-wallet-button.d.ts +33 -1
  41. package/bundles/types/open-wallets/google-pay-open-wallet-button.d.ts.map +1 -1
  42. package/bundles/types/open-wallets/index.d.ts +82 -1
  43. package/bundles/types/open-wallets/index.d.ts.map +1 -1
  44. package/bundles/types/open-wallets/interfaces/apple-pay/apple-pay-availability.interface.d.ts +41 -0
  45. package/bundles/types/open-wallets/interfaces/apple-pay/apple-pay-availability.interface.d.ts.map +1 -0
  46. package/bundles/types/open-wallets/interfaces/apple-pay/index.d.ts +1 -0
  47. package/bundles/types/open-wallets/interfaces/apple-pay/index.d.ts.map +1 -1
  48. package/bundles/types/open-wallets/interfaces/google-pay/google-pay-availability.interface.d.ts +25 -0
  49. package/bundles/types/open-wallets/interfaces/google-pay/google-pay-availability.interface.d.ts.map +1 -0
  50. package/bundles/types/open-wallets/interfaces/google-pay/index.d.ts +1 -0
  51. package/bundles/types/open-wallets/interfaces/google-pay/index.d.ts.map +1 -1
  52. package/bundles/types/open-wallets/interfaces/index.d.ts +3 -0
  53. package/bundles/types/open-wallets/interfaces/index.d.ts.map +1 -1
  54. package/bundles/types/open-wallets/interfaces/open-wallet-availability.interface.d.ts +31 -0
  55. package/bundles/types/open-wallets/interfaces/open-wallet-availability.interface.d.ts.map +1 -0
  56. package/bundles/types/open-wallets/services/apple-pay/apple-pay-availability.d.ts +58 -0
  57. package/bundles/types/open-wallets/services/apple-pay/apple-pay-availability.d.ts.map +1 -0
  58. package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts +8 -10
  59. package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts.map +1 -1
  60. package/bundles/types/open-wallets/services/apple-pay/index.d.ts +1 -0
  61. package/bundles/types/open-wallets/services/apple-pay/index.d.ts.map +1 -1
  62. package/bundles/types/open-wallets/services/google-pay/google-pay-availability.d.ts +53 -0
  63. package/bundles/types/open-wallets/services/google-pay/google-pay-availability.d.ts.map +1 -0
  64. package/bundles/types/open-wallets/services/google-pay/google-pay.open-wallet.service.d.ts.map +1 -1
  65. package/bundles/types/open-wallets/services/google-pay/index.d.ts +1 -0
  66. package/bundles/types/open-wallets/services/google-pay/index.d.ts.map +1 -1
  67. package/bundles/types/widget/multi-widget.d.ts +19 -0
  68. package/bundles/types/widget/multi-widget.d.ts.map +1 -1
  69. package/bundles/widget.umd.js +2683 -599
  70. package/bundles/widget.umd.js.d.ts +322 -21
  71. package/bundles/widget.umd.js.min.d.ts +322 -21
  72. package/bundles/widget.umd.min.js +1 -1
  73. package/docs/api-canvas3ds.md +10 -8
  74. package/docs/api-checkout-button.md +15 -0
  75. package/docs/api-ps-widget.md +15 -0
  76. package/docs/api-widget.md +15 -0
  77. package/docs/canvas3ds-examples.md +43 -1
  78. package/docs/open-wallet-buttons-examples.md +170 -2
  79. package/docs/open-wallet-buttons.md +252 -29
  80. package/docs/widget-examples.md +41 -0
  81. package/package.json +20 -11
  82. package/slate.md +254 -3
package/README.md CHANGED
@@ -194,8 +194,48 @@ widget.setRefId('id'); // your unique identifier to identify the data
194
194
  widget.setFormFields(['phone', 'email']); // add additional fields for form of widget
195
195
 
196
196
  widget.setSupportedCardIcons(['mastercard', 'visa']); // add icons of supported card types
197
+
198
+ widget.setAllowedCardSchemes(['mastercard', 'visa']); // restrict which card schemes the card number field accepts
199
+ ```
200
+
201
+ ### Restricting accepted card schemes
202
+
203
+ `setAllowedCardSchemes(schemes)` restricts which card schemes the card number field accepts, **without** changing
204
+ which card icons the widget displays. Call it before `load()`.
205
+
206
+ ```javascript
207
+ widget.setAllowedCardSchemes(['visa', 'mastercard']);
197
208
  ```
198
209
 
210
+ Accepted identifiers — the schemes the widget can resolve from a card number:
211
+
212
+ `amex`, `ausbc`, `diners`, `discover`, `eftpos`, `japcb`, `mastercard`, `solo`, `unionpay`, `visa`
213
+
214
+ Behaviour:
215
+
216
+ - **Not called, or an empty array** — every scheme is accepted. Existing integrations are unaffected.
217
+ - **Case-insensitive**, and surrounding whitespace is ignored: `' Visa '` and `'MASTERCARD'` both work. Note that
218
+ `setSupportedCardIcons` matches case-**sensitively**; the two methods differ here.
219
+ - **Unsupported identifiers are ignored with a `console.warn`** naming the value, and never throw. A list in which
220
+ every identifier is unsupported therefore applies **no restriction at all** — check the console if a restriction
221
+ seems to have no effect. The icon-only values `visa_white` and `eftpos_white` are not schemes and are rejected,
222
+ as are `laser` and `maestro`, which the widget can never resolve from a card number.
223
+ - **Takes precedence over `setSupportedCardIcons`.** When a non-empty list is supplied here, it is the only list
224
+ used for validation, and the second argument of `setSupportedCardIcons` no longer affects validation. Icons keep
225
+ coming from `setSupportedCardIcons`, so a scheme can legitimately be shown as an icon and still be rejected —
226
+ make sure that is what you intend:
227
+
228
+ ```javascript
229
+ widget.setSupportedCardIcons(['visa', 'mastercard', 'amex'], true);
230
+ widget.setAllowedCardSchemes(['visa', 'mastercard']);
231
+ // three icons are displayed; an Amex card is rejected
232
+ ```
233
+
234
+ - **Calling it again replaces the previous list** rather than merging with it.
235
+ - A card of a rejected scheme shows `Card type not accepted.` on the card number field, the submit button is
236
+ disabled, and the submit handler refuses the card even if the button is re-enabled outside the widget. The same
237
+ message is shown for a card whose scheme cannot be resolved at all.
238
+
199
239
  This example shows how you can use a lot of other methods to settings your form
200
240
 
201
241
  ### Error handling
@@ -355,6 +395,7 @@ When handling errors, consider:
355
395
  var widget = new paydock.HtmlWidget('#widget', 'publicKey', 'gatewayId');
356
396
 
357
397
  widget.setSupportedCardIcons(['mastercard', 'visa']);
398
+ widget.setAllowedCardSchemes(['mastercard', 'visa']);
358
399
  widget.setFormFields(['phone', 'email']);
359
400
  widget.setRefId('custom-ref-id');
360
401
  widget.onFinishInsert('input[name="payment_source_token"]', 'payment_source');
@@ -400,6 +441,12 @@ When handling errors, consider:
400
441
  <dt><a href="#user-content-w_GENERIC_VALIDATORS">GENERIC_VALIDATORS</a> : <code>Record.&lt;string, string&gt;</code></dt>
401
442
  <dd><p>List of available generic form field validators and their definition</p>
402
443
  </dd>
444
+ <dt><a href="#user-content-w_CARD_SCHEME">CARD_SCHEME</a></dt>
445
+ <dd><p>Card schemes the widget is able to resolve from a card number, and therefore the only values
446
+ <code>setAllowedCardSchemes</code> accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
447
+ card icons: it omits the icon-only variants <code>visa_white</code> / <code>eftpos_white</code>, and the <code>laser</code> / <code>maestro</code>
448
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.</p>
449
+ </dd>
403
450
  <dt><a href="#user-content-w_TRIGGER">TRIGGER</a> : <code>object</code></dt>
404
451
  <dd><p>List of available triggers</p>
405
452
  </dd>
@@ -786,6 +833,15 @@ List of available generic form field validators and their definition
786
833
  | --- | --- | --- | --- |
787
834
  | REQUIRED | <code>string</code> | <code>&quot;required&quot;</code> | Asserts the input or form field has a value defined truthy value |
788
835
 
836
+ <a name="w_CARD_SCHEME" id="w_CARD_SCHEME" href="#user-content-w_CARD_SCHEME">&nbsp;</a>
837
+
838
+ ## CARD\_SCHEME
839
+ Card schemes the widget is able to resolve from a card number, and therefore the only values
840
+ `setAllowedCardSchemes` accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
841
+ card icons: it omits the icon-only variants `visa_white` / `eftpos_white`, and the `laser` / `maestro`
842
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.
843
+
844
+ **Kind**: global constant
789
845
  <a name="w_TRIGGER" id="w_TRIGGER" href="#user-content-w_TRIGGER">&nbsp;</a>
790
846
 
791
847
  ## TRIGGER : <code>object</code>
@@ -958,6 +1014,12 @@ This example shows how you can use a lot of other methods to settings your form
958
1014
  <dt><a href="#user-content-psw_PAYMENT_SOURCE_TYPE">PAYMENT_SOURCE_TYPE</a> : <code>object</code></dt>
959
1015
  <dd><p>List of available payment source types</p>
960
1016
  </dd>
1017
+ <dt><a href="#user-content-psw_CARD_SCHEME">CARD_SCHEME</a></dt>
1018
+ <dd><p>Card schemes the widget is able to resolve from a card number, and therefore the only values
1019
+ <code>setAllowedCardSchemes</code> accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
1020
+ card icons: it omits the icon-only variants <code>visa_white</code> / <code>eftpos_white</code>, and the <code>laser</code> / <code>maestro</code>
1021
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.</p>
1022
+ </dd>
961
1023
  </dl>
962
1024
 
963
1025
  ## Typedefs
@@ -1509,6 +1571,15 @@ List of available payment source types
1509
1571
  | BANK_ACCOUNT | <code>string</code> | <code>&quot;bank_account&quot;</code> |
1510
1572
  | CHECKOUT | <code>string</code> | <code>&quot;checkout&quot;</code> |
1511
1573
 
1574
+ <a name="psw_CARD_SCHEME" id="psw_CARD_SCHEME" href="#user-content-psw_CARD_SCHEME">&nbsp;</a>
1575
+
1576
+ ## CARD\_SCHEME
1577
+ Card schemes the widget is able to resolve from a card number, and therefore the only values
1578
+ `setAllowedCardSchemes` accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
1579
+ card icons: it omits the icon-only variants `visa_white` / `eftpos_white`, and the `laser` / `maestro`
1580
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.
1581
+
1582
+ **Kind**: global constant
1512
1583
  <a name="psw_listener--PaymentSourceWidget" id="psw_listener--PaymentSourceWidget" href="#user-content-psw_listener--PaymentSourceWidget">&nbsp;</a>
1513
1584
 
1514
1585
  ## listener--PaymentSourceWidget : <code>function</code>
@@ -1670,6 +1741,12 @@ Then write only need 1 line of code in js to initialize widget
1670
1741
  <dl>
1671
1742
  <dt><a href="#user-content-cb_CHECKOUT_BUTTON_EVENT">CHECKOUT_BUTTON_EVENT</a> : <code>object</code></dt>
1672
1743
  <dd></dd>
1744
+ <dt><a href="#user-content-cb_CARD_SCHEME">CARD_SCHEME</a></dt>
1745
+ <dd><p>Card schemes the widget is able to resolve from a card number, and therefore the only values
1746
+ <code>setAllowedCardSchemes</code> accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
1747
+ card icons: it omits the icon-only variants <code>visa_white</code> / <code>eftpos_white</code>, and the <code>laser</code> / <code>maestro</code>
1748
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.</p>
1749
+ </dd>
1673
1750
  </dl>
1674
1751
 
1675
1752
  ## Typedefs
@@ -2203,6 +2280,15 @@ button.turnOffBackdrop();
2203
2280
  | FINISH | <code>string</code> | <code>&quot;finish&quot;</code> |
2204
2281
  | CLOSE | <code>string</code> | <code>&quot;close&quot;</code> |
2205
2282
 
2283
+ <a name="cb_CARD_SCHEME" id="cb_CARD_SCHEME" href="#user-content-cb_CARD_SCHEME">&nbsp;</a>
2284
+
2285
+ ## CARD\_SCHEME
2286
+ Card schemes the widget is able to resolve from a card number, and therefore the only values
2287
+ `setAllowedCardSchemes` accepts. This is a separate vocabulary from SUPPORTED_CARD_TYPES, which drives the
2288
+ card icons: it omits the icon-only variants `visa_white` / `eftpos_white`, and the `laser` / `maestro`
2289
+ identifiers the widget can never resolve — allowing those would be configuration that can never match.
2290
+
2291
+ **Kind**: global constant
2206
2292
  <a name="cb_listener" id="cb_listener" href="#user-content-cb_listener">&nbsp;</a>
2207
2293
 
2208
2294
  ## listener : <code>function</code>
@@ -2459,7 +2545,13 @@ After you initialized the standalone 3ds charge via `v1/charges/standalone-3ds`
2459
2545
  console.log(data);
2460
2546
  });
2461
2547
  canvas3ds.on("chargeAuthChallenge", function (data) {
2462
- console.log(data);
2548
+ console.log(data); // keep your loader up — the challenge page is still loading
2549
+ });
2550
+ canvas3ds.on("chargeAuthChallengeLoaded", function (data) {
2551
+ console.log(data.reason); // 'load' | 'timeout' — hide your loader, the challenge is visible
2552
+ });
2553
+ canvas3ds.on("chargeAuthChallengeCompleted", function (data) {
2554
+ console.log(data.source); // 'poll' | 'callback' — shopper finished, cover the challenge with "Completing verification"
2463
2555
  });
2464
2556
  canvas3ds.on("chargeAuthDecoupled", function (data) {
2465
2557
  console.log(data.result.description);
@@ -2482,10 +2574,26 @@ After you initialized the standalone 3ds charge via `v1/charges/standalone-3ds`
2482
2574
  - A `data.status` of `rejected` will be received when the authorization was rejected.
2483
2575
  - A `data.status` of `invalid_event` will be received for unhandled situations.
2484
2576
  - The `chargeAuthChallenge` event is sent before starting a challenge flow (i.e. opening an IFrame for the customer to complete a challenge with ther bank). Once the end customer performs the challenge, the Canvas3ds will be able to identify the challenge result and will either produce a `chargeAuthSuccess` or `chargeAuthReject` event.
2577
+ - The `chargeAuthChallengeLoaded` event (SDK **v1.147.0+**) is sent once per challenge, after `chargeAuthChallenge`, when the challenge IFrame has finished loading the bank's page (its first `load` event) — this is the moment the customer can actually see the challenge. `data.reason` is `load` for a real load, or `timeout` when no load was observed within 2.5 seconds: the event is emitted anyway so you never hold a loading indicator forever (a `load` arriving later is simply ignored). Hide your loader on this event either way; `data.reason` is only informational (e.g. analytics). Not sent for decoupled challenges (no challenge IFrame).
2578
+ - The `chargeAuthChallengeCompleted` event (SDK **v1.147.0+**) is sent once the customer has finished the challenge (or approved a decoupled authentication): the bank has delivered the final result to the 3DS server and the Canvas3ds is now obtaining the outcome. Whatever the bank or the 3DS server render inside the IFrame from here on is plumbing, not UX — cover the IFrame with your own "Completing verification" state and hold it until the terminal event. `data.source` tells you how the SDK learned about it: `poll` (the 3DS server's result monitor — the usual case, it flips before the IFrame has even left the bank's page) or `callback` (the callback message carrying the outcome arrived first; the terminal event follows immediately) — handle both the same way. Sent at most once per authentication, always before `chargeAuthSuccess` / `chargeAuthReject` / `error` and never after them. A wrong OTP or a further interactive step (e.g. a second OTP screen) does **not** send it — no result has been delivered yet — so no grace timer or reveal fallback is needed on your side. Also sent for decoupled challenges.
2485
2579
  - The `chargeAuthDecoupled` event is sent when the flow is a decoupled challenge, alongside a `data.result.description` field that you must show to the customer, indicating the method the user must use to authenticate. For example this may happen by having the cardholder authenticating directly with their banking app through biometrics. Once the end customer does this, the Canvas3ds will be able to recognize the challenge result is ready and will either produce a `chargeAuthSuccess` or `chargeAuthReject` event.
2486
2580
  - The `error` event is sent if an unexpected issue with the client library occurs. In such scenarios, you should consider the autentication process as interrupted:
2487
2581
  - When getting this event, you will get on `data.error` the full error object.
2488
2582
 
2583
+ ### Recommended loading indicator pattern
2584
+
2585
+ > Requires SDK **v1.147.0 or later** (`chargeAuthChallengeLoaded` / `chargeAuthChallengeCompleted`). On older versions the same effect needs a `MutationObserver` on the container plus `load` listeners on the challenge IFrame — see the Standalone 3DS UX guide in the playground for that legacy approach.
2586
+
2587
+ The Canvas3ds renders nothing visible until a challenge is presented, and `chargeAuthChallenge` fires when the API responds — about 1–2 seconds before the bank's page actually paints inside the IFrame. Drive a single loading indicator from the events:
2588
+
2589
+ 1. Show the loader **before** you `POST /v1/charges/standalone-3ds` and keep it up through `canvas3ds.load()` (fingerprinting and processing are invisible).
2590
+ 2. Keep it up on `chargeAuthChallenge` — the challenge IFrame is being injected but is still blank.
2591
+ 3. Hide it on `chargeAuthChallengeLoaded` — the challenge is visible. `data.reason` tells you whether it was a real paint (`load`) or the 2.5 s safety fallback (`timeout`); either way, no further handling is needed.
2592
+ 4. Cover the IFrame with a "Completing verification" indicator on `chargeAuthChallengeCompleted` — the customer finished the challenge and the SDK is obtaining the outcome — and hold it until the terminal event. No grace timer or reveal fallback is needed: a wrong OTP or a second interactive step does not fire this event.
2593
+ 5. Finish on `chargeAuthSuccess` / `chargeAuthReject` / `error`.
2594
+
2595
+ Decoupled challenges (`chargeAuthDecoupled`) never emit `chargeAuthChallengeLoaded` (there is no challenge IFrame) but do emit `chargeAuthChallengeCompleted` once the customer approved out-of-band: show a dedicated waiting state with `data.result.description` until then, and "Completing verification" until the terminal event. Frictionless flows go straight from `load()` to the terminal event.
2596
+
2489
2597
  ### Events and Values
2490
2598
 
2491
2599
  | Event Value | Type | Description |
@@ -2493,6 +2601,8 @@ After you initialized the standalone 3ds charge via `v1/charges/standalone-3ds`
2493
2601
  | <code>chargeAuthSuccess</code> | <code>object</code> | Instance of [ChargeEventResponse](#cb_chargeEventResponse) |
2494
2602
  | <code>chargeAuthReject</code> | <code>object</code> | Instance of [ChargeEventResponse](#cb_chargeEventResponse) |
2495
2603
  | <code>chargeAuthChallenge</code> | <code>object</code> | Instance of [ChargeEventResponse](#cb_chargeEventResponse) |
2604
+ | <code>chargeAuthChallengeLoaded</code> | <code>object</code> | Instance of [ChallengeLoadedResponse](#cb_challengeLoadedResponse) |
2605
+ | <code>chargeAuthChallengeCompleted</code> | <code>object</code> | Instance of [ChallengeCompletedResponse](#cb_challengeCompletedResponse) |
2496
2606
  | <code>chargeAuthDecoupled</code> | <code>object</code> | Instance of [ChargeEventResponse](#cb_chargeEventResponse) |
2497
2607
  | <code>chargeAuthInfo</code> | <code>object</code> | Instance of [ChargeEventResponse](#cb_chargeEventResponse) |
2498
2608
  | <code>error</code> | <code>object</code> | Instance of [chargeError](#cb_chargeError) |
@@ -2510,6 +2620,24 @@ After you initialized the standalone 3ds charge via `v1/charges/standalone-3ds`
2510
2620
  | <code>info</code> | <code>string</code> | info field for `chargeAuthInfo` event |
2511
2621
  | <code>result.description</code> | <code>string</code> [Optional] | field that you must show to the customer, indicating the method the user must use to authenticate during the decoupled challenge flow. |
2512
2622
 
2623
+ <a name="cb_challengeLoadedResponse" id="cb_challengeLoadedResponse"></a>
2624
+
2625
+ ### ChallengeLoadedResponse
2626
+
2627
+ | Param | Type | Description |
2628
+ | ------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------- |
2629
+ | <code>charge_3ds_id</code> | <code>string</code> | Universal unique transaction identifier to identify the transaction |
2630
+ | <code>reason</code> | <code>string</code> | `load` — the challenge IFrame fired its first load event; `timeout` — no load within 2.5 s, emitted so a loader is never held forever (a later load is ignored) |
2631
+
2632
+ <a name="cb_challengeCompletedResponse" id="cb_challengeCompletedResponse"></a>
2633
+
2634
+ ### ChallengeCompletedResponse
2635
+
2636
+ | Param | Type | Description |
2637
+ | ------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------- |
2638
+ | <code>charge_3ds_id</code> | <code>string</code> | Universal unique transaction identifier to identify the transaction |
2639
+ | <code>source</code> | <code>string</code> | `poll` — the 3DS server's result monitor reported that the bank delivered the result (the usual case); `callback` — the callback message carrying the outcome arrived first (the terminal event follows immediately). Informational only — handle both the same way |
2640
+
2513
2641
  ### ChargeError
2514
2642
 
2515
2643
  <a name="cb_chargeError" id="cb_chargeError"></a>
@@ -5652,6 +5780,106 @@ Bear in mind that you must set an environment before calling `button.load()`.
5652
5780
  button.setEnv('sandbox');
5653
5781
  ```
5654
5782
 
5783
+ ### Checking availability before instantiation (static)
5784
+
5785
+ `ApplePayOpenWalletButton.checkAvailability(options)` is a **static** method so you can decide
5786
+ whether to show an Apple Pay option — or which payment method to default to — **without
5787
+ instantiating the button** and waiting for the `onUnavailable` event.
5788
+
5789
+ > **Apple Pay is no longer Safari-only.** Since iOS 16 (third-party mobile browsers) and the
5790
+ > iOS 18 / 2025 desktop rollout, Apple Pay also works in Chrome, Edge and Firefox — including
5791
+ > on Windows — via a **cross-device QR handoff**: the user scans a code and completes the
5792
+ > payment on their iPhone. Because the paying device is often *not* the browsing device, the
5793
+ > only authoritative availability signal is the async `checkAvailability()`.
5794
+ > `applePayCapabilities()` is what Apple recommends; `canMakePayments()` is just a coarse
5795
+ > local-device hint. See
5796
+ > [Apple — Checking for Apple Pay availability](https://developer.apple.com/documentation/applepayontheweb/checking-for-apple-pay-availability).
5797
+
5798
+ #### `ApplePayOpenWalletButton.checkAvailability(options)`
5799
+
5800
+ The single, authoritative, cross-browser-aware check. It resolves the merchant identifier,
5801
+ loads Apple's web SDK if needed, and queries `ApplePaySession.applePayCapabilities()`.
5802
+
5803
+ You may supply the merchant context in either of two ways:
5804
+
5805
+ ```javascript
5806
+ // 1) Lightest path — no network — when you already know the Apple merchant identifier:
5807
+ const result = await paydock.ApplePayOpenWalletButton.checkAvailability({
5808
+ merchant_id: 'merchant.com.example',
5809
+ });
5810
+
5811
+ // 2) Resolve the merchant identifier from the service configuration (fetched & cached):
5812
+ const result = await paydock.ApplePayOpenWalletButton.checkAvailability({
5813
+ public_key_or_access_token: publicKeyOrAccessToken,
5814
+ service_id: serviceId,
5815
+ env: 'sandbox',
5816
+ // Optional — which device statuses count as "available".
5817
+ // Defaults to ['credentials_available', 'credentials_status_unknown'].
5818
+ apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown'],
5819
+ });
5820
+ ```
5821
+
5822
+ **Result shape (`ApplePayAvailabilityResult`):**
5823
+
5824
+ ```javascript
5825
+ {
5826
+ available: true, // verdict vs the allowed capability set
5827
+ supported: true, // Apple Pay usable here AT ALL (incl. cross-device QR)
5828
+ has_native_session: false, // native same-device session present (canMakePayments)
5829
+ payment_credential_status: // OUTPUT — the device's reported status
5830
+ 'paymentCredentialStatusUnknown',
5831
+ reason: undefined, // set when not available, see below
5832
+ }
5833
+ ```
5834
+
5835
+ **Inferring the transport (Apple does not expose it directly):**
5836
+ - `available && has_native_session` ⇒ **native** Apple Pay sheet is likely (Safari on an Apple device).
5837
+ - `available && !has_native_session` ⇒ **cross-device / QR** handoff is likely (e.g. Chrome on desktop).
5838
+
5839
+ `payment_credential_status` is the device's actual status:
5840
+ `'paymentCredentialsAvailable'`, `'paymentCredentialStatusUnknown'`,
5841
+ `'paymentCredentialsUnavailable'`, or `'applePayUnsupported'`. **Third-party / desktop
5842
+ browsers normally report `paymentCredentialStatusUnknown`** (Apple can't see the remote
5843
+ iPhone's cards until the user scans the QR), which is why the default allowed set includes it.
5844
+
5845
+ The `apple_pay_capabilities` **input** maps to those statuses
5846
+ (`credentials_available` → `paymentCredentialsAvailable`,
5847
+ `credentials_status_unknown` → `paymentCredentialStatusUnknown`,
5848
+ `credentials_unavailable` → `paymentCredentialsUnavailable`) and decides which ones make
5849
+ `available` true. When omitted, **both** `paymentCredentialsAvailable` and
5850
+ `paymentCredentialStatusUnknown` count — narrow it to `['credentials_available']` only if you
5851
+ want to require a confirmed local card (this will hide the button in cross-browser/QR contexts).
5852
+
5853
+ When `available` is `false`, `reason` is one of: `'unsupported_browser'`,
5854
+ `'missing_merchant_id'`, `'service_type_mismatch'`, `'config_fetch_failed'`,
5855
+ `'sdk_load_failed'`, `'query_failed'`, `'no_credentials'`, or `'no_native_session'`
5856
+ (only from the synchronous check below).
5857
+
5858
+ ```javascript
5859
+ const result = await paydock.ApplePayOpenWalletButton.checkAvailability({ merchant_id: merchantId });
5860
+ if (result.available) {
5861
+ renderApplePayButton();
5862
+ } else {
5863
+ console.log('Apple Pay unavailable:', result.reason, result.payment_credential_status);
5864
+ }
5865
+ ```
5866
+
5867
+ **Synchronous native-only fast check (`sync: true`).** Pass `{ sync: true }` for a cheap,
5868
+ network-free pre-check that resolves immediately — it runs only the native same-device check
5869
+ (`window.ApplePaySession` + `canMakePayments()`), with no merchant resolution, SDK load, or
5870
+ `applePayCapabilities()` query. In this mode `available` reflects the native session only and
5871
+ `payment_credential_status` is `undefined`. It is a Safari-oriented hint and is **not**
5872
+ authoritative for cross-browser / QR availability (which require the full async check above).
5873
+
5874
+ ```javascript
5875
+ const { has_native_session } = await paydock.ApplePayOpenWalletButton.checkAvailability({
5876
+ sync: true,
5877
+ });
5878
+ if (has_native_session) {
5879
+ // Native Apple Pay is ready on this device (Safari fast path).
5880
+ }
5881
+ ```
5882
+
5655
5883
  ### Full Apple Pay example
5656
5884
 
5657
5885
  ```html
@@ -6070,6 +6298,58 @@ The GooglePayOpenWalletButton constructor accepts the following parameters:
6070
6298
 
6071
6299
  > **Note:** Required meta fields (`amount`, `currency`, `country`) are validated automatically by the `GooglePayOpenWalletButton` class. You do not need to specify them manually.
6072
6300
 
6301
+ ### Checking availability before instantiation (static)
6302
+
6303
+ `GooglePayOpenWalletButton.checkAvailability(options)` is a **static** method that reports
6304
+ whether Google Pay can be used in the current context **without instantiating the button**.
6305
+ It loads the Google Pay JS SDK if needed and runs `PaymentsClient.isReadyToPay()`.
6306
+
6307
+ Unlike Apple Pay, **all options are optional** — Google Pay's readiness check does not
6308
+ require a merchant identifier. Supplying `publicKeyOrAccessToken` + `serviceId` additionally
6309
+ validates that the service is a Google Pay service (and resolves the merchant id).
6310
+
6311
+ ```javascript
6312
+ // Simplest form — no merchant context needed:
6313
+ const result = await paydock.GooglePayOpenWalletButton.checkAvailability();
6314
+
6315
+ // Or validate the service is a Google Pay service while checking:
6316
+ const result = await paydock.GooglePayOpenWalletButton.checkAvailability({
6317
+ public_key_or_access_token: publicKeyOrAccessToken,
6318
+ service_id: serviceId,
6319
+ env: 'sandbox',
6320
+ });
6321
+ ```
6322
+
6323
+ **Result shape (`GooglePayAvailabilityResult`):**
6324
+
6325
+ ```javascript
6326
+ {
6327
+ available: true, // isReadyToPay().result — ready to pay in this context
6328
+ supported: true, // the Google Pay JS API is present and the query ran
6329
+ payment_method_present: true, // OUTPUT — whether the buyer already has a usable card
6330
+ reason: undefined, // set when not available, see below
6331
+ }
6332
+ ```
6333
+
6334
+ > **Note:** the static check uses the **default** card configuration (standard auth methods
6335
+ > and card networks). A button instance configured with a custom `card_config` may produce a
6336
+ > different result.
6337
+
6338
+ When `available` is `false`, `reason` is one of: `'unsupported_browser'`,
6339
+ `'service_type_mismatch'`, `'config_fetch_failed'`, `'sdk_load_failed'`, `'query_failed'`,
6340
+ `'no_payment_method'`, or `'api_not_loaded'` (only from the synchronous check below).
6341
+
6342
+ **Synchronous fast check (`sync: true`).** Google Pay has no synchronous device/card
6343
+ capability API, so `{ sync: true }` only reports whether the Google Pay JS API is already
6344
+ present in the page — it does **not** run `isReadyToPay()`:
6345
+
6346
+ ```javascript
6347
+ const { available } = await paydock.GooglePayOpenWalletButton.checkAvailability({
6348
+ sync: true,
6349
+ });
6350
+ // `available` here means "the Google Pay JS API script is loaded", not "ready to pay".
6351
+ ```
6352
+
6073
6353
  ### Full Google Pay Example
6074
6354
 
6075
6355
  ```html
@@ -6212,12 +6492,28 @@ Both `ApplePayOpenWalletButton` and `GooglePayOpenWalletButton` share the same e
6212
6492
 
6213
6493
  ### Checking for button availability
6214
6494
 
6215
- If the customer's browser is not supported, or the customer does not have any card added to their wallet, the button will not load. In this case the callback onUnavailable() will be called. You can define the behavior of this function before loading the button.
6495
+ There are two ways to know whether a wallet is available:
6496
+
6497
+ **1. After `load()` — the `onUnavailable()` callback.** If the customer's browser is not supported, or the customer does not have any card added to their wallet, the button will not load. In this case the callback onUnavailable() will be called. You can define the behavior of this function before loading the button.
6216
6498
 
6217
6499
  ```javascript
6218
6500
  button.onUnavailable(({ data }) => console.log("No wallet button available", data));
6219
6501
  ```
6220
6502
 
6503
+ **2. Before instantiation — the static `checkAvailability()` method.** Each button class exposes a static `checkAvailability(options)` that resolves availability **without instantiating the button**, so you can decide whether to render a wallet option (or which payment method to default to) up front. The options and result are wallet-specific — see [Apple Pay → Checking availability before instantiation](#checking-availability-before-instantiation-static) and [Google Pay → Checking availability before instantiation](#checking-availability-before-instantiation-static-1).
6504
+
6505
+ ```javascript
6506
+ // Apple Pay
6507
+ const apple = await paydock.ApplePayOpenWalletButton.checkAvailability({ merchant_id: merchantId });
6508
+
6509
+ // Google Pay (merchant context optional)
6510
+ const google = await paydock.GooglePayOpenWalletButton.checkAvailability();
6511
+
6512
+ if (apple.available || google.available) {
6513
+ // Show a wallet payment option.
6514
+ }
6515
+ ```
6516
+
6221
6517
  ### Service type validation
6222
6518
 
6223
6519
  Each button validates that the service configuration matches its expected wallet type. If you use an Apple Pay service ID with `GooglePayOpenWalletButton` (or vice versa), an error will be emitted via `onError`:
@@ -6379,7 +6675,7 @@ A full description of the [ApplePayOpenWalletMeta](#ApplePayOpenWalletMeta) prop
6379
6675
  - `request_shipping?: boolean`: Enable shipping address collection
6380
6676
  - `shipping_options?: IApplePayShippingOption[]`: Array of shipping options
6381
6677
  - `show_billing_address?: boolean`: Show billing address fields
6382
- - `apple_pay_capabilities?: string[]`: Device capabilities
6678
+ - `apple_pay_capabilities?: string[]`: Device credential statuses that make the button render. **Defaults to `['credentials_available', 'credentials_status_unknown']`**: `credentials_available` means the device has a confirmed Apple Pay card ready to use; `credentials_status_unknown` means a local card can't be confirmed but Apple Pay can still proceed (e.g. the cross-device QR flow used by Chrome, Edge and Firefox). Narrow to `['credentials_available']` to require a confirmed local card.
6383
6679
  - `merchant_capabilities?: string[]`: Merchant capabilities
6384
6680
  - `supported_networks?: string[]`: Supported payment networks
6385
6681
  - `required_billing_contact_fields?: string[]`: Required billing contact fields
@@ -6561,6 +6857,37 @@ Apple will determine if the device has an ApplePay wallet available and at least
6561
6857
  <dt><a href="#GooglePayOpenWalletMeta">GooglePayOpenWalletMeta</a> : <code>object</code></dt>
6562
6858
  <dd><p>Interface for Google Pay-specific metadata.</p>
6563
6859
  </dd>
6860
+ <dt><a href="#OpenWalletAvailabilityOptions">OpenWalletAvailabilityOptions</a> : <code>object</code></dt>
6861
+ <dd><p>Base options shared by every wallet&#39;s static availability check
6862
+ (e.g. <a href="#ApplePayOpenWalletButton">ApplePayOpenWalletButton</a>.checkAvailability). Wallet-specific option
6863
+ interfaces (such as <a href="#ApplePayAvailabilityOptions">ApplePayAvailabilityOptions</a>) extend this.</p>
6864
+ </dd>
6865
+ <dt><a href="#OpenWalletAvailabilityResult">OpenWalletAvailabilityResult</a> : <code>object</code></dt>
6866
+ <dd><p>Base result shared by every wallet&#39;s static availability check. Wallet-specific
6867
+ result interfaces (such as <a href="#ApplePayAvailabilityResult">ApplePayAvailabilityResult</a>) extend this.</p>
6868
+ </dd>
6869
+ <dt><a href="#ApplePayAvailabilityOptions">ApplePayAvailabilityOptions</a> : <code>object</code></dt>
6870
+ <dd><p>Options for <code>ApplePayOpenWalletButton.checkAvailability</code>. Extends
6871
+ <a href="#OpenWalletAvailabilityOptions">OpenWalletAvailabilityOptions</a>. Provide <code>merchant_id</code> directly to skip the network
6872
+ call, <strong>or</strong> provide <code>public_key_or_access_token</code> + <code>service_id</code> to resolve the merchant
6873
+ identifier from the service configuration.</p>
6874
+ </dd>
6875
+ <dt><a href="#ApplePayAvailabilityResult">ApplePayAvailabilityResult</a> : <code>object</code></dt>
6876
+ <dd><p>Result of <code>ApplePayOpenWalletButton.checkAvailability</code>. Extends
6877
+ <a href="#OpenWalletAvailabilityResult">OpenWalletAvailabilityResult</a>.</p>
6878
+ <p>Infer the transport (Apple does not expose it directly): <code>available &amp;&amp; has_native_session</code>
6879
+ ⇒ native sheet likely; <code>available &amp;&amp; !has_native_session</code> ⇒ cross-device / QR handoff likely.</p>
6880
+ </dd>
6881
+ <dt><a href="#GooglePayAvailabilityOptions">GooglePayAvailabilityOptions</a> : <code>object</code></dt>
6882
+ <dd><p>Options for <code>GooglePayOpenWalletButton.checkAvailability</code>. Extends
6883
+ <a href="#OpenWalletAvailabilityOptions">OpenWalletAvailabilityOptions</a>. All fields are optional — Google Pay&#39;s
6884
+ <code>isReadyToPay</code> check does not require a merchant identifier. Supplying
6885
+ <code>public_key_or_access_token</code> + <code>service_id</code> additionally validates the service type.</p>
6886
+ </dd>
6887
+ <dt><a href="#GooglePayAvailabilityResult">GooglePayAvailabilityResult</a> : <code>object</code></dt>
6888
+ <dd><p>Result of <code>GooglePayOpenWalletButton.checkAvailability</code>. Extends
6889
+ <a href="#OpenWalletAvailabilityResult">OpenWalletAvailabilityResult</a>.</p>
6890
+ </dd>
6564
6891
  <dt><a href="#OnClickEventData">OnClickEventData</a> : <code>object</code></dt>
6565
6892
  <dd><p>Interface for OnClickEventData.
6566
6893
  Emitted when the wallet button is clicked.</p>
@@ -6648,7 +6975,7 @@ Apple will determine if the device has an ApplePay wallet available and at least
6648
6975
  | [shipping_options] | [<code>Array.&lt;IApplePayShippingOption&gt;</code>](#IApplePayShippingOption) | Array of available shipping options. The first item is used as the default selected option. Requires `request_shipping` to be `true`. |
6649
6976
  | [show_billing_address] | <code>boolean</code> | Show billing address fields in the Apple Pay sheet. |
6650
6977
  | store_name | <code>string</code> | The merchant's store name displayed during payment. |
6651
- | [apple_pay_capabilities] | <code>Array.&lt;(&#x27;credentials\_available&#x27;\|&#x27;credentials\_status\_unknown&#x27;\|&#x27;credentials\_unavailable&#x27;)&gt;</code> | Device capabilities needed for the wallet button to be available. |
6978
+ | [apple_pay_capabilities] | <code>Array.&lt;(&#x27;credentials\_available&#x27;\|&#x27;credentials\_status\_unknown&#x27;\|&#x27;credentials\_unavailable&#x27;)&gt;</code> | Device credential statuses that make the button render. Defaults to `['credentials_available', 'credentials_status_unknown']`: `credentials_available` means the device has a confirmed Apple Pay card ready to use; `credentials_status_unknown` means a local card can't be confirmed but Apple Pay can still proceed (e.g. the cross-device QR flow used by Chrome, Edge and Firefox). Narrow to `['credentials_available']` to require a confirmed local card. |
6652
6979
  | [merchant_capabilities] | <code>Array.&lt;(&#x27;supports3DS&#x27;\|&#x27;supportsEMV&#x27;\|&#x27;supportsCredit&#x27;\|&#x27;supportsDebit&#x27;)&gt;</code> | Array of merchant capabilities influencing the transaction processing features available. |
6653
6980
  | [supported_networks] | <code>Array.&lt;(&#x27;visa&#x27;\|&#x27;masterCard&#x27;\|&#x27;amex&#x27;\|&#x27;chinaUnionPay&#x27;\|&#x27;discover&#x27;\|&#x27;interac&#x27;\|&#x27;jcb&#x27;\|&#x27;privateLabel&#x27;)&gt;</code> | List of payment networks supported for Apple Pay transactions. |
6654
6981
  | [required_billing_contact_fields] | <code>Array.&lt;(&#x27;email&#x27;\|&#x27;name&#x27;\|&#x27;phone&#x27;\|&#x27;postalAddress&#x27;)&gt;</code> | Contact fields required from the user for billing purposes. Phone and email are currently not returned by Apple. |
@@ -6682,6 +7009,105 @@ Interface for Google Pay-specific metadata.
6682
7009
  | [style.button_color] | <code>GooglePayButtonColor</code> | The color of the Google Pay button (`'default'`, `'black'`, `'white'`). |
6683
7010
  | [style.button_size_mode] | <code>GooglePayButtonSizeMode</code> | The size mode (`'static'`, `'fill'`). |
6684
7011
 
7012
+ <a name="OpenWalletAvailabilityOptions" id="OpenWalletAvailabilityOptions" href="#OpenWalletAvailabilityOptions">&nbsp;</a>
7013
+
7014
+ ## OpenWalletAvailabilityOptions : <code>object</code>
7015
+ Base options shared by every wallet's static availability check
7016
+ (e.g. [ApplePayOpenWalletButton](#ApplePayOpenWalletButton).checkAvailability). Wallet-specific option
7017
+ interfaces (such as [ApplePayAvailabilityOptions](#ApplePayAvailabilityOptions)) extend this.
7018
+
7019
+ **Kind**: global interface
7020
+
7021
+ | Param | Type | Description |
7022
+ | --- | --- | --- |
7023
+ | [public_key_or_access_token] | <code>string</code> | Public key or access token used to fetch the service config when needed. |
7024
+ | [service_id] | <code>string</code> | Service ID — used with `public_key_or_access_token` to resolve the wallet configuration. |
7025
+ | [env] | <code>string</code> | Environment for the config fetch (e.g. `'sandbox'`). Defaults to the SDK default. |
7026
+ | [sync] | <code>boolean</code> | When `true`, performs only the cheap, network-free synchronous check and resolves immediately — no config fetch, SDK load, or remote capability query. |
7027
+
7028
+ <a name="OpenWalletAvailabilityResult" id="OpenWalletAvailabilityResult" href="#OpenWalletAvailabilityResult">&nbsp;</a>
7029
+
7030
+ ## OpenWalletAvailabilityResult : <code>object</code>
7031
+ Base result shared by every wallet's static availability check. Wallet-specific
7032
+ result interfaces (such as [ApplePayAvailabilityResult](#ApplePayAvailabilityResult)) extend this.
7033
+
7034
+ **Kind**: global interface
7035
+
7036
+ | Param | Type | Description |
7037
+ | --- | --- | --- |
7038
+ | available | <code>boolean</code> | Convenience verdict: the wallet is usable for a payment in the current context. |
7039
+ | supported | <code>boolean</code> | Whether the wallet is supported here at all (may be available via a fallback flow). |
7040
+ | [reason] | <code>string</code> | Machine-readable reason when not available. |
7041
+
7042
+ <a name="ApplePayAvailabilityOptions" id="ApplePayAvailabilityOptions" href="#ApplePayAvailabilityOptions">&nbsp;</a>
7043
+
7044
+ ## ApplePayAvailabilityOptions : <code>object</code>
7045
+ Options for `ApplePayOpenWalletButton.checkAvailability`. Extends
7046
+ [OpenWalletAvailabilityOptions](#OpenWalletAvailabilityOptions). Provide `merchant_id` directly to skip the network
7047
+ call, **or** provide `public_key_or_access_token` + `service_id` to resolve the merchant
7048
+ identifier from the service configuration.
7049
+
7050
+ **Kind**: global interface
7051
+ **Extends**: [<code>OpenWalletAvailabilityOptions</code>](#OpenWalletAvailabilityOptions)
7052
+
7053
+ | Param | Type | Description |
7054
+ | --- | --- | --- |
7055
+ | [merchant_id] | <code>string</code> | Apple merchant identifier. Provide this OR (`public_key_or_access_token` + `service_id`). |
7056
+ | [apple_pay_capabilities] | <code>Array.&lt;(&#x27;credentials\_available&#x27;\|&#x27;credentials\_status\_unknown&#x27;\|&#x27;credentials\_unavailable&#x27;)&gt;</code> | Device credential statuses that count as available. Defaults to `['credentials_available', 'credentials_status_unknown']` — `credentials_status_unknown` is what third-party / cross-device (QR) browsers report, so the default keeps Apple Pay visible outside Safari. |
7057
+ | [sync] | <code>boolean</code> | When `true`, runs only the synchronous native same-device check (`window.ApplePaySession` + `canMakePayments()`) and resolves immediately — no merchant resolution, SDK load, or `applePayCapabilities()` query. In this mode `available` reflects the native session only and `payment_credential_status` is `undefined`; it is **not** authoritative for cross-browser / QR availability. |
7058
+
7059
+ <a name="ApplePayAvailabilityResult" id="ApplePayAvailabilityResult" href="#ApplePayAvailabilityResult">&nbsp;</a>
7060
+
7061
+ ## ApplePayAvailabilityResult : <code>object</code>
7062
+ Result of `ApplePayOpenWalletButton.checkAvailability`. Extends
7063
+ [OpenWalletAvailabilityResult](#OpenWalletAvailabilityResult).
7064
+
7065
+ Infer the transport (Apple does not expose it directly): `available && has_native_session`
7066
+ ⇒ native sheet likely; `available && !has_native_session` ⇒ cross-device / QR handoff likely.
7067
+
7068
+ **Kind**: global interface
7069
+ **Extends**: [<code>OpenWalletAvailabilityResult</code>](#OpenWalletAvailabilityResult)
7070
+
7071
+ | Param | Type | Description |
7072
+ | --- | --- | --- |
7073
+ | available | <code>boolean</code> | Whether the device credential status is within the allowed capability set. |
7074
+ | supported | <code>boolean</code> | Whether Apple Pay is usable here at all (incl. the cross-device QR flow). Derived from `payment_credential_status` (anything other than `applePayUnsupported`); falls back to the native `canMakePayments()` signal when the capabilities query could not run. |
7075
+ | has_native_session | <code>boolean</code> | Whether a native, same-device Apple Pay session is present right now (`ApplePaySession` exists and `canMakePayments()` is `true`). |
7076
+ | [payment_credential_status] | <code>&#x27;paymentCredentialsAvailable&#x27;</code> \| <code>&#x27;paymentCredentialStatusUnknown&#x27;</code> \| <code>&#x27;paymentCredentialsUnavailable&#x27;</code> \| <code>&#x27;applePayUnsupported&#x27;</code> | The raw device-reported credential status. Undefined when unsupported or not queried. |
7077
+ | [reason] | <code>string</code> | Machine-readable reason when not available: `'unsupported_browser'`, `'missing_merchant_id'`, `'service_type_mismatch'`, `'config_fetch_failed'`, `'sdk_load_failed'`, `'query_failed'`, `'no_credentials'`, or `'no_native_session'` (only from the synchronous `sync: true` check). |
7078
+
7079
+ <a name="GooglePayAvailabilityOptions" id="GooglePayAvailabilityOptions" href="#GooglePayAvailabilityOptions">&nbsp;</a>
7080
+
7081
+ ## GooglePayAvailabilityOptions : <code>object</code>
7082
+ Options for `GooglePayOpenWalletButton.checkAvailability`. Extends
7083
+ [OpenWalletAvailabilityOptions](#OpenWalletAvailabilityOptions). All fields are optional — Google Pay's
7084
+ `isReadyToPay` check does not require a merchant identifier. Supplying
7085
+ `public_key_or_access_token` + `service_id` additionally validates the service type.
7086
+
7087
+ **Kind**: global interface
7088
+ **Extends**: [<code>OpenWalletAvailabilityOptions</code>](#OpenWalletAvailabilityOptions)
7089
+
7090
+ | Param | Type | Description |
7091
+ | --- | --- | --- |
7092
+ | [merchant_id] | <code>string</code> | Google Pay gateway merchant identifier. Optional; the readiness check runs without it. |
7093
+ | [sync] | <code>boolean</code> | When `true`, reports only whether the Google Pay JS API is already present in the page (no `isReadyToPay` call). It does **not** run the device/card readiness check. |
7094
+
7095
+ <a name="GooglePayAvailabilityResult" id="GooglePayAvailabilityResult" href="#GooglePayAvailabilityResult">&nbsp;</a>
7096
+
7097
+ ## GooglePayAvailabilityResult : <code>object</code>
7098
+ Result of `GooglePayOpenWalletButton.checkAvailability`. Extends
7099
+ [OpenWalletAvailabilityResult](#OpenWalletAvailabilityResult).
7100
+
7101
+ **Kind**: global interface
7102
+ **Extends**: [<code>OpenWalletAvailabilityResult</code>](#OpenWalletAvailabilityResult)
7103
+
7104
+ | Param | Type | Description |
7105
+ | --- | --- | --- |
7106
+ | available | <code>boolean</code> | Whether Google Pay is ready to pay in the current context (from `isReadyToPay().result`). |
7107
+ | supported | <code>boolean</code> | Whether the Google Pay JS API is present and the readiness query could run. |
7108
+ | [payment_method_present] | <code>boolean</code> | Google's `isReadyToPay` `paymentMethodPresent` — whether the buyer already has a usable payment method. Undefined when not reported. |
7109
+ | [reason] | <code>string</code> | Machine-readable reason when not available: `'unsupported_browser'`, `'service_type_mismatch'`, `'config_fetch_failed'`, `'sdk_load_failed'`, `'query_failed'`, `'no_payment_method'`, or `'api_not_loaded'` (only from the synchronous `sync: true` check). |
7110
+
6685
7111
  <a name="OnClickEventData" id="OnClickEventData" href="#OnClickEventData">&nbsp;</a>
6686
7112
 
6687
7113
  ## OnClickEventData : <code>object</code>
@@ -6948,20 +7374,23 @@ if the service type does not match Apple Pay.
6948
7374
 
6949
7375
  * [ApplePayOpenWalletButton](#ApplePayOpenWalletButton) ⇐ [<code>OpenWalletButtons</code>](#OpenWalletButtons)
6950
7376
  * [new ApplePayOpenWalletButton(selector, publicKeyOrAccessToken, serviceId, meta)](#new_ApplePayOpenWalletButton_new)
6951
- * [.load()](#OpenWalletButtons+load)
6952
- * [.enable()](#OpenWalletButtons+enable)
6953
- * [.disable()](#OpenWalletButtons+disable)
6954
- * [.setEnv(env, [alias])](#OpenWalletButtons+setEnv)
6955
- * [.setMeta(meta)](#OpenWalletButtons+setMeta)
6956
- * [.destroy()](#OpenWalletButtons+destroy)
6957
- * [.onClick(handler)](#OpenWalletButtons+onClick)
6958
- * [.onSuccess(handler)](#OpenWalletButtons+onSuccess)
6959
- * [.onUnavailable(handler)](#OpenWalletButtons+onUnavailable)
6960
- * [.onError(handler)](#OpenWalletButtons+onError)
6961
- * [.onCancel(handler)](#OpenWalletButtons+onCancel)
6962
- * [.onLoaded(handler)](#OpenWalletButtons+onLoaded)
6963
- * [.onShippingAddressChange(handler)](#OpenWalletButtons+onShippingAddressChange)
6964
- * [.onShippingOptionsChange(handler)](#OpenWalletButtons+onShippingOptionsChange)
7377
+ * _instance_
7378
+ * [.load()](#OpenWalletButtons+load)
7379
+ * [.enable()](#OpenWalletButtons+enable)
7380
+ * [.disable()](#OpenWalletButtons+disable)
7381
+ * [.setEnv(env, [alias])](#OpenWalletButtons+setEnv)
7382
+ * [.setMeta(meta)](#OpenWalletButtons+setMeta)
7383
+ * [.destroy()](#OpenWalletButtons+destroy)
7384
+ * [.onClick(handler)](#OpenWalletButtons+onClick)
7385
+ * [.onSuccess(handler)](#OpenWalletButtons+onSuccess)
7386
+ * [.onUnavailable(handler)](#OpenWalletButtons+onUnavailable)
7387
+ * [.onError(handler)](#OpenWalletButtons+onError)
7388
+ * [.onCancel(handler)](#OpenWalletButtons+onCancel)
7389
+ * [.onLoaded(handler)](#OpenWalletButtons+onLoaded)
7390
+ * [.onShippingAddressChange(handler)](#OpenWalletButtons+onShippingAddressChange)
7391
+ * [.onShippingOptionsChange(handler)](#OpenWalletButtons+onShippingOptionsChange)
7392
+ * _static_
7393
+ * [.checkAvailability([options])](#ApplePayOpenWalletButton.checkAvailability) ⇒ [<code>Promise.&lt;ApplePayAvailabilityResult&gt;</code>](#ApplePayAvailabilityResult)
6965
7394
 
6966
7395
  <a name="new_ApplePayOpenWalletButton_new" id="new_ApplePayOpenWalletButton_new" href="#new_ApplePayOpenWalletButton_new">&nbsp;</a>
6967
7396
 
@@ -7334,6 +7763,54 @@ button.onShippingOptionsChange((data) => {
7334
7763
  };
7335
7764
  });
7336
7765
  ```
7766
+ <a name="ApplePayOpenWalletButton.checkAvailability" id="ApplePayOpenWalletButton.checkAvailability" href="#ApplePayOpenWalletButton.checkAvailability">&nbsp;</a>
7767
+
7768
+ ### ApplePayOpenWalletButton.checkAvailability([options]) ⇒ [<code>Promise.&lt;ApplePayAvailabilityResult&gt;</code>](#ApplePayAvailabilityResult)
7769
+ Checks Apple Pay availability **without instantiating the button** — the single,
7770
+ authoritative, cross-browser-aware availability entry point.
7771
+
7772
+ Resolves the merchant identifier (either supplied directly or fetched from the
7773
+ service configuration), loads Apple's web SDK if needed, then queries
7774
+ `ApplePaySession.applePayCapabilities()`. Returns a convenience `available` verdict
7775
+ (computed against `apple_pay_capabilities`), the raw device-reported
7776
+ `payment_credential_status`, and `has_native_session` so callers can infer the transport:
7777
+ `available && has_native_session` ⇒ native sheet likely; `available && !has_native_session`
7778
+ ⇒ cross-device / QR handoff likely.
7779
+
7780
+ Pass `{ sync: true }` for a cheap, network-free native same-device pre-check that
7781
+ resolves immediately (see [ApplePayAvailabilityOptions.sync](ApplePayAvailabilityOptions.sync)).
7782
+
7783
+ **Kind**: static method of [<code>ApplePayOpenWalletButton</code>](#ApplePayOpenWalletButton)
7784
+ **Returns**: [<code>Promise.&lt;ApplePayAvailabilityResult&gt;</code>](#ApplePayAvailabilityResult) - The availability result.
7785
+
7786
+ | Param | Type | Description |
7787
+ | --- | --- | --- |
7788
+ | [options] | [<code>ApplePayAvailabilityOptions</code>](#ApplePayAvailabilityOptions) | Merchant context, allowed capabilities, and mode. |
7789
+
7790
+ **Example**
7791
+ ```js
7792
+ // Lightest path — no network, when you already know the merchant identifier:
7793
+ const result = await ApplePayOpenWalletButton.checkAvailability({ merchant_id });
7794
+ ```
7795
+ **Example**
7796
+ ```js
7797
+ // Resolve the merchant identifier from the service configuration:
7798
+ const result = await ApplePayOpenWalletButton.checkAvailability({
7799
+ public_key_or_access_token,
7800
+ service_id,
7801
+ env: 'sandbox',
7802
+ });
7803
+ if (result.available) {
7804
+ // Render the Apple Pay button (native sheet or cross-device QR, per has_native_session).
7805
+ } else {
7806
+ console.log('Unavailable:', result.reason, result.payment_credential_status);
7807
+ }
7808
+ ```
7809
+ **Example**
7810
+ ```js
7811
+ // Synchronous native-only fast check (no network / SDK load):
7812
+ const { has_native_session } = await ApplePayOpenWalletButton.checkAvailability({ sync: true });
7813
+ ```
7337
7814
  <a name="GooglePayOpenWalletButton" id="GooglePayOpenWalletButton" href="#GooglePayOpenWalletButton">&nbsp;</a>
7338
7815
 
7339
7816
  ## GooglePayOpenWalletButton ⇐ [<code>OpenWalletButtons</code>](#OpenWalletButtons)
@@ -7349,20 +7826,23 @@ if the service type does not match Google Pay.
7349
7826
 
7350
7827
  * [GooglePayOpenWalletButton](#GooglePayOpenWalletButton) ⇐ [<code>OpenWalletButtons</code>](#OpenWalletButtons)
7351
7828
  * [new GooglePayOpenWalletButton(selector, publicKeyOrAccessToken, serviceId, meta)](#new_GooglePayOpenWalletButton_new)
7352
- * [.load()](#OpenWalletButtons+load)
7353
- * [.enable()](#OpenWalletButtons+enable)
7354
- * [.disable()](#OpenWalletButtons+disable)
7355
- * [.setEnv(env, [alias])](#OpenWalletButtons+setEnv)
7356
- * [.setMeta(meta)](#OpenWalletButtons+setMeta)
7357
- * [.destroy()](#OpenWalletButtons+destroy)
7358
- * [.onClick(handler)](#OpenWalletButtons+onClick)
7359
- * [.onSuccess(handler)](#OpenWalletButtons+onSuccess)
7360
- * [.onUnavailable(handler)](#OpenWalletButtons+onUnavailable)
7361
- * [.onError(handler)](#OpenWalletButtons+onError)
7362
- * [.onCancel(handler)](#OpenWalletButtons+onCancel)
7363
- * [.onLoaded(handler)](#OpenWalletButtons+onLoaded)
7364
- * [.onShippingAddressChange(handler)](#OpenWalletButtons+onShippingAddressChange)
7365
- * [.onShippingOptionsChange(handler)](#OpenWalletButtons+onShippingOptionsChange)
7829
+ * _instance_
7830
+ * [.load()](#OpenWalletButtons+load)
7831
+ * [.enable()](#OpenWalletButtons+enable)
7832
+ * [.disable()](#OpenWalletButtons+disable)
7833
+ * [.setEnv(env, [alias])](#OpenWalletButtons+setEnv)
7834
+ * [.setMeta(meta)](#OpenWalletButtons+setMeta)
7835
+ * [.destroy()](#OpenWalletButtons+destroy)
7836
+ * [.onClick(handler)](#OpenWalletButtons+onClick)
7837
+ * [.onSuccess(handler)](#OpenWalletButtons+onSuccess)
7838
+ * [.onUnavailable(handler)](#OpenWalletButtons+onUnavailable)
7839
+ * [.onError(handler)](#OpenWalletButtons+onError)
7840
+ * [.onCancel(handler)](#OpenWalletButtons+onCancel)
7841
+ * [.onLoaded(handler)](#OpenWalletButtons+onLoaded)
7842
+ * [.onShippingAddressChange(handler)](#OpenWalletButtons+onShippingAddressChange)
7843
+ * [.onShippingOptionsChange(handler)](#OpenWalletButtons+onShippingOptionsChange)
7844
+ * _static_
7845
+ * [.checkAvailability([options])](#GooglePayOpenWalletButton.checkAvailability) ⇒ [<code>Promise.&lt;GooglePayAvailabilityResult&gt;</code>](#GooglePayAvailabilityResult)
7366
7846
 
7367
7847
  <a name="new_GooglePayOpenWalletButton_new" id="new_GooglePayOpenWalletButton_new" href="#new_GooglePayOpenWalletButton_new">&nbsp;</a>
7368
7848
 
@@ -7733,6 +8213,45 @@ button.onShippingOptionsChange((data) => {
7733
8213
  };
7734
8214
  });
7735
8215
  ```
8216
+ <a name="GooglePayOpenWalletButton.checkAvailability" id="GooglePayOpenWalletButton.checkAvailability" href="#GooglePayOpenWalletButton.checkAvailability">&nbsp;</a>
8217
+
8218
+ ### GooglePayOpenWalletButton.checkAvailability([options]) ⇒ [<code>Promise.&lt;GooglePayAvailabilityResult&gt;</code>](#GooglePayAvailabilityResult)
8219
+ Checks Google Pay availability **without instantiating the button** — the static
8220
+ availability entry point.
8221
+
8222
+ Loads the Google Pay JS SDK if needed, then runs `PaymentsClient.isReadyToPay()` using
8223
+ the **default** card configuration (a button instance with a custom `card_config` may
8224
+ produce a different result). All options are optional — unlike Apple Pay, Google Pay's
8225
+ readiness check does not require a merchant identifier; supplying `service_id` +
8226
+ `public_key_or_access_token` additionally validates that the service is a Google Pay service.
8227
+
8228
+ Pass `{ sync: true }` for a cheap, network-free check that only reports whether the
8229
+ Google Pay JS API is already present (see [GooglePayAvailabilityOptions.sync](GooglePayAvailabilityOptions.sync)).
8230
+
8231
+ **Kind**: static method of [<code>GooglePayOpenWalletButton</code>](#GooglePayOpenWalletButton)
8232
+ **Returns**: [<code>Promise.&lt;GooglePayAvailabilityResult&gt;</code>](#GooglePayAvailabilityResult) - The availability result.
8233
+
8234
+ | Param | Type | Description |
8235
+ | --- | --- | --- |
8236
+ | [options] | [<code>GooglePayAvailabilityOptions</code>](#GooglePayAvailabilityOptions) | Optional merchant context and mode. |
8237
+
8238
+ **Example**
8239
+ ```js
8240
+ // Simplest form — no merchant context needed:
8241
+ const result = await GooglePayOpenWalletButton.checkAvailability();
8242
+ if (result.available) {
8243
+ // Render the Google Pay button.
8244
+ }
8245
+ ```
8246
+ **Example**
8247
+ ```js
8248
+ // Validate the service is a Google Pay service while checking:
8249
+ const result = await GooglePayOpenWalletButton.checkAvailability({
8250
+ public_key_or_access_token,
8251
+ service_id,
8252
+ env: 'sandbox',
8253
+ });
8254
+ ```
7736
8255
  <a name="OpenWalletButtons" id="OpenWalletButtons" href="#OpenWalletButtons">&nbsp;</a>
7737
8256
 
7738
8257
  ## *OpenWalletButtons*