@paydock/client-sdk 1.131.0 → 1.133.1-beta

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 (135) hide show
  1. package/README.md +166 -0
  2. package/bundles/index.cjs +12754 -11064
  3. package/bundles/index.cjs.d.ts +1231 -905
  4. package/bundles/index.mjs +12753 -11064
  5. package/bundles/index.mjs.d.ts +1231 -905
  6. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.d.ts +40 -0
  7. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.d.ts.map +1 -0
  8. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.interfaces.d.ts +29 -0
  9. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.interfaces.d.ts.map +1 -0
  10. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.service.d.ts +14 -0
  11. package/bundles/types/afterpay-on-site-messaging/afterpay-on-site-messaging.service.d.ts.map +1 -0
  12. package/bundles/types/afterpay-on-site-messaging/index.d.ts +18 -0
  13. package/bundles/types/afterpay-on-site-messaging/index.d.ts.map +1 -0
  14. package/bundles/types/api/api-payment-source-internal.d.ts +2 -1
  15. package/bundles/types/api/api-payment-source-internal.d.ts.map +1 -1
  16. package/bundles/types/api/api-service-internal.d.ts +13 -6
  17. package/bundles/types/api/api-service-internal.d.ts.map +1 -1
  18. package/bundles/types/checkout/v1/layout-widgets/payment-methods-template.d.ts.map +1 -1
  19. package/bundles/types/checkout/v3/instructions/instruction.card_form.show.d.ts +1 -0
  20. package/bundles/types/checkout/v3/instructions/instruction.card_form.show.d.ts.map +1 -1
  21. package/bundles/types/checkout/v3/instructions/instruction.payment_methods.show.d.ts.map +1 -1
  22. package/bundles/types/components/param.d.ts +3 -1
  23. package/bundles/types/components/param.d.ts.map +1 -1
  24. package/bundles/types/index-cba.d.ts +9 -6
  25. package/bundles/types/index-cba.d.ts.map +1 -1
  26. package/bundles/types/index.d.ts +9 -6
  27. package/bundles/types/index.d.ts.map +1 -1
  28. package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts +198 -0
  29. package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts.map +1 -0
  30. package/bundles/types/open-wallets/base/open-wallet.service.d.ts +27 -0
  31. package/bundles/types/open-wallets/base/open-wallet.service.d.ts.map +1 -0
  32. package/bundles/types/open-wallets/enum/event.enum.d.ts +8 -1
  33. package/bundles/types/open-wallets/enum/event.enum.d.ts.map +1 -1
  34. package/bundles/types/open-wallets/enum/payload-format.enum.d.ts +4 -0
  35. package/bundles/types/open-wallets/enum/payload-format.enum.d.ts.map +1 -0
  36. package/bundles/types/open-wallets/enum/service-group.enum.d.ts +5 -0
  37. package/bundles/types/open-wallets/enum/service-group.enum.d.ts.map +1 -0
  38. package/bundles/types/open-wallets/index.d.ts +2 -2
  39. package/bundles/types/open-wallets/index.d.ts.map +1 -1
  40. package/bundles/types/open-wallets/interfaces/apple-pay/apple-pay-payment-request.interface.d.ts +495 -0
  41. package/bundles/types/open-wallets/interfaces/apple-pay/apple-pay-payment-request.interface.d.ts.map +1 -0
  42. package/bundles/types/open-wallets/interfaces/apple-pay/index.d.ts +2 -0
  43. package/bundles/types/open-wallets/interfaces/apple-pay/index.d.ts.map +1 -0
  44. package/bundles/types/open-wallets/interfaces/events.interface.d.ts +5 -6
  45. package/bundles/types/open-wallets/interfaces/events.interface.d.ts.map +1 -1
  46. package/bundles/types/open-wallets/interfaces/google-pay/google-pay-meta.interface.d.ts +54 -0
  47. package/bundles/types/open-wallets/interfaces/google-pay/google-pay-meta.interface.d.ts.map +1 -0
  48. package/bundles/types/open-wallets/interfaces/google-pay/index.d.ts +2 -0
  49. package/bundles/types/open-wallets/interfaces/google-pay/index.d.ts.map +1 -0
  50. package/bundles/types/open-wallets/interfaces/index.d.ts +1 -3
  51. package/bundles/types/open-wallets/interfaces/index.d.ts.map +1 -1
  52. package/bundles/types/open-wallets/interfaces/open-wallet-meta.interface.d.ts +11 -0
  53. package/bundles/types/open-wallets/interfaces/open-wallet-meta.interface.d.ts.map +1 -0
  54. package/bundles/types/open-wallets/interfaces/payment-source.interface.d.ts +0 -1
  55. package/bundles/types/open-wallets/interfaces/payment-source.interface.d.ts.map +1 -1
  56. package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts +64 -0
  57. package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts.map +1 -0
  58. package/bundles/types/open-wallets/services/apple-pay/index.d.ts +2 -0
  59. package/bundles/types/open-wallets/services/apple-pay/index.d.ts.map +1 -0
  60. package/bundles/types/open-wallets/services/google-pay/constants/google-pay.constants.d.ts +11 -0
  61. package/bundles/types/open-wallets/services/google-pay/constants/google-pay.constants.d.ts.map +1 -0
  62. package/bundles/types/open-wallets/services/google-pay/constants/index.d.ts +2 -0
  63. package/bundles/types/open-wallets/services/google-pay/constants/index.d.ts.map +1 -0
  64. package/bundles/types/open-wallets/services/google-pay/google-pay.open-wallet.service.d.ts +55 -0
  65. package/bundles/types/open-wallets/services/google-pay/google-pay.open-wallet.service.d.ts.map +1 -0
  66. package/bundles/types/open-wallets/services/google-pay/index.d.ts +2 -0
  67. package/bundles/types/open-wallets/services/google-pay/index.d.ts.map +1 -0
  68. package/bundles/types/open-wallets/services/google-pay/utils/google-pay.utils.d.ts +20 -0
  69. package/bundles/types/open-wallets/services/google-pay/utils/google-pay.utils.d.ts.map +1 -0
  70. package/bundles/types/open-wallets/services/google-pay/utils/index.d.ts +2 -0
  71. package/bundles/types/open-wallets/services/google-pay/utils/index.d.ts.map +1 -0
  72. package/bundles/types/open-wallets/services/google-pay/validation/google-pay.validation.d.ts +3 -0
  73. package/bundles/types/open-wallets/services/google-pay/validation/google-pay.validation.d.ts.map +1 -0
  74. package/bundles/types/open-wallets/services/google-pay/validation/index.d.ts +2 -0
  75. package/bundles/types/open-wallets/services/google-pay/validation/index.d.ts.map +1 -0
  76. package/bundles/types/open-wallets/types/apple-pay/apple-pay-button-style.type.d.ts +2 -0
  77. package/bundles/types/open-wallets/types/apple-pay/apple-pay-button-style.type.d.ts.map +1 -0
  78. package/bundles/types/open-wallets/types/apple-pay/apple-pay-button-type.type.d.ts +2 -0
  79. package/bundles/types/open-wallets/types/apple-pay/apple-pay-button-type.type.d.ts.map +1 -0
  80. package/bundles/types/open-wallets/types/apple-pay/index.d.ts +3 -0
  81. package/bundles/types/open-wallets/types/apple-pay/index.d.ts.map +1 -0
  82. package/bundles/types/open-wallets/types/base-event-data.interface.d.ts +5 -0
  83. package/bundles/types/open-wallets/types/base-event-data.interface.d.ts.map +1 -0
  84. package/bundles/types/open-wallets/types/google-pay/google-pay-button-color.type.d.ts +2 -0
  85. package/bundles/types/open-wallets/types/google-pay/google-pay-button-color.type.d.ts.map +1 -0
  86. package/bundles/types/open-wallets/types/google-pay/google-pay-button-size-mode.type.d.ts +2 -0
  87. package/bundles/types/open-wallets/types/google-pay/google-pay-button-size-mode.type.d.ts.map +1 -0
  88. package/bundles/types/open-wallets/types/google-pay/google-pay-button-type.type.d.ts +2 -0
  89. package/bundles/types/open-wallets/types/google-pay/google-pay-button-type.type.d.ts.map +1 -0
  90. package/bundles/types/open-wallets/types/google-pay/index.d.ts +4 -0
  91. package/bundles/types/open-wallets/types/google-pay/index.d.ts.map +1 -0
  92. package/bundles/types/open-wallets/types/index.d.ts +1 -2
  93. package/bundles/types/open-wallets/types/index.d.ts.map +1 -1
  94. package/bundles/types/open-wallets/types/on-shipping-address-change-event-data.interface.d.ts +21 -0
  95. package/bundles/types/open-wallets/types/on-shipping-address-change-event-data.interface.d.ts.map +1 -0
  96. package/bundles/types/open-wallets/types/on-shipping-address-change-event-response.interface.d.ts +6 -0
  97. package/bundles/types/open-wallets/types/on-shipping-address-change-event-response.interface.d.ts.map +1 -0
  98. package/bundles/types/open-wallets/types/on-shipping-option-change-event-data.interface.d.ts +13 -0
  99. package/bundles/types/open-wallets/types/on-shipping-option-change-event-data.interface.d.ts.map +1 -0
  100. package/bundles/types/open-wallets/types/on-shipping-option-change-event-response.interface.d.ts +4 -0
  101. package/bundles/types/open-wallets/types/on-shipping-option-change-event-response.interface.d.ts.map +1 -0
  102. package/bundles/types/open-wallets/types/payment-source.type.d.ts +85 -0
  103. package/bundles/types/open-wallets/types/payment-source.type.d.ts.map +1 -0
  104. package/bundles/types/open-wallets/types/shipping-event-to-response.type.d.ts +6 -0
  105. package/bundles/types/open-wallets/types/shipping-event-to-response.type.d.ts.map +1 -0
  106. package/bundles/types/open-wallets/types/wallet-type.type.d.ts +2 -2
  107. package/bundles/types/open-wallets/types/wallet-type.type.d.ts.map +1 -1
  108. package/bundles/types/secure-remote-commerce/secure-remote-commerce.d.ts +16 -16
  109. package/bundles/types/secure-remote-commerce/secure-remote-commerce.d.ts.map +1 -1
  110. package/bundles/types/wallet-buttons-express/base.wallet-button-express.d.ts +9 -9
  111. package/bundles/types/wallet-buttons-express/base.wallet-button-express.d.ts.map +1 -1
  112. package/bundles/types/widget/html-multi-widget.d.ts +13 -1
  113. package/bundles/types/widget/html-multi-widget.d.ts.map +1 -1
  114. package/bundles/types/widget/multi-widget.d.ts +7 -4
  115. package/bundles/types/widget/multi-widget.d.ts.map +1 -1
  116. package/bundles/widget.umd.js +12754 -11064
  117. package/bundles/widget.umd.js.d.ts +1231 -905
  118. package/bundles/widget.umd.js.min.d.ts +1231 -905
  119. package/bundles/widget.umd.min.js +1 -1
  120. package/docs/afterpay-on-site-messaging-examples.md +60 -0
  121. package/docs/afterpay-on-site-messaging.md +104 -0
  122. package/docs/open-wallet-buttons-examples.md +1188 -0
  123. package/package.json +4 -1
  124. package/bundles/types/open-wallets/base/base-open-wallet.d.ts +0 -33
  125. package/bundles/types/open-wallets/base/base-open-wallet.d.ts.map +0 -1
  126. package/bundles/types/open-wallets/interfaces/base-service-config.interface.d.ts +0 -30
  127. package/bundles/types/open-wallets/interfaces/base-service-config.interface.d.ts.map +0 -1
  128. package/bundles/types/open-wallets/interfaces/base-wallet-meta.interface.d.ts +0 -5
  129. package/bundles/types/open-wallets/interfaces/base-wallet-meta.interface.d.ts.map +0 -1
  130. package/bundles/types/open-wallets/services/index.d.ts +0 -9
  131. package/bundles/types/open-wallets/services/index.d.ts.map +0 -1
  132. package/bundles/types/open-wallets/types/ott-backend.type.d.ts +0 -26
  133. package/bundles/types/open-wallets/types/ott-backend.type.d.ts.map +0 -1
  134. package/bundles/types/open-wallets/types/ott-response.type.d.ts +0 -8
  135. package/bundles/types/open-wallets/types/ott-response.type.d.ts.map +0 -1
@@ -0,0 +1,1188 @@
1
+ ## Open Wallet Buttons
2
+ You can find description of all methods and parameters [here](https://www.npmjs.com/package/@paydock/client-sdk#open-wallet-buttons-simple-example)
3
+
4
+ Open Wallet Buttons provide a next-generation approach to integrating E-Wallets into your checkout with improved event handling and more granular control over wallet interactions.
5
+ Currently supports Apple Pay and Google Pay, with more wallet types planned for future releases.
6
+
7
+ If available in your client environment, you will display a simple button that upon clicking it the user will follow the standard flow for the appropriate Wallet. If not available an event will be raised and no button will be displayed.
8
+
9
+ ## Open Wallet Buttons simple example
10
+
11
+ ### Container
12
+
13
+ ```html
14
+ <div id="widget"></div>
15
+ ```
16
+
17
+ You must create a container for the Open Wallet Buttons. Inside this tag, the button will be initialized.
18
+
19
+ Before initializing the button, you must configure your wallet service through the PayDock dashboard and obtain the service ID that will be used to load the button configuration.
20
+
21
+ ### Initialization
22
+
23
+ For Apple Pay and Google Pay wallets, the amount and currency are required:
24
+
25
+ **Apple Pay Example:**
26
+ ```javascript
27
+ let button = new paydock.OpenWalletButtons(
28
+ "#widget",
29
+ publicKeyOrAccessToken,
30
+ serviceId,
31
+ {
32
+ amount: 100,
33
+ currency: "USD",
34
+ },
35
+ [] // Optional: required meta fields validation
36
+ );
37
+ button.load();
38
+ ```
39
+
40
+ **Google Pay Example:**
41
+ ```javascript
42
+ let button = new paydock.OpenWalletButtons(
43
+ "#widget",
44
+ publicKeyOrAccessToken,
45
+ serviceId,
46
+ {
47
+ amount: 100,
48
+ currency: "USD",
49
+ merchant_name: "Your Store"
50
+ },
51
+ [] // Optional: required meta fields validation
52
+ );
53
+ button.load();
54
+ ```
55
+
56
+ ```javascript
57
+ // ES2015 | TypeScript
58
+ import { OpenWalletButtons } from '@paydock/client-sdk';
59
+
60
+ var button = new OpenWalletButtons(
61
+ '#widget',
62
+ publicKeyOrAccessToken,
63
+ serviceId,
64
+ {
65
+ amount: 100,
66
+ currency: 'USD',
67
+ },
68
+ [] // Optional: required meta fields validation
69
+ );
70
+ button.load();
71
+ ```
72
+
73
+ For Apple Pay with shipping enabled:
74
+ ```javascript
75
+ let button = new paydock.OpenWalletButtons(
76
+ "#widget",
77
+ publicKeyOrAccessToken,
78
+ serviceId,
79
+ {
80
+ amount: 100,
81
+ currency: "USD",
82
+ amount_label: "Total",
83
+ country: "US",
84
+ request_shipping: true,
85
+ shipping_options: [
86
+ {
87
+ id: "standard",
88
+ label: "Standard Shipping",
89
+ detail: "5-7 business days",
90
+ amount: 5.00
91
+ },
92
+ {
93
+ id: "express",
94
+ label: "Express Shipping",
95
+ detail: "1-2 business days",
96
+ amount: 15.00
97
+ }
98
+ ]
99
+ },
100
+ ['amount_label', 'country', 'request_shipping'] // Required meta fields validation
101
+ );
102
+ button.load();
103
+ ```
104
+
105
+ ### Constructor Parameters
106
+
107
+ The OpenWalletButtons constructor accepts the following parameters:
108
+
109
+ 1. **selector** (string): CSS selector for the container element
110
+ 2. **publicKeyOrAccessToken** (string): Your PayDock public key or access token
111
+ 3. **serviceId** (string): The service ID configured in PayDock dashboard
112
+ 4. **meta** (OpenWalletMeta): Configuration object with payment and wallet settings
113
+ 5. **requiredMetaFields** (string[], optional): Array of meta field names that must be present
114
+
115
+ ### Setting environment
116
+
117
+ Current method can change environment. By default environment = sandbox.
118
+ Bear in mind that you must set an environment before calling `button.load()`.
119
+
120
+ ```javascript
121
+ button.setEnv('sandbox');
122
+ ```
123
+
124
+ ### Full example
125
+
126
+ ```html
127
+ <!DOCTYPE html>
128
+ <html lang="en">
129
+ <head>
130
+ <meta charset="UTF-8">
131
+ <title>Title</title>
132
+ </head>
133
+ <body>
134
+ <h2>Payment using PayDock Open Wallet Button!</h2>
135
+ <div id="widget"></div>
136
+ </body>
137
+ <script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js" ></script>
138
+ <script>
139
+ let button = new paydock.OpenWalletButtons(
140
+ "#widget",
141
+ publicKeyOrAccessToken,
142
+ serviceId,
143
+ {
144
+ amount: 100,
145
+ currency: "USD",
146
+ amount_label: "Total",
147
+ country: "US",
148
+ },
149
+ ['amount', 'currency'] // Required meta fields
150
+ );
151
+ button.load();
152
+ </script>
153
+ </html>
154
+ ```
155
+
156
+ ## Open Wallet Buttons advanced example
157
+
158
+ ### Checking for button availability
159
+
160
+ 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.
161
+
162
+ ```javascript
163
+ button.onUnavailable((data) => console.log("No open wallet buttons available", data));
164
+ ```
165
+
166
+ ### Performing actions when the wallet button is clicked
167
+
168
+ You can perform validations or actions when the user clicks on the wallet button. The callback supports both synchronous and asynchronous operations using the `attachResult` method.
169
+
170
+ ```javascript
171
+ // Synchronous example
172
+ button.onClick((data) => {
173
+ console.log("Perform actions on button click");
174
+ // Perform validation logic
175
+ // Optionally use attachResult to control flow
176
+ data.attachResult(true); // Continue with payment
177
+ // data.attachResult(false); // Halt payment
178
+ });
179
+
180
+ // Asynchronous example
181
+ button.onClick((data) => {
182
+ // Attach a Promise to control the wallet flow
183
+ data.attachResult(
184
+ fetch('/api/validate-order')
185
+ .then(response => response.json())
186
+ .then(result => {
187
+ if (!result.valid) {
188
+ throw new Error('Order validation failed');
189
+ }
190
+ return result;
191
+ })
192
+ );
193
+ });
194
+ ```
195
+
196
+ ### Handling successful OTT creation
197
+
198
+ When the One Time Token (OTT) is successfully created, the onSuccess callback will be called with the token data. **This callback is required** - if no handler is provided, an error will be thrown.
199
+
200
+ ```javascript
201
+ button.onSuccess((data) => {
202
+ console.log("OTT created successfully:", data.token);
203
+ console.log("Amount:", data.amount);
204
+ console.log("Shipping:", data.shipping);
205
+ console.log("Billing:", data.billing);
206
+
207
+ // Use the OTT token to complete payment on your backend
208
+ fetch('/api/process-payment', {
209
+ method: 'POST',
210
+ headers: { 'Content-Type': 'application/json' },
211
+ body: JSON.stringify({ ott_token: data.token })
212
+ });
213
+ });
214
+ ```
215
+
216
+ **Important**: The `onSuccess` event handler is mandatory. Not providing one will result in an error.
217
+
218
+ ### Performing actions when shipping address is updated
219
+
220
+ When shipping is enabled and the customer updates their shipping address, you can recalculate shipping costs and update the payment amount. **This handler is required when shipping is enabled** - if no handler is provided, an error will be thrown.
221
+
222
+ ```javascript
223
+ button.onShippingAddressChange(async (data) => {
224
+ console.log("Shipping address updated:", data);
225
+ console.log("Address details:", {
226
+ country: data.address_country,
227
+ state: data.address_state,
228
+ city: data.address_city,
229
+ postcode: data.address_postcode,
230
+ contact: data.contact
231
+ });
232
+
233
+ // Call your backend to recalculate shipping
234
+ const response = await fetch('/api/calculate-shipping', {
235
+ method: 'POST',
236
+ headers: { 'Content-Type': 'application/json' },
237
+ body: JSON.stringify({
238
+ address_country: data.address_country,
239
+ address_state: data.address_state,
240
+ address_city: data.address_city,
241
+ address_postcode: data.address_postcode
242
+ })
243
+ });
244
+
245
+ const result = await response.json();
246
+
247
+ return {
248
+ amount: result.newAmount,
249
+ shipping_options: result.availableShippingOptions
250
+ };
251
+ });
252
+ ```
253
+
254
+ **Important**: This event handler is required when using shipping functionality.
255
+
256
+ ### Performing actions when shipping option is selected
257
+
258
+ When the customer selects a different shipping option, you can update the total amount accordingly. **This handler is required when shipping options are provided** - if no handler is provided, an error will be thrown.
259
+
260
+ ```javascript
261
+ button.onShippingOptionsChange(async (data) => {
262
+ console.log("Shipping option selected:", data);
263
+ console.log("Selected option:", {
264
+ id: data.shipping_option_id,
265
+ label: data.label,
266
+ detail: data.detail,
267
+ amount: data.amount
268
+ });
269
+
270
+ // Call your backend to update total with new shipping cost
271
+ const response = await fetch('/api/update-shipping-cost', {
272
+ method: 'POST',
273
+ headers: { 'Content-Type': 'application/json' },
274
+ body: JSON.stringify({
275
+ shipping_option_id: data.shipping_option_id,
276
+ shipping_amount: data.amount
277
+ })
278
+ });
279
+
280
+ const result = await response.json();
281
+
282
+ // Note: In some implementations, you might need to access data.data.amount
283
+ // Check your actual data structure in console.log output
284
+ return {
285
+ amount: result.newTotalAmount
286
+ };
287
+ });
288
+ ```
289
+
290
+ **Important**: This event handler is required when providing shipping options.
291
+
292
+ ### Handling errors
293
+
294
+ Register a callback function to handle errors that occur during wallet operations.
295
+
296
+ ```javascript
297
+ button.onError((data) => {
298
+ console.error("Open Wallet error:", data.error);
299
+ console.log("Error context:", data.context);
300
+
301
+ // Show user-friendly error message
302
+ showErrorMessage("Payment initialization failed. Please try again.");
303
+ });
304
+ ```
305
+
306
+ ### Handling checkout cancellation
307
+
308
+ When the user cancels or closes the wallet payment interface, you can perform cleanup operations.
309
+
310
+ ```javascript
311
+ button.onCancel((data) => {
312
+ console.log("Wallet checkout cancelled", data);
313
+
314
+ // Perform cleanup or redirect user
315
+ window.location.href = '/checkout';
316
+ });
317
+ ```
318
+
319
+ ### Apple Pay Full example
320
+
321
+ ```html
322
+ <!DOCTYPE html>
323
+ <html lang="en">
324
+ <head>
325
+ <meta charset="UTF-8">
326
+ <title>Apple Pay with Open Wallets</title>
327
+ </head>
328
+ <body>
329
+ <h2>Payment using PayDock Open Wallet Button!</h2>
330
+ <div id="widget"></div>
331
+ </body>
332
+ <script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js" ></script>
333
+ <script>
334
+ let button = new paydock.OpenWalletButtons(
335
+ "#widget",
336
+ publicKeyOrAccessToken,
337
+ serviceId,
338
+ {
339
+ amount: 100,
340
+ currency: "USD",
341
+ amount_label: "Total",
342
+ country: "US",
343
+ request_shipping: true,
344
+ request_payer_name: true,
345
+ request_payer_email: true,
346
+ request_payer_phone: true,
347
+ show_billing_address: true,
348
+ style: {
349
+ button_type: 'buy',
350
+ button_style: 'black'
351
+ },
352
+ shipping_options: [
353
+ {
354
+ id: "standard",
355
+ label: "Standard Shipping",
356
+ detail: "Arrives in 5 to 7 days",
357
+ amount: 5.00,
358
+ date_components_range: {
359
+ start_date_components: {
360
+ years: 0,
361
+ months: 0,
362
+ days: 5,
363
+ hours: 0,
364
+ },
365
+ end_date_components: {
366
+ years: 0,
367
+ months: 0,
368
+ days: 7,
369
+ hours: 0,
370
+ }
371
+ }
372
+ },
373
+ {
374
+ id: "express",
375
+ label: "Express Shipping",
376
+ detail: "Arrives in 1 to 2 days",
377
+ amount: 15.00,
378
+ date_components_range: {
379
+ start_date_components: {
380
+ years: 0,
381
+ months: 0,
382
+ days: 1,
383
+ hours: 0,
384
+ },
385
+ end_date_components: {
386
+ years: 0,
387
+ months: 0,
388
+ days: 2,
389
+ hours: 0,
390
+ }
391
+ }
392
+ }
393
+ ],
394
+ apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable']
395
+ },
396
+ ['amount_label', 'country', 'request_shipping', 'shipping_options', 'apple_pay_capabilities'] // Required fields validation
397
+ );
398
+
399
+ button.setEnv('sandbox');
400
+
401
+ button.onUnavailable((data) => {
402
+ console.log("Apple Pay not available:", data);
403
+ // Show alternative payment methods
404
+ });
405
+
406
+ button.onClick((data) => {
407
+ console.log("Apple Pay button clicked");
408
+ // Perform pre-payment validation
409
+ });
410
+
411
+ button.onSuccess((data) => {
412
+ console.log("Payment successful:", data);
413
+ // Process the OTT token on your backend
414
+ processPayment(data.token);
415
+ });
416
+
417
+ button.onError((data) => {
418
+ console.error("Payment error:", data);
419
+ // Handle error appropriately
420
+ });
421
+
422
+ button.onCancel((data) => {
423
+ console.log("Payment cancelled");
424
+ // Handle cancellation
425
+ });
426
+
427
+ button.onShippingAddressChange(async (addressData) => {
428
+ // Update shipping costs based on address
429
+ const response = await updateShippingCosts(addressData);
430
+ return {
431
+ amount: response.newAmount,
432
+ shipping_options: response.shippingOptions
433
+ };
434
+ });
435
+
436
+ button.onShippingOptionsChange(async (optionData) => {
437
+ // Update total based on selected shipping option
438
+ const response = await updateTotal(optionData);
439
+ return {
440
+ amount: response.newAmount
441
+ };
442
+ });
443
+
444
+ button.load();
445
+
446
+ async function updateShippingCosts(addressData) {
447
+ // Your shipping calculation logic based on address
448
+ const baseAmount = 100;
449
+ const updatedShippingOptions = [
450
+ {
451
+ id: "updated-standard",
452
+ label: "Updated Standard Shipping",
453
+ detail: "Based on your location",
454
+ amount: 8.00
455
+ },
456
+ {
457
+ id: "updated-express",
458
+ label: "Updated Express Shipping",
459
+ detail: "Fast delivery to your area",
460
+ amount: 18.00
461
+ }
462
+ ];
463
+
464
+ return {
465
+ newAmount: baseAmount + updatedShippingOptions[0].amount,
466
+ shippingOptions: updatedShippingOptions
467
+ };
468
+ }
469
+
470
+ async function updateTotal(optionData) {
471
+ // Your total calculation logic
472
+ const baseAmount = 100;
473
+ // Note: Check if you need data.data.amount or data.amount based on your implementation
474
+ const shippingAmount = optionData.amount || optionData.data?.amount;
475
+ return {
476
+ newAmount: baseAmount + shippingAmount
477
+ };
478
+ }
479
+
480
+ function processPayment(ottToken) {
481
+ // Send OTT token to your backend for payment processing
482
+ fetch('/api/process-payment', {
483
+ method: 'POST',
484
+ headers: { 'Content-Type': 'application/json' },
485
+ body: JSON.stringify({ ott_token: ottToken })
486
+ });
487
+ }
488
+ </script>
489
+ </html>
490
+ ```
491
+
492
+ ### Google Pay Full Example
493
+
494
+ ```html
495
+ <!DOCTYPE html>
496
+ <html lang="en">
497
+ <head>
498
+ <meta charset="UTF-8">
499
+ <title>Google Pay with Open Wallets</title>
500
+ </head>
501
+ <body>
502
+ <h2>Payment using PayDock Google Pay Open Wallet Button!</h2>
503
+ <div id="widget"></div>
504
+ </body>
505
+ <script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js" ></script>
506
+ <script>
507
+ let button = new paydock.OpenWalletButtons(
508
+ "#widget",
509
+ publicKeyOrAccessToken,
510
+ serviceId,
511
+ {
512
+ amount: 100,
513
+ currency: "USD",
514
+ amount_label: "Total",
515
+ country: "AU",
516
+ request_shipping: true,
517
+ show_billing_address: true,
518
+ merchant_name: 'Test Merchant',
519
+ style: {
520
+ google: {
521
+ button_type: 'buy',
522
+ button_color: 'default',
523
+ button_size_mode: 'fill'
524
+ }
525
+ },
526
+ // Google Pay specific properties
527
+ payment_method_type: 'CARD',
528
+ allowed_auth_methods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
529
+ allowed_card_networks: ['AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'],
530
+ billing_address_required: true,
531
+ shipping_options: [
532
+ {
533
+ id: "standard",
534
+ label: "Standard Shipping",
535
+ detail: "Arrives in 5 to 7 days",
536
+ amount: 5.00,
537
+ type: "ELECTRONIC"
538
+ },
539
+ {
540
+ id: "express",
541
+ label: "Express Shipping",
542
+ detail: "Arrives in 1 to 2 days",
543
+ amount: 15.00,
544
+ type: "PICKUP"
545
+ }
546
+ ]
547
+ },
548
+ ['amount_label', 'country', 'request_shipping', 'shipping_options', 'merchant_name']
549
+ );
550
+
551
+ button.setEnv('sandbox');
552
+
553
+ // Required handlers
554
+ button.onSuccess((data) => {
555
+ console.log("Payment successful:", data);
556
+ processPayment(data.token);
557
+ });
558
+
559
+ button.onShippingAddressChange(async (addressData) => {
560
+ const response = await updateShippingCosts(addressData);
561
+ return {
562
+ amount: response.newAmount,
563
+ shipping_options: response.shippingOptions
564
+ };
565
+ });
566
+
567
+ button.onShippingOptionsChange(async (optionData) => {
568
+ const response = await updateTotal(optionData);
569
+ return {
570
+ amount: response.newAmount
571
+ };
572
+ });
573
+
574
+ // Optional handlers
575
+ button.onUnavailable((data) => {
576
+ console.log("Google Pay not available:", data);
577
+ // Show alternative payment methods
578
+ });
579
+
580
+ button.onError((data) => {
581
+ console.error("Payment error:", data);
582
+ // Handle error appropriately
583
+ });
584
+
585
+ button.onCancel((data) => {
586
+ console.log("Payment cancelled");
587
+ // Handle cancellation
588
+ });
589
+
590
+ button.onClick((data) => {
591
+ console.log("Google Pay button clicked");
592
+ // Perform pre-payment validation
593
+ });
594
+
595
+ button.load();
596
+
597
+ // Helper functions (same implementation as Apple Pay example)
598
+ async function updateShippingCosts(addressData) {
599
+ // Your shipping calculation logic based on address
600
+ const baseAmount = 100;
601
+ const updatedShippingOptions = [
602
+ {
603
+ id: "updated-standard",
604
+ label: "Updated Standard Shipping",
605
+ detail: "Based on your location",
606
+ amount: 8.00,
607
+ type: "ELECTRONIC"
608
+ },
609
+ {
610
+ id: "updated-express",
611
+ label: "Updated Express Shipping",
612
+ detail: "Fast delivery to your area",
613
+ amount: 18.00,
614
+ type: "PICKUP"
615
+ }
616
+ ];
617
+
618
+ return {
619
+ newAmount: baseAmount + updatedShippingOptions[0].amount,
620
+ shippingOptions: updatedShippingOptions
621
+ };
622
+ }
623
+
624
+ async function updateTotal(optionData) {
625
+ // Your total calculation logic
626
+ const baseAmount = 100;
627
+ const shippingAmount = optionData.amount || optionData.data?.amount;
628
+ return {
629
+ newAmount: baseAmount + shippingAmount
630
+ };
631
+ }
632
+
633
+ function processPayment(ottToken) {
634
+ // Send OTT token to your backend for payment processing
635
+ fetch('/api/process-payment', {
636
+ method: 'POST',
637
+ headers: { 'Content-Type': 'application/json' },
638
+ body: JSON.stringify({ ott_token: ottToken })
639
+ });
640
+ }
641
+ </script>
642
+ </html>
643
+ ```
644
+
645
+ ### Events
646
+ The above events can be used in a more generic way via the `eventEmitter.subscribe` method internally, but the recommended approach is to use the dedicated event handler methods provided by the OpenWalletButtons class.
647
+
648
+ **Available Event Handler Methods:**
649
+ - `onClick(handler)` - Button click events (supports attachResult for flow control)
650
+ - `onSuccess(handler)` - **Required** - OTT creation success events
651
+ - `onUnavailable(handler)` - Wallet unavailable events (supports Promise pattern)
652
+ - `onError(handler)` - Error events (supports Promise pattern)
653
+ - `onCancel(handler)` - Checkout cancellation events (supports Promise pattern)
654
+ - `onShippingAddressChange(handler)` - **Required for shipping** - Address change events
655
+ - `onShippingOptionsChange(handler)` - **Required for shipping options** - Option change events
656
+
657
+ **Event Handler Patterns:**
658
+
659
+ ```javascript
660
+ // Required handlers (will throw error if not provided)
661
+ button.onSuccess(handler); // Always required
662
+ button.onShippingAddressChange(handler); // Required when shipping enabled
663
+ button.onShippingOptionsChange(handler); // Required when shipping options provided
664
+
665
+ // Optional handlers with Promise support
666
+ button.onUnavailable(handler); // or await button.onUnavailable()
667
+ button.onError(handler); // or await button.onError()
668
+ button.onCancel(handler); // or await button.onCancel()
669
+
670
+ // Click handler with flow control
671
+ button.onClick(handler); // Use data.attachResult() for async operations
672
+ ```
673
+
674
+ ### Configuration Options
675
+
676
+ #### Required Meta Fields
677
+
678
+ - `amount`: The payment amount (number)
679
+ - `currency`: The currency code (string, e.g., "USD")
680
+
681
+ #### PayDock-Specific Meta Fields
682
+
683
+ The following are PayDock-specific properties available in `OpenWalletMeta`:
684
+
685
+ **Payment Configuration:**
686
+ - `amount_label?: string`: Label for the total amount
687
+ - `country?: string`: Country code (e.g., "US")
688
+ - `capture?: boolean`: Whether to capture the payment immediately
689
+ - `reference?: string`: Payment reference
690
+ - `id?: string`: Payment ID
691
+ - `credentials?: object`: Gateway credentials
692
+
693
+ **Contact and Shipping:**
694
+ - `request_shipping?: boolean`: Enable shipping address collection
695
+ - `request_payer_name?: boolean`: Request payer name
696
+ - `request_payer_email?: boolean`: Request payer email
697
+ - `request_payer_phone?: boolean`: Request payer phone
698
+ - `show_billing_address?: boolean`: Show billing address fields
699
+ - `shipping_options?: IShippingOption[]`: Array of shipping options
700
+
701
+ **UI and Display:**
702
+ - `style?: WalletStyles`: Button styling options
703
+ - `pay_later?: boolean`: Enable pay later options
704
+ - `hide_message?: boolean`: Hide payment messages
705
+ - `standalone?: boolean`: Standalone mode
706
+ - `merchant_name?: string`: Merchant display name
707
+
708
+ **Wallet-Specific:**
709
+ - `apple_pay_capabilities?: string[]`: Apple Pay capability requirements
710
+ - `wallets?: WALLET_TYPES[]`: Supported wallet types
711
+ - `access_token?: string`: Access token
712
+ - `refresh_token?: string`: Refresh token
713
+ - `client_id?: string`: Client ID
714
+
715
+ #### Extended Native Properties
716
+ Since `OpenWalletMeta` extends `ApplePayJS.ApplePayPaymentRequest` and Google Pay interfaces, you can use any native Apple Pay or Google Pay properties directly in the configuration object alongside PayDock properties. See the [Extended Interface Properties](#extended-interface-properties) section for comprehensive details.
717
+
718
+ #### Configuration Comparison Quick Reference
719
+
720
+ | Feature | PayDock Property | Apple Pay Native Property | Google Pay Native Property |
721
+ |---------|------------------|---------------------------|----------------------------|
722
+ | **Country** | `country: 'US'` | `countryCode: 'US'` | `parameters.allowedCountries: ['US']` |
723
+ | **Currency** | `currency: 'USD'` | `currencyCode: 'USD'` | Via PayDock property |
724
+ | **Amount** | `amount: 100` | `total: { amount: '100.00' }` | Via PayDock property |
725
+ | **Billing Address** | `show_billing_address: true` | `requiredBillingContactFields: [...]` | `billingAddressRequired: true` |
726
+ | **Shipping Address** | `request_shipping: true` | `requiredShippingContactFields: [...]` | `shippingAddressRequired: true` |
727
+ | **Card Networks** | Auto-configured | `supportedNetworks: ['visa', ...]` | `allowedCardNetworks: ['VISA', ...]` |
728
+ | **Button Style** | `style.apple.button_style` | Via PayDock style property | `style.google.button_color` |
729
+
730
+ #### Apple Pay Specific Style Options
731
+ ```javascript
732
+ style: {
733
+ apple: {
734
+ button_type: 'add-money' | 'book' | 'buy' | 'check-out' | 'continue' | 'contribute' | 'donate' | 'order' | 'pay' | 'plain' | 'reload' | 'rent' | 'set-up' | 'subscribe' | 'support' | 'tip' | 'top-up',
735
+ button_style: 'black' | 'white' | 'white-outline'
736
+ },
737
+ google: {
738
+ button_type: 'book' | 'buy' | 'checkout' | 'donate' | 'order' | 'pay' | 'plain' | 'subscribe',
739
+ button_color: 'default' | 'black' | 'white',
740
+ button_size_mode: 'static' | 'fill'
741
+ }
742
+ }
743
+ ```
744
+
745
+ ### Google Pay Specific Properties
746
+
747
+ The following are Google Pay-specific properties available in `GooglePayMeta`:
748
+
749
+ **Payment Method Configuration:**
750
+ - `payment_method_type?: google.payments.api.PaymentMethodType`: Payment method type (usually 'CARD')
751
+ - `allowed_auth_methods?: google.payments.api.CardAuthMethod[]`: Authentication methods (e.g., ['PAN_ONLY', 'CRYPTOGRAM_3DS'])
752
+ - `allowed_card_networks?: google.payments.api.CardNetwork[]`: Supported card networks (e.g., ['AMEX', 'DISCOVER', 'INTERAC', 'JCB', 'MASTERCARD', 'VISA'])
753
+
754
+ **Billing Address Configuration:**
755
+ - `billing_address_required?: boolean`: Override for show_billing_address
756
+ - `billing_address_format?: google.payments.api.BillingAddressFormat`: Billing address format specification
757
+
758
+ **Merchant Configuration:**
759
+ - `merchant_name?: string`: Display name for the merchant
760
+
761
+ ### Extended Interface Properties
762
+
763
+ The `OpenWalletMeta` interface extends native Apple Pay and Google Pay interfaces, giving you access to their native properties alongside PayDock-specific configurations:
764
+
765
+ - Extends `ApplePayJS.ApplePayPaymentRequest` (full Apple Pay interface)
766
+ - Extends `google.payments.api.IsReadyToPayPaymentMethodSpecification` (except `tokenizationSpecification`)
767
+ - Extends `google.payments.api.PaymentMethodSpecification`
768
+
769
+ #### Apple Pay Extended Properties (ApplePayJS.ApplePayPaymentRequest)
770
+
771
+ Since `OpenWalletMeta` extends `ApplePayJS.ApplePayPaymentRequest`, you can use any native Apple Pay property:
772
+
773
+ ```javascript
774
+ const applePayConfig = {
775
+ // PayDock specific properties
776
+ amount: 100,
777
+ currency: 'USD',
778
+ amount_label: 'Total',
779
+ country: 'US',
780
+
781
+ // Native Apple Pay properties
782
+ countryCode: 'US', // Country code for the payment
783
+ currencyCode: 'USD', // Currency code for the payment
784
+ merchantCapabilities: [ // Merchant capabilities
785
+ 'supports3DS',
786
+ 'supportsCredit',
787
+ 'supportsDebit'
788
+ ],
789
+ supportedNetworks: [ // Supported card networks
790
+ 'visa',
791
+ 'masterCard',
792
+ 'amex',
793
+ 'discover'
794
+ ],
795
+ requiredBillingContactFields: [ // Required billing fields
796
+ 'name',
797
+ 'postalAddress',
798
+ 'email',
799
+ 'phone'
800
+ ],
801
+ requiredShippingContactFields: [ // Required shipping fields
802
+ 'postalAddress',
803
+ 'name',
804
+ 'phone',
805
+ 'email'
806
+ ],
807
+ supportedCountries: [ // Supported countries for shipping
808
+ 'US', 'CA', 'GB'
809
+ ],
810
+ total: { // Total amount object
811
+ label: 'Total',
812
+ amount: '100.00',
813
+ type: 'final'
814
+ },
815
+ shippingContact: { // Pre-filled shipping contact
816
+ givenName: 'John',
817
+ familyName: 'Doe',
818
+ emailAddress: 'john@example.com'
819
+ },
820
+ billingContact: { // Pre-filled billing contact
821
+ givenName: 'John',
822
+ familyName: 'Doe'
823
+ }
824
+ };
825
+ ```
826
+
827
+ #### Google Pay Extended Properties
828
+
829
+ Since `OpenWalletMeta` extends Google Pay interfaces, you can use native Google Pay properties:
830
+
831
+ ```javascript
832
+ const googlePayConfig = {
833
+ // PayDock specific properties
834
+ amount: 100,
835
+ currency: 'USD',
836
+ amount_label: 'Total',
837
+ country: 'US',
838
+
839
+ // Native Google Pay properties (from IsReadyToPayPaymentMethodSpecification)
840
+ type: 'CARD', // Payment method type
841
+ parameters: {
842
+ allowedAuthMethods: [ // Allowed authentication methods
843
+ 'PAN_ONLY',
844
+ 'CRYPTOGRAM_3DS'
845
+ ],
846
+ allowedCardNetworks: [ // Allowed card networks
847
+ 'AMEX',
848
+ 'DISCOVER',
849
+ 'JCB',
850
+ 'MASTERCARD',
851
+ 'VISA'
852
+ ],
853
+ billingAddressRequired: true, // Require billing address
854
+ billingAddressParameters: { // Billing address parameters
855
+ format: 'FULL',
856
+ phoneNumberRequired: true
857
+ }
858
+ },
859
+
860
+ // Note: tokenizationSpecification is omitted from OpenWalletMeta
861
+ // as it's handled automatically by PayDock
862
+ };
863
+ ```
864
+
865
+ #### Property Inheritance
866
+
867
+ Since `OpenWalletMeta` extends native Apple Pay and Google Pay interfaces, you get access to both:
868
+
869
+ 1. **PayDock Properties**: Simplified, cross-wallet properties (e.g., `amount`, `currency`, `country`)
870
+ 2. **Native Extended Properties**: Full native wallet properties (e.g., `merchantCapabilities`, `supportedNetworks`)
871
+
872
+ Both types of properties can be used together in the same configuration object:
873
+
874
+ ```javascript
875
+ // Example combining PayDock and native properties
876
+ const config = {
877
+ // PayDock simplified properties
878
+ amount: 100,
879
+ currency: 'USD',
880
+ country: 'US',
881
+ show_billing_address: true,
882
+
883
+ // Native Apple Pay properties (available due to interface extension)
884
+ merchantCapabilities: ['supports3DS', 'supportsCredit'],
885
+ supportedNetworks: ['visa', 'masterCard', 'amex'],
886
+ requiredBillingContactFields: ['name', 'postalAddress'],
887
+
888
+ // Native Google Pay properties (available due to interface extension)
889
+ type: 'CARD',
890
+ parameters: {
891
+ allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
892
+ allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX']
893
+ }
894
+ };
895
+ ```
896
+
897
+ **Important Notes**:
898
+ - PayDock automatically handles the conversion and mapping between your configuration and the appropriate wallet APIs
899
+ - The `tokenizationSpecification` property is omitted from the Google Pay interface extension as PayDock handles tokenization automatically
900
+ - All properties shown are directly available in the `OpenWalletMeta` configuration object
901
+
902
+ #### Shipping Options Format
903
+ ```javascript
904
+ shipping_options: [
905
+ {
906
+ id: "option_id", // Unique identifier (string)
907
+ label: "Option Name", // Display name (string)
908
+ detail: "Description", // Optional description (string)
909
+ amount: 10.00, // Shipping cost as number
910
+ date_components_range: { // Optional: delivery date range
911
+ start_date_components: {
912
+ years: 0, // Years from now
913
+ months: 0, // Months from now
914
+ days: 5, // Days from now
915
+ hours: 0, // Hours from now
916
+ },
917
+ end_date_components: {
918
+ years: 0,
919
+ months: 0,
920
+ days: 10,
921
+ hours: 0,
922
+ }
923
+ }
924
+ }
925
+ ]
926
+ ```
927
+
928
+ **Important**:
929
+ - `amount` should be a **number**, not a string
930
+ - `date_components_range` is optional but provides delivery estimates
931
+ - Updated shipping options returned from event handlers don't require `date_components_range`
932
+
933
+ #### Required Meta Fields Validation
934
+
935
+ The `requiredMetaFields` parameter allows you to specify which fields in the meta object must be present. If any required field is missing, the constructor will throw an error:
936
+
937
+ ```javascript
938
+ // Example with validation
939
+ const button = new paydock.OpenWalletButtons(
940
+ '#widget',
941
+ publicKeyOrAccessToken,
942
+ serviceId,
943
+ {
944
+ amount: 100,
945
+ currency: 'USD',
946
+ // Missing amount_label will cause an error
947
+ },
948
+ ['amount', 'currency', 'amount_label'] // This will throw an error
949
+ );
950
+
951
+ // To avoid validation, pass an empty array or omit the parameter
952
+ const button = new paydock.OpenWalletButtons(
953
+ '#widget',
954
+ publicKeyOrAccessToken,
955
+ serviceId,
956
+ meta,
957
+ [] // No validation
958
+ );
959
+ ```
960
+
961
+ ### Complete Test Setup Example
962
+
963
+ Based on the actual test implementation, here's a complete working example for testing:
964
+
965
+ ```html
966
+ <!DOCTYPE html>
967
+ <html lang="en">
968
+ <head>
969
+ <meta charset="UTF-8">
970
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
971
+ <title>Open Wallet Apple Pay Test</title>
972
+ </head>
973
+ <body>
974
+ <h1>Apple Pay Test Page</h1>
975
+ <table>
976
+ <tr>
977
+ <td>Service ID:</td>
978
+ <td><input type="text" id="service_id" placeholder="Enter your service ID" /></td>
979
+ </tr>
980
+ <tr>
981
+ <td>Access Token/Public Key:</td>
982
+ <td><input type="text" id="access_token" placeholder="Enter your access token" /></td>
983
+ </tr>
984
+ </table>
985
+ <button onclick="loadApplePayButton()">Load Apple Pay Button</button>
986
+ <div id="widget"></div>
987
+
988
+ <script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js"></script>
989
+ <script>
990
+ function loadApplePayButton() {
991
+ const shippingOptions = [
992
+ {
993
+ label: "Standard Shipping",
994
+ detail: "Arrives in 5-7 business days",
995
+ amount: 10,
996
+ id: "standard",
997
+ date_components_range: {
998
+ start_date_components: { years: 0, months: 0, days: 5, hours: 0 },
999
+ end_date_components: { years: 0, months: 0, days: 7, hours: 0 }
1000
+ }
1001
+ },
1002
+ {
1003
+ label: "Express Shipping",
1004
+ detail: "Arrives in 1-2 business days",
1005
+ amount: 20,
1006
+ id: "express",
1007
+ date_components_range: {
1008
+ start_date_components: { years: 0, months: 0, days: 1, hours: 0 },
1009
+ end_date_components: { years: 0, months: 0, days: 2, hours: 0 }
1010
+ }
1011
+ }
1012
+ ];
1013
+
1014
+ const widget = new paydock.OpenWalletButtons(
1015
+ '#widget',
1016
+ document.getElementById("access_token").value,
1017
+ document.getElementById("service_id").value,
1018
+ {
1019
+ amount: 100,
1020
+ currency: 'USD',
1021
+ country: 'US',
1022
+ amount_label: 'Total',
1023
+ apple_pay_capabilities: [
1024
+ 'credentials_available',
1025
+ 'credentials_status_unknown',
1026
+ 'credentials_unavailable'
1027
+ ],
1028
+ shipping_options: shippingOptions,
1029
+ request_shipping: true,
1030
+
1031
+ // Extended Apple Pay properties (native interface)
1032
+ merchantCapabilities: [
1033
+ 'supports3DS',
1034
+ 'supportsCredit',
1035
+ 'supportsDebit'
1036
+ ],
1037
+ supportedNetworks: [
1038
+ 'visa',
1039
+ 'masterCard',
1040
+ 'amex',
1041
+ 'discover'
1042
+ ],
1043
+ requiredBillingContactFields: [
1044
+ 'name',
1045
+ 'postalAddress'
1046
+ ],
1047
+ requiredShippingContactFields: [
1048
+ 'postalAddress',
1049
+ 'name',
1050
+ 'phone',
1051
+ 'email'
1052
+ ]
1053
+ },
1054
+ ['amount_label', 'country', 'request_shipping', 'shipping_options', 'apple_pay_capabilities']
1055
+ );
1056
+
1057
+ // Required handlers
1058
+ widget.onSuccess(async function (data) {
1059
+ console.log("Payment successful:", data);
1060
+ // Process the OTT token
1061
+ alert(`Payment successful! OTT Token: ${data.token}`);
1062
+ });
1063
+
1064
+ widget.onShippingAddressChange(async function (data) {
1065
+ console.log("Shipping address changed:", data);
1066
+
1067
+ // Simulate updated shipping options based on address
1068
+ const updatedOptions = [
1069
+ { label: "Local Delivery", detail: "Same day delivery", amount: 5, id: "local" },
1070
+ { label: "Regional Delivery", detail: "Next day delivery", amount: 15, id: "regional" }
1071
+ ];
1072
+
1073
+ return {
1074
+ amount: 100 + updatedOptions[0].amount,
1075
+ shipping_options: updatedOptions
1076
+ };
1077
+ });
1078
+
1079
+ widget.onShippingOptionsChange(async function (data) {
1080
+ console.log("Shipping option changed:", data);
1081
+
1082
+ // Note: Check your actual data structure - might be data.data.amount
1083
+ const shippingCost = data.amount || data.data?.amount || 0;
1084
+ return {
1085
+ amount: 100 + shippingCost
1086
+ };
1087
+ });
1088
+
1089
+ // Optional handlers
1090
+ widget.onError(function (data) {
1091
+ console.error("Payment error:", data);
1092
+ alert("Payment failed: " + data.error.message);
1093
+ });
1094
+
1095
+ widget.onCancel(function (data) {
1096
+ console.log("Payment cancelled:", data);
1097
+ alert("Payment was cancelled");
1098
+ });
1099
+
1100
+ widget.onClick(function (data) {
1101
+ console.log("Apple Pay button clicked:", data);
1102
+ // Optional: Add validation logic here
1103
+ });
1104
+
1105
+ widget.setEnv('sandbox');
1106
+ widget.load();
1107
+ }
1108
+ </script>
1109
+ </body>
1110
+ </html>
1111
+ ```
1112
+
1113
+ ### Common Issues and Troubleshooting
1114
+
1115
+ #### Event Data Structure Variations
1116
+ Different implementations might return data in slightly different structures. Always check the actual data structure in your console:
1117
+
1118
+ ```javascript
1119
+ // In your event handlers, log the data to see the actual structure
1120
+ widget.onShippingOptionsChange(async function (data) {
1121
+ console.log("Full data object:", data);
1122
+
1123
+ // Try different access patterns based on your implementation
1124
+ const amount = data.amount || // Direct access
1125
+ data.data?.amount || // Nested in data property
1126
+ data.shippingCost || // Alternative property name
1127
+ 0; // Fallback
1128
+
1129
+ return { amount: baseAmount + amount };
1130
+ });
1131
+ ```
1132
+
1133
+ #### Required vs Optional Configuration
1134
+ ```javascript
1135
+ // Minimal required configuration
1136
+ const minimalConfig = {
1137
+ amount: 100,
1138
+ currency: 'USD'
1139
+ };
1140
+
1141
+ // Recommended configuration with validation
1142
+ const recommendedConfig = {
1143
+ amount: 100,
1144
+ currency: 'USD',
1145
+ amount_label: 'Total',
1146
+ country: 'US',
1147
+ apple_pay_capabilities: ['credentials_available']
1148
+ };
1149
+
1150
+ // Full configuration with shipping
1151
+ const fullConfig = {
1152
+ amount: 100,
1153
+ currency: 'USD',
1154
+ amount_label: 'Total',
1155
+ country: 'US',
1156
+ request_shipping: true,
1157
+ shipping_options: [...],
1158
+ apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable']
1159
+ };
1160
+ ```
1161
+
1162
+ #### Environment Setup
1163
+ ```javascript
1164
+ // Always set environment before loading
1165
+ widget.setEnv('sandbox');
1166
+ widget.load();
1167
+ ```
1168
+
1169
+ #### Error Handling Best Practices
1170
+ ```javascript
1171
+ widget.onError(function(data) {
1172
+ console.error('Full error object:', data);
1173
+
1174
+ // Check different error properties
1175
+ const errorMessage = data.error?.message ||
1176
+ data.message ||
1177
+ 'Unknown error occurred';
1178
+
1179
+ // Handle different error types
1180
+ if (data.context?.operation === 'wallet_operation') {
1181
+ // Handle wallet-specific errors
1182
+ showWalletError(errorMessage);
1183
+ } else {
1184
+ // Handle general errors
1185
+ showGeneralError(errorMessage);
1186
+ }
1187
+ });
1188
+ ```