@cshah18/sdk 3.0.0 → 3.0.1
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/dist/cobuy-sdk.esm.js +320 -40
- package/dist/cobuy-sdk.esm.js.map +1 -1
- package/dist/cobuy-sdk.umd.js +320 -40
- package/dist/cobuy-sdk.umd.js.map +1 -1
- package/dist/types/core/api-client.d.ts +36 -1
- package/dist/types/core/cobuy.d.ts +54 -1
- package/dist/types/core/endpoints.d.ts +3 -0
- package/dist/types/core/types.d.ts +43 -8
- package/dist/types/ui/lobby/lobby-modal.d.ts +1 -2
- package/dist/types/ui/widget/widget-root.d.ts +2 -1
- package/package.json +1 -1
package/dist/cobuy-sdk.umd.js
CHANGED
|
@@ -1308,6 +1308,21 @@ var CoBuySDK = (function (exports) {
|
|
|
1308
1308
|
this.socketListenerRegistered = false;
|
|
1309
1309
|
this.currentGroupId = null;
|
|
1310
1310
|
this.shareOverlay = null;
|
|
1311
|
+
/**
|
|
1312
|
+
* Unsubscribe from socket events - testing out flow will remove once we have conviction
|
|
1313
|
+
*/
|
|
1314
|
+
// private unsubscribeFromSocketEvents(): void {
|
|
1315
|
+
// if (typeof window === "undefined" || !this.socketListenerRegistered) {
|
|
1316
|
+
// return;
|
|
1317
|
+
// }
|
|
1318
|
+
// window.removeEventListener("group:fulfilled", this.handleSocketGroupUpdate as EventListener);
|
|
1319
|
+
// window.removeEventListener(
|
|
1320
|
+
// "group:member:joined",
|
|
1321
|
+
// this.handleSocketGroupUpdate as EventListener,
|
|
1322
|
+
// );
|
|
1323
|
+
// window.removeEventListener("group:created", this.handleSocketGroupUpdate as EventListener);
|
|
1324
|
+
// this.socketListenerRegistered = false;
|
|
1325
|
+
// }
|
|
1311
1326
|
/**
|
|
1312
1327
|
* Handle socket group update events
|
|
1313
1328
|
*/
|
|
@@ -2329,11 +2344,11 @@ var CoBuySDK = (function (exports) {
|
|
|
2329
2344
|
// Stop timers and animations
|
|
2330
2345
|
this.stopTimer();
|
|
2331
2346
|
this.stopActivityAnimation();
|
|
2332
|
-
// Unsubscribe from socket events and group
|
|
2333
|
-
this.unsubscribeFromSocketEvents();
|
|
2334
|
-
if (this.socketManager && this.currentGroupId) {
|
|
2335
|
-
|
|
2336
|
-
}
|
|
2347
|
+
// // Unsubscribe from socket events and group - testing out flow will remove once we have conviction
|
|
2348
|
+
// this.unsubscribeFromSocketEvents();
|
|
2349
|
+
// if (this.socketManager && this.currentGroupId) {
|
|
2350
|
+
// this.socketManager.unsubscribeFromGroup(this.currentGroupId);
|
|
2351
|
+
// }
|
|
2337
2352
|
// Remove modal from DOM
|
|
2338
2353
|
document.body.removeChild(this.modalElement);
|
|
2339
2354
|
this.modalElement = null;
|
|
@@ -2448,18 +2463,6 @@ var CoBuySDK = (function (exports) {
|
|
|
2448
2463
|
window.addEventListener("group:created", this.handleSocketGroupUpdate);
|
|
2449
2464
|
this.socketListenerRegistered = true;
|
|
2450
2465
|
}
|
|
2451
|
-
/**
|
|
2452
|
-
* Unsubscribe from socket events
|
|
2453
|
-
*/
|
|
2454
|
-
unsubscribeFromSocketEvents() {
|
|
2455
|
-
if (typeof window === "undefined" || !this.socketListenerRegistered) {
|
|
2456
|
-
return;
|
|
2457
|
-
}
|
|
2458
|
-
window.removeEventListener("group:fulfilled", this.handleSocketGroupUpdate);
|
|
2459
|
-
window.removeEventListener("group:member:joined", this.handleSocketGroupUpdate);
|
|
2460
|
-
window.removeEventListener("group:created", this.handleSocketGroupUpdate);
|
|
2461
|
-
this.socketListenerRegistered = false;
|
|
2462
|
-
}
|
|
2463
2466
|
/**
|
|
2464
2467
|
* Create activity item from socket event data
|
|
2465
2468
|
*/
|
|
@@ -2585,9 +2588,9 @@ var CoBuySDK = (function (exports) {
|
|
|
2585
2588
|
this.groupListModal = null;
|
|
2586
2589
|
this.lastGroupDataRefreshTime = 0;
|
|
2587
2590
|
this.GROUP_REFRESH_DEBOUNCE = 1000; // 1 second min between refreshes
|
|
2591
|
+
this.groupExpiryRefreshTriggered = false; // Track if expiry refresh already triggered for current group
|
|
2588
2592
|
/** Handle backend fulfillment notifications */
|
|
2589
2593
|
this.handleGroupFulfilledEvent = (event) => {
|
|
2590
|
-
console.log("CHIRAG");
|
|
2591
2594
|
const detail = event.detail;
|
|
2592
2595
|
if (!detail || !detail.productId) {
|
|
2593
2596
|
return;
|
|
@@ -2599,9 +2602,10 @@ var CoBuySDK = (function (exports) {
|
|
|
2599
2602
|
};
|
|
2600
2603
|
/** Handle realtime group creation/join events by refreshing group UI */
|
|
2601
2604
|
this.handleGroupUpdatedEvent = (event) => {
|
|
2605
|
+
var _a;
|
|
2602
2606
|
const detail = event.detail || {};
|
|
2603
|
-
const productId = detail.
|
|
2604
|
-
const groupId = detail.
|
|
2607
|
+
const productId = detail.product_id;
|
|
2608
|
+
const groupId = (_a = detail.group) === null || _a === void 0 ? void 0 : _a.id;
|
|
2605
2609
|
if (productId && this.currentProductId && productId !== this.currentProductId) {
|
|
2606
2610
|
return;
|
|
2607
2611
|
}
|
|
@@ -2867,14 +2871,10 @@ var CoBuySDK = (function (exports) {
|
|
|
2867
2871
|
footer.style.display = "flex";
|
|
2868
2872
|
footer.style.justifyContent = "flex-end";
|
|
2869
2873
|
footer.style.alignItems = "center";
|
|
2870
|
-
const viewAllLink = this.createInlineViewAllLink();
|
|
2871
|
-
if (viewAllLink) {
|
|
2872
|
-
footer.appendChild(viewAllLink);
|
|
2873
|
-
}
|
|
2874
2874
|
root.appendChild(footer);
|
|
2875
2875
|
return root;
|
|
2876
2876
|
}
|
|
2877
|
-
/** Update countdown text */
|
|
2877
|
+
/** Update countdown text and trigger refresh when group expires */
|
|
2878
2878
|
updateTimer(el, expiryMs, remaining) {
|
|
2879
2879
|
const now = Date.now();
|
|
2880
2880
|
const diff = Math.max(0, Math.floor((expiryMs - now) / 1000));
|
|
@@ -2888,6 +2888,12 @@ var CoBuySDK = (function (exports) {
|
|
|
2888
2888
|
else {
|
|
2889
2889
|
el.textContent = "✨ Discount activated!";
|
|
2890
2890
|
el.classList.add("activated");
|
|
2891
|
+
// Trigger group refresh only once when expiry is reached, regardless of modal state
|
|
2892
|
+
if (!this.groupExpiryRefreshTriggered && diff <= 0) {
|
|
2893
|
+
this.groupExpiryRefreshTriggered = true;
|
|
2894
|
+
this.logger.info("[Expiry] Group expired, refreshing group data");
|
|
2895
|
+
void this.refreshGroupDataFromRealtime();
|
|
2896
|
+
}
|
|
2891
2897
|
}
|
|
2892
2898
|
}
|
|
2893
2899
|
/** Build and attach the shared "View all Groups" link section */
|
|
@@ -2999,6 +3005,7 @@ var CoBuySDK = (function (exports) {
|
|
|
2999
3005
|
this.frozenReward = null;
|
|
3000
3006
|
this.currentGroupId = null;
|
|
3001
3007
|
this.currentRewardData = null;
|
|
3008
|
+
this.groupExpiryRefreshTriggered = false; // Reset expiry refresh flag for new render
|
|
3002
3009
|
// Listen for realtime fulfillment updates once per page
|
|
3003
3010
|
this.subscribeToSocketEvents();
|
|
3004
3011
|
// Host safety + idempotency markers
|
|
@@ -3413,7 +3420,6 @@ var CoBuySDK = (function (exports) {
|
|
|
3413
3420
|
}
|
|
3414
3421
|
}
|
|
3415
3422
|
createWidget(rewardData, container, options) {
|
|
3416
|
-
var _a, _b;
|
|
3417
3423
|
const isFulfilled = this.groupFulfilled;
|
|
3418
3424
|
const activeReward = this.frozenReward || (rewardData === null || rewardData === void 0 ? void 0 : rewardData.reward) || null;
|
|
3419
3425
|
const wrapper = document.createElement("div");
|
|
@@ -3463,7 +3469,7 @@ var CoBuySDK = (function (exports) {
|
|
|
3463
3469
|
rewardLine.setAttribute("aria-label", rewardText ? `Reward locked in: ${rewardText}` : "Reward available for this group");
|
|
3464
3470
|
rewardLine.title = rewardLine.textContent;
|
|
3465
3471
|
}
|
|
3466
|
-
else if (
|
|
3472
|
+
else if (activeReward) {
|
|
3467
3473
|
const rewardText = this.formatRewardText(activeReward);
|
|
3468
3474
|
rewardLine.textContent = rewardText
|
|
3469
3475
|
? `Save up to ${rewardText} with CoBuy`
|
|
@@ -3471,12 +3477,6 @@ var CoBuySDK = (function (exports) {
|
|
|
3471
3477
|
rewardLine.setAttribute("aria-label", `Eligible for CoBuy reward: ${rewardLine.textContent}`);
|
|
3472
3478
|
rewardLine.title = rewardLine.textContent;
|
|
3473
3479
|
}
|
|
3474
|
-
else if (rewardData && !((_b = rewardData.eligibility) === null || _b === void 0 ? void 0 : _b.isEligible)) {
|
|
3475
|
-
rewardLine.textContent = "Join with CoBuy to unlock rewards";
|
|
3476
|
-
rewardLine.setAttribute("aria-label", "Join with CoBuy to unlock rewards");
|
|
3477
|
-
rewardLine.title = "Join with CoBuy to unlock rewards";
|
|
3478
|
-
rewardLine.style.color = "#6b7280";
|
|
3479
|
-
}
|
|
3480
3480
|
else {
|
|
3481
3481
|
rewardLine.textContent = "CoBuy offer loading or unavailable";
|
|
3482
3482
|
rewardLine.setAttribute("aria-label", "CoBuy offer loading or unavailable");
|
|
@@ -3880,7 +3880,6 @@ var CoBuySDK = (function (exports) {
|
|
|
3880
3880
|
* Format reward text for rendering in external container
|
|
3881
3881
|
*/
|
|
3882
3882
|
formatRewardForContainer(rewardData) {
|
|
3883
|
-
var _a;
|
|
3884
3883
|
const reward = this.frozenReward || (rewardData === null || rewardData === void 0 ? void 0 : rewardData.reward);
|
|
3885
3884
|
if (this.groupFulfilled) {
|
|
3886
3885
|
const rewardText = this.formatRewardText(reward);
|
|
@@ -3890,12 +3889,7 @@ var CoBuySDK = (function (exports) {
|
|
|
3890
3889
|
return "Join with CoBuy to unlock rewards";
|
|
3891
3890
|
}
|
|
3892
3891
|
const rewardText = this.formatRewardText(reward);
|
|
3893
|
-
|
|
3894
|
-
return rewardText ? `Save up to ${rewardText} with CoBuy` : "CoBuy reward available";
|
|
3895
|
-
}
|
|
3896
|
-
else {
|
|
3897
|
-
return "Join with CoBuy to unlock rewards";
|
|
3898
|
-
}
|
|
3892
|
+
return rewardText ? `Save up to ${rewardText} with CoBuy` : "CoBuy reward available";
|
|
3899
3893
|
}
|
|
3900
3894
|
}
|
|
3901
3895
|
|
|
@@ -3911,6 +3905,9 @@ var CoBuySDK = (function (exports) {
|
|
|
3911
3905
|
GROUP_CREATE_AND_JOIN: "/v1/sdk/groups/new/join",
|
|
3912
3906
|
PRODUCT_ACTIVE_GROUPS: "/v1/sdk/products/:productId/groups/active",
|
|
3913
3907
|
GROUP_INVITE: "/v1/sdk/groups/:groupId/invite",
|
|
3908
|
+
GROUP_CHECKOUT_PREPARE: "/v1/sdk/groups/:groupId/checkout/prepare",
|
|
3909
|
+
GROUP_CHECKOUT_VALIDATE: "/v1/sdk/groups/:groupId/checkout/validate",
|
|
3910
|
+
GROUP_CHECKOUT_CONFIRM: "/v1/sdk/groups/:groupId/checkout/confirm",
|
|
3914
3911
|
};
|
|
3915
3912
|
/**
|
|
3916
3913
|
* Build full API URL from base URL and endpoint path
|
|
@@ -4365,6 +4362,100 @@ var CoBuySDK = (function (exports) {
|
|
|
4365
4362
|
},
|
|
4366
4363
|
};
|
|
4367
4364
|
}
|
|
4365
|
+
/**
|
|
4366
|
+
* Prepare checkout for a group
|
|
4367
|
+
*
|
|
4368
|
+
* Signals the backend that the user is proceeding to checkout for a specific group.
|
|
4369
|
+
* This allows the backend to prepare order data, lock pricing, and track conversion.
|
|
4370
|
+
* Returns a checkout reference to be used in subsequent validate and confirm calls.
|
|
4371
|
+
*
|
|
4372
|
+
* @param groupId - The group ID to prepare checkout for
|
|
4373
|
+
* @returns Promise with success status and checkout reference
|
|
4374
|
+
*/
|
|
4375
|
+
async prepareCheckout(groupId) {
|
|
4376
|
+
var _a, _b;
|
|
4377
|
+
const endpoint = buildApiUrl("", API_ENDPOINTS.GROUP_CHECKOUT_PREPARE, { groupId });
|
|
4378
|
+
this.logger.info(`Preparing checkout for group: ${groupId}`);
|
|
4379
|
+
const response = await this.post(endpoint);
|
|
4380
|
+
if (response.success && ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.checkout_ref)) {
|
|
4381
|
+
this.logger.info(`Checkout prepared successfully with ref: ${response.data.data.checkout_ref}`);
|
|
4382
|
+
return {
|
|
4383
|
+
success: true,
|
|
4384
|
+
data: {
|
|
4385
|
+
checkout_ref: response.data.data.checkout_ref,
|
|
4386
|
+
},
|
|
4387
|
+
};
|
|
4388
|
+
}
|
|
4389
|
+
return {
|
|
4390
|
+
success: false,
|
|
4391
|
+
error: response.error || {
|
|
4392
|
+
message: "Failed to prepare checkout",
|
|
4393
|
+
code: "PREPARE_CHECKOUT_ERROR",
|
|
4394
|
+
},
|
|
4395
|
+
};
|
|
4396
|
+
}
|
|
4397
|
+
/**
|
|
4398
|
+
* Validate checkout for a group
|
|
4399
|
+
*
|
|
4400
|
+
* Validates the checkout reference and confirms the order can proceed.
|
|
4401
|
+
* This should be called after prepareCheckout to verify the checkout state.
|
|
4402
|
+
*
|
|
4403
|
+
* @param groupId - The group ID to validate checkout for
|
|
4404
|
+
* @param checkoutRef - The checkout reference ID from the prepare step
|
|
4405
|
+
* @returns Promise with success status
|
|
4406
|
+
*/
|
|
4407
|
+
async validateCheckout(groupId, checkoutRef) {
|
|
4408
|
+
var _a;
|
|
4409
|
+
const endpoint = buildApiUrl("", API_ENDPOINTS.GROUP_CHECKOUT_VALIDATE, { groupId });
|
|
4410
|
+
this.logger.info(`Validating checkout for group: ${groupId}`);
|
|
4411
|
+
const response = await this.post(endpoint, {
|
|
4412
|
+
checkout_ref: checkoutRef,
|
|
4413
|
+
});
|
|
4414
|
+
if (response.success) {
|
|
4415
|
+
this.logger.info("Checkout validated successfully");
|
|
4416
|
+
return {
|
|
4417
|
+
success: true,
|
|
4418
|
+
data: (_a = response.data) === null || _a === void 0 ? void 0 : _a.data,
|
|
4419
|
+
};
|
|
4420
|
+
}
|
|
4421
|
+
return {
|
|
4422
|
+
success: false,
|
|
4423
|
+
error: response.error || {
|
|
4424
|
+
message: "Failed to validate checkout",
|
|
4425
|
+
code: "VALIDATE_CHECKOUT_ERROR",
|
|
4426
|
+
},
|
|
4427
|
+
};
|
|
4428
|
+
}
|
|
4429
|
+
/**
|
|
4430
|
+
* Confirm checkout for a group
|
|
4431
|
+
*
|
|
4432
|
+
* Finalizes the checkout and confirms the order.
|
|
4433
|
+
* This should be called after validateCheckout to complete the checkout process.
|
|
4434
|
+
*
|
|
4435
|
+
* @param groupId - The group ID to confirm checkout for
|
|
4436
|
+
* @param checkoutRef - The checkout reference ID from the prepare step
|
|
4437
|
+
* @returns Promise with success status
|
|
4438
|
+
*/
|
|
4439
|
+
async confirmCheckout(groupId, checkoutRef) {
|
|
4440
|
+
const endpoint = buildApiUrl("", API_ENDPOINTS.GROUP_CHECKOUT_CONFIRM, { groupId });
|
|
4441
|
+
this.logger.info(`Confirming checkout for group: ${groupId}`);
|
|
4442
|
+
const response = await this.post(endpoint, {
|
|
4443
|
+
checkout_ref: checkoutRef,
|
|
4444
|
+
});
|
|
4445
|
+
if (response.success) {
|
|
4446
|
+
this.logger.info("Checkout confirmed successfully");
|
|
4447
|
+
return {
|
|
4448
|
+
success: true,
|
|
4449
|
+
};
|
|
4450
|
+
}
|
|
4451
|
+
return {
|
|
4452
|
+
success: false,
|
|
4453
|
+
error: response.error || {
|
|
4454
|
+
message: "Failed to confirm checkout",
|
|
4455
|
+
code: "CONFIRM_CHECKOUT_ERROR",
|
|
4456
|
+
},
|
|
4457
|
+
};
|
|
4458
|
+
}
|
|
4368
4459
|
}
|
|
4369
4460
|
|
|
4370
4461
|
/**
|
|
@@ -8759,6 +8850,7 @@ var CoBuySDK = (function (exports) {
|
|
|
8759
8850
|
this.analyticsClient = null;
|
|
8760
8851
|
this.sessionId = "";
|
|
8761
8852
|
this.SESSION_STORAGE_KEY = "cobuy_sdk_session_id";
|
|
8853
|
+
this.CHECKOUT_REF_PREFIX = "cobuy_checkout_ref";
|
|
8762
8854
|
this.lobbyModal = null;
|
|
8763
8855
|
this.modals = new Map();
|
|
8764
8856
|
this.socketManager = null;
|
|
@@ -8802,12 +8894,97 @@ var CoBuySDK = (function (exports) {
|
|
|
8802
8894
|
// Fallback for environments without crypto.randomUUID
|
|
8803
8895
|
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
8804
8896
|
}
|
|
8897
|
+
/**
|
|
8898
|
+
* Store checkout reference for a product/group (session-level)
|
|
8899
|
+
* Storage key format: cobuy_checkout_ref_<sessionId>_<productId>_<groupId>
|
|
8900
|
+
*/
|
|
8901
|
+
storeCheckoutRef(productId, groupId, checkoutRef) {
|
|
8902
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
8903
|
+
this.logger.warn("[SDK] localStorage not available, cannot store checkout reference");
|
|
8904
|
+
return;
|
|
8905
|
+
}
|
|
8906
|
+
const storageKey = `${this.CHECKOUT_REF_PREFIX}_${this.sessionId}_${productId}_${groupId}`;
|
|
8907
|
+
try {
|
|
8908
|
+
window.localStorage.setItem(storageKey, checkoutRef);
|
|
8909
|
+
this.logger.debug(`[SDK] Stored checkout reference: ${storageKey}`);
|
|
8910
|
+
}
|
|
8911
|
+
catch (e) {
|
|
8912
|
+
this.logger.warn("[SDK] Could not store checkout reference to localStorage", e);
|
|
8913
|
+
}
|
|
8914
|
+
}
|
|
8915
|
+
/**
|
|
8916
|
+
* Retrieve checkout reference for a product/group (session-level)
|
|
8917
|
+
* If groupId provided, try exact match first; otherwise fall back to any key for that product
|
|
8918
|
+
* Returns both the matched storage key and the checkout reference value (or null if not found)
|
|
8919
|
+
*/
|
|
8920
|
+
getCheckoutRef(productId, groupId) {
|
|
8921
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
8922
|
+
return { key: null, checkoutRef: null, groupId: null };
|
|
8923
|
+
}
|
|
8924
|
+
const basePrefix = `${this.CHECKOUT_REF_PREFIX}_${this.sessionId}_${productId}`;
|
|
8925
|
+
// Try exact match if groupId supplied
|
|
8926
|
+
if (groupId) {
|
|
8927
|
+
const exactKey = `${basePrefix}_${groupId}`;
|
|
8928
|
+
const exactRef = window.localStorage.getItem(exactKey);
|
|
8929
|
+
if (exactRef) {
|
|
8930
|
+
this.logger.debug(`[SDK] Retrieved checkout reference: ${exactKey}`);
|
|
8931
|
+
return { key: exactKey, checkoutRef: exactRef, groupId };
|
|
8932
|
+
}
|
|
8933
|
+
}
|
|
8934
|
+
// Fallback: find any checkout ref for this product (ignore group)
|
|
8935
|
+
for (let i = 0; i < window.localStorage.length; i++) {
|
|
8936
|
+
const key = window.localStorage.key(i);
|
|
8937
|
+
if (key && key.startsWith(basePrefix)) {
|
|
8938
|
+
const ref = window.localStorage.getItem(key);
|
|
8939
|
+
if (ref) {
|
|
8940
|
+
this.logger.debug(`[SDK] Retrieved checkout reference via prefix: ${key}`);
|
|
8941
|
+
const parsedGroupId = key.startsWith(`${basePrefix}_`) ? key.substring(basePrefix.length + 1) : null;
|
|
8942
|
+
return { key, checkoutRef: ref, groupId: parsedGroupId };
|
|
8943
|
+
}
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
return { key: null, checkoutRef: null, groupId: null };
|
|
8947
|
+
}
|
|
8805
8948
|
/**
|
|
8806
8949
|
* Get the current session ID (core SDK concept)
|
|
8807
8950
|
*/
|
|
8808
8951
|
getSessionId() {
|
|
8809
8952
|
return this.sessionId;
|
|
8810
8953
|
}
|
|
8954
|
+
/**
|
|
8955
|
+
* Prepare checkout for a group if not already prepared
|
|
8956
|
+
* Checks localStorage to prevent duplicate calls for the same product/group/session
|
|
8957
|
+
*/
|
|
8958
|
+
async prepareCheckoutIfNotDone(productId, groupId) {
|
|
8959
|
+
var _a;
|
|
8960
|
+
// Check if checkout already prepared for this product/group (session)
|
|
8961
|
+
const { checkoutRef: existingRef } = this.getCheckoutRef(productId, groupId);
|
|
8962
|
+
if (existingRef) {
|
|
8963
|
+
this.logger.debug(`[SDK] Checkout already prepared for product ${productId} (session), skipping`);
|
|
8964
|
+
return;
|
|
8965
|
+
}
|
|
8966
|
+
if (!this.apiClient) {
|
|
8967
|
+
this.logger.warn("[SDK] API client not available, cannot prepare checkout");
|
|
8968
|
+
return;
|
|
8969
|
+
}
|
|
8970
|
+
try {
|
|
8971
|
+
this.logger.info(`[SDK] Preparing checkout for product: ${productId}, group: ${groupId}`);
|
|
8972
|
+
// Call prepareCheckout to get the checkout reference
|
|
8973
|
+
const response = await this.apiClient.prepareCheckout(groupId);
|
|
8974
|
+
if (response.success && ((_a = response.data) === null || _a === void 0 ? void 0 : _a.checkout_ref)) {
|
|
8975
|
+
const checkoutRef = response.data.checkout_ref;
|
|
8976
|
+
// Store the checkout reference for this specific product and group
|
|
8977
|
+
this.storeCheckoutRef(productId, groupId, checkoutRef);
|
|
8978
|
+
this.logger.info(`[SDK] Checkout prepared and stored for ${productId}:${groupId} - Ref: ${checkoutRef}`);
|
|
8979
|
+
}
|
|
8980
|
+
else {
|
|
8981
|
+
this.logger.error("[SDK] Failed to prepare checkout", response.error);
|
|
8982
|
+
}
|
|
8983
|
+
}
|
|
8984
|
+
catch (error) {
|
|
8985
|
+
this.logger.error("[SDK] Error preparing checkout", error);
|
|
8986
|
+
}
|
|
8987
|
+
}
|
|
8811
8988
|
/**
|
|
8812
8989
|
* Initialize the SDK with configuration
|
|
8813
8990
|
*/
|
|
@@ -8868,6 +9045,21 @@ var CoBuySDK = (function (exports) {
|
|
|
8868
9045
|
},
|
|
8869
9046
|
onGroupMemberJoined: (payload) => {
|
|
8870
9047
|
var _a;
|
|
9048
|
+
const group = payload.group;
|
|
9049
|
+
const productId = payload.product_id;
|
|
9050
|
+
const groupId = group === null || group === void 0 ? void 0 : group.id;
|
|
9051
|
+
const maxParticipants = group === null || group === void 0 ? void 0 : group.max_participants;
|
|
9052
|
+
const participantsCount = group === null || group === void 0 ? void 0 : group.participants_count;
|
|
9053
|
+
const status = group === null || group === void 0 ? void 0 : group.status;
|
|
9054
|
+
const isFulfilled = status === "fulfilled" ||
|
|
9055
|
+
(maxParticipants !== undefined &&
|
|
9056
|
+
participantsCount !== undefined &&
|
|
9057
|
+
participantsCount >= maxParticipants);
|
|
9058
|
+
if (isFulfilled && productId && groupId) {
|
|
9059
|
+
// Prepare checkout when group is fulfilled (if not already prepared)
|
|
9060
|
+
this.prepareCheckoutIfNotDone(productId, groupId);
|
|
9061
|
+
}
|
|
9062
|
+
// Emit user-defined callback if provided
|
|
8871
9063
|
if ((_a = config.events) === null || _a === void 0 ? void 0 : _a.onGroupMemberJoined) {
|
|
8872
9064
|
config.events.onGroupMemberJoined(payload);
|
|
8873
9065
|
}
|
|
@@ -8976,6 +9168,17 @@ var CoBuySDK = (function (exports) {
|
|
|
8976
9168
|
this.lobbyModal = modal;
|
|
8977
9169
|
// Open the modal
|
|
8978
9170
|
modal.open(options.groupId);
|
|
9171
|
+
// Prepare checkout if group is fulfilled
|
|
9172
|
+
if (options.groupId) {
|
|
9173
|
+
const isFulfilled = options.status === "complete" ||
|
|
9174
|
+
options.progress === 100 ||
|
|
9175
|
+
(options.currentMembers !== undefined &&
|
|
9176
|
+
options.totalMembers !== undefined &&
|
|
9177
|
+
options.currentMembers >= options.totalMembers);
|
|
9178
|
+
if (isFulfilled) {
|
|
9179
|
+
this.prepareCheckoutIfNotDone(options.productId, options.groupId);
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
8979
9182
|
// Call callback if provided
|
|
8980
9183
|
if (options.onOpen) {
|
|
8981
9184
|
options.onOpen(options.productId);
|
|
@@ -9057,6 +9260,83 @@ var CoBuySDK = (function (exports) {
|
|
|
9057
9260
|
this.logger.error("Error setting contact information", error);
|
|
9058
9261
|
}
|
|
9059
9262
|
}
|
|
9263
|
+
/**
|
|
9264
|
+
* Validate checkout for a group
|
|
9265
|
+
*
|
|
9266
|
+
* Validates the checkout reference and confirms the order can proceed.
|
|
9267
|
+
* Should be called after prepareCheckout to verify the checkout state.
|
|
9268
|
+
*
|
|
9269
|
+
* @param groupId - The group ID to validate checkout for
|
|
9270
|
+
* @param checkoutRef - The checkout reference ID from the prepare step
|
|
9271
|
+
*
|
|
9272
|
+
* @example
|
|
9273
|
+
* ```typescript
|
|
9274
|
+
* // Validate checkout for a group
|
|
9275
|
+
* await CoBuy.validateCheckout('fae238ae-7468-47e9-9eec-b6d52fe3b012', 'chk_9a6d8750-ed60-4795-a207-2abe955e8509');
|
|
9276
|
+
* ```
|
|
9277
|
+
*/
|
|
9278
|
+
async validateCheckout(groupId, checkoutRef) {
|
|
9279
|
+
if (!this.configManager.isInitialized()) {
|
|
9280
|
+
this.logger.warn("SDK not initialized, cannot validate checkout");
|
|
9281
|
+
return null;
|
|
9282
|
+
}
|
|
9283
|
+
if (!this.apiClient) {
|
|
9284
|
+
this.logger.error("API client not available");
|
|
9285
|
+
return null;
|
|
9286
|
+
}
|
|
9287
|
+
try {
|
|
9288
|
+
const response = await this.apiClient.validateCheckout(groupId, checkoutRef);
|
|
9289
|
+
if (response.success) {
|
|
9290
|
+
this.logger.info(`Checkout validated successfully for group: ${groupId}`);
|
|
9291
|
+
return response.data || null;
|
|
9292
|
+
}
|
|
9293
|
+
else {
|
|
9294
|
+
this.logger.error("Failed to validate checkout", response.error);
|
|
9295
|
+
return null;
|
|
9296
|
+
}
|
|
9297
|
+
}
|
|
9298
|
+
catch (error) {
|
|
9299
|
+
this.logger.error("Error validating checkout", error);
|
|
9300
|
+
return null;
|
|
9301
|
+
}
|
|
9302
|
+
}
|
|
9303
|
+
/**
|
|
9304
|
+
* Confirm checkout for a group
|
|
9305
|
+
*
|
|
9306
|
+
* Finalizes the checkout and confirms the order.
|
|
9307
|
+
* Should be called after validateCheckout to complete the checkout process.
|
|
9308
|
+
*
|
|
9309
|
+
* @param groupId - The group ID to confirm checkout for
|
|
9310
|
+
* @param checkoutRef - The checkout reference ID from the prepare step
|
|
9311
|
+
*
|
|
9312
|
+
* @example
|
|
9313
|
+
* ```typescript
|
|
9314
|
+
* // Confirm checkout for a group
|
|
9315
|
+
* await CoBuy.confirmCheckout('fae238ae-7468-47e9-9eec-b6d52fe3b012', 'chk_9a6d8750-ed60-4795-a207-2abe955e8509');
|
|
9316
|
+
* ```
|
|
9317
|
+
*/
|
|
9318
|
+
async confirmCheckout(groupId, checkoutRef) {
|
|
9319
|
+
if (!this.configManager.isInitialized()) {
|
|
9320
|
+
this.logger.warn("SDK not initialized, cannot confirm checkout");
|
|
9321
|
+
return;
|
|
9322
|
+
}
|
|
9323
|
+
if (!this.apiClient) {
|
|
9324
|
+
this.logger.error("API client not available");
|
|
9325
|
+
return;
|
|
9326
|
+
}
|
|
9327
|
+
try {
|
|
9328
|
+
const response = await this.apiClient.confirmCheckout(groupId, checkoutRef);
|
|
9329
|
+
if (response.success) {
|
|
9330
|
+
this.logger.info(`Checkout confirmed successfully for group: ${groupId}`);
|
|
9331
|
+
}
|
|
9332
|
+
else {
|
|
9333
|
+
this.logger.error("Failed to confirm checkout", response.error);
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
catch (error) {
|
|
9337
|
+
this.logger.error("Error confirming checkout", error);
|
|
9338
|
+
}
|
|
9339
|
+
}
|
|
9060
9340
|
/**
|
|
9061
9341
|
* Get the initialized API client instance
|
|
9062
9342
|
*/
|