@paydock/client-sdk 1.139.0 → 1.140.0-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.
- package/README.md +2573 -0
- package/bundles/index.cjs +1296 -508
- package/bundles/index.cjs.d.ts +1377 -200
- package/bundles/index.mjs +1295 -509
- package/bundles/index.mjs.d.ts +1377 -200
- package/bundles/types/checkout/checkout.d.ts.map +1 -1
- package/bundles/types/checkout/v1/instructions/instruction.card_form.show.d.ts.map +1 -1
- package/bundles/types/checkout/v3/instructions/instruction.card_form.show.d.ts.map +1 -1
- package/bundles/types/checkout/v3/instructions/instruction.payment_methods.show.d.ts.map +1 -1
- package/bundles/types/checkout-button/zipmoney/zipmoney-contextual.runner.d.ts +1 -2
- package/bundles/types/checkout-button/zipmoney/zipmoney-contextual.runner.d.ts.map +1 -1
- package/bundles/types/open-wallets/apple-pay-open-wallet-button.d.ts +70 -0
- package/bundles/types/open-wallets/apple-pay-open-wallet-button.d.ts.map +1 -0
- package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts +242 -74
- package/bundles/types/open-wallets/base/open-wallet-buttons.d.ts.map +1 -1
- package/bundles/types/open-wallets/base/open-wallet.service.d.ts +62 -4
- package/bundles/types/open-wallets/base/open-wallet.service.d.ts.map +1 -1
- package/bundles/types/open-wallets/enum/error-operation.enum.d.ts +15 -0
- package/bundles/types/open-wallets/enum/error-operation.enum.d.ts.map +1 -0
- package/bundles/types/open-wallets/enum/event.enum.d.ts +11 -3
- package/bundles/types/open-wallets/enum/event.enum.d.ts.map +1 -1
- package/bundles/types/open-wallets/enum/token-type.enum.d.ts +10 -0
- package/bundles/types/open-wallets/enum/token-type.enum.d.ts.map +1 -0
- package/bundles/types/open-wallets/google-pay-open-wallet-button.d.ts +65 -0
- package/bundles/types/open-wallets/google-pay-open-wallet-button.d.ts.map +1 -0
- package/bundles/types/open-wallets/index.d.ts +293 -0
- package/bundles/types/open-wallets/index.d.ts.map +1 -1
- package/bundles/types/open-wallets/interfaces/events.interface.d.ts +87 -14
- package/bundles/types/open-wallets/interfaces/events.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/interfaces/google-pay/google-pay-meta.interface.d.ts +6 -0
- package/bundles/types/open-wallets/interfaces/google-pay/google-pay-meta.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/interfaces/index.d.ts +2 -2
- package/bundles/types/open-wallets/interfaces/index.d.ts.map +1 -1
- package/bundles/types/open-wallets/interfaces/open-wallet-meta.interface.d.ts +12 -0
- package/bundles/types/open-wallets/interfaces/open-wallet-meta.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/interfaces/payment-source.interface.d.ts +28 -2
- package/bundles/types/open-wallets/interfaces/payment-source.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts +27 -2
- package/bundles/types/open-wallets/services/apple-pay/apple-pay.open-wallet.service.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/google-pay/constants/google-pay.constants.d.ts +9 -0
- package/bundles/types/open-wallets/services/google-pay/constants/google-pay.constants.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/google-pay/google-pay.open-wallet.service.d.ts +20 -9
- package/bundles/types/open-wallets/services/google-pay/google-pay.open-wallet.service.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/google-pay/utils/google-pay.utils.d.ts +45 -0
- package/bundles/types/open-wallets/services/google-pay/utils/google-pay.utils.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/google-pay/utils/index.d.ts +1 -1
- package/bundles/types/open-wallets/services/google-pay/utils/index.d.ts.map +1 -1
- package/bundles/types/open-wallets/services/google-pay/validation/google-pay.validation.d.ts +13 -0
- package/bundles/types/open-wallets/services/google-pay/validation/google-pay.validation.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/base-event-data.interface.d.ts +24 -2
- package/bundles/types/open-wallets/types/base-event-data.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/index.d.ts +2 -1
- package/bundles/types/open-wallets/types/index.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/on-shipping-address-change-event-data.interface.d.ts +16 -2
- package/bundles/types/open-wallets/types/on-shipping-address-change-event-data.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/on-shipping-address-change-event-response.interface.d.ts +20 -2
- package/bundles/types/open-wallets/types/on-shipping-address-change-event-response.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/on-shipping-option-change-event-data.interface.d.ts +13 -2
- package/bundles/types/open-wallets/types/on-shipping-option-change-event-data.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/on-shipping-option-change-event-response.interface.d.ts +12 -0
- package/bundles/types/open-wallets/types/on-shipping-option-change-event-response.interface.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/payment-source.type.d.ts +3 -2
- package/bundles/types/open-wallets/types/payment-source.type.d.ts.map +1 -1
- package/bundles/types/open-wallets/types/shipping-event-to-response.type.d.ts +8 -0
- package/bundles/types/open-wallets/types/shipping-event-to-response.type.d.ts.map +1 -1
- package/bundles/widget.umd.js +1296 -508
- package/bundles/widget.umd.js.d.ts +1377 -200
- package/bundles/widget.umd.js.min.d.ts +1377 -200
- package/bundles/widget.umd.min.js +1 -1
- package/docs/open-wallet-buttons-examples.md +561 -830
- package/docs/open-wallet-buttons.md +1652 -0
- package/package.json +1 -1
- package/slate.md +1673 -0
|
@@ -2,11 +2,16 @@
|
|
|
2
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
3
|
|
|
4
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
|
-
|
|
5
|
+
|
|
6
|
+
Each wallet type has its own dedicated class with fully typed metadata:
|
|
7
|
+
- [ApplePayOpenWalletButton](#ApplePayOpenWalletButton) - for Apple Pay integration
|
|
8
|
+
- [GooglePayOpenWalletButton](#GooglePayOpenWalletButton) - for Google Pay integration
|
|
9
|
+
|
|
10
|
+
On `load()`, each button fetches the service configuration from PayDock and validates that the service type matches the expected wallet. If there is a mismatch (e.g. using an Apple Pay service ID with `GooglePayOpenWalletButton`), an error will be raised via the `onError` callback.
|
|
6
11
|
|
|
7
12
|
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
13
|
|
|
9
|
-
## Open Wallet
|
|
14
|
+
## Apple Pay Open Wallet Button
|
|
10
15
|
|
|
11
16
|
### Container
|
|
12
17
|
|
|
@@ -14,103 +19,58 @@ If available in your client environment, you will display a simple button that u
|
|
|
14
19
|
<div id="widget"></div>
|
|
15
20
|
```
|
|
16
21
|
|
|
17
|
-
You must create a container for the Open Wallet
|
|
22
|
+
You must create a container for the Open Wallet Button. Inside this tag, the button will be initialized.
|
|
18
23
|
|
|
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.
|
|
24
|
+
Before initializing the button, you must configure your Apple Pay wallet service through the PayDock dashboard and obtain the service ID that will be used to load the button configuration.
|
|
20
25
|
|
|
21
26
|
### Initialization
|
|
22
27
|
|
|
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
28
|
```javascript
|
|
42
|
-
let button = new paydock.
|
|
29
|
+
let button = new paydock.ApplePayOpenWalletButton(
|
|
43
30
|
"#widget",
|
|
44
31
|
publicKeyOrAccessToken,
|
|
45
32
|
serviceId,
|
|
46
33
|
{
|
|
47
34
|
amount: 100,
|
|
48
|
-
currency: "
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
currency: "AUD",
|
|
36
|
+
country: "AU",
|
|
37
|
+
amount_label: "TOTAL",
|
|
38
|
+
store_name: "My Store",
|
|
39
|
+
apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable'],
|
|
40
|
+
}
|
|
52
41
|
);
|
|
53
42
|
button.load();
|
|
54
43
|
```
|
|
55
44
|
|
|
56
45
|
```javascript
|
|
57
46
|
// ES2015 | TypeScript
|
|
58
|
-
import {
|
|
47
|
+
import { ApplePayOpenWalletButton } from '@paydock/client-sdk';
|
|
59
48
|
|
|
60
|
-
var button = new
|
|
49
|
+
var button = new ApplePayOpenWalletButton(
|
|
61
50
|
'#widget',
|
|
62
51
|
publicKeyOrAccessToken,
|
|
63
52
|
serviceId,
|
|
64
53
|
{
|
|
65
54
|
amount: 100,
|
|
66
|
-
currency: '
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
55
|
+
currency: 'AUD',
|
|
56
|
+
country: 'AU',
|
|
57
|
+
amount_label: 'TOTAL',
|
|
58
|
+
store_name: 'My Store',
|
|
59
|
+
}
|
|
101
60
|
);
|
|
102
61
|
button.load();
|
|
103
62
|
```
|
|
104
63
|
|
|
105
64
|
### Constructor Parameters
|
|
106
65
|
|
|
107
|
-
The
|
|
66
|
+
The ApplePayOpenWalletButton constructor accepts the following parameters:
|
|
108
67
|
|
|
109
68
|
1. **selector** (string): CSS selector for the container element
|
|
110
69
|
2. **publicKeyOrAccessToken** (string): Your PayDock public key or access token
|
|
111
|
-
3. **serviceId** (string): The service ID configured in PayDock dashboard
|
|
112
|
-
4. **meta** (
|
|
113
|
-
|
|
70
|
+
3. **serviceId** (string): The Apple Pay service ID configured in PayDock dashboard
|
|
71
|
+
4. **meta** (ApplePayOpenWalletMeta): Apple Pay-specific configuration object
|
|
72
|
+
|
|
73
|
+
> **Note:** Required meta fields (`amount`, `currency`, `country`, `amount_label`, `store_name`) are validated automatically by the `ApplePayOpenWalletButton` class. You do not need to specify them manually.
|
|
114
74
|
|
|
115
75
|
### Setting environment
|
|
116
76
|
|
|
@@ -121,202 +81,7 @@ Bear in mind that you must set an environment before calling `button.load()`.
|
|
|
121
81
|
button.setEnv('sandbox');
|
|
122
82
|
```
|
|
123
83
|
|
|
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
|
|
84
|
+
### Full Apple Pay example
|
|
320
85
|
|
|
321
86
|
```html
|
|
322
87
|
<!DOCTYPE html>
|
|
@@ -326,20 +91,21 @@ button.onCancel((data) => {
|
|
|
326
91
|
<title>Apple Pay with Open Wallets</title>
|
|
327
92
|
</head>
|
|
328
93
|
<body>
|
|
329
|
-
<h2>Payment using PayDock Open Wallet Button!</h2>
|
|
94
|
+
<h2>Payment using PayDock Apple Pay Open Wallet Button!</h2>
|
|
330
95
|
<div id="widget"></div>
|
|
331
96
|
</body>
|
|
332
97
|
<script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js" ></script>
|
|
333
98
|
<script>
|
|
334
|
-
let button = new paydock.
|
|
99
|
+
let button = new paydock.ApplePayOpenWalletButton(
|
|
335
100
|
"#widget",
|
|
336
101
|
publicKeyOrAccessToken,
|
|
337
102
|
serviceId,
|
|
338
103
|
{
|
|
339
104
|
amount: 100,
|
|
340
|
-
currency: "
|
|
341
|
-
|
|
342
|
-
|
|
105
|
+
currency: "AUD",
|
|
106
|
+
country: "AU",
|
|
107
|
+
amount_label: "TOTAL",
|
|
108
|
+
store_name: "My Store",
|
|
343
109
|
request_shipping: true,
|
|
344
110
|
request_payer_name: true,
|
|
345
111
|
request_payer_email: true,
|
|
@@ -392,38 +158,37 @@ button.onCancel((data) => {
|
|
|
392
158
|
}
|
|
393
159
|
],
|
|
394
160
|
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
|
|
161
|
+
}
|
|
397
162
|
);
|
|
398
|
-
|
|
163
|
+
|
|
399
164
|
button.setEnv('sandbox');
|
|
400
|
-
|
|
165
|
+
|
|
401
166
|
button.onUnavailable((data) => {
|
|
402
167
|
console.log("Apple Pay not available:", data);
|
|
403
168
|
// Show alternative payment methods
|
|
404
169
|
});
|
|
405
|
-
|
|
170
|
+
|
|
406
171
|
button.onClick((data) => {
|
|
407
172
|
console.log("Apple Pay button clicked");
|
|
408
173
|
// Perform pre-payment validation
|
|
409
174
|
});
|
|
410
|
-
|
|
175
|
+
|
|
411
176
|
button.onSuccess((data) => {
|
|
412
177
|
console.log("Payment successful:", data);
|
|
413
178
|
// Process the OTT token on your backend
|
|
414
179
|
processPayment(data.token);
|
|
415
180
|
});
|
|
416
|
-
|
|
181
|
+
|
|
417
182
|
button.onError((data) => {
|
|
418
183
|
console.error("Payment error:", data);
|
|
419
184
|
// Handle error appropriately
|
|
420
185
|
});
|
|
421
|
-
|
|
186
|
+
|
|
422
187
|
button.onCancel((data) => {
|
|
423
188
|
console.log("Payment cancelled");
|
|
424
189
|
// Handle cancellation
|
|
425
190
|
});
|
|
426
|
-
|
|
191
|
+
|
|
427
192
|
button.onShippingAddressChange(async (addressData) => {
|
|
428
193
|
// Update shipping costs based on address
|
|
429
194
|
const response = await updateShippingCosts(addressData);
|
|
@@ -432,7 +197,7 @@ button.onCancel((data) => {
|
|
|
432
197
|
shipping_options: response.shippingOptions
|
|
433
198
|
};
|
|
434
199
|
});
|
|
435
|
-
|
|
200
|
+
|
|
436
201
|
button.onShippingOptionsChange(async (optionData) => {
|
|
437
202
|
// Update total based on selected shipping option
|
|
438
203
|
const response = await updateTotal(optionData);
|
|
@@ -440,9 +205,9 @@ button.onCancel((data) => {
|
|
|
440
205
|
amount: response.newAmount
|
|
441
206
|
};
|
|
442
207
|
});
|
|
443
|
-
|
|
208
|
+
|
|
444
209
|
button.load();
|
|
445
|
-
|
|
210
|
+
|
|
446
211
|
async function updateShippingCosts(addressData) {
|
|
447
212
|
// Your shipping calculation logic based on address
|
|
448
213
|
const baseAmount = 100;
|
|
@@ -460,23 +225,22 @@ button.onCancel((data) => {
|
|
|
460
225
|
amount: 18.00
|
|
461
226
|
}
|
|
462
227
|
];
|
|
463
|
-
|
|
228
|
+
|
|
464
229
|
return {
|
|
465
230
|
newAmount: baseAmount + updatedShippingOptions[0].amount,
|
|
466
231
|
shippingOptions: updatedShippingOptions
|
|
467
232
|
};
|
|
468
233
|
}
|
|
469
|
-
|
|
234
|
+
|
|
470
235
|
async function updateTotal(optionData) {
|
|
471
236
|
// Your total calculation logic
|
|
472
237
|
const baseAmount = 100;
|
|
473
|
-
// Note: Check if you need data.data.amount or data.amount based on your implementation
|
|
474
238
|
const shippingAmount = optionData.amount || optionData.data?.amount;
|
|
475
239
|
return {
|
|
476
240
|
newAmount: baseAmount + shippingAmount
|
|
477
241
|
};
|
|
478
242
|
}
|
|
479
|
-
|
|
243
|
+
|
|
480
244
|
function processPayment(ottToken) {
|
|
481
245
|
// Send OTT token to your backend for payment processing
|
|
482
246
|
fetch('/api/process-payment', {
|
|
@@ -489,114 +253,362 @@ button.onCancel((data) => {
|
|
|
489
253
|
</html>
|
|
490
254
|
```
|
|
491
255
|
|
|
492
|
-
###
|
|
256
|
+
### Apple Pay with Shipping
|
|
493
257
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
google: {
|
|
521
|
-
button_type: 'buy',
|
|
522
|
-
button_color: 'default',
|
|
523
|
-
button_size_mode: 'fill'
|
|
524
|
-
}
|
|
258
|
+
For Apple Pay with shipping enabled:
|
|
259
|
+
```javascript
|
|
260
|
+
let button = new paydock.ApplePayOpenWalletButton(
|
|
261
|
+
"#widget",
|
|
262
|
+
publicKeyOrAccessToken,
|
|
263
|
+
serviceId,
|
|
264
|
+
{
|
|
265
|
+
amount: 100,
|
|
266
|
+
currency: "AUD",
|
|
267
|
+
country: "AU",
|
|
268
|
+
amount_label: "TOTAL",
|
|
269
|
+
store_name: "My Store",
|
|
270
|
+
request_shipping: true,
|
|
271
|
+
shipping_editing_mode: 'available',
|
|
272
|
+
required_shipping_contact_fields: [
|
|
273
|
+
'postalAddress',
|
|
274
|
+
'name',
|
|
275
|
+
'phone',
|
|
276
|
+
'email',
|
|
277
|
+
],
|
|
278
|
+
shipping_options: [
|
|
279
|
+
{
|
|
280
|
+
id: "standard",
|
|
281
|
+
label: "Standard Shipping",
|
|
282
|
+
detail: "5-7 business days",
|
|
283
|
+
amount: 5.00
|
|
525
284
|
},
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
//
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
285
|
+
{
|
|
286
|
+
id: "express",
|
|
287
|
+
label: "Express Shipping",
|
|
288
|
+
detail: "1-2 business days",
|
|
289
|
+
amount: 15.00
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable']
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
button.load();
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
When supporting shipping, the methods `onShippingAddressChange` and `onShippingOptionsChange` are required to update the shipping address and options.
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
button.onShippingAddressChange(async function(data) {
|
|
302
|
+
console.log("Shipping address has been updated", data);
|
|
303
|
+
// Call your backend to recalculate shipping
|
|
304
|
+
return {
|
|
305
|
+
amount: newAmount,
|
|
306
|
+
shipping_options: updatedShippingOptions
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
button.onShippingOptionsChange(async function(data) {
|
|
311
|
+
console.log("Shipping option selected", data);
|
|
312
|
+
// Update total based on selected shipping option
|
|
313
|
+
return {
|
|
314
|
+
amount: newTotalAmount
|
|
315
|
+
};
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Supported Shipping Cases
|
|
320
|
+
|
|
321
|
+
#### Injected Shipping Address, non-editable by the customer
|
|
322
|
+
|
|
323
|
+
This is the case where the shipping address is injected by the merchant and is not editable by the customer. The customer can only select the shipping option.
|
|
324
|
+
|
|
325
|
+
The required meta parameters for this case are:
|
|
326
|
+
- shipping_editing_mode: 'store_pickup'
|
|
327
|
+
- required_shipping_contact_fields: ['postalAddress'] <-- At least one of the fields is required so the shipping address is shown at Apple Pay.
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
meta: {
|
|
331
|
+
apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable'],
|
|
332
|
+
amount_label: 'TOTAL',
|
|
333
|
+
country: 'AU',
|
|
334
|
+
currency: 'AUD',
|
|
335
|
+
amount: 10,
|
|
336
|
+
shipping_editing_mode: 'store_pickup',
|
|
337
|
+
required_shipping_contact_fields: [
|
|
338
|
+
'postalAddress',
|
|
339
|
+
'name',
|
|
340
|
+
'phone',
|
|
341
|
+
'email',
|
|
342
|
+
],
|
|
343
|
+
shipping: {
|
|
344
|
+
amount: 5,
|
|
345
|
+
address_line1: "Address Line 1",
|
|
346
|
+
address_city: "Test Locality",
|
|
347
|
+
address_state: "NSW",
|
|
348
|
+
address_country: "Australia",
|
|
349
|
+
address_country_code: "AU",
|
|
350
|
+
address_postcode: "3000",
|
|
351
|
+
contact: {
|
|
352
|
+
phone: "+61400245562",
|
|
353
|
+
email: "test@example.com",
|
|
354
|
+
first_name: "QA",
|
|
355
|
+
last_name: "QA",
|
|
356
|
+
},
|
|
357
|
+
options: [
|
|
358
|
+
{
|
|
359
|
+
label: "Test 1",
|
|
360
|
+
detail: "This is a test 1 shipping methods",
|
|
361
|
+
amount: 10,
|
|
362
|
+
id: "randomId1",
|
|
363
|
+
}
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### Injected Shipping Address, editable by the customer
|
|
370
|
+
|
|
371
|
+
This is the case where the shipping address is injected by the merchant and is editable by the customer. The customer can edit the shipping address and select the shipping option.
|
|
372
|
+
|
|
373
|
+
The required meta parameters for this case are:
|
|
374
|
+
- shipping_editing_mode: 'available'
|
|
375
|
+
- required_shipping_contact_fields: ['postalAddress'] <-- At least one of the fields is required so the shipping address is shown at Apple Pay.
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
meta: {
|
|
379
|
+
apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable'],
|
|
380
|
+
amount_label: 'TOTAL',
|
|
381
|
+
country: 'AU',
|
|
382
|
+
currency: 'AUD',
|
|
383
|
+
amount: 10,
|
|
384
|
+
shipping_editing_mode: 'available',
|
|
385
|
+
required_shipping_contact_fields: [
|
|
386
|
+
'postalAddress',
|
|
387
|
+
'name',
|
|
388
|
+
'phone',
|
|
389
|
+
'email',
|
|
390
|
+
],
|
|
391
|
+
shipping: {
|
|
392
|
+
amount: 5,
|
|
393
|
+
address_line1: "Address Line 1",
|
|
394
|
+
address_city: "Test Locality",
|
|
395
|
+
address_state: "NSW",
|
|
396
|
+
address_country: "Australia",
|
|
397
|
+
address_country_code: "AU",
|
|
398
|
+
address_postcode: "3000",
|
|
399
|
+
contact: {
|
|
400
|
+
phone: "+61400245562",
|
|
401
|
+
email: "test@example.com",
|
|
402
|
+
first_name: "QA",
|
|
403
|
+
last_name: "QA",
|
|
404
|
+
},
|
|
405
|
+
options: [
|
|
406
|
+
{
|
|
407
|
+
label: "Test 1",
|
|
408
|
+
detail: "This is a test 1 shipping methods",
|
|
409
|
+
amount: 10,
|
|
410
|
+
id: "randomId1",
|
|
411
|
+
}
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### Shipping address editable by the customer (no pre-filled address)
|
|
418
|
+
|
|
419
|
+
This is the case where the shipping address is not injected by the merchant and is editable by the customer. The customer can edit the shipping address and select the shipping option.
|
|
420
|
+
|
|
421
|
+
The required meta parameters for this case are:
|
|
422
|
+
- shipping_editing_mode: 'available'
|
|
423
|
+
- required_shipping_contact_fields: ['postalAddress'] <-- At least one of the fields is required so the shipping address is shown at Apple Pay.
|
|
424
|
+
|
|
425
|
+
```javascript
|
|
426
|
+
meta: {
|
|
427
|
+
apple_pay_capabilities: ['credentials_available', 'credentials_status_unknown', 'credentials_unavailable'],
|
|
428
|
+
amount_label: 'TOTAL',
|
|
429
|
+
country: 'AU',
|
|
430
|
+
currency: 'AUD',
|
|
431
|
+
amount: 10,
|
|
432
|
+
shipping_editing_mode: 'available',
|
|
433
|
+
required_shipping_contact_fields: [
|
|
434
|
+
'postalAddress',
|
|
435
|
+
'name',
|
|
436
|
+
'phone',
|
|
437
|
+
'email',
|
|
438
|
+
],
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
#### No shipping address
|
|
443
|
+
|
|
444
|
+
This is the case where no shipping address is required at all in the popup (e.g., digital goods, services, or virtual products, or Shipping Address collected separately by the merchant). The "Send to" UI field will not be shown in the Apple Pay sheet, it will be hidden.
|
|
445
|
+
|
|
446
|
+
**Important:**
|
|
447
|
+
- No shipping address should be provided in the meta object.
|
|
448
|
+
- Shipping address could be provided in the initial POST `/v1/charges/wallet` endpoint, if collected previously.
|
|
449
|
+
|
|
450
|
+
The required meta parameters for this case are:
|
|
451
|
+
- `required_shipping_contact_fields`: Only include contact fields if needed (phone, email), but NOT `postalAddress`.
|
|
452
|
+
|
|
453
|
+
```javascript
|
|
454
|
+
meta: {
|
|
455
|
+
amount_label: "TOTAL",
|
|
456
|
+
country: "AU",
|
|
457
|
+
currency: "AUD",
|
|
458
|
+
amount: 10,
|
|
459
|
+
shipping_editing_mode: "available",
|
|
460
|
+
required_shipping_contact_fields: ["phone", "email"],
|
|
461
|
+
apple_pay_capabilities: ["credentials_available", "credentials_status_unknown", "credentials_unavailable"]
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## Google Pay Open Wallet Button
|
|
466
|
+
|
|
467
|
+
### Initialization
|
|
468
|
+
|
|
469
|
+
```javascript
|
|
470
|
+
let button = new paydock.GooglePayOpenWalletButton(
|
|
471
|
+
"#widget",
|
|
472
|
+
publicKeyOrAccessToken,
|
|
473
|
+
serviceId,
|
|
474
|
+
{
|
|
475
|
+
amount: 100,
|
|
476
|
+
currency: "AUD",
|
|
477
|
+
country: "AU",
|
|
478
|
+
merchant_name: "Your Store",
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
button.load();
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
// ES2015 | TypeScript
|
|
486
|
+
import { GooglePayOpenWalletButton } from '@paydock/client-sdk';
|
|
487
|
+
|
|
488
|
+
var button = new GooglePayOpenWalletButton(
|
|
489
|
+
'#widget',
|
|
490
|
+
publicKeyOrAccessToken,
|
|
491
|
+
serviceId,
|
|
492
|
+
{
|
|
493
|
+
amount: 100,
|
|
494
|
+
currency: 'AUD',
|
|
495
|
+
country: 'AU',
|
|
496
|
+
merchant_name: 'Your Store',
|
|
497
|
+
}
|
|
498
|
+
);
|
|
499
|
+
button.load();
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Constructor Parameters
|
|
503
|
+
|
|
504
|
+
The GooglePayOpenWalletButton constructor accepts the following parameters:
|
|
505
|
+
|
|
506
|
+
1. **selector** (string): CSS selector for the container element
|
|
507
|
+
2. **publicKeyOrAccessToken** (string): Your PayDock public key or access token
|
|
508
|
+
3. **serviceId** (string): The Google Pay service ID configured in PayDock dashboard
|
|
509
|
+
4. **meta** (GooglePayOpenWalletMeta): Google Pay-specific configuration object
|
|
510
|
+
|
|
511
|
+
> **Note:** Required meta fields (`amount`, `currency`, `country`) are validated automatically by the `GooglePayOpenWalletButton` class. You do not need to specify them manually.
|
|
512
|
+
|
|
513
|
+
### Full Google Pay Example
|
|
514
|
+
|
|
515
|
+
```html
|
|
516
|
+
<!DOCTYPE html>
|
|
517
|
+
<html lang="en">
|
|
518
|
+
<head>
|
|
519
|
+
<meta charset="UTF-8">
|
|
520
|
+
<title>Google Pay with Open Wallets</title>
|
|
521
|
+
</head>
|
|
522
|
+
<body>
|
|
523
|
+
<h2>Payment using PayDock Google Pay Open Wallet Button!</h2>
|
|
524
|
+
<div id="widget"></div>
|
|
525
|
+
</body>
|
|
526
|
+
<script src="https://widget.paydock.com/sdk/latest/widget.umd.min.js" ></script>
|
|
527
|
+
<script>
|
|
528
|
+
let button = new paydock.GooglePayOpenWalletButton(
|
|
529
|
+
"#widget",
|
|
530
|
+
publicKeyOrAccessToken,
|
|
531
|
+
serviceId,
|
|
532
|
+
{
|
|
533
|
+
amount: 100,
|
|
534
|
+
currency: "AUD",
|
|
535
|
+
country: "AU",
|
|
536
|
+
amount_label: "Total",
|
|
537
|
+
request_shipping: true,
|
|
538
|
+
show_billing_address: true,
|
|
539
|
+
merchant_name: 'Test Merchant',
|
|
540
|
+
style: {
|
|
541
|
+
button_type: 'buy',
|
|
542
|
+
button_color: 'default',
|
|
543
|
+
button_size_mode: 'fill'
|
|
544
|
+
},
|
|
545
|
+
shipping_options: [
|
|
546
|
+
{
|
|
547
|
+
id: "standard",
|
|
548
|
+
label: "Standard Shipping",
|
|
549
|
+
detail: "Arrives in 5 to 7 days",
|
|
550
|
+
amount: 5.00,
|
|
551
|
+
type: "ELECTRONIC"
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
id: "express",
|
|
555
|
+
label: "Express Shipping",
|
|
556
|
+
detail: "Arrives in 1 to 2 days",
|
|
557
|
+
amount: 15.00,
|
|
558
|
+
type: "PICKUP"
|
|
559
|
+
}
|
|
560
|
+
]
|
|
561
|
+
}
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
button.setEnv('sandbox');
|
|
565
|
+
|
|
566
|
+
// Required handlers
|
|
567
|
+
button.onSuccess((data) => {
|
|
568
|
+
console.log("Payment successful:", data);
|
|
569
|
+
processPayment(data.token);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
button.onShippingAddressChange(async (addressData) => {
|
|
573
|
+
const response = await updateShippingCosts(addressData);
|
|
574
|
+
return {
|
|
575
|
+
amount: response.newAmount,
|
|
576
|
+
shipping_options: response.shippingOptions
|
|
564
577
|
};
|
|
565
578
|
});
|
|
566
|
-
|
|
579
|
+
|
|
567
580
|
button.onShippingOptionsChange(async (optionData) => {
|
|
568
581
|
const response = await updateTotal(optionData);
|
|
569
582
|
return {
|
|
570
583
|
amount: response.newAmount
|
|
571
584
|
};
|
|
572
585
|
});
|
|
573
|
-
|
|
586
|
+
|
|
574
587
|
// Optional handlers
|
|
575
588
|
button.onUnavailable((data) => {
|
|
576
589
|
console.log("Google Pay not available:", data);
|
|
577
590
|
// Show alternative payment methods
|
|
578
591
|
});
|
|
579
|
-
|
|
592
|
+
|
|
580
593
|
button.onError((data) => {
|
|
581
594
|
console.error("Payment error:", data);
|
|
582
595
|
// Handle error appropriately
|
|
583
596
|
});
|
|
584
|
-
|
|
597
|
+
|
|
585
598
|
button.onCancel((data) => {
|
|
586
599
|
console.log("Payment cancelled");
|
|
587
600
|
// Handle cancellation
|
|
588
601
|
});
|
|
589
|
-
|
|
602
|
+
|
|
590
603
|
button.onClick((data) => {
|
|
591
604
|
console.log("Google Pay button clicked");
|
|
592
605
|
// Perform pre-payment validation
|
|
593
606
|
});
|
|
594
|
-
|
|
607
|
+
|
|
595
608
|
button.load();
|
|
596
|
-
|
|
597
|
-
// Helper functions
|
|
609
|
+
|
|
610
|
+
// Helper functions
|
|
598
611
|
async function updateShippingCosts(addressData) {
|
|
599
|
-
// Your shipping calculation logic based on address
|
|
600
612
|
const baseAmount = 100;
|
|
601
613
|
const updatedShippingOptions = [
|
|
602
614
|
{
|
|
@@ -614,24 +626,22 @@ button.onCancel((data) => {
|
|
|
614
626
|
type: "PICKUP"
|
|
615
627
|
}
|
|
616
628
|
];
|
|
617
|
-
|
|
629
|
+
|
|
618
630
|
return {
|
|
619
631
|
newAmount: baseAmount + updatedShippingOptions[0].amount,
|
|
620
632
|
shippingOptions: updatedShippingOptions
|
|
621
633
|
};
|
|
622
634
|
}
|
|
623
|
-
|
|
635
|
+
|
|
624
636
|
async function updateTotal(optionData) {
|
|
625
|
-
// Your total calculation logic
|
|
626
637
|
const baseAmount = 100;
|
|
627
638
|
const shippingAmount = optionData.amount || optionData.data?.amount;
|
|
628
639
|
return {
|
|
629
640
|
newAmount: baseAmount + shippingAmount
|
|
630
641
|
};
|
|
631
642
|
}
|
|
632
|
-
|
|
643
|
+
|
|
633
644
|
function processPayment(ottToken) {
|
|
634
|
-
// Send OTT token to your backend for payment processing
|
|
635
645
|
fetch('/api/process-payment', {
|
|
636
646
|
method: 'POST',
|
|
637
647
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -642,264 +652,214 @@ button.onCancel((data) => {
|
|
|
642
652
|
</html>
|
|
643
653
|
```
|
|
644
654
|
|
|
645
|
-
|
|
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.
|
|
655
|
+
## Common API
|
|
647
656
|
|
|
648
|
-
|
|
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
|
|
657
|
+
Both `ApplePayOpenWalletButton` and `GooglePayOpenWalletButton` share the same event handler API inherited from the base class.
|
|
656
658
|
|
|
657
|
-
|
|
659
|
+
### Checking for button availability
|
|
660
|
+
|
|
661
|
+
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.
|
|
658
662
|
|
|
659
663
|
```javascript
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
button.onShippingAddressChange(handler); // Required when shipping enabled
|
|
663
|
-
button.onShippingOptionsChange(handler); // Required when shipping options provided
|
|
664
|
+
button.onUnavailable((data) => console.log("No wallet button available", data));
|
|
665
|
+
```
|
|
664
666
|
|
|
665
|
-
|
|
666
|
-
button.onUnavailable(handler); // or await button.onUnavailable()
|
|
667
|
-
button.onError(handler); // or await button.onError()
|
|
668
|
-
button.onCancel(handler); // or await button.onCancel()
|
|
667
|
+
### Service type validation
|
|
669
668
|
|
|
670
|
-
|
|
671
|
-
|
|
669
|
+
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`:
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
// This will raise an error if the service ID does not correspond to a Google Pay service
|
|
673
|
+
let button = new paydock.GooglePayOpenWalletButton(
|
|
674
|
+
"#widget",
|
|
675
|
+
publicKeyOrAccessToken,
|
|
676
|
+
applePayServiceId, // Wrong! This is an Apple Pay service ID
|
|
677
|
+
meta
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
button.onError((data) => {
|
|
681
|
+
// Error: Service configuration type 'ApplePay' does not match expected wallet type 'google'.
|
|
682
|
+
console.error(data.error.message);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
button.load();
|
|
672
686
|
```
|
|
673
687
|
|
|
674
|
-
###
|
|
688
|
+
### Performing actions when the wallet button is clicked
|
|
675
689
|
|
|
676
|
-
|
|
690
|
+
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.
|
|
677
691
|
|
|
678
|
-
|
|
679
|
-
|
|
692
|
+
```javascript
|
|
693
|
+
// Synchronous example
|
|
694
|
+
button.onClick((data) => {
|
|
695
|
+
console.log("Perform actions on button click");
|
|
696
|
+
// Perform validation logic
|
|
697
|
+
// Optionally use attachResult to control flow
|
|
698
|
+
data.attachResult(true); // Continue with payment
|
|
699
|
+
// data.attachResult(false); // Halt payment
|
|
700
|
+
});
|
|
680
701
|
|
|
681
|
-
|
|
702
|
+
// Asynchronous example
|
|
703
|
+
button.onClick((data) => {
|
|
704
|
+
// Attach a Promise to control the wallet flow
|
|
705
|
+
data.attachResult(
|
|
706
|
+
fetch('/api/validate-order')
|
|
707
|
+
.then(response => response.json())
|
|
708
|
+
.then(result => {
|
|
709
|
+
if (!result.valid) {
|
|
710
|
+
throw new Error('Order validation failed');
|
|
711
|
+
}
|
|
712
|
+
return result;
|
|
713
|
+
})
|
|
714
|
+
);
|
|
715
|
+
});
|
|
716
|
+
```
|
|
682
717
|
|
|
683
|
-
|
|
718
|
+
### Handling successful OTT creation
|
|
684
719
|
|
|
685
|
-
**
|
|
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
|
|
720
|
+
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.
|
|
692
721
|
|
|
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
722
|
```javascript
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
}
|
|
723
|
+
button.onSuccess((data) => {
|
|
724
|
+
console.log("OTT created successfully:", data.token);
|
|
725
|
+
console.log("Amount:", data.amount);
|
|
726
|
+
console.log("Shipping:", data.shipping);
|
|
727
|
+
console.log("Billing:", data.billing);
|
|
728
|
+
|
|
729
|
+
// Use the OTT token to complete payment on your backend
|
|
730
|
+
fetch('/api/process-payment', {
|
|
731
|
+
method: 'POST',
|
|
732
|
+
headers: { 'Content-Type': 'application/json' },
|
|
733
|
+
body: JSON.stringify({ ott_token: data.token })
|
|
734
|
+
});
|
|
735
|
+
});
|
|
743
736
|
```
|
|
744
737
|
|
|
745
|
-
|
|
738
|
+
**Important**: The `onSuccess` event handler is mandatory. Not providing one will result in an error.
|
|
746
739
|
|
|
747
|
-
|
|
740
|
+
### Updating meta after initialization
|
|
748
741
|
|
|
749
|
-
|
|
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'])
|
|
742
|
+
If the screen where the button is rendered allows for cart/amount changes, call `setMeta` method to update the meta information. The `setMeta` method is fully typed for each wallet:
|
|
753
743
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
744
|
+
```javascript
|
|
745
|
+
// For Apple Pay - accepts ApplePayOpenWalletMeta
|
|
746
|
+
applePayButton.setMeta({ ...meta, amount: 29.99, amount_label: 'NEW TOTAL' });
|
|
757
747
|
|
|
758
|
-
|
|
759
|
-
|
|
748
|
+
// For Google Pay - accepts GooglePayOpenWalletMeta
|
|
749
|
+
googlePayButton.setMeta({ ...meta, amount: 29.99, merchant_name: 'Updated Store' });
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### Handling errors
|
|
760
753
|
|
|
761
|
-
|
|
754
|
+
Register a callback function to handle errors that occur during wallet operations, including service type mismatches.
|
|
762
755
|
|
|
763
|
-
|
|
756
|
+
```javascript
|
|
757
|
+
button.onError((data) => {
|
|
758
|
+
console.error("Open Wallet error:", data.error);
|
|
759
|
+
console.log("Error context:", data.context);
|
|
764
760
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
761
|
+
// Show user-friendly error message
|
|
762
|
+
showErrorMessage("Payment initialization failed. Please try again.");
|
|
763
|
+
});
|
|
764
|
+
```
|
|
768
765
|
|
|
769
|
-
|
|
766
|
+
### Handling checkout cancellation
|
|
770
767
|
|
|
771
|
-
|
|
768
|
+
When the user cancels or closes the wallet payment interface, you can perform cleanup operations.
|
|
772
769
|
|
|
773
770
|
```javascript
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
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
|
-
};
|
|
771
|
+
button.onCancel((data) => {
|
|
772
|
+
console.log("Wallet checkout cancelled", data);
|
|
773
|
+
|
|
774
|
+
// Perform cleanup or redirect user
|
|
775
|
+
window.location.href = '/checkout';
|
|
776
|
+
});
|
|
825
777
|
```
|
|
826
778
|
|
|
827
|
-
|
|
779
|
+
### Cleaning up
|
|
828
780
|
|
|
829
|
-
|
|
781
|
+
Remove the wallet button from the DOM when it is no longer needed:
|
|
830
782
|
|
|
831
783
|
```javascript
|
|
832
|
-
|
|
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
|
-
};
|
|
784
|
+
button.destroy();
|
|
863
785
|
```
|
|
864
786
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
Since `OpenWalletMeta` extends native Apple Pay and Google Pay interfaces, you get access to both:
|
|
787
|
+
### Events
|
|
788
|
+
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 button classes.
|
|
868
789
|
|
|
869
|
-
|
|
870
|
-
|
|
790
|
+
**Available Event Handler Methods:**
|
|
791
|
+
- `onClick(handler)` - Button click events (supports attachResult for flow control)
|
|
792
|
+
- `onSuccess(handler)` - **Required** - OTT creation success events
|
|
793
|
+
- `onUnavailable(handler)` - Wallet unavailable events (supports Promise pattern)
|
|
794
|
+
- `onError(handler)` - Error events (supports Promise pattern)
|
|
795
|
+
- `onCancel(handler)` - Checkout cancellation events (supports Promise pattern)
|
|
796
|
+
- `onLoaded(handler)` - Button loaded/rendered events
|
|
797
|
+
- `onShippingAddressChange(handler)` - **Required for shipping** - Address change events
|
|
798
|
+
- `onShippingOptionsChange(handler)` - **Required for shipping options** - Option change events
|
|
871
799
|
|
|
872
|
-
|
|
800
|
+
**Event Handler Patterns:**
|
|
873
801
|
|
|
874
802
|
```javascript
|
|
875
|
-
//
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
parameters: {
|
|
891
|
-
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
|
|
892
|
-
allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX']
|
|
893
|
-
}
|
|
894
|
-
};
|
|
803
|
+
// Required handlers (will throw error if not provided)
|
|
804
|
+
button.onSuccess(handler); // Always required
|
|
805
|
+
button.onShippingAddressChange(handler); // Required when shipping enabled
|
|
806
|
+
button.onShippingOptionsChange(handler); // Required when shipping options provided
|
|
807
|
+
|
|
808
|
+
// Optional handlers with Promise support
|
|
809
|
+
button.onUnavailable(handler); // or await button.onUnavailable()
|
|
810
|
+
button.onError(handler); // or await button.onError()
|
|
811
|
+
button.onCancel(handler); // or await button.onCancel()
|
|
812
|
+
|
|
813
|
+
// Click handler with flow control
|
|
814
|
+
button.onClick(handler); // Use data.attachResult() for async operations
|
|
815
|
+
|
|
816
|
+
// Loaded handler
|
|
817
|
+
button.onLoaded(handler); // Notified when button renders
|
|
895
818
|
```
|
|
896
819
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
820
|
+
### Apple Pay-Specific Meta Properties
|
|
821
|
+
|
|
822
|
+
A full description of the [ApplePayOpenWalletMeta](#ApplePayOpenWalletMeta) properties:
|
|
823
|
+
|
|
824
|
+
**Required:**
|
|
825
|
+
- `amount`: The payment amount (number)
|
|
826
|
+
- `currency`: The currency code (string, e.g., "AUD")
|
|
827
|
+
- `country`: The country code (string, e.g., "AU")
|
|
828
|
+
- `amount_label`: Label for the total amount (string)
|
|
829
|
+
- `store_name`: Merchant store name (string)
|
|
830
|
+
|
|
831
|
+
**Optional:**
|
|
832
|
+
- `request_shipping?: boolean`: Enable shipping address collection
|
|
833
|
+
- `shipping_options?: IApplePayShippingOption[]`: Array of shipping options
|
|
834
|
+
- `show_billing_address?: boolean`: Show billing address fields
|
|
835
|
+
- `apple_pay_capabilities?: string[]`: Device capabilities
|
|
836
|
+
- `merchant_capabilities?: string[]`: Merchant capabilities
|
|
837
|
+
- `supported_networks?: string[]`: Supported payment networks
|
|
838
|
+
- `required_billing_contact_fields?: string[]`: Required billing contact fields
|
|
839
|
+
- `required_shipping_contact_fields?: string[]`: Required shipping contact fields
|
|
840
|
+
- `supported_countries?: string[]`: Supported countries
|
|
841
|
+
- `shipping_editing_mode?: 'available' | 'store_pickup'`: Shipping address editing mode
|
|
842
|
+
- `style?: { button_type?: ApplePayButtonType, button_style?: ApplePayButtonStyle }`: Button styling
|
|
843
|
+
|
|
844
|
+
### Google Pay-Specific Meta Properties
|
|
845
|
+
|
|
846
|
+
A full description of the [GooglePayOpenWalletMeta](#GooglePayOpenWalletMeta) properties:
|
|
901
847
|
|
|
902
|
-
|
|
848
|
+
**Required:**
|
|
849
|
+
- `amount`: The payment amount (number)
|
|
850
|
+
- `currency`: The currency code (string, e.g., "AUD")
|
|
851
|
+
- `country`: The country code (string, e.g., "AU")
|
|
852
|
+
|
|
853
|
+
**Optional:**
|
|
854
|
+
- `amount_label?: string`: Label for the total amount
|
|
855
|
+
- `merchant_name?: string`: Display name for the merchant
|
|
856
|
+
- `request_shipping?: boolean`: Enable shipping address collection
|
|
857
|
+
- `shipping_options?: IGooglePayShippingOption[]`: Array of shipping options
|
|
858
|
+
- `show_billing_address?: boolean`: Show billing address fields
|
|
859
|
+
- `card_config?: GooglePayCardConfig`: Card configuration (auth methods, networks, tokenization)
|
|
860
|
+
- `style?: { button_type?: GooglePayButtonType, button_color?: GooglePayButtonColor, button_size_mode?: GooglePayButtonSizeMode }`: Button styling
|
|
861
|
+
|
|
862
|
+
### Shipping Options Format
|
|
903
863
|
```javascript
|
|
904
864
|
shipping_options: [
|
|
905
865
|
{
|
|
@@ -907,12 +867,12 @@ shipping_options: [
|
|
|
907
867
|
label: "Option Name", // Display name (string)
|
|
908
868
|
detail: "Description", // Optional description (string)
|
|
909
869
|
amount: 10.00, // Shipping cost as number
|
|
910
|
-
date_components_range: { // Optional: delivery date range
|
|
870
|
+
date_components_range: { // Optional: delivery date range (Apple Pay only)
|
|
911
871
|
start_date_components: {
|
|
912
|
-
years: 0,
|
|
913
|
-
months: 0,
|
|
914
|
-
days: 5,
|
|
915
|
-
hours: 0,
|
|
872
|
+
years: 0,
|
|
873
|
+
months: 0,
|
|
874
|
+
days: 5,
|
|
875
|
+
hours: 0,
|
|
916
876
|
},
|
|
917
877
|
end_date_components: {
|
|
918
878
|
years: 0,
|
|
@@ -925,257 +885,28 @@ shipping_options: [
|
|
|
925
885
|
]
|
|
926
886
|
```
|
|
927
887
|
|
|
928
|
-
**Important**:
|
|
888
|
+
**Important**:
|
|
929
889
|
- `amount` should be a **number**, not a string
|
|
930
|
-
- `date_components_range` is optional but provides delivery estimates
|
|
890
|
+
- `date_components_range` is optional but provides delivery estimates (Apple Pay only)
|
|
931
891
|
- Updated shipping options returned from event handlers don't require `date_components_range`
|
|
932
892
|
|
|
933
|
-
|
|
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
|
|
893
|
+
### Environment Setup
|
|
1163
894
|
```javascript
|
|
1164
895
|
// Always set environment before loading
|
|
1165
|
-
|
|
1166
|
-
|
|
896
|
+
button.setEnv('sandbox');
|
|
897
|
+
button.load();
|
|
1167
898
|
```
|
|
1168
899
|
|
|
1169
|
-
|
|
900
|
+
### Error Handling Best Practices
|
|
1170
901
|
```javascript
|
|
1171
|
-
|
|
902
|
+
button.onError(function(data) {
|
|
1172
903
|
console.error('Full error object:', data);
|
|
1173
|
-
|
|
904
|
+
|
|
1174
905
|
// Check different error properties
|
|
1175
|
-
const errorMessage = data.error?.message ||
|
|
1176
|
-
data.message ||
|
|
906
|
+
const errorMessage = data.error?.message ||
|
|
907
|
+
data.message ||
|
|
1177
908
|
'Unknown error occurred';
|
|
1178
|
-
|
|
909
|
+
|
|
1179
910
|
// Handle different error types
|
|
1180
911
|
if (data.context?.operation === 'wallet_operation') {
|
|
1181
912
|
// Handle wallet-specific errors
|