@liquidcommerce/cloud-sdk 1.3.0 → 1.4.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/README.md +371 -119
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/liquidcommerce-cloud-sdk.ssr.js +1 -1
- package/dist/types/constants/core.constant.d.ts +8 -0
- package/dist/types/core/cart-helper.service.d.ts +1 -1
- package/dist/types/core/catalog-helper.service.d.ts +24 -4
- package/dist/types/core/checkout-helper.service.d.ts +23 -8
- package/dist/types/core/location-helper.service.d.ts +4 -3
- package/dist/types/core/payment-provider.service.d.ts +16 -1
- package/dist/types/core/singleton.service.d.ts +9 -10
- package/dist/types/{enums.d.ts → enums/enums.d.ts} +62 -92
- package/dist/types/enums/index.d.ts +2 -0
- package/dist/types/enums/taxonomy.d.ts +285 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/interfaces/address.interface.d.ts +86 -1
- package/dist/types/interfaces/cart.interface.d.ts +28 -10
- package/dist/types/interfaces/catalog.interface.d.ts +268 -8
- package/dist/types/interfaces/checkout.interface.d.ts +265 -50
- package/dist/types/interfaces/index.d.ts +8 -0
- package/dist/types/interfaces/liquid-commerce-client.interface.d.ts +34 -9
- package/dist/types/interfaces/payment.interface.d.ts +81 -2
- package/dist/types/interfaces/retailer.interface.d.ts +121 -0
- package/dist/types/interfaces/user.interface.d.ts +115 -8
- package/dist/types/liquid-commerce-client.d.ts +3 -192
- package/dist/types/services/address.service.d.ts +2 -18
- package/dist/types/services/cart.service.d.ts +1 -1
- package/dist/types/services/catalog.service.d.ts +1 -12
- package/dist/types/services/checkout.service.d.ts +1 -1
- package/dist/types/services/index.d.ts +5 -0
- package/dist/types/services/payment.service.d.ts +1 -1
- package/dist/types/services/user.service.d.ts +53 -1
- package/dist/types/types.d.ts +11 -5
- package/package.json +105 -105
- package/umd/liquidcommerce-cloud-sdk.min.js +1 -1
- package/dist/types/interfaces/catalog.service.interface.d.ts +0 -65
package/README.md
CHANGED
|
@@ -7,16 +7,17 @@ The LiquidCommerce Cloud SDK provides an easy way to interact with our APIs thro
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
- [Installation](#installation)
|
|
10
|
-
- [
|
|
10
|
+
- [Configuration](#configuration)
|
|
11
11
|
- [Usage](#usage)
|
|
12
|
-
- [
|
|
12
|
+
- [Services](#services)
|
|
13
13
|
- [Address](#address)
|
|
14
14
|
- [Catalog](#catalog)
|
|
15
15
|
- [Cart](#cart)
|
|
16
16
|
- [User](#user)
|
|
17
17
|
- [Payment](#payment)
|
|
18
18
|
- [Checkout](#checkout)
|
|
19
|
-
- [
|
|
19
|
+
- [Response Types](#response-types)
|
|
20
|
+
- [Error Handling](#error-handling)
|
|
20
21
|
- [Documentation](#documentation)
|
|
21
22
|
|
|
22
23
|
## Installation
|
|
@@ -27,57 +28,88 @@ Install the package with:
|
|
|
27
28
|
npm install @liquidcommerce/cloud-sdk
|
|
28
29
|
# or
|
|
29
30
|
yarn add @liquidcommerce/cloud-sdk
|
|
31
|
+
# or
|
|
32
|
+
pnpm add @liquidcommerce/cloud-sdk
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
The LiquidCommerce library uses API keys to authenticate requests. You can request your keys from your Partnerships liaison.
|
|
35
|
-
|
|
36
|
-
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.
|
|
35
|
+
## Configuration
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
The SDK requires configuration during initialization:
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
```typescript
|
|
40
|
+
import { LiquidCommerce, LIQUID_COMMERCE_ENV } from '@liquidcommerce/cloud-sdk';
|
|
41
41
|
|
|
42
|
-
```javascript
|
|
43
|
-
import LiquidCommerce from '@liquidcommerce/cloud-sdk';
|
|
44
|
-
|
|
45
|
-
// Your Account token provided to you through your account representative
|
|
46
42
|
const client = await LiquidCommerce('YOUR_LIQUIDCOMMERCE_API_KEY', {
|
|
47
|
-
googlePlacesApiKey: 'YOUR_GOOGLE_PLACES_API_KEY',
|
|
48
|
-
env:
|
|
43
|
+
googlePlacesApiKey: 'YOUR_GOOGLE_PLACES_API_KEY', // Required for address services
|
|
44
|
+
env: LIQUID_COMMERCE_ENV.STAGE // STAGE or PROD
|
|
49
45
|
});
|
|
50
46
|
|
|
51
|
-
// Initialize the client
|
|
52
47
|
await client.init();
|
|
53
48
|
```
|
|
54
49
|
|
|
55
|
-
##
|
|
50
|
+
## Response Types
|
|
51
|
+
|
|
52
|
+
All API responses follow a consistent structure:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
interface ApiResponse<T> {
|
|
56
|
+
statusCode: number;
|
|
57
|
+
message: string;
|
|
58
|
+
metadata: {
|
|
59
|
+
languages: string[];
|
|
60
|
+
timestamp: number;
|
|
61
|
+
timezone: string;
|
|
62
|
+
requestId: string;
|
|
63
|
+
path: string;
|
|
64
|
+
version: string;
|
|
65
|
+
};
|
|
66
|
+
data?: T; // Present in responses with data
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Services
|
|
56
71
|
|
|
57
72
|
### Address
|
|
58
73
|
|
|
59
|
-
|
|
74
|
+
Services for address validation and lookup:
|
|
60
75
|
|
|
61
|
-
```
|
|
76
|
+
```typescript
|
|
62
77
|
// Address autocompletion
|
|
63
|
-
const
|
|
78
|
+
const autocompleteResponse = await client.address.autocomplete({
|
|
64
79
|
input: '100 Madison Ave, New York'
|
|
65
80
|
});
|
|
66
81
|
|
|
67
|
-
//
|
|
68
|
-
|
|
82
|
+
// Response type: IApiResponseWithData<IAddressAutocompleteResult[]>
|
|
83
|
+
// {
|
|
84
|
+
// id: string;
|
|
85
|
+
// description: string;
|
|
86
|
+
// }
|
|
87
|
+
|
|
88
|
+
// Get detailed address information
|
|
89
|
+
const detailsResponse = await client.address.details({
|
|
69
90
|
id: 'ChIJd8BlQ2BZwokRjMKtTjMezRw'
|
|
70
91
|
});
|
|
92
|
+
|
|
93
|
+
// Response type: IApiResponseWithData<IAddressDetailsResult>
|
|
94
|
+
// {
|
|
95
|
+
// formattedAddress: string;
|
|
96
|
+
// coords: {
|
|
97
|
+
// lat: number;
|
|
98
|
+
// long: number;
|
|
99
|
+
// }
|
|
100
|
+
// }
|
|
71
101
|
```
|
|
72
102
|
|
|
73
103
|
### Catalog
|
|
74
104
|
|
|
75
|
-
|
|
105
|
+
Product catalog search and availability services:
|
|
76
106
|
|
|
77
|
-
```
|
|
78
|
-
// Check availability
|
|
107
|
+
```typescript
|
|
108
|
+
// Check product availability
|
|
79
109
|
const availabilityResponse = await client.catalog.availability({
|
|
80
|
-
upcs: ['123456789012', '210987654321'],
|
|
110
|
+
upcs: ['123456789012', '210987654321'], // UPC codes
|
|
111
|
+
grouping: ['group1', 'group2'], // Optional group identifiers
|
|
112
|
+
ids: ['id1', 'id2'], // Optional product IDs
|
|
81
113
|
loc: {
|
|
82
114
|
address: {
|
|
83
115
|
one: '123 Main St',
|
|
@@ -89,17 +121,26 @@ const availabilityResponse = await client.catalog.availability({
|
|
|
89
121
|
shouldShowOffHours: true
|
|
90
122
|
});
|
|
91
123
|
|
|
92
|
-
// Search catalog
|
|
93
|
-
const
|
|
124
|
+
// Search catalog with filters
|
|
125
|
+
const searchResponse = await client.catalog.search({
|
|
94
126
|
search: 'whiskey',
|
|
95
|
-
pageToken: '',
|
|
96
127
|
page: 1,
|
|
97
128
|
perPage: 20,
|
|
98
|
-
orderBy:
|
|
99
|
-
orderDirection:
|
|
129
|
+
orderBy: ENUM_ORDER_BY.PRICE,
|
|
130
|
+
orderDirection: ENUM_NAVIGATION_ORDER_DIRECTION_TYPE.ASC,
|
|
100
131
|
filters: [
|
|
101
|
-
{
|
|
102
|
-
|
|
132
|
+
{
|
|
133
|
+
key: ENUM_FILTER_KEYS.CATEGORIES,
|
|
134
|
+
values: [ENUM_SPIRITS.WHISKEY]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: ENUM_FILTER_KEYS.PRICE,
|
|
138
|
+
values: { min: 2000, max: 10000 } // Prices in cents
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: ENUM_FILTER_KEYS.AVAILABILITY,
|
|
142
|
+
values: ENUM_AVAILABILITY_VALUE.IN_STOCK
|
|
143
|
+
}
|
|
103
144
|
],
|
|
104
145
|
loc: {
|
|
105
146
|
address: {
|
|
@@ -114,25 +155,25 @@ const searchResults = await client.catalog.search({
|
|
|
114
155
|
|
|
115
156
|
### Cart
|
|
116
157
|
|
|
117
|
-
|
|
158
|
+
Shopping cart management:
|
|
118
159
|
|
|
119
|
-
```
|
|
120
|
-
//
|
|
121
|
-
const
|
|
160
|
+
```typescript
|
|
161
|
+
// Create new cart
|
|
162
|
+
const newCart = await client.cart.get();
|
|
122
163
|
|
|
123
|
-
//
|
|
124
|
-
const existingCart = await client.cart.get('
|
|
164
|
+
// Retrieve existing cart
|
|
165
|
+
const existingCart = await client.cart.get('cart_id', true); // Second parameter for refresh
|
|
125
166
|
|
|
126
167
|
// Update cart
|
|
127
168
|
const updatedCart = await client.cart.update({
|
|
128
|
-
id: '
|
|
169
|
+
id: 'cart_id',
|
|
129
170
|
items: [
|
|
130
171
|
{
|
|
131
|
-
|
|
132
|
-
partNumber: '123456789012_retailer_id',
|
|
172
|
+
partNumber: '123456789012_retailer_id', // Required: {UPC}_{retailerId}
|
|
133
173
|
quantity: 2,
|
|
134
|
-
|
|
135
|
-
|
|
174
|
+
fulfillmentId: 'fulfillment_id',
|
|
175
|
+
engravingLines: ['Line 1', 'Line 2'], // Optional
|
|
176
|
+
scheduledFor: '2024-12-25', // Optional
|
|
136
177
|
}
|
|
137
178
|
],
|
|
138
179
|
loc: {
|
|
@@ -142,154 +183,365 @@ const updatedCart = await client.cart.update({
|
|
|
142
183
|
state: 'NY',
|
|
143
184
|
zip: '10001'
|
|
144
185
|
}
|
|
145
|
-
}
|
|
186
|
+
},
|
|
187
|
+
promoCode: 'DISCOUNT10', // Optional
|
|
188
|
+
giftCards: ['GC123456'] // Optional
|
|
146
189
|
});
|
|
147
190
|
```
|
|
148
191
|
|
|
149
192
|
### User
|
|
150
193
|
|
|
151
|
-
|
|
194
|
+
User profile and preferences management:
|
|
152
195
|
|
|
153
|
-
```
|
|
154
|
-
// Create
|
|
196
|
+
```typescript
|
|
197
|
+
// Create/update user session
|
|
155
198
|
const userSession = await client.user.session({
|
|
156
199
|
email: "user@example.com",
|
|
157
|
-
firstName: "John"
|
|
200
|
+
firstName: "John",
|
|
201
|
+
lastName: "Smith",
|
|
202
|
+
phone: "2125551234",
|
|
203
|
+
company: "Company Inc",
|
|
204
|
+
profileImage: "https://...",
|
|
205
|
+
birthDate: "1990-01-01"
|
|
158
206
|
});
|
|
159
207
|
|
|
160
|
-
//
|
|
208
|
+
// Fetch user by ID or email
|
|
209
|
+
const userData = await client.user.fetch('user_id_or_email');
|
|
210
|
+
|
|
211
|
+
// Address management
|
|
161
212
|
const newAddress = await client.user.addAddress({
|
|
162
|
-
customerId: '
|
|
213
|
+
customerId: 'customer_id',
|
|
214
|
+
placesId: 'google_places_id', // Optional if providing address details
|
|
163
215
|
one: '100 Madison St',
|
|
216
|
+
two: 'Apt 4B',
|
|
164
217
|
city: 'New York',
|
|
165
218
|
state: 'NY',
|
|
166
219
|
zip: '10004',
|
|
167
|
-
|
|
220
|
+
country: 'US',
|
|
221
|
+
lat: 40.7128, // Optional
|
|
222
|
+
long: -74.0060, // Optional
|
|
223
|
+
type: ENUM_ADDRESS_TYPE.SHIPPING,
|
|
168
224
|
isDefault: true
|
|
169
225
|
});
|
|
170
226
|
|
|
171
|
-
// Update an existing address
|
|
172
227
|
const updatedAddress = await client.user.updateAddress({
|
|
173
|
-
|
|
174
|
-
one: '101 Madison St',
|
|
175
|
-
city: 'New York',
|
|
176
|
-
state: 'NY',
|
|
177
|
-
zip: '10004',
|
|
178
|
-
type: 'shipping',
|
|
179
|
-
isDefault: true
|
|
228
|
+
// Same parameters as addAddress
|
|
180
229
|
});
|
|
181
230
|
|
|
182
|
-
//
|
|
231
|
+
// Payment methods
|
|
183
232
|
const newPayment = await client.user.addPayment({
|
|
184
|
-
customerId: '
|
|
185
|
-
paymentMethodId: '
|
|
233
|
+
customerId: 'customer_id',
|
|
234
|
+
paymentMethodId: 'payment_method_id',
|
|
186
235
|
isDefault: true
|
|
187
236
|
});
|
|
188
237
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// Purge user address
|
|
196
|
-
const addressPurgeResponse = await client.user.purgeAddress('26af8958-0deb-44ec-b9fd-ca150b198e45');
|
|
238
|
+
const updatedPayment = await client.user.updatePayment({
|
|
239
|
+
customerId: 'customer_id',
|
|
240
|
+
paymentMethodId: 'payment_method_id',
|
|
241
|
+
isDefault: true // Required for updates
|
|
242
|
+
});
|
|
197
243
|
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
244
|
+
// Data removal
|
|
245
|
+
await client.user.purge('user_id_or_email');
|
|
246
|
+
await client.user.purgeAddress('address_id');
|
|
247
|
+
await client.user.purgePayment('customer_id', 'payment_id');
|
|
203
248
|
```
|
|
204
249
|
|
|
205
250
|
### Payment
|
|
206
251
|
|
|
207
|
-
The
|
|
252
|
+
The payment system uses secure elements for handling sensitive payment data. Before using payment features, you must first create a user session.
|
|
208
253
|
|
|
209
|
-
|
|
210
|
-
|
|
254
|
+
#### Prerequisites
|
|
255
|
+
|
|
256
|
+
1. User Session Creation:
|
|
257
|
+
```typescript
|
|
258
|
+
// First create or get a user session
|
|
259
|
+
const userSession = await client.user.session({
|
|
260
|
+
email: "user@example.com",
|
|
261
|
+
// ... other user details
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// The session response includes necessary payment credentials
|
|
265
|
+
const { setupIntent, publicKey } = userSession.data.session;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### Payment Element Integration
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// Initialize payment form using session credentials
|
|
211
272
|
await client.payment.mount({
|
|
212
|
-
clientSecret:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
273
|
+
clientSecret: userSession.data.session.setupIntent, // Required: from session
|
|
274
|
+
key: userSession.data.session.publicKey, // Required: from session
|
|
275
|
+
elementId: 'payment-element-container', // Your DOM element ID
|
|
276
|
+
appearance: {
|
|
277
|
+
theme: 'night' // 'default' | 'night' | 'flat'
|
|
278
|
+
},
|
|
279
|
+
elementOptions: {
|
|
280
|
+
layout: 'tabs' // 'tabs' | 'accordion' | 'auto'
|
|
281
|
+
}
|
|
216
282
|
});
|
|
217
283
|
|
|
218
|
-
//
|
|
219
|
-
|
|
284
|
+
// Monitor payment element state
|
|
285
|
+
client.payment.subscribe('ready', () => {
|
|
286
|
+
// Element is ready to accept input
|
|
287
|
+
});
|
|
220
288
|
|
|
221
|
-
// Subscribe to payment events
|
|
222
289
|
client.payment.subscribe('change', (event) => {
|
|
223
|
-
|
|
290
|
+
const { complete, empty, value } = event;
|
|
291
|
+
// Handle validation state changes
|
|
224
292
|
});
|
|
225
293
|
|
|
226
|
-
//
|
|
227
|
-
client.payment.
|
|
294
|
+
// Process payment when ready
|
|
295
|
+
const tokenResult = await client.payment.generateToken();
|
|
228
296
|
|
|
229
|
-
//
|
|
230
|
-
|
|
297
|
+
// Handle the result
|
|
298
|
+
if ('error' in tokenResult) {
|
|
299
|
+
const { type, message, code } = tokenResult.error;
|
|
300
|
+
// type can be: 'validation_error' | 'api_error' | 'client_error' | 'confirm_error'
|
|
301
|
+
} else {
|
|
302
|
+
// Use tokenResult.id for checkout completion or saving payment method
|
|
303
|
+
const { id, card } = tokenResult;
|
|
304
|
+
}
|
|
231
305
|
|
|
232
|
-
//
|
|
306
|
+
// Always clean up when done
|
|
233
307
|
client.payment.unmount();
|
|
234
|
-
|
|
235
|
-
// Destroy the payment element
|
|
236
308
|
client.payment.destroy();
|
|
237
309
|
```
|
|
238
310
|
|
|
311
|
+
#### Security Considerations
|
|
312
|
+
|
|
313
|
+
1. **PCI Compliance**: The payment element handles card data securely within an iframe, ensuring your application never directly touches sensitive payment information.
|
|
314
|
+
|
|
315
|
+
2. **Token-Based**: All payment data is tokenized - you only receive secure tokens that can't be used to retrieve the original card details.
|
|
316
|
+
|
|
317
|
+
3. **Single Use**: Payment tokens are single-use and expire after a short time period.
|
|
318
|
+
|
|
319
|
+
4. **Domain Validation**: Payment elements will only work on domains that have been pre-registered with your account.
|
|
320
|
+
|
|
321
|
+
#### Best Practices
|
|
322
|
+
|
|
323
|
+
1. **Error Handling**: Always implement proper error handling:
|
|
324
|
+
```typescript
|
|
325
|
+
try {
|
|
326
|
+
const token = await client.payment.generateToken();
|
|
327
|
+
if ('error' in token) {
|
|
328
|
+
switch(token.error.type) {
|
|
329
|
+
case 'validation_error':
|
|
330
|
+
// Handle invalid card data
|
|
331
|
+
break;
|
|
332
|
+
case 'api_error':
|
|
333
|
+
// Handle API/network issues
|
|
334
|
+
break;
|
|
335
|
+
case 'client_error':
|
|
336
|
+
// Handle setup/configuration issues
|
|
337
|
+
break;
|
|
338
|
+
case 'confirm_error':
|
|
339
|
+
// Handle payment confirmation failures
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
} catch (error) {
|
|
344
|
+
// Handle unexpected errors
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
2. **Cleanup**: Always clean up payment elements when done:
|
|
349
|
+
- When navigation away from payment page
|
|
350
|
+
- After successful payment
|
|
351
|
+
- After failed payment attempt
|
|
352
|
+
- Before unmounting payment component
|
|
353
|
+
|
|
354
|
+
3. **Event Handling**: Monitor element state for better user experience:
|
|
355
|
+
```typescript
|
|
356
|
+
client.payment.subscribe('change', (event) => {
|
|
357
|
+
// Update UI based on validation state
|
|
358
|
+
const { complete, empty } = event;
|
|
359
|
+
submitButton.disabled = !complete || empty;
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
client.payment.subscribe('loaderror', (event) => {
|
|
363
|
+
// Handle element loading failures
|
|
364
|
+
console.error('Payment element failed:', event.error);
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### Responsive Design
|
|
369
|
+
|
|
370
|
+
The payment element automatically adapts to:
|
|
371
|
+
- Mobile and desktop viewports
|
|
372
|
+
- Right-to-left languages
|
|
373
|
+
- Dark/light themes
|
|
374
|
+
- Different container sizes
|
|
375
|
+
|
|
376
|
+
#### Testing Cards
|
|
377
|
+
|
|
378
|
+
When testing payments in staging environment, use these test cards:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
// Test Visa Card
|
|
382
|
+
Card Number: 4242 4242 4242 4242
|
|
383
|
+
Expiry: Any future date
|
|
384
|
+
CVC: Any 3 digits
|
|
385
|
+
ZIP: Any 5 digits
|
|
386
|
+
|
|
387
|
+
// Test Mastercard
|
|
388
|
+
Card Number: 5555 5555 5555 4444
|
|
389
|
+
Expiry: Any future date
|
|
390
|
+
CVC: Any 3 digits
|
|
391
|
+
ZIP: Any 5 digits
|
|
392
|
+
|
|
393
|
+
// Example test card usage:
|
|
394
|
+
/*
|
|
395
|
+
Card: 4242 4242 4242 4242
|
|
396
|
+
Expiry: 12/29
|
|
397
|
+
CVC: 123
|
|
398
|
+
ZIP: 10001
|
|
399
|
+
*/
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
These cards will be accepted in test mode and will simulate successful payments. They should only be used in the staging environment, never in production.
|
|
403
|
+
|
|
404
|
+
**Important Notes:**
|
|
405
|
+
- These cards work only in test/staging environment
|
|
406
|
+
- Real cards will be declined in test mode
|
|
407
|
+
- Test cards will be declined in production
|
|
408
|
+
- All test transactions use simulated funds
|
|
409
|
+
- Use test credentials in staging environment
|
|
410
|
+
- Never use production credentials in development
|
|
411
|
+
- Test all error scenarios
|
|
412
|
+
- Verify proper cleanup implementation
|
|
413
|
+
- Test on multiple devices and browsers
|
|
414
|
+
|
|
239
415
|
### Checkout
|
|
240
416
|
|
|
241
|
-
|
|
417
|
+
Checkout process management:
|
|
242
418
|
|
|
243
|
-
```
|
|
419
|
+
```typescript
|
|
244
420
|
// Prepare checkout
|
|
245
421
|
const preparedCheckout = await client.checkout.prepare({
|
|
246
|
-
cartId: "
|
|
247
|
-
|
|
248
|
-
|
|
422
|
+
cartId: "cart_id",
|
|
423
|
+
customer: {
|
|
424
|
+
id: "customer_id", // Optional
|
|
425
|
+
email: "customer@example.com",
|
|
426
|
+
firstName: "John",
|
|
249
427
|
lastName: "Smith",
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
birthDate: "11-22-1998",
|
|
253
|
-
hasAgeVerify: false
|
|
428
|
+
phone: "2125551234",
|
|
429
|
+
birthDate: "1990-01-01"
|
|
254
430
|
},
|
|
431
|
+
hasAgeVerify: true,
|
|
255
432
|
billingAddress: {
|
|
256
|
-
firstName: "
|
|
433
|
+
firstName: "John",
|
|
257
434
|
lastName: "Smith",
|
|
258
|
-
email: "
|
|
259
|
-
phone: "
|
|
260
|
-
one: "
|
|
435
|
+
email: "billing@example.com",
|
|
436
|
+
phone: "2125551234",
|
|
437
|
+
one: "123 Main St",
|
|
438
|
+
two: "Apt 4B",
|
|
261
439
|
city: "New York",
|
|
262
440
|
state: "NY",
|
|
263
|
-
zip: "
|
|
441
|
+
zip: "10001",
|
|
442
|
+
country: "US"
|
|
264
443
|
},
|
|
265
444
|
hasSubstitutionPolicy: true,
|
|
266
|
-
isGift:
|
|
445
|
+
isGift: true,
|
|
267
446
|
billingSameAsShipping: false,
|
|
447
|
+
giftOptions: {
|
|
448
|
+
message: "Happy Birthday!",
|
|
449
|
+
recipient: {
|
|
450
|
+
name: "Jane Smith",
|
|
451
|
+
email: "jane@example.com",
|
|
452
|
+
phone: "2125555678"
|
|
453
|
+
}
|
|
454
|
+
},
|
|
268
455
|
marketingPreferences: {
|
|
269
456
|
canEmail: true,
|
|
270
457
|
canSms: true
|
|
271
458
|
},
|
|
272
459
|
deliveryTips: [
|
|
273
460
|
{
|
|
274
|
-
fulfillmentId: "
|
|
275
|
-
tip:
|
|
461
|
+
fulfillmentId: "fulfillment_id",
|
|
462
|
+
tip: 500 // Amount in cents
|
|
276
463
|
}
|
|
277
|
-
]
|
|
464
|
+
],
|
|
465
|
+
acceptedAccountCreation: true,
|
|
466
|
+
scheduledDelivery: "2024-12-25T14:00:00Z"
|
|
278
467
|
});
|
|
279
468
|
|
|
280
469
|
// Complete checkout
|
|
281
470
|
const completedCheckout = await client.checkout.complete({
|
|
282
|
-
token:
|
|
283
|
-
payment: "
|
|
471
|
+
token: preparedCheckout.token,
|
|
472
|
+
payment: "payment_token"
|
|
473
|
+
});
|
|
474
|
+
```_
|
|
475
|
+
|
|
476
|
+
#### Checkout Payment
|
|
477
|
+
|
|
478
|
+
For direct checkout payments, the flow is similar but uses the checkout session:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
// 1. First prepare the checkout
|
|
482
|
+
const preparedCheckout = await client.checkout.prepare({
|
|
483
|
+
cartId: "cart_id",
|
|
484
|
+
// ... other checkout details
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// 2. Initialize payment form with checkout data
|
|
488
|
+
await client.payment.mount({
|
|
489
|
+
clientSecret: preparedCheckout.payment.clientSecret, // From checkout prepare response
|
|
490
|
+
key: preparedCheckout.payment.publicKey, // From checkout prepare response
|
|
491
|
+
elementId: 'payment-element-container',
|
|
492
|
+
appearance: { theme: 'night' },
|
|
493
|
+
elementOptions: { layout: 'tabs' }
|
|
284
494
|
});
|
|
495
|
+
|
|
496
|
+
// 3. Handle payment element events
|
|
497
|
+
client.payment.subscribe('change', (event) => {
|
|
498
|
+
// Monitor payment form state
|
|
499
|
+
const { complete, empty, value } = event;
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
// 4. When ready to complete checkout, generate payment token
|
|
503
|
+
const tokenResult = await client.payment.generateToken();
|
|
504
|
+
if (!('error' in tokenResult)) {
|
|
505
|
+
// 5. Complete checkout with payment token
|
|
506
|
+
const completedCheckout = await client.checkout.complete({
|
|
507
|
+
token: preparedCheckout.token,
|
|
508
|
+
payment: tokenResult.id
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// 6. Clean up
|
|
513
|
+
client.payment.unmount();
|
|
514
|
+
client.payment.destroy();
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Error Handling
|
|
518
|
+
|
|
519
|
+
The SDK throws errors for various scenarios. Always wrap SDK calls in try-catch blocks:
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
try {
|
|
523
|
+
const result = await client.someMethod();
|
|
524
|
+
} catch (error) {
|
|
525
|
+
console.error('Operation failed:', error.message);
|
|
526
|
+
// Handle specific error cases
|
|
527
|
+
}
|
|
285
528
|
```
|
|
286
529
|
|
|
287
|
-
|
|
530
|
+
Common error scenarios:
|
|
531
|
+
- Authentication failures
|
|
532
|
+
- Invalid parameters
|
|
533
|
+
- Network errors
|
|
534
|
+
- Resource not found
|
|
535
|
+
- Rate limiting
|
|
536
|
+
- Validation errors
|
|
288
537
|
|
|
289
|
-
## Price
|
|
538
|
+
## Price Handling
|
|
290
539
|
|
|
291
|
-
All
|
|
540
|
+
All monetary values in the SDK are handled in cents (the smallest currency unit). For example:
|
|
541
|
+
- $10.00 is represented as 1000
|
|
542
|
+
- $5.99 is represented as 599
|
|
543
|
+
- $0.50 is represented as 50
|
|
292
544
|
|
|
293
545
|
## Documentation
|
|
294
546
|
|
|
295
|
-
For more detailed information about each method and its parameters, please refer to our [official documentation](https://docs.liquidcommerce.
|
|
547
|
+
For more detailed information about each method and its parameters, please refer to our [official documentation](https://docs.liquidcommerce.cloud).
|