@tagadapay/headless-sdk 1.20.1 → 1.22.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 +43 -0
- package/README.md +25 -0
- package/dist/core/helpers/paymentsApi.d.ts +139 -0
- package/dist/core/helpers/paymentsApi.d.ts.map +1 -0
- package/dist/core/helpers/paymentsApi.js +291 -0
- package/dist/core/helpers/paymentsApi.js.map +1 -0
- package/dist/core/helpers/paymentsApiAnswer.d.ts +26 -0
- package/dist/core/helpers/paymentsApiAnswer.d.ts.map +1 -0
- package/dist/core/helpers/paymentsApiAnswer.js +56 -0
- package/dist/core/helpers/paymentsApiAnswer.js.map +1 -0
- package/dist/core/helpers/stripeJs.d.ts +15 -0
- package/dist/core/helpers/stripeJs.d.ts.map +1 -0
- package/dist/core/helpers/stripeJs.js +24 -0
- package/dist/core/helpers/stripeJs.js.map +1 -0
- package/dist/core/helpers/stripeRadar.d.ts +14 -0
- package/dist/core/helpers/stripeRadar.d.ts.map +1 -0
- package/dist/core/helpers/stripeRadar.js +34 -0
- package/dist/core/helpers/stripeRadar.js.map +1 -0
- package/dist/core/modules/checkout.d.ts.map +1 -1
- package/dist/core/modules/checkout.js +1 -0
- package/dist/core/modules/checkout.js.map +1 -1
- package/dist/core/modules/payment.d.ts +18 -0
- package/dist/core/modules/payment.d.ts.map +1 -1
- package/dist/core/modules/payment.js +93 -29
- package/dist/core/modules/payment.js.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/react/hooks/usePayment.d.ts +3 -0
- package/dist/react/hooks/usePayment.d.ts.map +1 -1
- package/dist/react/hooks/usePayment.js.map +1 -1
- package/dist/tagada-headless-commerce.min.js +1 -1
- package/dist/tagada-headless-react.min.js +2 -2
- package/dist/tagada-headless-react.min.js.map +4 -4
- package/dist/tagada-headless.js +163 -34
- package/dist/tagada-headless.min.js +2 -2
- package/dist/tagada-headless.min.js.map +4 -4
- package/dist/tagada-pixels.min.js +1 -1
- package/dist/tgd/contract/registry.d.ts +1 -1
- package/dist/tgd/contract/registry.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/tagada-headless.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @tagadapay/headless-sdk v1.
|
|
2
|
+
* @tagadapay/headless-sdk v1.22.0
|
|
3
3
|
* Headless checkout, payments, offers, and CRM
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -142,7 +142,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
142
142
|
|
|
143
143
|
// src/core/version.ts
|
|
144
144
|
var SDK_NAME = "headless";
|
|
145
|
-
var SDK_VERSION = "1.
|
|
145
|
+
var SDK_VERSION = "1.22.0";
|
|
146
146
|
|
|
147
147
|
// src/core/http.ts
|
|
148
148
|
var BASE_URLS = {
|
|
@@ -724,7 +724,8 @@ var TagadaHeadlessBundle = (() => {
|
|
|
724
724
|
shippingAddress: this.normalizeAddress(cs.shippingAddress),
|
|
725
725
|
billingAddress: this.normalizeAddress(cs.billingAddress),
|
|
726
726
|
selectedShippingRateId: cs.shippingRateId ?? null,
|
|
727
|
-
metadata: cs.metadata
|
|
727
|
+
metadata: cs.metadata,
|
|
728
|
+
...typeof cs.draft === "boolean" ? { draft: cs.draft } : {}
|
|
728
729
|
};
|
|
729
730
|
}
|
|
730
731
|
/**
|
|
@@ -804,7 +805,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
804
805
|
}
|
|
805
806
|
|
|
806
807
|
// src/core/modules/track.ts
|
|
807
|
-
var CDN_URL = false ? "" : "https://cdn.jsdelivr.net/npm/@tagadapay/headless-sdk@1.
|
|
808
|
+
var CDN_URL = false ? "" : "https://cdn.jsdelivr.net/npm/@tagadapay/headless-sdk@1.22.0/dist/tagada-pixels.min.js";
|
|
808
809
|
function loadScript(src, isReady) {
|
|
809
810
|
if (isReady())
|
|
810
811
|
return Promise.resolve();
|
|
@@ -1430,6 +1431,71 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1430
1431
|
return error instanceof Error && error.message ? error.message : UNAVAILABLE;
|
|
1431
1432
|
}
|
|
1432
1433
|
|
|
1434
|
+
// src/core/helpers/paymentsApiAnswer.ts
|
|
1435
|
+
function readStartedPayment(answer) {
|
|
1436
|
+
if (!answer || typeof answer !== "object" || Array.isArray(answer))
|
|
1437
|
+
return null;
|
|
1438
|
+
const { payment, order, paymentId, clientSecret, amount, currency, checkoutSessionId, radar } = answer;
|
|
1439
|
+
if (payment !== void 0 || order !== void 0)
|
|
1440
|
+
return null;
|
|
1441
|
+
if (typeof paymentId !== "string" || !paymentId || typeof clientSecret !== "string" || !clientSecret)
|
|
1442
|
+
return null;
|
|
1443
|
+
return {
|
|
1444
|
+
paymentId,
|
|
1445
|
+
clientSecret,
|
|
1446
|
+
...typeof amount === "number" ? { amount } : {},
|
|
1447
|
+
...typeof currency === "string" ? { currency } : {},
|
|
1448
|
+
...typeof checkoutSessionId === "string" ? { checkoutSessionId } : {},
|
|
1449
|
+
...radarKey(radar) ? { radar: { publishableKey: radarKey(radar) } } : {}
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
function radarKey(radar) {
|
|
1453
|
+
const key = radar && typeof radar === "object" ? radar.publishableKey : null;
|
|
1454
|
+
return typeof key === "string" && key.startsWith("pk_") ? key : null;
|
|
1455
|
+
}
|
|
1456
|
+
var PENDING_KEY = "tgd_payments_api_return";
|
|
1457
|
+
var PENDING_TTL_MS = 60 * 6e4;
|
|
1458
|
+
function takeParkedPaymentsApiReturn(paymentId) {
|
|
1459
|
+
try {
|
|
1460
|
+
const raw = sessionStorage.getItem(PENDING_KEY);
|
|
1461
|
+
if (!raw)
|
|
1462
|
+
return null;
|
|
1463
|
+
const parked = JSON.parse(raw);
|
|
1464
|
+
if (parked.paymentId !== paymentId)
|
|
1465
|
+
return null;
|
|
1466
|
+
sessionStorage.removeItem(PENDING_KEY);
|
|
1467
|
+
if (!parked.checkoutSessionId || !parked.at || Date.now() - parked.at > PENDING_TTL_MS)
|
|
1468
|
+
return null;
|
|
1469
|
+
return { checkoutSessionId: parked.checkoutSessionId };
|
|
1470
|
+
} catch {
|
|
1471
|
+
return null;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
// src/core/helpers/stripeJs.ts
|
|
1476
|
+
function loadStripeJs() {
|
|
1477
|
+
if (typeof window === "undefined")
|
|
1478
|
+
return Promise.reject(new Error("Stripe Radar needs a browser"));
|
|
1479
|
+
const fromPage = () => window.Stripe;
|
|
1480
|
+
const loaded = fromPage();
|
|
1481
|
+
if (loaded)
|
|
1482
|
+
return Promise.resolve(loaded);
|
|
1483
|
+
return new Promise((resolve, reject) => {
|
|
1484
|
+
const script2 = document.createElement("script");
|
|
1485
|
+
script2.src = "https://js.stripe.com/v3/";
|
|
1486
|
+
script2.async = true;
|
|
1487
|
+
script2.onload = () => {
|
|
1488
|
+
const stripe = fromPage();
|
|
1489
|
+
if (stripe)
|
|
1490
|
+
resolve(stripe);
|
|
1491
|
+
else
|
|
1492
|
+
reject(new Error("Stripe.js loaded without window.Stripe"));
|
|
1493
|
+
};
|
|
1494
|
+
script2.onerror = () => reject(new Error("Failed to load Stripe.js"));
|
|
1495
|
+
document.head.appendChild(script2);
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1433
1499
|
// src/core/helpers/oceanpayment.ts
|
|
1434
1500
|
var OCEAN_SDK_URL = "https://secure.oceanpayment.com/pages/js/oceanpayment.js";
|
|
1435
1501
|
var OCEAN_CONTAINER_ID = "oceanpayment-element";
|
|
@@ -1512,6 +1578,16 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1512
1578
|
}
|
|
1513
1579
|
|
|
1514
1580
|
// src/core/modules/payment.ts
|
|
1581
|
+
function loadPaymentsApiFlow() {
|
|
1582
|
+
if (true) {
|
|
1583
|
+
return Promise.reject(
|
|
1584
|
+
new Error(
|
|
1585
|
+
"This store takes payments through the Payments API, which the CDN build does not support yet: install @tagadapay/headless-sdk and @tagadapay/core-js 3.7.0 or later from npm."
|
|
1586
|
+
)
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
return import("../helpers/paymentsApi.js");
|
|
1590
|
+
}
|
|
1515
1591
|
var FAILED_PAYMENT_STATUSES = /* @__PURE__ */ new Set(["failed", "declined", "rejected", "error"]);
|
|
1516
1592
|
var oceanSlot = null;
|
|
1517
1593
|
var oceanSlotTaken = () => !!oceanSlot && (!oceanSlot.attached || oceanSlot.element.isConnected);
|
|
@@ -1539,28 +1615,6 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1539
1615
|
metadata: entry.metadata ?? void 0
|
|
1540
1616
|
};
|
|
1541
1617
|
}
|
|
1542
|
-
function loadStripeJs() {
|
|
1543
|
-
if (typeof window === "undefined")
|
|
1544
|
-
return Promise.reject(new Error("Stripe Radar needs a browser"));
|
|
1545
|
-
const fromPage = () => window.Stripe;
|
|
1546
|
-
const loaded = fromPage();
|
|
1547
|
-
if (loaded)
|
|
1548
|
-
return Promise.resolve(loaded);
|
|
1549
|
-
return new Promise((resolve, reject) => {
|
|
1550
|
-
const script2 = document.createElement("script");
|
|
1551
|
-
script2.src = "https://js.stripe.com/v3/";
|
|
1552
|
-
script2.async = true;
|
|
1553
|
-
script2.onload = () => {
|
|
1554
|
-
const stripe = fromPage();
|
|
1555
|
-
if (stripe)
|
|
1556
|
-
resolve(stripe);
|
|
1557
|
-
else
|
|
1558
|
-
reject(new Error("Stripe.js loaded without window.Stripe"));
|
|
1559
|
-
};
|
|
1560
|
-
script2.onerror = () => reject(new Error("Failed to load Stripe.js"));
|
|
1561
|
-
document.head.appendChild(script2);
|
|
1562
|
-
});
|
|
1563
|
-
}
|
|
1564
1618
|
var PaymentModule = class {
|
|
1565
1619
|
constructor(http, storeId, environment, checkout, onPaid, onSignal) {
|
|
1566
1620
|
this.http = http;
|
|
@@ -1575,6 +1629,11 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1575
1629
|
* without a second network round-trip inside Apple's authorization window.
|
|
1576
1630
|
*/
|
|
1577
1631
|
this.lastPaymentSetup = null;
|
|
1632
|
+
/**
|
|
1633
|
+
* Payments API (V3) store: what the pay call knew about each payment it started (the session it
|
|
1634
|
+
* pays, the shopper's method), so `finalize()` can confirm it from the bare pay answer.
|
|
1635
|
+
*/
|
|
1636
|
+
this.paymentsApiStarts = /* @__PURE__ */ new Map();
|
|
1578
1637
|
}
|
|
1579
1638
|
// ---------------------------------------------------------------------------
|
|
1580
1639
|
// Discovery: what payment methods are available?
|
|
@@ -1785,7 +1844,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1785
1844
|
*/
|
|
1786
1845
|
async pay(opts) {
|
|
1787
1846
|
if (opts.tagadaToken && !opts.paymentInstrumentId) {
|
|
1788
|
-
return this.http.post("/api/v1/payment/pay-with-token", {
|
|
1847
|
+
return this.rememberPaymentsApiStart(await this.http.post("/api/v1/payment/pay-with-token", {
|
|
1789
1848
|
tagadaToken: opts.tagadaToken,
|
|
1790
1849
|
checkoutSessionId: opts.checkoutSessionId,
|
|
1791
1850
|
returnUrl: opts.returnUrl,
|
|
@@ -1794,9 +1853,9 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1794
1853
|
paymentMethod: opts.paymentMethod,
|
|
1795
1854
|
isExpress: opts.isExpress,
|
|
1796
1855
|
metadata: opts.metadata
|
|
1797
|
-
});
|
|
1856
|
+
}), opts);
|
|
1798
1857
|
}
|
|
1799
|
-
return this.http.post("/api/public/v1/checkout/pay-v2", {
|
|
1858
|
+
return this.rememberPaymentsApiStart(await this.http.post("/api/public/v1/checkout/pay-v2", {
|
|
1800
1859
|
checkoutSessionId: opts.checkoutSessionId,
|
|
1801
1860
|
paymentInstrumentId: opts.paymentInstrumentId,
|
|
1802
1861
|
storeId: this.storeId,
|
|
@@ -1807,14 +1866,14 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1807
1866
|
isExpress: opts.isExpress,
|
|
1808
1867
|
metadata: opts.metadata,
|
|
1809
1868
|
returnUrl: opts.returnUrl
|
|
1810
|
-
});
|
|
1869
|
+
}), opts);
|
|
1811
1870
|
}
|
|
1812
1871
|
/**
|
|
1813
1872
|
* Low-level pay: process payment with an existing instrument or for APM/express flows
|
|
1814
1873
|
* where no instrument is needed (redirect-based methods).
|
|
1815
1874
|
*/
|
|
1816
1875
|
async payDirect(opts) {
|
|
1817
|
-
return this.http.post("/api/public/v1/checkout/pay-v2", {
|
|
1876
|
+
return this.rememberPaymentsApiStart(await this.http.post("/api/public/v1/checkout/pay-v2", {
|
|
1818
1877
|
checkoutSessionId: opts.checkoutSessionId,
|
|
1819
1878
|
paymentInstrumentId: opts.paymentInstrumentId ?? "",
|
|
1820
1879
|
storeId: this.storeId,
|
|
@@ -1824,7 +1883,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
1824
1883
|
isExpress: opts.isExpress,
|
|
1825
1884
|
threedsSessionId: opts.threedsSessionId,
|
|
1826
1885
|
returnUrl: opts.returnUrl
|
|
1827
|
-
});
|
|
1886
|
+
}), opts);
|
|
1828
1887
|
}
|
|
1829
1888
|
/**
|
|
1830
1889
|
* Persist a wallet contact onto the session before the charge.
|
|
@@ -2001,13 +2060,18 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2001
2060
|
/**
|
|
2002
2061
|
* Process an APM payment (Klarna, iDEAL, etc.) via redirect.
|
|
2003
2062
|
* These typically don't require a payment instrument -- the processor handles the redirect.
|
|
2063
|
+
*
|
|
2064
|
+
* `returnUrl` is the page that runs `maybeResumeFromUrl()` after the redirect. It defaults to the
|
|
2065
|
+
* current page, like `processPayment()`. pay-v2 still prefers the session's checkout page when it
|
|
2066
|
+
* has a live one, so this applies to headless pages. Pass the same value to `finalize()`.
|
|
2004
2067
|
*/
|
|
2005
2068
|
async processApm(opts) {
|
|
2006
2069
|
return this.payDirect({
|
|
2007
2070
|
checkoutSessionId: opts.checkoutSessionId,
|
|
2008
2071
|
paymentMethod: opts.paymentMethod,
|
|
2009
2072
|
processorId: opts.processorId,
|
|
2010
|
-
paymentFlowId: opts.paymentFlowId
|
|
2073
|
+
paymentFlowId: opts.paymentFlowId,
|
|
2074
|
+
returnUrl: opts.returnUrl ?? (typeof window !== "undefined" ? window.location.href : void 0)
|
|
2011
2075
|
});
|
|
2012
2076
|
}
|
|
2013
2077
|
/**
|
|
@@ -2307,6 +2371,11 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2307
2371
|
var _a, _b, _c;
|
|
2308
2372
|
const payment = input.payment;
|
|
2309
2373
|
const returnUrl = (opts == null ? void 0 : opts.returnUrl) ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
2374
|
+
if (!payment) {
|
|
2375
|
+
const started = readStartedPayment(input);
|
|
2376
|
+
if (started)
|
|
2377
|
+
return this.finalizeOnPaymentsApi(started, returnUrl);
|
|
2378
|
+
}
|
|
2310
2379
|
if (payment.status === "succeeded") {
|
|
2311
2380
|
this.emitPaid((_a = input.order) == null ? void 0 : _a.id, payment);
|
|
2312
2381
|
return { status: "succeeded", payment, order: input.order };
|
|
@@ -2327,6 +2396,11 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2327
2396
|
* You can also call it manually in non-React apps.
|
|
2328
2397
|
*/
|
|
2329
2398
|
async resumeAfterRedirect(paymentId) {
|
|
2399
|
+
const parked = takeParkedPaymentsApiReturn(paymentId);
|
|
2400
|
+
if (parked) {
|
|
2401
|
+
const url2 = typeof window !== "undefined" ? window.location.href : void 0;
|
|
2402
|
+
return this.onPaymentsApi((flow, host) => flow.resumeOnPaymentsApi(host, paymentId, parked.checkoutSessionId, url2));
|
|
2403
|
+
}
|
|
2330
2404
|
return this.pollUntilDone(paymentId);
|
|
2331
2405
|
}
|
|
2332
2406
|
/**
|
|
@@ -2616,6 +2690,48 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2616
2690
|
return { status: "pending", paymentId };
|
|
2617
2691
|
}
|
|
2618
2692
|
// ---------------------------------------------------------------------------
|
|
2693
|
+
// Internal: Payments API (V3) stores
|
|
2694
|
+
// ---------------------------------------------------------------------------
|
|
2695
|
+
/** Keeps what a V3 pay answer does not say (its session, the method); returns the answer as is. */
|
|
2696
|
+
rememberPaymentsApiStart(answer, opts) {
|
|
2697
|
+
const started = answer && !answer.payment ? readStartedPayment(answer) : null;
|
|
2698
|
+
if (started) {
|
|
2699
|
+
this.paymentsApiStarts.set(started.paymentId, {
|
|
2700
|
+
checkoutSessionId: started.checkoutSessionId ?? opts.checkoutSessionId,
|
|
2701
|
+
...opts.paymentMethod ? { paymentMethod: opts.paymentMethod } : {}
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2704
|
+
return answer;
|
|
2705
|
+
}
|
|
2706
|
+
/** Confirms a started V3 payment with payments-js and runs it to the V2-shaped result. */
|
|
2707
|
+
finalizeOnPaymentsApi(started, returnUrl) {
|
|
2708
|
+
const known = this.paymentsApiStarts.get(started.paymentId);
|
|
2709
|
+
this.paymentsApiStarts.delete(started.paymentId);
|
|
2710
|
+
return this.onPaymentsApi(
|
|
2711
|
+
(flow, host) => flow.finalizeOnPaymentsApi(host, started, {
|
|
2712
|
+
checkoutSessionId: known == null ? void 0 : known.checkoutSessionId,
|
|
2713
|
+
paymentMethod: known == null ? void 0 : known.paymentMethod,
|
|
2714
|
+
returnUrl
|
|
2715
|
+
})
|
|
2716
|
+
);
|
|
2717
|
+
}
|
|
2718
|
+
/** Runs `run` with the lazily imported V3 flow; a flow that cannot load is a failed payment. */
|
|
2719
|
+
async onPaymentsApi(run) {
|
|
2720
|
+
let flow;
|
|
2721
|
+
try {
|
|
2722
|
+
flow = await loadPaymentsApiFlow();
|
|
2723
|
+
} catch (error) {
|
|
2724
|
+
return { status: "failed", error: error instanceof Error ? error.message : String(error) };
|
|
2725
|
+
}
|
|
2726
|
+
return run(flow, {
|
|
2727
|
+
http: this.http,
|
|
2728
|
+
storeId: this.storeId,
|
|
2729
|
+
checkout: this.checkout,
|
|
2730
|
+
stepConfig: this.readInjectedStepConfigRaw(),
|
|
2731
|
+
onPaid: (orderId, payment) => this.emitPaid(orderId, payment)
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
// ---------------------------------------------------------------------------
|
|
2619
2735
|
// Internal helpers
|
|
2620
2736
|
// ---------------------------------------------------------------------------
|
|
2621
2737
|
/**
|
|
@@ -2635,6 +2751,19 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2635
2751
|
return null;
|
|
2636
2752
|
}
|
|
2637
2753
|
}
|
|
2754
|
+
/** The whole injected step config (Tagada-hosted pages), or null. */
|
|
2755
|
+
readInjectedStepConfigRaw() {
|
|
2756
|
+
if (typeof window === "undefined")
|
|
2757
|
+
return null;
|
|
2758
|
+
const raw = window.__TGD_STEP_CONFIG__;
|
|
2759
|
+
if (!raw)
|
|
2760
|
+
return null;
|
|
2761
|
+
try {
|
|
2762
|
+
return typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
2763
|
+
} catch {
|
|
2764
|
+
return null;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2638
2767
|
/** Tracking hook. Never throws, never awaits: a pixel must not be able to break a payment. */
|
|
2639
2768
|
emitPaid(orderId, payment) {
|
|
2640
2769
|
var _a;
|
|
@@ -2667,7 +2796,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
2667
2796
|
|
|
2668
2797
|
// src/core/modules/lazyCommerce.ts
|
|
2669
2798
|
var script = typeof document === "undefined" ? null : document.currentScript;
|
|
2670
|
-
var url = (script == null ? void 0 : script.src) ? new URL("tagada-headless-commerce.min.js", script.src).href : "https://cdn.jsdelivr.net/npm/@tagadapay/headless-sdk@1.
|
|
2799
|
+
var url = (script == null ? void 0 : script.src) ? new URL("tagada-headless-commerce.min.js", script.src).href : "https://cdn.jsdelivr.net/npm/@tagadapay/headless-sdk@1.22.0/dist/tagada-headless-commerce.min.js";
|
|
2671
2800
|
var loading;
|
|
2672
2801
|
function loadCommerce() {
|
|
2673
2802
|
if (window.TagadaHeadlessCommerce)
|