@primer-io/checkout-web 2.0.0-alpha.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -521
- package/README.md +501 -904
- package/dist/Checkout.css +1 -1
- package/dist/index.d.ts +234 -945
- package/dist/loader.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,1071 +1,668 @@
|
|
|
1
|
-
|
|
1
|
+
<br/>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<h1 align="center"><img src="https://github.com/primer-io/example-web-checkout/blob/master/images/primer-logo.png?raw=true" height="24px"> Primer Web SDK</h1>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<div align="center">
|
|
6
|
+
<h3 align="center">
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
[Primer's](https://primer.io) Official Universal Checkout Web SDK
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
</h3>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
|
|
15
|
+
<img src="https://img.shields.io/npm/v/@primer-io/checkout-web" />
|
|
16
|
+
<!-- Potentially add test coverage in the future -->
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<br/>
|
|
20
|
+
|
|
21
|
+
<div align="center"><img src="https://github.com/primer-io/example-web-checkout/blob/master/images/checkout-banner.gif?raw=true" width="50%"/></div>
|
|
22
|
+
|
|
23
|
+
<br/>
|
|
24
|
+
<br/>
|
|
25
|
+
|
|
26
|
+
# 💪 Features of the Web SDK
|
|
27
|
+
|
|
28
|
+
<p>💳 Create great payment experiences with our highly customizable Universal Checkout</p>
|
|
29
|
+
<p>🧩 Connect and configure any new payment method without a single line of code</p>
|
|
30
|
+
<p>✅ Dynamically handle 3DS 2.0 across processors and be SCA ready</p>
|
|
31
|
+
<p>♻️ Store payment methods for one-click checkout, recurring and repeat payments</p>
|
|
32
|
+
<p>📱 Proprietary Apple & Google Pay integrations that work with any PSP</p>
|
|
33
|
+
<p>🔒 Always PCI compliant without redirecting customers</p>
|
|
34
|
+
|
|
35
|
+
<br/>
|
|
36
|
+
|
|
37
|
+
# 📚 Documentation
|
|
38
|
+
|
|
39
|
+
Consider looking at the following resources:
|
|
40
|
+
|
|
41
|
+
- [Documentation](https://primer.io/docs)
|
|
42
|
+
- [Client session creation](https://primer.io/docs/accept-payments/manage-client-sessions/#create-a-client-session)
|
|
43
|
+
- [API reference](https://apiref.primer.io/docs)
|
|
44
|
+
- [Changelogs](https://primer.io/docs/changelog/sdk-changelog/web)
|
|
45
|
+
|
|
46
|
+
<br/>
|
|
47
|
+
|
|
48
|
+
# 💡 Support
|
|
49
|
+
|
|
50
|
+
For any support or integration related queries, feel free to [Contact Us](mailto:https://support@primer.io).
|
|
51
|
+
|
|
52
|
+
<br/>
|
|
53
|
+
|
|
54
|
+
## 🚀 Quick start
|
|
55
|
+
|
|
56
|
+
Take a look at our [Quick Start Guide](https://primer.io/docs/integration-builder/) for accepting your first payment with Universal Checkout.
|
|
57
|
+
|
|
58
|
+
<br/>
|
|
59
|
+
|
|
60
|
+
# 📋 Prerequisites
|
|
61
|
+
|
|
62
|
+
- 🔑 Generate a client token by [creating a client session](https://primer.io/docs/api/#operation/create_client_side_token_client_session_post) in your backend
|
|
63
|
+
- 🧱 Prepare a container in which to render Universal Checkout
|
|
64
|
+
- 🎉 _That's it!_
|
|
65
|
+
|
|
66
|
+
<br/>
|
|
67
|
+
|
|
68
|
+
# 🧱 Installation
|
|
69
|
+
|
|
70
|
+
## With npm (recommended)
|
|
71
|
+
|
|
72
|
+
Our Web SDK is available on npm under the name [`@primer-io/checkout-web`](https://www.npmjs.com/package/@primer-io/checkout-web).
|
|
73
|
+
|
|
74
|
+
This package includes TypeScript definitions.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
|
|
78
|
+
# With yarn
|
|
79
|
+
yarn add @primer-io/checkout-web
|
|
80
|
+
|
|
81
|
+
# With npm
|
|
82
|
+
npm install --save @primer-io/checkout-web
|
|
11
83
|
|
|
12
84
|
```
|
|
13
|
-
import {loadPrimer} from '@primer-io/checkout-web'
|
|
14
85
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
86
|
+
```typescript
|
|
87
|
+
import { Primer } from '@primer-io/checkout-web';
|
|
88
|
+
|
|
89
|
+
Primer.showUniversalCheckout(clientToken, {
|
|
90
|
+
/* Options */
|
|
18
91
|
});
|
|
19
92
|
```
|
|
20
93
|
|
|
21
|
-
|
|
94
|
+
## With our CDN
|
|
22
95
|
|
|
23
|
-
|
|
96
|
+
Include the `Primer.min.js` script on the page where you want the checkout to be rendered.
|
|
24
97
|
|
|
25
|
-
|
|
98
|
+
Ensure that you're providing the desired version in the script tag. In the case below, it's `v2.0.0`:
|
|
26
99
|
|
|
27
|
-
|
|
100
|
+
```html
|
|
101
|
+
<link rel="stylesheet" href="https://sdk.primer.io/web/v2.0.0/Checkout.css" />
|
|
28
102
|
|
|
29
|
-
|
|
103
|
+
<script
|
|
104
|
+
src="https://sdk.primer.io/web/v2.0.0/Primer.min.js"
|
|
105
|
+
crossorigin="anonymous"
|
|
106
|
+
></script>
|
|
107
|
+
```
|
|
30
108
|
|
|
31
|
-
|
|
109
|
+
`Primer.min.js` will add the Primer object to the global scope:
|
|
32
110
|
|
|
33
111
|
```typescript
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// maximum time in milliseconds to wait for third party scripts to load [default=10000]
|
|
41
|
-
thirdPartyScriptTimeout?: number;
|
|
42
|
-
}
|
|
112
|
+
const { Primer } = window;
|
|
113
|
+
|
|
114
|
+
Primer.showUniversalCheckout(clientToken, {
|
|
115
|
+
/* Options */
|
|
116
|
+
});
|
|
43
117
|
```
|
|
44
118
|
|
|
45
|
-
|
|
119
|
+
<br/>
|
|
46
120
|
|
|
47
|
-
##
|
|
121
|
+
## 👩💻 Usage
|
|
48
122
|
|
|
49
|
-
###
|
|
123
|
+
### 🔍 Rendering the checkout
|
|
50
124
|
|
|
51
|
-
|
|
125
|
+
Availing Universal Checkout is as easy as implementing one line of code:
|
|
52
126
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- `MANAGE_PAYMENT_METHODS`: to render a UI for managing saved payment methods
|
|
127
|
+
```javascript
|
|
128
|
+
import { Primer } from '@primer-io/checkout-web';
|
|
56
129
|
|
|
57
|
-
|
|
130
|
+
const universalCheckout = await Primer.showUniversalCheckout(
|
|
131
|
+
clientToken,
|
|
132
|
+
options,
|
|
133
|
+
);
|
|
134
|
+
```
|
|
58
135
|
|
|
59
|
-
|
|
136
|
+
Below is an example of a basic implementation of Universal Checkout:
|
|
60
137
|
|
|
61
|
-
|
|
138
|
+
```javascript
|
|
139
|
+
const clientToken = '...'; // client token retrieved from your backend
|
|
62
140
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
uxFlow: 'CHECKOUT' | 'MANAGE_PAYMENT_METHODS' | 'SINGLE_PAYMENT_METhOD_CHECKOUT,
|
|
141
|
+
const options = {
|
|
142
|
+
// Container element which will contain the checkout
|
|
143
|
+
container: '#container',
|
|
67
144
|
|
|
68
|
-
|
|
69
|
-
|
|
145
|
+
onCheckoutComplete({ payment }) {
|
|
146
|
+
// Notifies you that a payment was created
|
|
147
|
+
// Move on to next step in your checkout flow:
|
|
148
|
+
// e.g. Show a success message, giving access to the service, fulfilling the order
|
|
149
|
+
},
|
|
150
|
+
};
|
|
70
151
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
152
|
+
const universalCheckout = await Primer.showUniversalCheckout(
|
|
153
|
+
clientToken,
|
|
154
|
+
options,
|
|
155
|
+
);
|
|
156
|
+
```
|
|
74
157
|
|
|
75
|
-
|
|
76
|
-
// See the section on 3DS below for more info.
|
|
77
|
-
threeDSecure?: ThreeDSecureVerifyOptions;
|
|
158
|
+
Note that there are more options which can be passed to Universal Checkout. Please refer to the section below for more information.
|
|
78
159
|
|
|
79
|
-
|
|
80
|
-
onTokenizeStart?: () => void;
|
|
160
|
+
<br/>
|
|
81
161
|
|
|
82
|
-
|
|
83
|
-
onTokenizeSuccess: (data: PaymentMethodToken) => Promise<SuccessCallbackReturnType>;
|
|
162
|
+
## 🧰 Checkout Options
|
|
84
163
|
|
|
85
|
-
|
|
86
|
-
onTokenizeError: (message: string) => void;
|
|
164
|
+
When calling `showUniversalCheckout` you can provide Universal Checkout with some configuration options.
|
|
87
165
|
|
|
88
|
-
|
|
89
|
-
onAmountChange?: (data: AmountChange) => void;
|
|
166
|
+
These options range from callbacks notifying you of the current payment's status, to styling options for certain UI elements.
|
|
90
167
|
|
|
91
|
-
|
|
92
|
-
onAmountChanging?: (isChanging: boolean) => void;
|
|
168
|
+
Below are some options to consider when integrating Universal Checkout:
|
|
93
169
|
|
|
94
|
-
|
|
95
|
-
onAmountChangeError?: (message: PrimerError) => void;
|
|
170
|
+
### 🚀 **General Options**
|
|
96
171
|
|
|
97
|
-
|
|
98
|
-
onClientSessionActions?: (data: onClientSessionActionData) => Promise<{ clientToken: string } | false>;
|
|
172
|
+
#### ⚙️ _Container and locale_
|
|
99
173
|
|
|
100
|
-
|
|
101
|
-
|
|
174
|
+
| option | Type | Description | |
|
|
175
|
+
| ----------- | --------------------- | ----------------------------------------------------------------------------------------- | -------- |
|
|
176
|
+
| `container` | `string` or `Element` | The container element in which the checkout should be rendered | required |
|
|
177
|
+
| `locale` | `string` | This option forces the locale. By default, the locale will be set to the browser's locale | optional |
|
|
102
178
|
|
|
103
|
-
|
|
104
|
-
style?: CheckoutStyle;
|
|
179
|
+
<br/>
|
|
105
180
|
|
|
106
|
-
|
|
107
|
-
form?: FormOptions;
|
|
181
|
+
#### ⚙️ _Payment Lifecycle Callbacks_
|
|
108
182
|
|
|
109
|
-
|
|
110
|
-
// Deprecated in favor of using `useBuiltInButton`
|
|
111
|
-
visible?: boolean;
|
|
183
|
+
Callbacks can be provided to Universal Checkout which will notify you on certain checkout events such as payment creation.
|
|
112
184
|
|
|
113
|
-
|
|
114
|
-
// Or use your own submit button
|
|
115
|
-
// Defaults to true
|
|
116
|
-
useBuiltInButton?: boolean;
|
|
185
|
+
These callbacks can be used to inform you on the current state of the checkout.
|
|
117
186
|
|
|
118
|
-
|
|
119
|
-
// Ensuring that your button has the correct state and content for a specific scene
|
|
187
|
+
We strongly recommend you to implement `onCheckoutComplete` to redirect the user to an order confirmation page when the payment is successful:
|
|
120
188
|
|
|
121
|
-
|
|
122
|
-
|
|
189
|
+
```javascript
|
|
190
|
+
const options = {
|
|
191
|
+
/* Other checkout options ... */
|
|
123
192
|
|
|
124
|
-
|
|
125
|
-
|
|
193
|
+
onBeforePaymentCreate(data, handler) {
|
|
194
|
+
// Notifies you that a payment will be created
|
|
195
|
+
// Update your UI accordingly
|
|
196
|
+
// e.g. Show custom loading UI, etc.
|
|
197
|
+
// Abort or continue with payment creation
|
|
198
|
+
// Primer will continue with payment creation if onBeforePaymentCreate is not implemented
|
|
126
199
|
|
|
127
|
-
//
|
|
128
|
-
onLoading: (isLoading: boolean, context: { currentSceneId: string }) => void;
|
|
200
|
+
// ⚠️ You MUST call one of the functions of the `handler` if `onBeforePaymentCreate` is implemented
|
|
129
201
|
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
processingIndicator?: {
|
|
135
|
-
// Show a processing indicator overlay on top of the checkout when submitting a form
|
|
136
|
-
// Default to false if the submit button is visible
|
|
137
|
-
// Default to true if the submit button is hidden
|
|
138
|
-
visible?: boolean;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
// Handles the error message displayed below the submit button when an error occurs
|
|
142
|
-
errorMessage?: {
|
|
143
|
-
// Disable the appearance of the default error message
|
|
144
|
-
// Default to false
|
|
145
|
-
disabled?: boolean;
|
|
146
|
-
|
|
147
|
-
// A callback for when the error message is displayed
|
|
148
|
-
onErrorMessageShow?: (message: string) => void;
|
|
149
|
-
|
|
150
|
-
// A callback for when the error message is hidden
|
|
151
|
-
onErrorMessageHide?: () => void;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* PAYMENT METHOD SPECIFIC */
|
|
155
|
-
|
|
156
|
-
// Card networks allowed for checkout
|
|
157
|
-
// An error will be showed to the customer if they attempt to pay with a card network that is not allowed, whether it is using a card form, or via Google Pay/Apple Pay/...
|
|
158
|
-
// By default, all card networks are allowed
|
|
159
|
-
allowedCardNetworks: CardNetwork[];
|
|
160
|
-
|
|
161
|
-
card?: CheckoutCardOptions;
|
|
162
|
-
paypal?: PayPalOptions;
|
|
163
|
-
googlePay?: GooglePayOptions;
|
|
164
|
-
applePay?: ApplePayOptions;
|
|
165
|
-
directDebit?: DirectDebitOptions;
|
|
166
|
-
|
|
167
|
-
redirect?: {
|
|
168
|
-
// URL to return to in case of a redirect
|
|
169
|
-
returnUrl?: string;
|
|
170
|
-
|
|
171
|
-
// Default to false. Set to true to force a redirect for testing purposes.
|
|
172
|
-
forceRedirect?: boolean;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
```
|
|
202
|
+
// Choose to abort a payment
|
|
203
|
+
return handler.abortPaymentCreation();
|
|
176
204
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
| 'diners-club'
|
|
181
|
-
| 'discover'
|
|
182
|
-
| 'elo'
|
|
183
|
-
| 'hiper'
|
|
184
|
-
| 'hipercard'
|
|
185
|
-
| 'interac'
|
|
186
|
-
| 'jcb'
|
|
187
|
-
| 'maestro'
|
|
188
|
-
| 'mastercard'
|
|
189
|
-
| 'mir'
|
|
190
|
-
| 'unionpay'
|
|
191
|
-
| 'visa';
|
|
192
|
-
```
|
|
205
|
+
// Choose to continue with payment creation
|
|
206
|
+
return handler.continuePaymentCreation();
|
|
207
|
+
},
|
|
193
208
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
```
|
|
209
|
+
onCheckoutComplete({ payment }) {
|
|
210
|
+
// Notifies you that a payment was created
|
|
211
|
+
// Move on to next step in your checkout flow:
|
|
212
|
+
// e.g. Show a success message, giving access to the service, fulfilling the order, ...
|
|
213
|
+
},
|
|
200
214
|
|
|
201
|
-
|
|
215
|
+
onCheckoutFail(error, { payment }, handler) {
|
|
216
|
+
// Notifies you that the checkout flow has failed and a payment could not be created
|
|
217
|
+
// This callback can also be used to display an error state within your own UI.
|
|
202
218
|
|
|
203
|
-
|
|
219
|
+
// ⚠️ `handler` is undefined if the SDK does not expect anything from you
|
|
220
|
+
if (!handler) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
204
223
|
|
|
205
|
-
|
|
206
|
-
// The data returned in onClientSessionActions
|
|
207
|
-
type ClientSessionActionData = {
|
|
208
|
-
actions: ClientSessionAction[];
|
|
209
|
-
clientToken: string;
|
|
210
|
-
};
|
|
211
|
-
```
|
|
224
|
+
// ⚠️ If `handler` exists, you MUST call one of the functions of the handler
|
|
212
225
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
226
|
+
// Show a default error message
|
|
227
|
+
return handler.showErrorMessage();
|
|
228
|
+
|
|
229
|
+
// Show a custom error message
|
|
230
|
+
return handler.showErrorMessage('This is my custom error message');
|
|
231
|
+
},
|
|
217
232
|
};
|
|
218
233
|
```
|
|
219
234
|
|
|
220
|
-
|
|
221
|
-
// The currently supported action types forwarded to onClientSessionActions
|
|
222
|
-
type ActionType = 'SELECT_PAYMENT_METHOD' | 'UNSELECT_PAYMENT_METHOD';
|
|
223
|
-
```
|
|
235
|
+
<br/>
|
|
224
236
|
|
|
225
|
-
|
|
226
|
-
type ActionParameters = SelectPaymentMethodParamters | DefaulActionParameters;
|
|
227
|
-
```
|
|
237
|
+
#### ⚙️ _Client Session Lifecycle Callbacks_
|
|
228
238
|
|
|
229
|
-
|
|
230
|
-
type SelectPaymentMethodParamters = {
|
|
231
|
-
paymentMethodType: string;
|
|
232
|
-
binData?: BinData;
|
|
233
|
-
};
|
|
234
|
-
```
|
|
239
|
+
Callbacks can be provided to Universal Checkout which will notify you on client session update events.
|
|
235
240
|
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
};
|
|
240
|
-
```
|
|
241
|
+
```javascript
|
|
242
|
+
const options = {
|
|
243
|
+
/* Other checkout options ... */
|
|
241
244
|
|
|
242
|
-
|
|
245
|
+
onBeforeClientSessionUpdate() {
|
|
246
|
+
// Notifies you that the client session is in the process of being updated
|
|
247
|
+
// Use it to show a loading indicator on your UI
|
|
248
|
+
},
|
|
243
249
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// Additional information relating to merchant operating address. Used for tax calculation
|
|
251
|
-
businessDetails?: {
|
|
252
|
-
address: {
|
|
253
|
-
countryCode: string;
|
|
254
|
-
state: string;
|
|
255
|
-
postalCode: string;
|
|
256
|
-
city: string;
|
|
257
|
-
addressLine1: string;
|
|
258
|
-
};
|
|
259
|
-
nexusAddresses: [
|
|
260
|
-
{
|
|
261
|
-
countryCode: string;
|
|
262
|
-
state: string;
|
|
263
|
-
postalCode: string;
|
|
264
|
-
city: string;
|
|
265
|
-
addressLine1: string;
|
|
266
|
-
},
|
|
267
|
-
];
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// Additional information relating to customer. Details can be used for tax calculation
|
|
271
|
-
customerDetails?: {
|
|
272
|
-
customerTaxId: string;
|
|
273
|
-
shippingAddress: {
|
|
274
|
-
countryCode: string;
|
|
275
|
-
state: string;
|
|
276
|
-
postalCode: string;
|
|
277
|
-
city: string;
|
|
278
|
-
addressLine1: string;
|
|
279
|
-
};
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
// Options regarding the vault and one-click checkout feature
|
|
283
|
-
vault?: {
|
|
284
|
-
// Fetch the vaulted payment methods of the customerId of the current session and display them
|
|
285
|
-
// Default to true
|
|
286
|
-
visible?: boolean;
|
|
287
|
-
|
|
288
|
-
// Disable the option to delete a saved payment method.
|
|
289
|
-
// Default to false
|
|
290
|
-
deletionDisabled?: boolean;
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
// A callback for when a resume action succeeds. This will receive the resume token used to resume a payment
|
|
294
|
-
onResumeSuccess: (data: ResumeToken) => Promise<SuccessCallbackReturnType>;
|
|
295
|
-
|
|
296
|
-
// A callback for when an error happened when resuming
|
|
297
|
-
onResumeError: (error: PrimerClientError) => void;
|
|
250
|
+
onClientSessionUpdate(clientSession) {
|
|
251
|
+
// Notifies you when the client session has been updated by the checkout
|
|
252
|
+
// Returns updated client session
|
|
253
|
+
// Updated client session can be used to inform your UI
|
|
254
|
+
// e.g. update tax, shipping or discount amounts displayed to your customers
|
|
255
|
+
},
|
|
298
256
|
};
|
|
299
257
|
```
|
|
300
258
|
|
|
301
|
-
|
|
302
|
-
enum PaymentMethodType {
|
|
303
|
-
PAYMENT_CARD = 'PAYMENT_CARD',
|
|
304
|
-
APPLE_PAY = 'APPLE_PAY',
|
|
305
|
-
GOOGLE_PAY = 'GOOGLE_PAY',
|
|
306
|
-
PAYPAL = 'PAYPAL',
|
|
307
|
-
GO_CARDLESS = 'GOCARDLESS',
|
|
308
|
-
}
|
|
309
|
-
```
|
|
259
|
+
---
|
|
310
260
|
|
|
311
|
-
|
|
312
|
-
interface FormOptions {
|
|
313
|
-
inputLabelsVisible?: boolean; // Show or hide form input labels
|
|
314
|
-
}
|
|
315
|
-
```
|
|
261
|
+
### 💳 **Payment Methods Options**
|
|
316
262
|
|
|
317
|
-
|
|
318
|
-
type SceneOptions = {
|
|
319
|
-
// A callback for receiving the current scene that is entering
|
|
320
|
-
onEntering?: (sceneId: string) => void;
|
|
321
|
-
|
|
322
|
-
// Specify options relating to scene transitions
|
|
323
|
-
// Setting to false disables all scene transitions
|
|
324
|
-
// Defaults to a 'SLIDE_UP' type transition with a duration of 700ms
|
|
325
|
-
transition?: SceneTransitionOptions | false
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
type SceneTransitionOptions = {
|
|
329
|
-
// The type of transition animation which will be used
|
|
330
|
-
type: TransitionType;
|
|
331
|
-
// The duration of the transition animation
|
|
332
|
-
duration: number;
|
|
333
|
-
};
|
|
263
|
+
Learn more about the [payment method specific options](https://www.notion.so/primerio/Checkout-Documentation-589aeae3387a4025917db6e29810ebaf).
|
|
334
264
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
| 'SLIDE_DOWN'
|
|
338
|
-
| 'SLIDE_HORIZONTAL
|
|
339
|
-
```
|
|
265
|
+
<!--
|
|
266
|
+
#### ⚙️ _Redirect Options_
|
|
340
267
|
|
|
341
|
-
|
|
268
|
+
Handling redirects is required for Payment Methods like iDeal that present a webpage for the customer to enter their credentials and validate their payment.
|
|
342
269
|
|
|
343
|
-
When a
|
|
270
|
+
When the user selects such a Payment Method, Universal Checkout will first attempt to show the webpage in a popup or a browser tab to maintain the context, and will then safely bring the user back to the initial page to continue the flow.
|
|
344
271
|
|
|
345
|
-
|
|
272
|
+
This however does not work properly in some scenario involving third-party apps through deep linking.
|
|
346
273
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
// Send the payment method token to your server to then create a payment
|
|
352
|
-
const response = await sendPaymentMethodToken(paymentMethod);
|
|
353
|
-
|
|
354
|
-
// If a new client token is available, resolve the Promise with it to refresh the checkout session
|
|
355
|
-
// The checkout will automatically perform the action required by the Workflow
|
|
356
|
-
// e.g. Perform a 3D Secure challenge
|
|
357
|
-
if (response.clientToken) {
|
|
358
|
-
return { clientToken: response.clientToken };
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// Display the success screen
|
|
362
|
-
return true;
|
|
363
|
-
}
|
|
364
|
-
```
|
|
274
|
+
| option | Type | Description | Default | |
|
|
275
|
+
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
|
|
276
|
+
| `redirect.returnUrl` | String | If creating a popup or tab is not possible, Universal Checkout will automatically redirect the user back to this URL. | | optional |
|
|
277
|
+
| `redirect.forceRedirect` | Boolean | Forces redirect instead of using popups. <br /> _This negatively affects the User Experience. We recommend to only use this option in your testing environment._ | false | optional |
|
|
365
278
|
|
|
366
|
-
|
|
279
|
+
#### ⚙️ _Card Options_
|
|
367
280
|
|
|
368
|
-
|
|
281
|
+
These options only apply to the native Card implementation (`PAYMENT_CARD`).
|
|
369
282
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const response = await sendResumeToken(resumeToken);
|
|
377
|
-
|
|
378
|
-
// If a new client token is available, resolve the Promise with it to refresh the checkout session
|
|
379
|
-
// The checkout will automatically perform the action required by the Workflow
|
|
380
|
-
if (response.clientToken) {
|
|
381
|
-
// e.g. Trigger a 3D Secure challenge
|
|
382
|
-
return { clientToken: response.clientToken };
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Display the success screen
|
|
386
|
-
return true;
|
|
387
|
-
}
|
|
388
|
-
```
|
|
283
|
+
| option | Type | Description | Default | |
|
|
284
|
+
| ----------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------- |
|
|
285
|
+
| `card.preferredFlow` | `DEDICATED_SCENE` or `EMBEDDED_IN_HOME` | `DEDICATED_SCENE`<br />Attempt to display a card button in the home scene. Clicking on this button will show the card form. <br /> <br /> `EMBEDDED_IN_HOME`<br /> Attempt to display the entire card form within the home scene. | `EMBEDDED_IN_HOME` | optional |
|
|
286
|
+
| `card.cardNumber.placeholder` | String | Placeholder for the card number field. | `1234 1234 1234 1234` | optional |
|
|
287
|
+
| `card.expiryDate.placeholder` | String | Placeholder for the card number field. | Localized version of `MM/YY` | optional |
|
|
288
|
+
| `card.expiryDate.cvv` | String | Placeholder for the card number field. | `***` or `****` depending on the card scheme | optional |
|
|
389
289
|
|
|
390
|
-
|
|
290
|
+
---
|
|
391
291
|
|
|
392
|
-
|
|
393
|
-
orderDetails?: {
|
|
394
|
-
currencyCode: string;
|
|
395
|
-
};
|
|
292
|
+
#### ⚙️ _Apple Pay Options_
|
|
396
293
|
|
|
397
|
-
|
|
398
|
-
// Default to false
|
|
399
|
-
deletionDisabled?: boolean;
|
|
400
|
-
```
|
|
294
|
+
These options only apply to the native Apple Pay implementation (`APPLE_PAY`).
|
|
401
295
|
|
|
402
|
-
|
|
296
|
+
| option | Type | Description | Default | |
|
|
297
|
+
| ---------------------- | ------------------------------------------------------------------- | -------------------------------------------- | ------- | -------- |
|
|
298
|
+
| `applePay.buttonType` | `plain`, `buy`, `set-up`, `donate`, `check-out`, `book`, `suscribe` | Control the content of the Apple Pay button. | `plain` | optional |
|
|
299
|
+
| `applePay.buttonStyle` | `white`, `white-outline`, `black` | Control the style of button. | `black` | optional |
|
|
403
300
|
|
|
404
|
-
|
|
405
|
-
type SinglePaymentMethodCheckoutOptions = {
|
|
406
|
-
// The single payment method to render
|
|
407
|
-
// Only "GOCARDLESS" at the moment
|
|
408
|
-
paymentMethod: PaymentMethodType;
|
|
409
|
-
};
|
|
410
|
-
```
|
|
301
|
+
#### ⚙️ _Google Pay Options_
|
|
411
302
|
|
|
412
|
-
|
|
303
|
+
These options only apply to the native Google Pay implementation (`GOOGLE_PAY`).
|
|
413
304
|
|
|
414
|
-
|
|
305
|
+
| option | Type | Description | Default | |
|
|
306
|
+
| ---------------------- | --------------------------- | ------------------------------------------- | --------- | -------- |
|
|
307
|
+
| `googlePay.buttonType` | `long`, `short` | Control the size of the Google Pay button. | `long` | optional |
|
|
308
|
+
| `google.buttonColor` | `default`, `black`, `white` | Control the color of the Google Pay button. | `default` | optional |
|
|
415
309
|
|
|
416
|
-
|
|
417
|
-
type CheckoutCardOptions = {
|
|
418
|
-
// A stylesheet to inject into each input element
|
|
419
|
-
// For more information see the guide on styling
|
|
420
|
-
css?: string;
|
|
421
|
-
|
|
422
|
-
// deprecated after v1.2.0
|
|
423
|
-
// Choose if the cardholder name should be required or not
|
|
424
|
-
// default value is true
|
|
425
|
-
cardholderNameRequired?: boolean;
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
cardholderName?: {
|
|
429
|
-
// Choose if the cardholder name should be visible
|
|
430
|
-
// default value is true
|
|
431
|
-
visible?: boolean;
|
|
432
|
-
|
|
433
|
-
// Choose if the cardholder name should be required
|
|
434
|
-
// If visible, the default value is true
|
|
435
|
-
required?: boolean;
|
|
436
|
-
|
|
437
|
-
// Placeholder text which will be displayed within input
|
|
438
|
-
// defaults to localized placeholder if not provided
|
|
439
|
-
placeholder?: string;
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
cardNumber?: {
|
|
443
|
-
// Placeholder card number which will be displayed within input
|
|
444
|
-
// default card number placeholder displayed if not provided
|
|
445
|
-
placeholder?: string;
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
expiryDate?: {
|
|
449
|
-
// Placeholder expiry date which will be displayed within input
|
|
450
|
-
// default expiry date placeholder displayed if not provided
|
|
451
|
-
placeholder?: Label;
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
cvv?: {
|
|
455
|
-
// Placeholder cvv which will be displayed within input
|
|
456
|
-
// default cvv placeholder displayed if not provided
|
|
457
|
-
placeholder?: Label;
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
// Choose if the card form should be embedded in the home scene
|
|
461
|
-
// Or have a dedicated card scene accessible by a card button
|
|
462
|
-
// Note that the preferredFlow will not necessarily be the chosen flow
|
|
463
|
-
preferredFlow?: CardPreferredFlow;
|
|
464
|
-
|
|
465
|
-
// Checkout will ask the customer id they want to save their card.
|
|
466
|
-
// To disable this feature provide a value for the vault option.
|
|
467
|
-
// When true: the card will be vaulted
|
|
468
|
-
// When false: the card will not be vaulted
|
|
469
|
-
vault?: boolean | () => boolean;
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
// DEDICATED_SCENE: can be used if more than one payment method is available
|
|
473
|
-
// EMBEDDED_IN_HOME: is provided by default. It will override the dedicated scene option
|
|
474
|
-
// When card is the only available payment method
|
|
475
|
-
type CardPreferredFlow = 'DEDICATED_SCENE' | 'EMBEDDED_IN_HOME';
|
|
476
|
-
```
|
|
310
|
+
#### ⚙️ _PayPal Options_
|
|
477
311
|
|
|
478
|
-
|
|
312
|
+
These options only apply to the native PayPal implementation (`PAYPAL`).
|
|
479
313
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
buttonHeight?: number;
|
|
486
|
-
buttonLabel?:
|
|
487
|
-
| 'checkout'
|
|
488
|
-
| 'credit'
|
|
489
|
-
| 'pay'
|
|
490
|
-
| 'buynow'
|
|
491
|
-
| 'paypal'
|
|
492
|
-
| 'installment';
|
|
493
|
-
buttonTagline?: boolean;
|
|
494
|
-
paymentFlow?: PaymentFlow;
|
|
495
|
-
};
|
|
496
|
-
```
|
|
314
|
+
| option | Type | Description | Default | |
|
|
315
|
+
| -------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- |
|
|
316
|
+
| `paypal.buttonColor` | `gold`, `blue`, `silver`, `white`, `black` | Control the color of the PayPal button. | `gold` | optional |
|
|
317
|
+
| `paypal.buttonLabel` | `checkout`, `credit`, `pay`, `buynow`, `paypal`, `installment` | Control the label written in the PayPal button. | `PayPal` | optional |
|
|
318
|
+
| `paypal.paymentFlow` | `DEFAULT`, `PREFER_VAULT` | `DEFAULT`<br />Prepare everything to make a payment with PayPal. <br /><br />`PREFER_VAULT`<br />Vaut PayPal before making a payment. <br />Make sure the [`customerId`](https://apiref.primer.io/reference/create_client_side_token_client_session_post#request.body.customerId) is set in the client session. | `DEFAULT` | optional |
|
|
497
319
|
|
|
498
|
-
####
|
|
320
|
+
#### ⚙️ _Klarna Options_
|
|
499
321
|
|
|
500
|
-
|
|
501
|
-
type DirectDebitOptions = {
|
|
502
|
-
customerCountryCode: Alpha2CountryCode;
|
|
503
|
-
|
|
504
|
-
// The following options are used in the Direct Debit mandate
|
|
505
|
-
companyName: string;
|
|
506
|
-
companyAddress: string;
|
|
507
|
-
|
|
508
|
-
// The following options are used to prefill the Direct Debit form
|
|
509
|
-
customerName?: string;
|
|
510
|
-
customerEmail?: string;
|
|
511
|
-
customerAddressLine1?: string;
|
|
512
|
-
customerAddressLine2?: string;
|
|
513
|
-
customerCity?: string;
|
|
514
|
-
customerPostalCode?: string;
|
|
515
|
-
iban?: string;
|
|
516
|
-
|
|
517
|
-
// Label of the submit button
|
|
518
|
-
submitButtonLabels?: {
|
|
519
|
-
// Label of the submit button in the form
|
|
520
|
-
form?: string;
|
|
521
|
-
|
|
522
|
-
// Label of the submit button in the mandate
|
|
523
|
-
mandate: string;
|
|
524
|
-
};
|
|
525
|
-
};
|
|
526
|
-
```
|
|
322
|
+
These options only apply to the native Klarna implementation (`KLARNA`).
|
|
527
323
|
|
|
528
|
-
|
|
324
|
+
| option | Type | Description | Default | |
|
|
325
|
+
| ------------------------------------ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -------- |
|
|
326
|
+
| `klarna.recurringPaymentDescription` | String | Payment description used for recurring payments | | optional |
|
|
327
|
+
| `klarna.allowedPaymentCategories` | Array of categories <br /> `pay_now`, `pay_later`, `pay_over_time` | List of categories allowed to be presented to the customer | `['pay_now', 'pay_later', 'pay_over_time']` | optional |
|
|
328
|
+
| `klarna.paymentFlow` | `DEFAULT`, `PREFER_VAULT` | `DEFAULT`<br />Prepare everything to make a payment with Klarna. <br /><br />`PREFER_VAULT`<br />Vaut Klarna before making a payment. <br />Make sure the [`customerId`](https://apiref.primer.io/reference/create_client_side_token_client_session_post#request.body.customerId) is set in the client session. | `DEFAULT` | optional |
|
|
529
329
|
|
|
530
|
-
|
|
531
|
-
type ApplePayOptions = {
|
|
532
|
-
buttonType?:
|
|
533
|
-
| 'plain'
|
|
534
|
-
| 'buy'
|
|
535
|
-
| 'set-up'
|
|
536
|
-
| 'donate'
|
|
537
|
-
| 'check-out'
|
|
538
|
-
| 'book'
|
|
539
|
-
| 'subscribe';
|
|
540
|
-
buttonStyle?: 'white' | 'white-outline' | 'black';
|
|
541
|
-
};
|
|
542
|
-
```
|
|
330
|
+
-->
|
|
543
331
|
|
|
544
|
-
|
|
332
|
+
---
|
|
545
333
|
|
|
546
|
-
|
|
547
|
-
buttonType?: "long" | "short";
|
|
548
|
-
buttonColor?: "default" | "black" | "white";
|
|
549
|
-
```
|
|
334
|
+
### 🎨 **Customization Options**
|
|
550
335
|
|
|
551
|
-
|
|
336
|
+
Learn more about the [customization options](https://primer.io/docs/accept-payments/customize-universal-checkout/web).
|
|
552
337
|
|
|
553
|
-
|
|
338
|
+
#### ⚙️ _Styling_
|
|
554
339
|
|
|
555
|
-
|
|
556
|
-
|
|
340
|
+
| option | Type | Description | Default | |
|
|
341
|
+
| ------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------- |
|
|
342
|
+
| `style` | Object | Custom style applied to the UI. <br /> Learn more about the capabilities in our [Customization Guide](docs/accept-payments/customize-universal-checkout/web/#styling-universal-checkout) | Default style | optional |
|
|
557
343
|
|
|
558
|
-
|
|
559
|
-
```
|
|
344
|
+
#### ⚙️ _Form Options_
|
|
560
345
|
|
|
561
|
-
|
|
346
|
+
| option | Type | Description | Default | |
|
|
347
|
+
| ------------------------- | ------- | --------------------------------------------- | ------- | -------- |
|
|
348
|
+
| `form.inputLabelsVisible` | Boolean | Choose whether to show the label above inputs | true | optional |
|
|
562
349
|
|
|
563
|
-
|
|
564
|
-
This is useful when using your own custom submit button.
|
|
350
|
+
#### ⚙️ _Submit Button Options & Callbacks_
|
|
565
351
|
|
|
566
|
-
|
|
567
|
-
const checkout = await primer.checkout(checkoutOptions);
|
|
352
|
+
Universal Checkout allows you to use your own submit button for submitting forms. By default, the built-in submit button will be favored:
|
|
568
353
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
};
|
|
573
|
-
```
|
|
354
|
+
| option | Type | Description | Default | |
|
|
355
|
+
| ------------------------------- | ------- | ------------------------------------------------------------------------------ | ------- | -------- |
|
|
356
|
+
| `submitButton.useBuiltInButton` | Boolean | Set whether to use built-in submit button or to display your own custom button | true | optional |
|
|
574
357
|
|
|
575
|
-
|
|
358
|
+
<br/>
|
|
576
359
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
fontFaces?: Array<FontFace>; // Injected into hosted fields
|
|
580
|
-
stylesheets?: Array<Stylesheet>; // Injected into hosted fields
|
|
581
|
-
|
|
582
|
-
loadingScreen?: {
|
|
583
|
-
// Color of the loading screen indicator
|
|
584
|
-
color?: string;
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
// Style of the inputs
|
|
588
|
-
input?: {
|
|
589
|
-
// Base style
|
|
590
|
-
base?: InputStyle & {
|
|
591
|
-
hover?: InputStyle; // :hover
|
|
592
|
-
focus?: InputStyle; // :focus
|
|
593
|
-
placeholder?: InputStyle; // ::placeholder
|
|
594
|
-
webkitAutofill?: InputStyle; // :-webkit-autofill
|
|
595
|
-
selection?: InputStyle; // ::selection
|
|
596
|
-
};
|
|
597
|
-
|
|
598
|
-
// Error
|
|
599
|
-
error?: InputStyle & {
|
|
600
|
-
hover?: InputStyle;
|
|
601
|
-
focus?: InputStyle;
|
|
602
|
-
placeholder?: InputStyle;
|
|
603
|
-
webkitAutofill?: InputStyle;
|
|
604
|
-
selection?: InputStyle;
|
|
605
|
-
};
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
// Style of the label displayed above the input fields
|
|
609
|
-
inputLabel?: TextStyle;
|
|
610
|
-
|
|
611
|
-
// Style of the error messages displayed below the input fields
|
|
612
|
-
inputErrorText?: TextStyle & TextAlignmentStyle;
|
|
613
|
-
|
|
614
|
-
formSpacings?: {
|
|
615
|
-
// Vertical spacing between a label and an input field
|
|
616
|
-
betweenLabelAndInput?: string;
|
|
617
|
-
|
|
618
|
-
// Vertical spacing between inputs
|
|
619
|
-
betweenInputs: string;
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
showMorePaymentMethodsButton?: {
|
|
623
|
-
base?: TextStyle;
|
|
624
|
-
disabled?: TextStyle;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
// Style APM buttons
|
|
628
|
-
// PayPal, Apple Pay, Google Pay and Klarna can only be styled in height and borderRadius.
|
|
629
|
-
paymentMethodButton: {
|
|
630
|
-
background?: string;
|
|
631
|
-
borderRadius?: number | string;
|
|
632
|
-
boxShadow?: string;
|
|
633
|
-
borderColor?: string;
|
|
634
|
-
height?: number;
|
|
635
|
-
primaryText?: TextStyle;
|
|
636
|
-
logoColor?: logoColor;
|
|
637
|
-
marginTop?: string;
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
submitButton?: {
|
|
641
|
-
base?: {
|
|
642
|
-
hover?: TextStyle & BlockStyle;
|
|
643
|
-
focus?: TextStyle & BlockStyle;
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
loading?: {
|
|
647
|
-
hover?: TextStyle & BlockStyle;
|
|
648
|
-
focus?: TextStyle & BlockStyle;
|
|
649
|
-
};
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
// Small print in direct debit
|
|
653
|
-
smallPrint?: TextStyle;
|
|
654
|
-
|
|
655
|
-
directDebit?: {
|
|
656
|
-
mandate?: {
|
|
657
|
-
header?: TextStyle;
|
|
658
|
-
label?: TextStyle;
|
|
659
|
-
content?: TextStyle;
|
|
660
|
-
creditorDetails?: TextStyle:
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
success?: {
|
|
664
|
-
icon?: {
|
|
665
|
-
color?: string;
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
backButton?: {
|
|
671
|
-
color?: string;
|
|
672
|
-
};
|
|
673
|
-
|
|
674
|
-
// Pop-up menu to manage the vaulted payment methods
|
|
675
|
-
vaultMenu?: {
|
|
676
|
-
// Pencil icon
|
|
677
|
-
editButton?: {
|
|
678
|
-
// Backend of the pencil icon
|
|
679
|
-
background?: string;
|
|
680
|
-
// Color of the pencil icon
|
|
681
|
-
color?: string;
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
item?: {
|
|
685
|
-
label?: textStyle;
|
|
686
|
-
// Delete & Cancel button
|
|
687
|
-
actionButton?: TextStyle;
|
|
688
|
-
confirmButton?: TextStyle & BlockStyle;
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
interface FontFace {
|
|
695
|
-
fontFamily?: string;
|
|
696
|
-
src?: string;
|
|
697
|
-
unicodeRange?: string;
|
|
698
|
-
fontVariant?: string;
|
|
699
|
-
fontFeatureSettings?: string;
|
|
700
|
-
fontVariationSettings?: string;
|
|
701
|
-
fontStretch?: string;
|
|
702
|
-
fontWeight?: string;
|
|
703
|
-
fontStyle?: string;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
interface Stylesheet {
|
|
707
|
-
href: string;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
interface TextStyle {
|
|
711
|
-
color?: string;
|
|
712
|
-
fontFamily?: string;
|
|
713
|
-
fontWeight?: string;
|
|
714
|
-
fontSize?: string;
|
|
715
|
-
fontSmoothing?: string;
|
|
716
|
-
lineHeight?: string;
|
|
717
|
-
textTransform?: string;
|
|
718
|
-
letterSpacing?: string;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
interface BlockStyle {
|
|
722
|
-
background?: string;
|
|
723
|
-
borderRadius?: number | string;
|
|
724
|
-
boxShadow?: string;
|
|
725
|
-
borderStyle?: string;
|
|
726
|
-
borderColor?: number | string;
|
|
727
|
-
borderWidth?: number | string;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
interface TextAlignmentStyle {
|
|
731
|
-
textAlign?: string;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
type IconColor = 'black' | 'white' | 'color';
|
|
360
|
+
Note that when **disabling** the built-in submit button and using your own custom submit button, it is **required** to implement the `submit()` function in order to notify Universal Checkout of form submissions. <br />
|
|
361
|
+
Read more about the `submit()` function in the [Manual Form Submission](#manual-form-submission) section referenced below.
|
|
735
362
|
|
|
736
|
-
|
|
363
|
+
<br/>
|
|
737
364
|
|
|
738
|
-
|
|
365
|
+
When using your own custom submit button, it's important to use the following callbacks to ensure that your submit button is in the correct state and in sync with the checkout as your customers interact with it:
|
|
739
366
|
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
paddingHorizontal?: number;
|
|
744
|
-
|
|
745
|
-
background?: string;
|
|
746
|
-
borderRadius?: number | string;
|
|
747
|
-
boxShadow?: string;
|
|
748
|
-
|
|
749
|
-
borderStyle?: string;
|
|
750
|
-
borderColor?: number | string;
|
|
751
|
-
borderWidth?: number | string;
|
|
752
|
-
|
|
753
|
-
color?: string;
|
|
754
|
-
fontFamily?: string;
|
|
755
|
-
fontWeight?: string;
|
|
756
|
-
fontSize?: string;
|
|
757
|
-
fontSmoothing?: string;
|
|
758
|
-
lineHeight?: string;
|
|
759
|
-
}
|
|
760
|
-
```
|
|
367
|
+
```javascript
|
|
368
|
+
const options = {
|
|
369
|
+
/* Other options ... */
|
|
761
370
|
|
|
762
|
-
|
|
371
|
+
submitButton: {
|
|
372
|
+
useBuiltInButton: false, // Default to true
|
|
763
373
|
|
|
764
|
-
|
|
374
|
+
// Callback for receiving the submit button's visible state in the current scene
|
|
375
|
+
onVisible(isVisible, context: { currentSceneId }) {
|
|
376
|
+
// Show or hide your custom submit button
|
|
377
|
+
},
|
|
765
378
|
|
|
766
|
-
|
|
379
|
+
// Callback for receiving the submit button's disabled state in the current scene
|
|
380
|
+
onDisable(isDisabled, context: { currentSceneId }) {
|
|
381
|
+
// Disable or enable your custom submit button
|
|
382
|
+
},
|
|
767
383
|
|
|
768
|
-
|
|
384
|
+
// Callback for receiving the submit button's loading state in the current scene
|
|
385
|
+
onLoading(isLoading, context: { currentSceneId }) {
|
|
386
|
+
// Show your submit button in a loading state
|
|
387
|
+
},
|
|
769
388
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
export type CheckSuccessScreenOptions = {
|
|
777
|
-
type: SuccessScreenType.CHECK;
|
|
778
|
-
title: Label;
|
|
389
|
+
// Callback for receiving the submit button's content in the current scene
|
|
390
|
+
onContentChange(content, context: { currentSceneId }) {
|
|
391
|
+
// Set your submit button's content with either the content provided or your own custom content
|
|
392
|
+
},
|
|
393
|
+
},
|
|
779
394
|
};
|
|
395
|
+
```
|
|
780
396
|
|
|
781
|
-
|
|
782
|
-
type: SuccessScreenType.PAYMENT_METHOD;
|
|
783
|
-
};
|
|
397
|
+
<br/>
|
|
784
398
|
|
|
785
|
-
|
|
786
|
-
| /* No success screen will be displayed */ false
|
|
787
|
-
| /* Show the default success screen of the payment method*/ undefined
|
|
788
|
-
// Proposed success screens
|
|
789
|
-
| CheckSuccessScreenOptions
|
|
790
|
-
| PaymentMethodSuccessScreenOptions;
|
|
791
|
-
```
|
|
399
|
+
#### ⚙️ _Processing Indicator Options_
|
|
792
400
|
|
|
793
|
-
|
|
401
|
+
Show a processing indicator overlay on top of the checkout when submitting a form:
|
|
794
402
|
|
|
795
|
-
|
|
403
|
+
| option | Type | Description | Default | |
|
|
404
|
+
| ----------------------------- | ------- | -------------------------------------------------------------------------------- | ------- | -------- |
|
|
405
|
+
| `processingIndicator.visible` | Boolean | Choose whether a processing indicator overlay should be shown on form submission | true | optional |
|
|
796
406
|
|
|
797
|
-
|
|
407
|
+
<br/>
|
|
798
408
|
|
|
799
|
-
|
|
409
|
+
#### ⚙️ _Error Message Options & Callbacks_
|
|
800
410
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
411
|
+
When Universal Checkout encounters errors processing payments, these errors will be shown to your users by default, below the submit button.
|
|
412
|
+
|
|
413
|
+
If you want to show your own error messages, you have the option to disable the default, built-in error messages:
|
|
414
|
+
|
|
415
|
+
| option | Type | Description | Default | |
|
|
416
|
+
| ----------------------- | ------- | ----------------------------------------------------------------- | ------- | -------- |
|
|
417
|
+
| `errorMessage.disabled` | Boolean | Choose whether to allow Universal Checkout to show error messages | false | optional |
|
|
418
|
+
|
|
419
|
+
<br/>
|
|
420
|
+
|
|
421
|
+
You can use the following callbacks to get notified when Universal Checkout intends to display an error message. By using these callbacks, you can respond with your own UI changes and avail a custom error message:
|
|
422
|
+
|
|
423
|
+
```javascript
|
|
424
|
+
const options = {
|
|
425
|
+
/* Other options ... */
|
|
426
|
+
|
|
427
|
+
errorMessage: {
|
|
428
|
+
disabled: false, // Default to false
|
|
429
|
+
|
|
430
|
+
// A callback for when the error message should be displayed
|
|
431
|
+
onErrorMessageShow(message) {
|
|
432
|
+
// Choose to use provided message for own purposes
|
|
816
433
|
},
|
|
817
|
-
nexusAddresses: [
|
|
818
|
-
{
|
|
819
|
-
countryCode: string;
|
|
820
|
-
state: string;
|
|
821
|
-
postalCode: string;
|
|
822
|
-
city: string;
|
|
823
|
-
addressLine1: string;
|
|
824
|
-
},
|
|
825
|
-
],
|
|
826
|
-
},
|
|
827
434
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
customerTaxId: string;
|
|
832
|
-
shippingAddress: {
|
|
833
|
-
countryCode: string;
|
|
834
|
-
state: string;
|
|
835
|
-
postalCode: string;
|
|
836
|
-
city: string;
|
|
837
|
-
addressLine1: string;
|
|
435
|
+
// A callback for when the error message should be hidden
|
|
436
|
+
onErrorMessageHide() {
|
|
437
|
+
// Update own UI accordingly
|
|
838
438
|
},
|
|
839
439
|
},
|
|
440
|
+
};
|
|
441
|
+
```
|
|
840
442
|
|
|
841
|
-
|
|
842
|
-
onTokenizeSuccess: (data: PaymentMethodToken) => void;
|
|
443
|
+
<br/>
|
|
843
444
|
|
|
844
|
-
|
|
845
|
-
onTokenizeStart?: () => void;
|
|
445
|
+
#### ⚙️ _Success Screen Options_
|
|
846
446
|
|
|
847
|
-
|
|
848
|
-
onTokenizeError?: (message: string) => void;
|
|
447
|
+
When the checkout is succefully complete, Universal Checkout displays a success scene with a default success message _"Your payment was successful!"_.
|
|
849
448
|
|
|
850
|
-
|
|
851
|
-
onTokenizeEnd?: () => void;
|
|
449
|
+
Set the option `successScreen` to modify the behavior of the success scene.
|
|
852
450
|
|
|
853
|
-
|
|
854
|
-
|
|
451
|
+
```javascript
|
|
452
|
+
const options = {
|
|
453
|
+
/* Other options ... */
|
|
855
454
|
|
|
856
|
-
//
|
|
857
|
-
|
|
455
|
+
// Remove the success screen
|
|
456
|
+
successScreen: false,
|
|
858
457
|
|
|
859
|
-
//
|
|
860
|
-
|
|
458
|
+
// Change the message of the default success screen
|
|
459
|
+
successScreen: {
|
|
460
|
+
type: 'CHECK',
|
|
461
|
+
title: 'This is a custom success message!',
|
|
462
|
+
},
|
|
463
|
+
};
|
|
464
|
+
```
|
|
861
465
|
|
|
862
|
-
|
|
863
|
-
onClientSessionActions?: (data: ClientSessionActionData) => Promise<{ clientToken: string } | false>;
|
|
466
|
+
---
|
|
864
467
|
|
|
865
|
-
|
|
866
|
-
card?: {
|
|
867
|
-
// The name of the cardholder
|
|
868
|
-
// If a function is set, the function will be called when calling the `tokenize` function
|
|
869
|
-
cardholderName?: string | () => string;
|
|
468
|
+
### 🔨 **Advanced Options**
|
|
870
469
|
|
|
871
|
-
|
|
872
|
-
onChange?: (state: FormState) => void;
|
|
470
|
+
#### ⚙️ _Manual Payment Creation & Tokenization Lifecycle Callbacks_
|
|
873
471
|
|
|
874
|
-
|
|
875
|
-
onCardMetadata?: (meta: CardMetadata) => void;
|
|
472
|
+
By default, Universal Checkout will automatically create payments and manage their lifecycles on your behalf. The manual payment creation flow used in previous Web SDK versions is still supported.
|
|
876
473
|
|
|
877
|
-
|
|
878
|
-
disabled?: () => boolean;
|
|
474
|
+
Check our [Manual Payment Creation guide](https://primer.io/docs/accept-payments/advanced-checkout-configuration/manual).
|
|
879
475
|
|
|
880
|
-
|
|
881
|
-
// For more information see the guide on styling
|
|
882
|
-
css?: string;
|
|
476
|
+
<!--
|
|
883
477
|
|
|
884
|
-
|
|
885
|
-
submitButton: string;
|
|
478
|
+
By default, Universal Checkout will automatically create payments and manage their lifecycles on your behalf.
|
|
886
479
|
|
|
887
|
-
|
|
888
|
-
fields: {
|
|
889
|
-
// Card number field configuration
|
|
890
|
-
cardNumber: CreditCardFieldConfig;
|
|
891
|
-
// Expiry Date field configuration
|
|
892
|
-
expiryDate: CreditCardFieldConfig;
|
|
893
|
-
// CVV field configuration
|
|
894
|
-
cvv: CreditCardFieldConfig;
|
|
895
|
-
};
|
|
896
|
-
};
|
|
480
|
+
The manual payment creation flow used in previous Web SDK versions is still supported. To activate it, make sure to:
|
|
897
481
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
applePay?: { container: string; };
|
|
901
|
-
googlePay?: { container: string; };
|
|
902
|
-
paypal?: { container: string; };
|
|
903
|
-
}
|
|
904
|
-
```
|
|
482
|
+
- set `paymentHandling` to `MANUAL`
|
|
483
|
+
- implement `onTokenizeSuccess` and `onResumeSuccess`
|
|
905
484
|
|
|
906
|
-
|
|
485
|
+
```javascript
|
|
486
|
+
const options = {
|
|
487
|
+
/* Other checkout options ... */
|
|
907
488
|
|
|
908
|
-
|
|
489
|
+
paymentHandling: 'MANUAL',
|
|
909
490
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
// The type of payment method which this token represents
|
|
915
|
-
paymentMethodType: 'PAYMENT_CARD' | 'GOOGLE_PAY' | 'APPLE_PAY' | 'PAYPAL';
|
|
916
|
-
// Additional data about the payment method
|
|
917
|
-
paymentMethodData: object;
|
|
918
|
-
}
|
|
919
|
-
```
|
|
491
|
+
async onTokenizeSuccess(paymentMethodTokenData, handler) {
|
|
492
|
+
// Send the Payment Method Token to your server
|
|
493
|
+
// to create a payment using Payments API
|
|
494
|
+
// const response = await createPayment(paymentMethodTokenData.token);
|
|
920
495
|
|
|
921
|
-
|
|
496
|
+
// Call `handler.handleFailure` to cancel the flow and display an error message
|
|
497
|
+
if (!response) {
|
|
498
|
+
return handler.handleFailure(
|
|
499
|
+
'The payment failed. Please try with another payment method.',
|
|
500
|
+
);
|
|
501
|
+
}
|
|
922
502
|
|
|
923
|
-
|
|
503
|
+
// If a new clientToken is available, call `handler.continueWithNewClientToken` to refresh the client session.
|
|
504
|
+
// The checkout will automatically perform the action required by the Workflow.
|
|
505
|
+
if (response.requiredAction.clientToken) {
|
|
506
|
+
return hander.continueWithNewClientToken(response.requiredAction.clientToken);
|
|
507
|
+
}
|
|
924
508
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
dirty: boolean;
|
|
929
|
-
// Whether any field was been touched
|
|
930
|
-
touched: boolean;
|
|
931
|
-
// Whether any field is active
|
|
932
|
-
active: boolean;
|
|
933
|
-
// Whether all fields are valid
|
|
934
|
-
valid: boolean;
|
|
935
|
-
// Whether the card form was submitted
|
|
936
|
-
submitted: boolean;
|
|
937
|
-
}
|
|
938
|
-
```
|
|
509
|
+
// Display the success screen
|
|
510
|
+
return hander.handleSuccess();
|
|
511
|
+
},
|
|
939
512
|
|
|
940
|
-
|
|
513
|
+
async onResumeSuccess(resumeTokenData, handler) {
|
|
514
|
+
// Send the resume token to your server to resume the payment
|
|
515
|
+
// const response = await resumePayment(resumeTokenData.resumeToken);
|
|
941
516
|
|
|
942
|
-
|
|
517
|
+
// Call `handler.handlehandleFailureError` to cancel the flow and display an error message
|
|
518
|
+
if (!response) {
|
|
519
|
+
return handler.handleFailure(
|
|
520
|
+
'The payment failed. Please try with another payment method.',
|
|
521
|
+
);
|
|
522
|
+
}
|
|
943
523
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
524
|
+
// If a new clientToken is available, call `handler.continueWithNewClientToken` to refresh the client session.
|
|
525
|
+
// The checkout will automatically perform the action required by the Workflow
|
|
526
|
+
if (response.requiredAction.clientToken) {
|
|
527
|
+
return hander.continueWithNewClientToken(response.requiredAction.clientToken);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Display the success screen
|
|
531
|
+
return hander.handleSuccess();
|
|
532
|
+
},
|
|
533
|
+
};
|
|
951
534
|
```
|
|
952
535
|
|
|
953
|
-
|
|
536
|
+
Additional optional callbacks are available:
|
|
954
537
|
|
|
955
|
-
|
|
538
|
+
```javascript
|
|
539
|
+
const options = {
|
|
540
|
+
/* Other checkout options ... */
|
|
956
541
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
542
|
+
async onTokenizeShouldStart({ paymentMethodType }) {
|
|
543
|
+
// Return true if tokenization is allowed to start
|
|
544
|
+
return true;
|
|
545
|
+
|
|
546
|
+
// Return false if tokenization is not allowed to start
|
|
547
|
+
// This is likely to happen if the user has not properly filled in a form owned by you
|
|
548
|
+
return false;
|
|
549
|
+
},
|
|
550
|
+
|
|
551
|
+
onTokenizeDidNotStart(reason) {
|
|
552
|
+
// Tokenization did not start
|
|
553
|
+
|
|
554
|
+
if (reason === 'TOKENIZATION_DISABLED') {
|
|
555
|
+
// Tokenization has been disabled with `setTokenizationEnabled`
|
|
556
|
+
} else if (reason === 'TOKENIZATION_SHOULD_NOT_START') {
|
|
557
|
+
// Tokenization has been disabled by returning false in `onTokenizeShouldStart`
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
onTokenizeStart() {
|
|
562
|
+
// Tokenization has started
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
onResumeError(error) {
|
|
566
|
+
// Resuming has failed
|
|
567
|
+
},
|
|
568
|
+
};
|
|
968
569
|
```
|
|
969
570
|
|
|
970
|
-
|
|
571
|
+
-->
|
|
971
572
|
|
|
972
|
-
|
|
573
|
+
#### ⚙️ _Show the flow for a single payment method_
|
|
973
574
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
// Whether or not the form has been submitted
|
|
987
|
-
submitted: boolean;
|
|
988
|
-
}
|
|
575
|
+
The payment methods featuring a dedicated screen allows you to directly display their flow. For that, make sure to:
|
|
576
|
+
|
|
577
|
+
- Set `uxFlow` to `SINGLE_PAYMENT_METHOD_CHECKOUT`
|
|
578
|
+
- Set `paymentMethod` to the payment method you want to display
|
|
579
|
+
|
|
580
|
+
```javascript
|
|
581
|
+
const options = {
|
|
582
|
+
/* Other options ... */
|
|
583
|
+
|
|
584
|
+
uxFlow: 'SINGLE_PAYMENT_METHOD_CHECKOUT',
|
|
585
|
+
paymentMethod: 'PAYMENT_CARD',
|
|
586
|
+
};
|
|
989
587
|
```
|
|
990
588
|
|
|
991
|
-
|
|
589
|
+
Payment methods that supports this flow
|
|
992
590
|
|
|
993
|
-
|
|
591
|
+
- Card: `PAYMENT_CARD`
|
|
592
|
+
- Klarna: `KLARNA`
|
|
593
|
+
- GoCardless: `GOCARDLESS`
|
|
994
594
|
|
|
995
|
-
|
|
595
|
+
#### ⚙️ _Customizable Payment Method Button options_
|
|
996
596
|
|
|
997
|
-
|
|
597
|
+
Some payment methods enables you to customize the payment method button.
|
|
998
598
|
|
|
999
|
-
|
|
599
|
+
| option | Type | Description | Default | |
|
|
600
|
+
| ------------ | ------ | -------------------------------------------------------------------------------- | ------------------- | -------- |
|
|
601
|
+
| `logoSrc` | String | Data URL representing the logo you want to display in the payment method button. | | required |
|
|
602
|
+
| `background` | String | Color of the background of the payment method button. | | required |
|
|
603
|
+
| `logoAlt` | String | Accessibility marker for the payment method button | | required |
|
|
604
|
+
| `text` | String | Label to display to the right of `logoSrc` | Only show `logoSrc` | optional |
|
|
1000
605
|
|
|
1001
|
-
|
|
606
|
+
Payment methods that supports this flow
|
|
1002
607
|
|
|
1003
|
-
|
|
608
|
+
- Gift Cards with Mollie: `PAYMENT_CARD`
|
|
1004
609
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
amount: {
|
|
1025
|
-
// The sale amount
|
|
1026
|
-
value: number | string;
|
|
1027
|
-
// The alpha3 currency code of the sale
|
|
1028
|
-
currency: string;
|
|
1029
|
-
};
|
|
1030
|
-
|
|
1031
|
-
// The customer's email address
|
|
1032
|
-
email: string;
|
|
1033
|
-
|
|
1034
|
-
billingAddress: {
|
|
1035
|
-
// Billing first name
|
|
1036
|
-
firstName: string;
|
|
1037
|
-
// Billing last name
|
|
1038
|
-
lastName: string;
|
|
1039
|
-
// Street address
|
|
1040
|
-
addressLine1: string;
|
|
1041
|
-
// Extended street address
|
|
1042
|
-
addressLine2?: string
|
|
1043
|
-
// Extended street address
|
|
1044
|
-
addressLine3?: string
|
|
1045
|
-
// City or town
|
|
1046
|
-
city: string;
|
|
1047
|
-
// State, region or province
|
|
1048
|
-
state?: string;
|
|
1049
|
-
// The alpha2 country code of the address
|
|
1050
|
-
countryCode: string;
|
|
1051
|
-
// The postal or zip code
|
|
1052
|
-
postalCode: string;
|
|
1053
|
-
}
|
|
1054
|
-
};
|
|
1055
|
-
}
|
|
610
|
+
## 🔧 <a id="checkout-methods"></a> Checkout Methods
|
|
611
|
+
|
|
612
|
+
Universal Checkout exposes some methods which can be called to perform some specific actions:
|
|
613
|
+
|
|
614
|
+
### **Set Client Token**
|
|
615
|
+
|
|
616
|
+
When updating the client session, after the checkout has been initialized, you will receive a client token in the response returned from `PATCH /client-session`.
|
|
617
|
+
|
|
618
|
+
In order for the checkout to know that you have updated the client session, you will need to pass this new client token back to the checkout:
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
const universalCheckout = await Primer.showUniversalCheckout(
|
|
622
|
+
clientToken,
|
|
623
|
+
options,
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
// Pass the new client token to Universal Checkout by calling setClientToken
|
|
627
|
+
// This will result in Universal Checkout having access to the latest changes made to the client session
|
|
628
|
+
universalCheckout.setClientToken(clientToken);
|
|
1056
629
|
```
|
|
1057
630
|
|
|
1058
|
-
###
|
|
631
|
+
### **Manual Form Submission**
|
|
1059
632
|
|
|
1060
|
-
The
|
|
633
|
+
The checkout provides a method for manually calling submit. This is useful when using your own custom submit button.
|
|
1061
634
|
|
|
1062
|
-
```
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
635
|
+
```javascript
|
|
636
|
+
const universalCheckout = await Primer.showUniversalCheckout(
|
|
637
|
+
clientToken,
|
|
638
|
+
options,
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
const handleMySubmitButtonClick = () => {
|
|
642
|
+
// Forward all submit button clicks to the SDK
|
|
643
|
+
universalCheckout.submit();
|
|
644
|
+
};
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
<br/>
|
|
648
|
+
|
|
649
|
+
### **Disabling Tokenization and Payment Creation**
|
|
650
|
+
|
|
651
|
+
The checkout provides `setPaymentCreationEnabled` and `setTokenizationEnabled` to enable or disable tokenization and payment creation. Use this if you would like to prevent users from paying because your side of the checkout is not valid.
|
|
652
|
+
|
|
653
|
+
These two functions can be used interchangibly.
|
|
654
|
+
|
|
655
|
+
```javascript
|
|
656
|
+
const universalCheckout = await Primer.showUniversalCheckout(
|
|
657
|
+
clientToken,
|
|
658
|
+
options,
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
// Disable payment creation
|
|
662
|
+
universalCheckout.setPaymentCreationEnabled(false);
|
|
663
|
+
universalCheckout.setTokenizationEnabled(false);
|
|
664
|
+
|
|
665
|
+
// Enable payment creation
|
|
666
|
+
universalCheckout.setPaymentCreationEnabled(true);
|
|
667
|
+
universalCheckout.setTokenizationEnabled(true);
|
|
1071
668
|
```
|