@liquidcommerce/cloud-sdk 1.6.0 → 1.8.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 +285 -103
- 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/core/authenticated.service.d.ts +6 -38
- package/dist/types/core/catalog-helper.service.d.ts +18 -5
- package/dist/types/core/checkout-helper.service.d.ts +9 -1
- package/dist/types/core/index.d.ts +3 -0
- package/dist/types/core/order-authenticated.service.d.ts +89 -0
- package/dist/types/core/order-singleton.service.d.ts +62 -0
- package/dist/types/core/payment-session-helper.service.d.ts +12 -0
- package/dist/types/core/singleton.service.d.ts +23 -3
- package/dist/types/core/utils.d.ts +48 -0
- package/dist/types/enums/enums.d.ts +70 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.umd.d.ts +2 -2
- package/dist/types/interfaces/address.interface.d.ts +2 -0
- package/dist/types/interfaces/cart.interface.d.ts +5 -15
- package/dist/types/interfaces/catalog.interface.d.ts +54 -6
- package/dist/types/interfaces/checkout.interface.d.ts +52 -57
- package/dist/types/interfaces/index.d.ts +3 -0
- package/dist/types/interfaces/liquid-commerce-client.interface.d.ts +83 -4
- package/dist/types/interfaces/liquid-commerce-order-client.interface.d.ts +54 -0
- package/dist/types/interfaces/order.interface.d.ts +197 -0
- package/dist/types/interfaces/payment-element.interface.d.ts +88 -0
- package/dist/types/interfaces/payment.interface.d.ts +11 -1
- package/dist/types/interfaces/retailer.interface.d.ts +2 -0
- package/dist/types/interfaces/user.interface.d.ts +13 -9
- package/dist/types/liquid-commerce-order-client.d.ts +19 -0
- package/dist/types/liquid-commerce-payment-element.d.ts +10 -0
- package/dist/types/services/index.d.ts +3 -0
- package/dist/types/services/order.service.d.ts +15 -0
- package/dist/types/services/user.service.d.ts +22 -4
- package/dist/types/services/webhook.service.d.ts +14 -0
- package/dist/types/types.d.ts +9 -0
- package/package.json +4 -4
- package/umd/liquidcommerce-cloud-sdk.min.js +1 -1
package/README.md
CHANGED
|
@@ -14,14 +14,18 @@ The LiquidCommerce Cloud SDK provides an easy way to interact with our APIs thro
|
|
|
14
14
|
|
|
15
15
|
- [Installation](#installation)
|
|
16
16
|
- [Configuration](#configuration)
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
17
|
+
- [API Key Authentication](#api-key-authentication)
|
|
18
|
+
- [Order API Authentication](#order-api-authentication)
|
|
19
|
+
- [Services & Usage](#services-and-usage)
|
|
19
20
|
- [Address](#address)
|
|
20
21
|
- [Catalog](#catalog)
|
|
21
22
|
- [Cart](#cart)
|
|
22
23
|
- [User](#user)
|
|
23
|
-
- [Payment](#payment)
|
|
24
|
+
- [Payment Element](#payment-element)
|
|
25
|
+
- [Legacy Payment](#legacy-payment)
|
|
24
26
|
- [Checkout](#checkout)
|
|
27
|
+
- [Order](#order)
|
|
28
|
+
- [Webhook](#webhook)
|
|
25
29
|
- [Response Types](#response-types)
|
|
26
30
|
- [Error Handling](#error-handling)
|
|
27
31
|
- [Documentation](#documentation)
|
|
@@ -40,19 +44,40 @@ pnpm add @liquidcommerce/cloud-sdk
|
|
|
40
44
|
|
|
41
45
|
## Configuration
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
### API Key Authentication
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
The LiquidCommerce API Key Authentication provides a secure method to obtain an access token for all other API calls to LiquidCommerce Services.
|
|
50
|
+
|
|
51
|
+
Example using LiquidCommerce client:
|
|
47
52
|
|
|
53
|
+
```typescript
|
|
54
|
+
// The SDK automatically handles authentication
|
|
48
55
|
const client = await LiquidCommerce('YOUR_LIQUIDCOMMERCE_API_KEY', {
|
|
49
56
|
googlePlacesApiKey: 'YOUR_GOOGLE_PLACES_API_KEY', // Required for address services
|
|
50
|
-
env: LIQUID_COMMERCE_ENV.STAGE //
|
|
57
|
+
env: LIQUID_COMMERCE_ENV.STAGE, // or PROD
|
|
51
58
|
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
[Click Here For Manual Authentication](https://docs.liquidcommerce.cloud/authentication-api-integration/get-access-token)
|
|
62
|
+
|
|
63
|
+
### Order API Authentication
|
|
64
|
+
|
|
65
|
+
LiquidCommerce provides a separate authentication mechanism for Order API endpoints. The Order client uses Basic Authentication with a username and password.
|
|
52
66
|
|
|
53
|
-
|
|
67
|
+
Example using LiquidCommerceOrders client:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const orderClient = await LiquidCommerceOrders({
|
|
71
|
+
userID: 'YOUR_ORDER_API_USER_ID',
|
|
72
|
+
password: 'YOUR_ORDER_API_PASSWORD',
|
|
73
|
+
env: LIQUID_COMMERCE_ENV.STAGE, // or PROD
|
|
74
|
+
});
|
|
54
75
|
```
|
|
55
76
|
|
|
77
|
+
[Click Here For Manual Authentication](https://docs.liquidcommerce.cloud/services/orders-api/authentication)
|
|
78
|
+
|
|
79
|
+
Note: Order authentication credentials are required to access Order API. The SDK will return appropriate authentication errors if these credentials are missing or invalid.
|
|
80
|
+
|
|
56
81
|
## Response Types
|
|
57
82
|
|
|
58
83
|
All API responses follow a consistent structure:
|
|
@@ -73,7 +98,7 @@ interface ApiResponse<T> {
|
|
|
73
98
|
}
|
|
74
99
|
```
|
|
75
100
|
|
|
76
|
-
## Services
|
|
101
|
+
## Services and Usage
|
|
77
102
|
|
|
78
103
|
### Address
|
|
79
104
|
|
|
@@ -82,7 +107,7 @@ Services for address validation and lookup:
|
|
|
82
107
|
```typescript
|
|
83
108
|
// Address autocompletion
|
|
84
109
|
const autocompleteResponse = await client.address.autocomplete({
|
|
85
|
-
input: '100 Madison Ave, New York'
|
|
110
|
+
input: '100 Madison Ave, New York',
|
|
86
111
|
});
|
|
87
112
|
|
|
88
113
|
// Response type: IApiResponseWithData<IAddressAutocompleteResult[]>
|
|
@@ -93,7 +118,7 @@ const autocompleteResponse = await client.address.autocomplete({
|
|
|
93
118
|
|
|
94
119
|
// Get detailed address information
|
|
95
120
|
const detailsResponse = await client.address.details({
|
|
96
|
-
id: 'ChIJd8BlQ2BZwokRjMKtTjMezRw'
|
|
121
|
+
id: 'ChIJd8BlQ2BZwokRjMKtTjMezRw',
|
|
97
122
|
});
|
|
98
123
|
|
|
99
124
|
// Response type: IApiResponseWithData<IAddressDetailsResult>
|
|
@@ -103,6 +128,14 @@ const detailsResponse = await client.address.details({
|
|
|
103
128
|
// lat: number;
|
|
104
129
|
// long: number;
|
|
105
130
|
// }
|
|
131
|
+
// address: {
|
|
132
|
+
// one: string,
|
|
133
|
+
// two: string,
|
|
134
|
+
// city": string,
|
|
135
|
+
// state: string,
|
|
136
|
+
// zip: string,
|
|
137
|
+
// country: "US"
|
|
138
|
+
// }
|
|
106
139
|
// }
|
|
107
140
|
```
|
|
108
141
|
|
|
@@ -121,41 +154,43 @@ const availabilityResponse = await client.catalog.availability({
|
|
|
121
154
|
one: '123 Main St',
|
|
122
155
|
city: 'New York',
|
|
123
156
|
state: 'NY',
|
|
124
|
-
zip: '10001'
|
|
125
|
-
}
|
|
157
|
+
zip: '10001',
|
|
158
|
+
},
|
|
126
159
|
},
|
|
127
|
-
shouldShowOffHours: true
|
|
160
|
+
shouldShowOffHours: true,
|
|
128
161
|
});
|
|
129
162
|
|
|
130
163
|
// Search catalog with filters
|
|
131
164
|
const searchResponse = await client.catalog.search({
|
|
132
165
|
search: 'whiskey',
|
|
166
|
+
pageToken: '',
|
|
167
|
+
entity: '',
|
|
133
168
|
page: 1,
|
|
134
169
|
perPage: 20,
|
|
135
170
|
orderBy: ENUM_ORDER_BY.PRICE,
|
|
136
171
|
orderDirection: ENUM_NAVIGATION_ORDER_DIRECTION_TYPE.ASC,
|
|
137
172
|
filters: [
|
|
138
|
-
{
|
|
139
|
-
key: ENUM_FILTER_KEYS.CATEGORIES,
|
|
140
|
-
values: [ENUM_SPIRITS.WHISKEY]
|
|
173
|
+
{
|
|
174
|
+
key: ENUM_FILTER_KEYS.CATEGORIES,
|
|
175
|
+
values: [ENUM_SPIRITS.WHISKEY],
|
|
141
176
|
},
|
|
142
|
-
{
|
|
143
|
-
key: ENUM_FILTER_KEYS.PRICE,
|
|
144
|
-
values: { min: 2000, max: 10000 } // Prices in cents
|
|
177
|
+
{
|
|
178
|
+
key: ENUM_FILTER_KEYS.PRICE,
|
|
179
|
+
values: { min: 2000, max: 10000 }, // Prices in cents
|
|
145
180
|
},
|
|
146
181
|
{
|
|
147
182
|
key: ENUM_FILTER_KEYS.AVAILABILITY,
|
|
148
|
-
values: ENUM_AVAILABILITY_VALUE.IN_STOCK
|
|
149
|
-
}
|
|
183
|
+
values: ENUM_AVAILABILITY_VALUE.IN_STOCK,
|
|
184
|
+
},
|
|
150
185
|
],
|
|
151
186
|
loc: {
|
|
152
187
|
address: {
|
|
153
188
|
one: '123 Main St',
|
|
154
189
|
city: 'New York',
|
|
155
190
|
state: 'NY',
|
|
156
|
-
zip: '10001'
|
|
157
|
-
}
|
|
158
|
-
}
|
|
191
|
+
zip: '10001',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
159
194
|
});
|
|
160
195
|
```
|
|
161
196
|
|
|
@@ -180,18 +215,18 @@ const updatedCart = await client.cart.update({
|
|
|
180
215
|
fulfillmentId: 'fulfillment_id',
|
|
181
216
|
engravingLines: ['Line 1', 'Line 2'], // Optional
|
|
182
217
|
scheduledFor: '2024-12-25', // Optional
|
|
183
|
-
}
|
|
218
|
+
},
|
|
184
219
|
],
|
|
185
220
|
loc: {
|
|
186
221
|
address: {
|
|
187
222
|
one: '123 Main St',
|
|
188
223
|
city: 'New York',
|
|
189
224
|
state: 'NY',
|
|
190
|
-
zip: '10001'
|
|
191
|
-
}
|
|
225
|
+
zip: '10001',
|
|
226
|
+
},
|
|
192
227
|
},
|
|
193
228
|
promoCode: 'DISCOUNT10', // Optional
|
|
194
|
-
giftCards: ['GC123456'] // Optional
|
|
229
|
+
giftCards: ['GC123456'], // Optional
|
|
195
230
|
});
|
|
196
231
|
```
|
|
197
232
|
|
|
@@ -202,13 +237,14 @@ User profile and preferences management:
|
|
|
202
237
|
```typescript
|
|
203
238
|
// Create/update user session
|
|
204
239
|
const userSession = await client.user.session({
|
|
205
|
-
email:
|
|
206
|
-
firstName:
|
|
207
|
-
lastName:
|
|
208
|
-
phone:
|
|
209
|
-
company:
|
|
210
|
-
profileImage:
|
|
211
|
-
birthDate:
|
|
240
|
+
email: 'user@example.com',
|
|
241
|
+
firstName: 'John',
|
|
242
|
+
lastName: 'Smith',
|
|
243
|
+
phone: '2125551234',
|
|
244
|
+
company: 'Company Inc',
|
|
245
|
+
profileImage: 'https://...',
|
|
246
|
+
birthDate: '1990-01-01',
|
|
247
|
+
id: 'user_id', // Existing user identifier (for updates only), email becomes optional
|
|
212
248
|
});
|
|
213
249
|
|
|
214
250
|
// Fetch user by ID or email
|
|
@@ -216,7 +252,7 @@ const userData = await client.user.fetch('user_id_or_email');
|
|
|
216
252
|
|
|
217
253
|
// Address management
|
|
218
254
|
const newAddress = await client.user.addAddress({
|
|
219
|
-
|
|
255
|
+
userId: 'user_id',
|
|
220
256
|
placesId: 'google_places_id', // Optional if providing address details
|
|
221
257
|
one: '100 Madison St',
|
|
222
258
|
two: 'Apt 4B',
|
|
@@ -225,9 +261,9 @@ const newAddress = await client.user.addAddress({
|
|
|
225
261
|
zip: '10004',
|
|
226
262
|
country: 'US',
|
|
227
263
|
lat: 40.7128, // Optional
|
|
228
|
-
long: -74.
|
|
264
|
+
long: -74.006, // Optional
|
|
229
265
|
type: ENUM_ADDRESS_TYPE.SHIPPING,
|
|
230
|
-
isDefault: true
|
|
266
|
+
isDefault: true,
|
|
231
267
|
});
|
|
232
268
|
|
|
233
269
|
const updatedAddress = await client.user.updateAddress({
|
|
@@ -238,13 +274,13 @@ const updatedAddress = await client.user.updateAddress({
|
|
|
238
274
|
const newPayment = await client.user.addPayment({
|
|
239
275
|
customerId: 'customer_id',
|
|
240
276
|
paymentMethodId: 'payment_method_id',
|
|
241
|
-
isDefault: true
|
|
277
|
+
isDefault: true,
|
|
242
278
|
});
|
|
243
279
|
|
|
244
280
|
const updatedPayment = await client.user.updatePayment({
|
|
245
281
|
customerId: 'customer_id',
|
|
246
282
|
paymentMethodId: 'payment_method_id',
|
|
247
|
-
isDefault: true // Required for updates
|
|
283
|
+
isDefault: true, // Required for updates
|
|
248
284
|
});
|
|
249
285
|
|
|
250
286
|
// Data removal
|
|
@@ -253,17 +289,117 @@ await client.user.purgeAddress('address_id');
|
|
|
253
289
|
await client.user.purgePayment('customer_id', 'payment_id');
|
|
254
290
|
```
|
|
255
291
|
|
|
256
|
-
### Payment
|
|
292
|
+
### Payment Element
|
|
257
293
|
|
|
258
|
-
The
|
|
294
|
+
The Payment Element is a secure and modern UI component for collecting payment details. It simplifies PCI compliance by handling all sensitive information within an iframe.
|
|
259
295
|
|
|
260
296
|
#### Prerequisites
|
|
261
297
|
|
|
262
|
-
|
|
298
|
+
Before mounting the Payment Element, you must create a payment session. This can be tied to a user, cart, or checkout.
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// Create a payment session to get a client secret
|
|
302
|
+
const paymentSession = await client.user.paymentSession({
|
|
303
|
+
// Optionally link to a cart, checkout, or customer
|
|
304
|
+
// cartId: 'your_cart_id',
|
|
305
|
+
// checkoutToken: 'your_checkout_token',
|
|
306
|
+
// customerId: 'your_customer_id',
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const { key, secret } = paymentSession.data.session;
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### Integration
|
|
313
|
+
|
|
314
|
+
1. **Initialize and Mount**
|
|
315
|
+
|
|
316
|
+
The `LiquidCommercePaymentElement` function creates and manages the UI component.
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// Initialize the payment element
|
|
320
|
+
const paymentElement = LiquidCommercePaymentElement({
|
|
321
|
+
session: {
|
|
322
|
+
key, // Public key from payment session
|
|
323
|
+
secret, // Client secret from payment session
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// Mount the element to a container in your DOM
|
|
328
|
+
await paymentElement.mount({
|
|
329
|
+
elementId: 'payment-element-container',
|
|
330
|
+
appearance: {
|
|
331
|
+
theme: 'night', // 'stripe' | 'night' | 'flat'
|
|
332
|
+
},
|
|
333
|
+
elementOptions: {
|
|
334
|
+
layout: 'tabs', // 'tabs' | 'accordion' | 'auto'
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
2. **Generate a Confirmation Token**
|
|
340
|
+
|
|
341
|
+
Once the user has filled out the payment form, create a confirmation token. This token securely represents the payment details.
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const result = await paymentElement.createConfirmationToken({
|
|
345
|
+
returnUrl: 'https://your-return-url.com/checkout/confirm',
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (result.token) {
|
|
349
|
+
// Token successfully created
|
|
350
|
+
const confirmationToken = result.token;
|
|
351
|
+
// Use this token to complete the checkout or save the payment method
|
|
352
|
+
} else {
|
|
353
|
+
// Handle error
|
|
354
|
+
console.error(result.message);
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
3. **Confirm the Payment Session**
|
|
359
|
+
|
|
360
|
+
Use the confirmation token to finalize the payment and retrieve the payment method details.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
const confirmation = await client.user.confirmPaymentSession(confirmationToken);
|
|
364
|
+
|
|
365
|
+
if (confirmation.data) {
|
|
366
|
+
const paymentMethod = confirmation.data;
|
|
367
|
+
// Now you have the payment method ID, card details, etc.
|
|
368
|
+
// e.g., paymentMethod.id, paymentMethod.card.brand
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
4. **Lifecycle Management**
|
|
373
|
+
|
|
374
|
+
Properly manage the element's lifecycle to ensure a smooth user experience and resource cleanup.
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// Listen to events
|
|
378
|
+
paymentElement.subscribe('ready', () => {
|
|
379
|
+
console.log('Payment element is ready.');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
paymentElement.subscribe('change', (event) => {
|
|
383
|
+
// Handle form state changes (e.g., enable/disable submit button)
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Clean up when the element is no longer needed
|
|
387
|
+
paymentElement.unmount();
|
|
388
|
+
paymentElement.destroy();
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Legacy Payment
|
|
392
|
+
|
|
393
|
+
The legacy payment system uses a previous version of our payment integration. For new integrations, we strongly recommend using the [Payment Element](#payment-element) for a more secure and flexible solution.
|
|
394
|
+
|
|
395
|
+
#### Prerequisites
|
|
396
|
+
|
|
397
|
+
1. User Session Creation:
|
|
398
|
+
|
|
263
399
|
```typescript
|
|
264
400
|
// First create or get a user session
|
|
265
401
|
const userSession = await client.user.session({
|
|
266
|
-
email:
|
|
402
|
+
email: 'user@example.com',
|
|
267
403
|
// ... other user details
|
|
268
404
|
});
|
|
269
405
|
|
|
@@ -276,15 +412,15 @@ const { setupIntent, publicKey } = userSession.data.session;
|
|
|
276
412
|
```typescript
|
|
277
413
|
// Initialize payment form using session credentials
|
|
278
414
|
await client.payment.mount({
|
|
279
|
-
clientSecret: userSession.data.session.setupIntent,
|
|
280
|
-
key: userSession.data.session.publicKey,
|
|
281
|
-
elementId: 'payment-element-container',
|
|
282
|
-
appearance: {
|
|
283
|
-
theme: 'night'
|
|
415
|
+
clientSecret: userSession.data.session.setupIntent, // Required: from session
|
|
416
|
+
key: userSession.data.session.publicKey, // Required: from session
|
|
417
|
+
elementId: 'payment-element-container', // Your DOM element ID
|
|
418
|
+
appearance: {
|
|
419
|
+
theme: 'night', // 'stripe' | 'night' | 'flat'
|
|
420
|
+
},
|
|
421
|
+
elementOptions: {
|
|
422
|
+
layout: 'tabs', // 'tabs' | 'accordion' | 'auto'
|
|
284
423
|
},
|
|
285
|
-
elementOptions: {
|
|
286
|
-
layout: 'tabs' // 'tabs' | 'accordion' | 'auto'
|
|
287
|
-
}
|
|
288
424
|
});
|
|
289
425
|
|
|
290
426
|
// Monitor payment element state
|
|
@@ -327,11 +463,12 @@ client.payment.destroy();
|
|
|
327
463
|
#### Best Practices
|
|
328
464
|
|
|
329
465
|
1. **Error Handling**: Always implement proper error handling:
|
|
466
|
+
|
|
330
467
|
```typescript
|
|
331
468
|
try {
|
|
332
469
|
const token = await client.payment.generateToken();
|
|
333
470
|
if ('error' in token) {
|
|
334
|
-
switch(token.error.type) {
|
|
471
|
+
switch (token.error.type) {
|
|
335
472
|
case 'validation_error':
|
|
336
473
|
// Handle invalid card data
|
|
337
474
|
break;
|
|
@@ -352,12 +489,14 @@ try {
|
|
|
352
489
|
```
|
|
353
490
|
|
|
354
491
|
2. **Cleanup**: Always clean up payment elements when done:
|
|
492
|
+
|
|
355
493
|
- When navigation away from payment page
|
|
356
494
|
- After successful payment
|
|
357
495
|
- After failed payment attempt
|
|
358
496
|
- Before unmounting payment component
|
|
359
497
|
|
|
360
498
|
3. **Event Handling**: Monitor element state for better user experience:
|
|
499
|
+
|
|
361
500
|
```typescript
|
|
362
501
|
client.payment.subscribe('change', (event) => {
|
|
363
502
|
// Update UI based on validation state
|
|
@@ -374,6 +513,7 @@ client.payment.subscribe('loaderror', (event) => {
|
|
|
374
513
|
#### Responsive Design
|
|
375
514
|
|
|
376
515
|
The payment element automatically adapts to:
|
|
516
|
+
|
|
377
517
|
- Mobile and desktop viewports
|
|
378
518
|
- Right-to-left languages
|
|
379
519
|
- Dark/light themes
|
|
@@ -383,7 +523,7 @@ The payment element automatically adapts to:
|
|
|
383
523
|
|
|
384
524
|
When testing payments in staging environment, use these test cards:
|
|
385
525
|
|
|
386
|
-
```
|
|
526
|
+
```
|
|
387
527
|
// Test Visa Card
|
|
388
528
|
Card Number: 4242 4242 4242 4242
|
|
389
529
|
Expiry: Any future date
|
|
@@ -408,6 +548,7 @@ ZIP: Any 5 digits
|
|
|
408
548
|
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.
|
|
409
549
|
|
|
410
550
|
**Important Notes:**
|
|
551
|
+
|
|
411
552
|
- These cards work only in test/staging environment
|
|
412
553
|
- Real cards will be declined in test mode
|
|
413
554
|
- Test cards will be declined in production
|
|
@@ -425,59 +566,67 @@ Checkout process management:
|
|
|
425
566
|
```typescript
|
|
426
567
|
// Prepare checkout
|
|
427
568
|
const preparedCheckout = await client.checkout.prepare({
|
|
428
|
-
cartId:
|
|
569
|
+
cartId: 'cart_id',
|
|
429
570
|
customer: {
|
|
430
|
-
id:
|
|
431
|
-
email:
|
|
432
|
-
firstName:
|
|
433
|
-
lastName:
|
|
434
|
-
phone:
|
|
435
|
-
birthDate:
|
|
571
|
+
id: 'customer_id', // Optional
|
|
572
|
+
email: 'customer@example.com',
|
|
573
|
+
firstName: 'John',
|
|
574
|
+
lastName: 'Smith',
|
|
575
|
+
phone: '2125551234',
|
|
576
|
+
birthDate: '1990-01-01',
|
|
436
577
|
},
|
|
437
578
|
hasAgeVerify: true,
|
|
438
579
|
billingAddress: {
|
|
439
|
-
firstName:
|
|
440
|
-
lastName:
|
|
441
|
-
email:
|
|
442
|
-
phone:
|
|
443
|
-
one:
|
|
444
|
-
two:
|
|
445
|
-
city:
|
|
446
|
-
state:
|
|
447
|
-
zip:
|
|
448
|
-
country:
|
|
580
|
+
firstName: 'John',
|
|
581
|
+
lastName: 'Smith',
|
|
582
|
+
email: 'billing@example.com',
|
|
583
|
+
phone: '2125551234',
|
|
584
|
+
one: '123 Main St',
|
|
585
|
+
two: 'Apt 4B',
|
|
586
|
+
city: 'New York',
|
|
587
|
+
state: 'NY',
|
|
588
|
+
zip: '10001',
|
|
589
|
+
country: 'US',
|
|
449
590
|
},
|
|
450
591
|
hasSubstitutionPolicy: true,
|
|
451
592
|
isGift: true,
|
|
452
593
|
billingSameAsShipping: false,
|
|
453
594
|
giftOptions: {
|
|
454
|
-
message:
|
|
595
|
+
message: 'Happy Birthday!',
|
|
455
596
|
recipient: {
|
|
456
|
-
name:
|
|
457
|
-
email:
|
|
458
|
-
phone:
|
|
459
|
-
}
|
|
597
|
+
name: 'Jane Smith',
|
|
598
|
+
email: 'jane@example.com',
|
|
599
|
+
phone: '2125555678',
|
|
600
|
+
},
|
|
460
601
|
},
|
|
461
602
|
marketingPreferences: {
|
|
462
603
|
canEmail: true,
|
|
463
|
-
canSms: true
|
|
604
|
+
canSms: true,
|
|
464
605
|
},
|
|
465
606
|
deliveryTips: [
|
|
466
607
|
{
|
|
467
|
-
fulfillmentId:
|
|
468
|
-
tip: 500 // Amount in cents
|
|
469
|
-
}
|
|
608
|
+
fulfillmentId: 'fulfillment_id',
|
|
609
|
+
tip: 500, // Amount in cents
|
|
610
|
+
},
|
|
611
|
+
],
|
|
612
|
+
deliveryInstructions: [
|
|
613
|
+
{
|
|
614
|
+
fulfillmentId: 'fulfillment_id',
|
|
615
|
+
instructions: "", // 250 Max characters
|
|
616
|
+
},
|
|
470
617
|
],
|
|
471
618
|
acceptedAccountCreation: true,
|
|
472
|
-
scheduledDelivery:
|
|
619
|
+
scheduledDelivery: '2024-12-25T14:00:00Z',
|
|
620
|
+
promoCode: 'DISCOUNT10', // Optional
|
|
621
|
+
giftCards: ['GC123456'], // Optional
|
|
473
622
|
});
|
|
474
623
|
|
|
475
624
|
// Complete checkout
|
|
476
625
|
const completedCheckout = await client.checkout.complete({
|
|
477
626
|
token: preparedCheckout.token,
|
|
478
|
-
payment:
|
|
627
|
+
payment: 'payment_id',
|
|
479
628
|
});
|
|
480
|
-
```
|
|
629
|
+
```
|
|
481
630
|
|
|
482
631
|
#### Checkout Payment
|
|
483
632
|
|
|
@@ -486,38 +635,69 @@ For direct checkout payments, the flow is similar but uses the checkout session:
|
|
|
486
635
|
```typescript
|
|
487
636
|
// 1. First prepare the checkout
|
|
488
637
|
const preparedCheckout = await client.checkout.prepare({
|
|
489
|
-
cartId:
|
|
638
|
+
cartId: 'cart_id',
|
|
490
639
|
// ... other checkout details
|
|
491
640
|
});
|
|
492
641
|
|
|
493
|
-
// 2. Initialize payment
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
642
|
+
// 2. Initialize payment element with checkout session
|
|
643
|
+
const paymentElement = LiquidCommercePaymentElement({
|
|
644
|
+
session: {
|
|
645
|
+
key: preparedCheckout.data.payment.publicKey, // From checkout prepare response
|
|
646
|
+
secret: preparedCheckout.data.payment.clientSecret, // From checkout prepare response
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
// 3. Mount the element
|
|
651
|
+
await paymentElement.mount({
|
|
497
652
|
elementId: 'payment-element-container',
|
|
498
653
|
appearance: { theme: 'night' },
|
|
499
|
-
elementOptions: { layout: 'tabs' }
|
|
654
|
+
elementOptions: { layout: 'tabs' },
|
|
500
655
|
});
|
|
501
656
|
|
|
502
|
-
//
|
|
503
|
-
|
|
504
|
-
// Monitor payment form state
|
|
505
|
-
const { complete, empty, value } = event;
|
|
506
|
-
});
|
|
657
|
+
// 4. Handle payment element events and create confirmation token
|
|
658
|
+
const result = await paymentElement.createConfirmationToken();
|
|
507
659
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (!('error' in tokenResult)) {
|
|
511
|
-
// 5. Complete checkout with payment token
|
|
660
|
+
if (result.token) {
|
|
661
|
+
// 5. Complete checkout with the confirmation token
|
|
512
662
|
const completedCheckout = await client.checkout.complete({
|
|
513
|
-
token: preparedCheckout.token,
|
|
514
|
-
payment:
|
|
663
|
+
token: preparedCheckout.data.token,
|
|
664
|
+
payment: result.token,
|
|
515
665
|
});
|
|
516
666
|
}
|
|
517
667
|
|
|
518
668
|
// 6. Clean up
|
|
519
|
-
|
|
520
|
-
|
|
669
|
+
paymentElement.unmount();
|
|
670
|
+
paymentElement.destroy();
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Order
|
|
674
|
+
|
|
675
|
+
Order retrieval services:
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
const orderClient = await LiquidCommerceOrders({
|
|
679
|
+
userID: 'YOUR_ORDER_API_USER_ID',
|
|
680
|
+
password: 'YOUR_ORDER_API_PASSWORD',
|
|
681
|
+
env: LIQUID_COMMERCE_ENV.STAGE, // or PROD
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
// Fetch order details by ID or number
|
|
685
|
+
const orderResponse = await orderClient.order.fetch(/* reference id or order number */);
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
[Click here to access the docs for the order response structure](https://docs.liquidcommerce.cloud/types/order)
|
|
689
|
+
|
|
690
|
+
### Webhook
|
|
691
|
+
|
|
692
|
+
Webhook test services:
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
// Test webhook endpoint
|
|
696
|
+
const webhookTestResult = await client.webhook.test(/* endpoint */);
|
|
697
|
+
|
|
698
|
+
// Response is a simple boolean indicating success or failure
|
|
699
|
+
// true = webhook test was successful
|
|
700
|
+
// false = webhook test failed
|
|
521
701
|
```
|
|
522
702
|
|
|
523
703
|
## Error Handling
|
|
@@ -534,6 +714,7 @@ try {
|
|
|
534
714
|
```
|
|
535
715
|
|
|
536
716
|
Common error scenarios:
|
|
717
|
+
|
|
537
718
|
- Authentication failures
|
|
538
719
|
- Invalid parameters
|
|
539
720
|
- Network errors
|
|
@@ -544,6 +725,7 @@ Common error scenarios:
|
|
|
544
725
|
## Price Handling
|
|
545
726
|
|
|
546
727
|
All monetary values in the SDK are handled in cents (the smallest currency unit). For example:
|
|
728
|
+
|
|
547
729
|
- $10.00 is represented as 1000
|
|
548
730
|
- $5.99 is represented as 599
|
|
549
731
|
- $0.50 is represented as 50
|