@tagadapay/headless-sdk 1.3.1 → 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 +91 -7
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/modules/checkout.d.ts +71 -8
- package/dist/core/modules/checkout.d.ts.map +1 -1
- package/dist/core/modules/checkout.js +129 -35
- package/dist/core/modules/checkout.js.map +1 -1
- package/dist/core/modules/payment.d.ts +62 -1
- package/dist/core/modules/payment.d.ts.map +1 -1
- package/dist/core/modules/payment.js +225 -0
- package/dist/core/modules/payment.js.map +1 -1
- package/dist/core/types.d.ts +80 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/react/hooks/useCheckout.d.ts.map +1 -1
- package/dist/react/hooks/useCheckout.js +2 -12
- package/dist/react/hooks/useCheckout.js.map +1 -1
- package/dist/react/hooks/usePayment.d.ts +39 -10
- package/dist/react/hooks/usePayment.d.ts.map +1 -1
- package/dist/react/hooks/usePayment.js +116 -8
- package/dist/react/hooks/usePayment.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/tagada-headless-react.min.js +2 -2
- package/dist/tagada-headless-react.min.js.map +3 -3
- package/dist/tagada-headless.js +321 -34
- package/dist/tagada-headless.min.js +2 -2
- package/dist/tagada-headless.min.js.map +3 -3
- package/package.json +1 -1
package/dist/tagada-headless.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @tagadapay/headless-sdk v1.
|
|
2
|
+
* @tagadapay/headless-sdk v1.4.0
|
|
3
3
|
* Headless checkout, payments, offers, and CRM
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -311,59 +311,117 @@ var TagadaHeadlessBundle = (() => {
|
|
|
311
311
|
);
|
|
312
312
|
}
|
|
313
313
|
/**
|
|
314
|
-
* Update customer
|
|
315
|
-
*
|
|
314
|
+
* Update customer identity (email, name, phone).
|
|
315
|
+
*
|
|
316
|
+
* Call this before `updateAddress()` — the SDK remembers the values and
|
|
317
|
+
* includes them automatically when addresses are submitted.
|
|
318
|
+
*
|
|
319
|
+
* If you prefer a single call, use `updateCustomerAndAddress()` instead.
|
|
316
320
|
*/
|
|
317
321
|
async updateCustomer(sessionId, customer) {
|
|
322
|
+
if (customer.email)
|
|
323
|
+
this.customerEmail = customer.email;
|
|
324
|
+
if (customer.firstName)
|
|
325
|
+
this.customerFirstName = customer.firstName;
|
|
326
|
+
if (customer.lastName)
|
|
327
|
+
this.customerLastName = customer.lastName;
|
|
328
|
+
if (customer.phone)
|
|
329
|
+
this.customerPhone = customer.phone;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Update shipping and/or billing address on the session.
|
|
333
|
+
*
|
|
334
|
+
* Automatically includes customer name/phone stored from `updateCustomer()`.
|
|
335
|
+
* Uses the same atomic API call as the production checkout, so email,
|
|
336
|
+
* customer name, and addresses are all persisted together.
|
|
337
|
+
*
|
|
338
|
+
* **Shipped products**: pass `shippingAddress`. If `billingAddress` is omitted,
|
|
339
|
+
* the shipping address is automatically used as billing.
|
|
340
|
+
*
|
|
341
|
+
* **Digital products**: pass only `billingAddress` (no shipping needed).
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* // Shipped product — billing = shipping automatically
|
|
345
|
+
* await checkout.updateAddress(sessionId, {
|
|
346
|
+
* shippingAddress: { line1: '10 Rue de la Paix', city: 'Paris', postalCode: '75002', country: 'FR' },
|
|
347
|
+
* });
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* // Digital product — billing only
|
|
351
|
+
* await checkout.updateAddress(sessionId, {
|
|
352
|
+
* billingAddress: { country: 'FR' },
|
|
353
|
+
* });
|
|
354
|
+
*/
|
|
355
|
+
async updateAddress(sessionId, addresses) {
|
|
356
|
+
const shipping = this.mapAddress(addresses.shippingAddress);
|
|
357
|
+
const billing = this.mapAddress(addresses.billingAddress);
|
|
358
|
+
const effectiveShipping = shipping ?? billing ?? {};
|
|
359
|
+
const effectiveBilling = billing ?? shipping;
|
|
360
|
+
const differentBilling = !!(addresses.billingAddress && addresses.shippingAddress);
|
|
318
361
|
await this.http.post(
|
|
319
362
|
`/api/v1/checkout-sessions/${sessionId}/customer-and-session-info`,
|
|
320
363
|
{
|
|
321
364
|
checkoutSessionId: sessionId,
|
|
322
|
-
partial: true,
|
|
323
365
|
customerData: {
|
|
324
|
-
email:
|
|
325
|
-
},
|
|
326
|
-
shippingAddress: {
|
|
327
|
-
firstName: customer.firstName,
|
|
328
|
-
lastName: customer.lastName,
|
|
329
|
-
phone: customer.phone
|
|
366
|
+
email: this.customerEmail
|
|
330
367
|
},
|
|
331
|
-
|
|
332
|
-
|
|
368
|
+
shippingAddress: effectiveShipping,
|
|
369
|
+
billingAddress: effectiveBilling ?? {},
|
|
370
|
+
differentBillingAddress: differentBilling
|
|
333
371
|
},
|
|
334
372
|
{ token: this.sessionToken }
|
|
335
373
|
);
|
|
336
374
|
}
|
|
337
375
|
/**
|
|
338
|
-
*
|
|
376
|
+
* Set customer info + addresses in one call (mirrors production checkout).
|
|
339
377
|
*
|
|
340
|
-
*
|
|
378
|
+
* Equivalent to calling `updateCustomer()` then `updateAddress()`, but
|
|
379
|
+
* in a single network request.
|
|
341
380
|
*/
|
|
342
|
-
async
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
381
|
+
async updateCustomerAndAddress(sessionId, data) {
|
|
382
|
+
if (data.customer.email)
|
|
383
|
+
this.customerEmail = data.customer.email;
|
|
384
|
+
if (data.customer.firstName)
|
|
385
|
+
this.customerFirstName = data.customer.firstName;
|
|
386
|
+
if (data.customer.lastName)
|
|
387
|
+
this.customerLastName = data.customer.lastName;
|
|
388
|
+
if (data.customer.phone)
|
|
389
|
+
this.customerPhone = data.customer.phone;
|
|
390
|
+
const shipping = this.mapAddress(data.shippingAddress);
|
|
391
|
+
const billing = this.mapAddress(data.billingAddress);
|
|
392
|
+
const effectiveShipping = shipping ?? billing ?? {};
|
|
393
|
+
const effectiveBilling = billing ?? shipping;
|
|
394
|
+
const differentBilling = !!(data.billingAddress && data.shippingAddress);
|
|
355
395
|
await this.http.post(
|
|
356
|
-
`/api/v1/checkout-sessions/${sessionId}/
|
|
396
|
+
`/api/v1/checkout-sessions/${sessionId}/customer-and-session-info`,
|
|
357
397
|
{
|
|
358
398
|
checkoutSessionId: sessionId,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
399
|
+
customerData: {
|
|
400
|
+
email: this.customerEmail
|
|
401
|
+
},
|
|
402
|
+
shippingAddress: effectiveShipping,
|
|
403
|
+
billingAddress: effectiveBilling ?? {},
|
|
404
|
+
differentBillingAddress: differentBilling
|
|
363
405
|
},
|
|
364
406
|
{ token: this.sessionToken }
|
|
365
407
|
);
|
|
366
408
|
}
|
|
409
|
+
/** Map an SDK Address to the API shape, injecting stored customer fields. */
|
|
410
|
+
mapAddress(a) {
|
|
411
|
+
if (!a)
|
|
412
|
+
return void 0;
|
|
413
|
+
return stripEmpty({
|
|
414
|
+
firstName: a.firstName ?? this.customerFirstName,
|
|
415
|
+
lastName: a.lastName ?? this.customerLastName,
|
|
416
|
+
phone: a.phone ?? this.customerPhone,
|
|
417
|
+
address1: a.line1,
|
|
418
|
+
address2: a.line2,
|
|
419
|
+
city: a.city,
|
|
420
|
+
state: a.state,
|
|
421
|
+
postal: a.postalCode,
|
|
422
|
+
country: a.country
|
|
423
|
+
});
|
|
424
|
+
}
|
|
367
425
|
/** Apply a promotion code to the session. */
|
|
368
426
|
async applyPromoCode(sessionId, code) {
|
|
369
427
|
await this.http.post(
|
|
@@ -380,7 +438,13 @@ var TagadaHeadlessBundle = (() => {
|
|
|
380
438
|
{ token: this.sessionToken }
|
|
381
439
|
);
|
|
382
440
|
}
|
|
383
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Fetch available shipping rates for the session's address.
|
|
443
|
+
* Only relevant for **shipped products** — digital products can skip this step.
|
|
444
|
+
*
|
|
445
|
+
* Requires a shipping address to be set first via `updateAddress()`.
|
|
446
|
+
* Returns an empty array if no rates are configured or address is missing.
|
|
447
|
+
*/
|
|
384
448
|
async getShippingRates(sessionId) {
|
|
385
449
|
const res = await this.http.get(
|
|
386
450
|
`/api/v1/checkout-sessions/${sessionId}/shipping-rates`,
|
|
@@ -388,7 +452,10 @@ var TagadaHeadlessBundle = (() => {
|
|
|
388
452
|
);
|
|
389
453
|
return res.rates ?? [];
|
|
390
454
|
}
|
|
391
|
-
/**
|
|
455
|
+
/**
|
|
456
|
+
* Select a shipping rate for the session.
|
|
457
|
+
* Only relevant for **shipped products** — digital products can skip this step.
|
|
458
|
+
*/
|
|
392
459
|
async selectShippingRate(sessionId, rateId) {
|
|
393
460
|
await this.http.post(
|
|
394
461
|
`/api/v1/checkout-sessions/${sessionId}/shipping-rate`,
|
|
@@ -452,6 +519,15 @@ var TagadaHeadlessBundle = (() => {
|
|
|
452
519
|
};
|
|
453
520
|
}
|
|
454
521
|
};
|
|
522
|
+
function stripEmpty(obj) {
|
|
523
|
+
const result = {};
|
|
524
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
525
|
+
if (v !== void 0 && v !== null && v !== "") {
|
|
526
|
+
result[k] = v;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
530
|
+
}
|
|
455
531
|
|
|
456
532
|
// src/core/modules/payment.ts
|
|
457
533
|
var PaymentModule = class {
|
|
@@ -598,6 +674,7 @@ var TagadaHeadlessBundle = (() => {
|
|
|
598
674
|
return this.http.post("/api/v1/payment/pay-with-token", {
|
|
599
675
|
tagadaToken: opts.tagadaToken,
|
|
600
676
|
checkoutSessionId: opts.checkoutSessionId,
|
|
677
|
+
returnUrl: opts.returnUrl,
|
|
601
678
|
paymentFlowId: opts.paymentFlowId,
|
|
602
679
|
processorId: opts.processorId,
|
|
603
680
|
paymentMethod: opts.paymentMethod,
|
|
@@ -682,6 +759,67 @@ var TagadaHeadlessBundle = (() => {
|
|
|
682
759
|
});
|
|
683
760
|
}
|
|
684
761
|
// ---------------------------------------------------------------------------
|
|
762
|
+
// High-level orchestrator — the ONE function beginners should call
|
|
763
|
+
// ---------------------------------------------------------------------------
|
|
764
|
+
/**
|
|
765
|
+
* Process a payment end-to-end: pay, handle 3DS / redirects, poll until done.
|
|
766
|
+
*
|
|
767
|
+
* This is the **recommended** way to process payments. It wraps `pay()`, detects
|
|
768
|
+
* `requireAction`, runs 3DS challenges (if `@tagadapay/core-js` is installed),
|
|
769
|
+
* and polls until a terminal status.
|
|
770
|
+
*
|
|
771
|
+
* Returns a discriminated union so you can pattern-match on `result.status`:
|
|
772
|
+
*
|
|
773
|
+
* @example
|
|
774
|
+
* ```ts
|
|
775
|
+
* const result = await payment.processPayment({
|
|
776
|
+
* checkoutSessionId: session.id,
|
|
777
|
+
* tagadaToken,
|
|
778
|
+
* });
|
|
779
|
+
*
|
|
780
|
+
* switch (result.status) {
|
|
781
|
+
* case 'succeeded':
|
|
782
|
+
* console.log('Paid!', result.payment.id);
|
|
783
|
+
* break;
|
|
784
|
+
* case 'requires_redirect':
|
|
785
|
+
* // In browser: window.location.href = result.redirectUrl
|
|
786
|
+
* // The React hook handles this automatically.
|
|
787
|
+
* break;
|
|
788
|
+
* case 'failed':
|
|
789
|
+
* console.error(result.error);
|
|
790
|
+
* break;
|
|
791
|
+
* }
|
|
792
|
+
* ```
|
|
793
|
+
*/
|
|
794
|
+
async processPayment(opts) {
|
|
795
|
+
var _a, _b;
|
|
796
|
+
if (!opts.returnUrl && typeof window !== "undefined") {
|
|
797
|
+
opts = { ...opts, returnUrl: window.location.href };
|
|
798
|
+
}
|
|
799
|
+
const payResult = await this.pay(opts);
|
|
800
|
+
const payment = payResult.payment;
|
|
801
|
+
if (payment.status === "succeeded") {
|
|
802
|
+
return { status: "succeeded", payment, order: payResult.order };
|
|
803
|
+
}
|
|
804
|
+
if (payment.status === "failed" || payment.status === "declined") {
|
|
805
|
+
const msg = ((_a = payment.requireActionData) == null ? void 0 : _a.message) || ((_b = payment.requireActionData) == null ? void 0 : _b.errorCode) || `Payment ${payment.status}`;
|
|
806
|
+
return { status: "failed", error: msg, payment };
|
|
807
|
+
}
|
|
808
|
+
if (payment.requireAction && payment.requireAction !== "none" && payment.requireActionData) {
|
|
809
|
+
return this.handlePaymentAction(payment, opts);
|
|
810
|
+
}
|
|
811
|
+
return this.pollUntilDone(payment.id);
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Resume a payment after the user returns from a redirect (3DS, processor auth, APM).
|
|
815
|
+
*
|
|
816
|
+
* Called automatically by `usePayment()` in React when it detects return-URL params.
|
|
817
|
+
* You can also call it manually in non-React apps.
|
|
818
|
+
*/
|
|
819
|
+
async resumeAfterRedirect(paymentId) {
|
|
820
|
+
return this.pollUntilDone(paymentId);
|
|
821
|
+
}
|
|
822
|
+
// ---------------------------------------------------------------------------
|
|
685
823
|
// Status polling
|
|
686
824
|
// ---------------------------------------------------------------------------
|
|
687
825
|
/** Get current status of a payment. */
|
|
@@ -711,6 +849,155 @@ var TagadaHeadlessBundle = (() => {
|
|
|
711
849
|
paymentId
|
|
712
850
|
});
|
|
713
851
|
}
|
|
852
|
+
/** Tell the server this action has been seen / is being processed. */
|
|
853
|
+
async markActionProcessed(paymentId) {
|
|
854
|
+
try {
|
|
855
|
+
await this.http.post("/api/v1/payments/require-action/processed", {
|
|
856
|
+
paymentId
|
|
857
|
+
});
|
|
858
|
+
} catch {
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
// ---------------------------------------------------------------------------
|
|
862
|
+
// Internal: action routing
|
|
863
|
+
// ---------------------------------------------------------------------------
|
|
864
|
+
/**
|
|
865
|
+
* Route a payment action to the appropriate handler.
|
|
866
|
+
* Returns `requires_redirect` for browser-level redirects,
|
|
867
|
+
* or attempts 3DS inline and polls to completion.
|
|
868
|
+
*/
|
|
869
|
+
async handlePaymentAction(payment, opts) {
|
|
870
|
+
const actionData = payment.requireActionData;
|
|
871
|
+
await this.markActionProcessed(payment.id);
|
|
872
|
+
const actionType = actionData.type;
|
|
873
|
+
switch (actionType) {
|
|
874
|
+
case "threeds_auth":
|
|
875
|
+
return this.handleThreedsAuth(payment, opts);
|
|
876
|
+
case "processor_auth":
|
|
877
|
+
case "redirect_to_payment":
|
|
878
|
+
return this.extractRedirect(payment, actionData);
|
|
879
|
+
case "redirect":
|
|
880
|
+
return this.extractRedirect(payment, actionData);
|
|
881
|
+
case "error":
|
|
882
|
+
return {
|
|
883
|
+
status: "failed",
|
|
884
|
+
error: actionData.message || actionData.errorCode || "Payment failed",
|
|
885
|
+
payment
|
|
886
|
+
};
|
|
887
|
+
default:
|
|
888
|
+
return this.extractRedirect(payment, actionData);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Extract redirect info from actionData.
|
|
893
|
+
* Works for processor_auth (GET or POST), redirect, and any unknown type with a URL.
|
|
894
|
+
*/
|
|
895
|
+
extractRedirect(payment, actionData) {
|
|
896
|
+
var _a, _b;
|
|
897
|
+
const redirect = (_a = actionData.metadata) == null ? void 0 : _a.redirect;
|
|
898
|
+
const url = (redirect == null ? void 0 : redirect.redirectUrl) || actionData.redirectUrl;
|
|
899
|
+
if (!url) {
|
|
900
|
+
return {
|
|
901
|
+
status: "failed",
|
|
902
|
+
error: `Payment requires action (${actionData.type}) but no redirect URL was provided`,
|
|
903
|
+
payment
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
return {
|
|
907
|
+
status: "requires_redirect",
|
|
908
|
+
redirectUrl: url,
|
|
909
|
+
method: ((_b = redirect == null ? void 0 : redirect.method) == null ? void 0 : _b.toUpperCase()) || "GET",
|
|
910
|
+
postData: redirect == null ? void 0 : redirect.data,
|
|
911
|
+
paymentId: payment.id
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Run a 3DS challenge using @tagadapay/core-js.
|
|
916
|
+
* If core-js is not installed, falls back to redirect.
|
|
917
|
+
*/
|
|
918
|
+
async handleThreedsAuth(payment, opts) {
|
|
919
|
+
var _a, _b;
|
|
920
|
+
const session = (_b = (_a = payment.requireActionData) == null ? void 0 : _a.metadata) == null ? void 0 : _b.threedsSession;
|
|
921
|
+
if (!(session == null ? void 0 : session.externalSessionId)) {
|
|
922
|
+
return this.extractRedirect(payment, payment.requireActionData);
|
|
923
|
+
}
|
|
924
|
+
let coreJs;
|
|
925
|
+
try {
|
|
926
|
+
coreJs = await import("@tagadapay/core-js");
|
|
927
|
+
} catch {
|
|
928
|
+
if (session.acsChallengeUrl) {
|
|
929
|
+
return {
|
|
930
|
+
status: "requires_redirect",
|
|
931
|
+
redirectUrl: session.acsChallengeUrl,
|
|
932
|
+
paymentId: payment.id
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
return this.extractRedirect(payment, payment.requireActionData);
|
|
936
|
+
}
|
|
937
|
+
try {
|
|
938
|
+
const manager = new coreJs.ThreedsManager({ provider: "basis_theory" });
|
|
939
|
+
await manager.initialize({ apiKey: void 0 });
|
|
940
|
+
await manager.startChallenge({
|
|
941
|
+
sessionId: session.externalSessionId,
|
|
942
|
+
acsChallengeUrl: session.acsChallengeUrl,
|
|
943
|
+
acsTransactionId: session.acsTransID,
|
|
944
|
+
threeDSVersion: session.messageVersion
|
|
945
|
+
});
|
|
946
|
+
await this.completeAfter3ds(payment.id);
|
|
947
|
+
return this.pollUntilDone(payment.id);
|
|
948
|
+
} catch {
|
|
949
|
+
if (session.acsChallengeUrl) {
|
|
950
|
+
return {
|
|
951
|
+
status: "requires_redirect",
|
|
952
|
+
redirectUrl: session.acsChallengeUrl,
|
|
953
|
+
paymentId: payment.id
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
return {
|
|
957
|
+
status: "failed",
|
|
958
|
+
error: "3D Secure authentication failed",
|
|
959
|
+
payment
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Poll until the payment reaches a terminal status, then return a ProcessPaymentResult.
|
|
965
|
+
* Also handles new requireAction that may appear during polling.
|
|
966
|
+
*/
|
|
967
|
+
async pollUntilDone(paymentId, opts) {
|
|
968
|
+
const interval = (opts == null ? void 0 : opts.intervalMs) ?? 1500;
|
|
969
|
+
const timeout = (opts == null ? void 0 : opts.timeoutMs) ?? 6e4;
|
|
970
|
+
const start = Date.now();
|
|
971
|
+
let consecutiveErrors = 0;
|
|
972
|
+
while (Date.now() - start < timeout) {
|
|
973
|
+
let status;
|
|
974
|
+
try {
|
|
975
|
+
status = await this.getPaymentStatus(paymentId);
|
|
976
|
+
consecutiveErrors = 0;
|
|
977
|
+
} catch {
|
|
978
|
+
consecutiveErrors++;
|
|
979
|
+
if (consecutiveErrors >= 3) {
|
|
980
|
+
return { status: "failed", error: "Payment verification failed due to network errors" };
|
|
981
|
+
}
|
|
982
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
if (status.status === "succeeded" || status.status === "pending" && status.subStatus === "authorized") {
|
|
986
|
+
return { status: "succeeded", payment: status, order: status.order };
|
|
987
|
+
}
|
|
988
|
+
if (status.status === "failed" || status.status === "declined") {
|
|
989
|
+
return { status: "failed", error: status.status, payment: status };
|
|
990
|
+
}
|
|
991
|
+
if (status.requireAction && status.requireAction !== "none" && status.requireActionData && !status.requireActionData.processed) {
|
|
992
|
+
return this.handlePaymentAction(
|
|
993
|
+
status,
|
|
994
|
+
{}
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
998
|
+
}
|
|
999
|
+
return { status: "pending", paymentId };
|
|
1000
|
+
}
|
|
714
1001
|
// ---------------------------------------------------------------------------
|
|
715
1002
|
// Internal helpers
|
|
716
1003
|
// ---------------------------------------------------------------------------
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @tagadapay/headless-sdk v1.
|
|
2
|
+
* @tagadapay/headless-sdk v1.4.0
|
|
3
3
|
* Headless checkout, payments, offers, and CRM
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
|
-
"use strict";var TagadaHeadlessBundle=(()=>{var re=Object.create;var G=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var ae=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var ce=(n,e)=>{for(var t in e)G(n,t,{get:e[t],enumerable:!0})},V=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ne(e))!ie.call(n,s)&&s!==t&&G(n,s,{get:()=>e[s],enumerable:!(r=se(e,s))||r.enumerable});return n};var de=(n,e,t)=>(t=n!=null?re(oe(n)):{},V(e||!n||!n.__esModule?G(t,"default",{value:n,enumerable:!0}):t,n)),ue=n=>V(G({},"__esModule",{value:!0}),n);var Ie={};ce(Ie,{AVAILABLE_LANGUAGES:()=>D,CatalogModule:()=>L,CheckoutModule:()=>C,CurrencyUtils:()=>w,CustomerModule:()=>R,GoogleAutocompleteCore:()=>E,HeadlessClient:()=>O,HttpClient:()=>I,ISODataCore:()=>U,OffersModule:()=>b,PaymentModule:()=>A,TagadaAuthError:()=>P,TagadaError:()=>y,TagadaNetworkError:()=>f,TagadaNotFoundError:()=>S,TagadaPaymentError:()=>H,TagadaRateLimitError:()=>v,TagadaValidationError:()=>k,createHeadlessClient:()=>Z,ensureGeoDataLoaded:()=>N,formatMoney:()=>J,getCountries:()=>T,getStatesForCountry:()=>_,isLanguageLoaded:()=>M,loadGoogleMapsScript:()=>B});var y=class extends Error{constructor(e,t,r,s){super(e),this.name="TagadaError",this.code=t,this.statusCode=r,this.details=s}},P=class extends y{constructor(e="Authentication failed. Check your API key or checkout token."){super(e,"auth_error",401),this.name="TagadaAuthError"}},k=class extends y{constructor(e,t=[]){super(e,"validation_error",422,{errors:t}),this.name="TagadaValidationError",this.errors=t}},S=class extends y{constructor(e,t){super(`${e} "${t}" not found.`,"not_found",404),this.name="TagadaNotFoundError"}},v=class extends y{constructor(e=1e3){super(`Rate limited. Retry after ${e}ms.`,"rate_limit",429),this.name="TagadaRateLimitError",this.retryAfterMs=e}},H=class extends y{constructor(e,t){super(e,"payment_error",void 0,t==null?void 0:t.details),this.name="TagadaPaymentError",this.paymentId=t==null?void 0:t.paymentId,this.requireAction=t==null?void 0:t.requireAction}},f=class extends y{constructor(e="Network request failed. Check your connection."){super(e,"network_error"),this.name="TagadaNetworkError"}};var W={production:"https://app.tagadapay.com",development:"https://app.dev.tagadapay.com",local:"http://localhost:3000"},I=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.timeout=e.timeout,this.apiKey=e.apiKey,this.getToken=e.getToken}static resolveBaseUrl(e,t){return t??W[e]??W.production}async request(e,t={}){var u;let{method:r="GET",body:s,headers:i={},params:o,token:a,signal:c}=t,l=`${this.baseUrl}${e}`;if(o){let g=new URLSearchParams;for(let[te,Y]of Object.entries(o))Y!==void 0&&g.set(te,String(Y));let x=g.toString();x&&(l+=`?${x}`)}let m={"Content-Type":"application/json",...i},p=a??this.apiKey??((u=this.getToken)==null?void 0:u.call(this));p&&(m["x-cms-token"]=p);let h=new AbortController,d=setTimeout(()=>h.abort(),this.timeout);try{let g=await fetch(l,{method:r,headers:m,body:s!=null?JSON.stringify(s):void 0,signal:c??h.signal});if(clearTimeout(d),g.ok){let x=await g.text();return x?JSON.parse(x):{}}throw await this.handleErrorResponse(g,e),new y("Unexpected error","unknown",g.status)}catch(g){throw clearTimeout(d),g instanceof y?g:g instanceof DOMException&&g.name==="AbortError"?new f(`Request to ${e} timed out after ${this.timeout}ms.`):new f(g instanceof Error?g.message:"Network request failed.")}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,r){return this.request(e,{...r,method:"POST",body:t})}patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t})}put(e,t,r){return this.request(e,{...r,method:"PUT",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}async handleErrorResponse(e,t){let r={};try{r=await e.json()}catch{}let s=r.message??r.error??`Request failed: ${e.status} ${e.statusText} on ${t}`;switch(e.status){case 401:case 403:throw new P(s);case 404:throw new S(t,"");case 422:{let i=Array.isArray(r.errors)?r.errors:[];throw new k(s,i)}case 429:{let i=Number(e.headers.get("Retry-After")??"1")*1e3;throw new v(i)}default:throw new y(s,"api_error",e.status,r)}}};var C=class{constructor(e,t,r){this.http=e;this.storeId=t;this.onTokenChange=r}async loadSession(e,t){var s;t&&(this.sessionToken=t,(s=this.onTokenChange)==null||s.call(this,t));let r=await this.http.get(`/api/v1/checkout-sessions/${e}/v2`,{params:{skipAsyncWait:"false"},token:this.sessionToken});return this.normalizeSession(r)}async createSession(e){var a;let t=e.items.map(c=>({variantId:c.variantId,priceId:c.priceId,quantity:c.quantity})),r={storeId:this.storeId,lineItems:t};e.currency&&(r.currency=e.currency),e.returnUrl&&(r.returnUrl=e.returnUrl),e.customerEmail&&(r.customer={email:e.customerEmail,firstName:e.customerFirstName,lastName:e.customerLastName,currency:e.currency});let s=await this.http.post("/api/v1/checkout/session/init",r),o=new URL(s.checkoutUrl).searchParams.get("token")??"";return this.sessionToken=o,o&&((a=this.onTokenChange)==null||a.call(this,o)),{checkoutUrl:s.checkoutUrl,checkoutToken:s.checkoutToken,sessionToken:o,customerId:s.customerId}}async updateCart(e,t){return this.http.post(`/api/v1/checkout-sessions/${e}/line-items`,{items:t},{token:this.sessionToken})}async updateCustomer(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,partial:!0,customerData:{email:t.email},shippingAddress:{firstName:t.firstName,lastName:t.lastName,phone:t.phone},billingAddress:{},differentBillingAddress:!1},{token:this.sessionToken})}async updateAddress(e,t){let r=s=>{if(s)return{address1:s.line1,address2:s.line2,city:s.city,state:s.state,postal:s.postalCode,country:s.country}};await this.http.post(`/api/v1/checkout-sessions/${e}/address`,{checkoutSessionId:e,data:{shippingAddress:r(t.shippingAddress)??{},billingAddress:r(t.billingAddress)}},{token:this.sessionToken})}async applyPromoCode(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/promotions/apply`,{checkoutSessionId:e,code:t},{token:this.sessionToken})}async removePromoCode(e,t){let r=t??"default";await this.http.delete(`/api/v1/checkout-sessions/${e}/promotions/${r}`,{token:this.sessionToken})}async getShippingRates(e){return(await this.http.get(`/api/v1/checkout-sessions/${e}/shipping-rates`,{token:this.sessionToken})).rates??[]}async selectShippingRate(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/shipping-rate`,{checkoutSessionId:e,shippingRateId:t},{token:this.sessionToken})}normalizeSession(e){let t=e.checkoutSession,r=t.orderSummaries??[],s=e.summary??t.summary??r[0]??{},i=t.sessionLineItems??[],o=t.customer,a=i.map(l=>{let m=l.price,p=(m==null?void 0:m.variant)??{},h=p.product??{},d=(m==null?void 0:m.currencyOptions)??{},u=d.USD??d[Object.keys(d)[0]];return{id:l.id,variantId:l.variantId,priceId:l.priceId,productName:h.name??"",variantName:p.name??"",quantity:l.quantity??1,unitAmount:(u==null?void 0:u.amount)??0,totalAmount:((u==null?void 0:u.amount)??0)*(l.quantity??1),currency:t.selectedPresentmentCurrency??"USD",imageUrl:p.imageUrl??""}}),c=s.items??[];return{id:t.id,storeId:t.storeId,checkoutToken:t.checkoutToken,currency:t.selectedPresentmentCurrency??"USD",items:a,totals:{subtotal:s.subtotalAmount??0,discount:s.totalPromotionAmount??0,shipping:s.shippingCost??0,tax:s.totalTaxAmount??0,total:s.totalAmount??c.reduce((l,m)=>l+(m.amount??0),0),currency:s.currency??t.selectedPresentmentCurrency??"USD"},customer:o?{id:o.id,email:o.email,firstName:o.firstName,lastName:o.lastName}:void 0,shippingAddress:t.shippingAddress,billingAddress:t.billingAddress,metadata:t.metadata}}};var A=class{constructor(e,t,r){this.http=e;this.storeId=t;this.environment=r}async getPaymentSetup(e){let t=await this.http.get("/api/v1/payment-methods",{params:{checkoutSessionId:e}}),r={};for(let s of t.methods??[]){let i=s.provider?`${s.method}:${s.provider}`:s.method;r[i]=s}return r}async getExpressMethods(e){var s,i;let t=await this.getPaymentSetup(e),r={};for(let[,o]of Object.entries(t)){if(!o.enabled||!o.express)continue;let a=o.method,c={type:a,available:!0,processorId:o.processorId,publishableKey:o.publishableKey,metadata:o.metadata};if(a==="apple_pay"||o.type==="apple_pay"){let l=typeof window<"u"&&"ApplePaySession"in window&&((i=(s=window.ApplePaySession)==null?void 0:s.canMakePayments)==null?void 0:i.call(s));r.applePay={...c,available:!!l}}else a==="google_pay"||o.type==="google_pay"?r.googlePay=c:a==="paypal"?r.paypal=c:a==="klarna"||a==="klarna_express"?r.klarna=c:a==="link"&&(r.link=c)}return r}async getStoreConfig(){let e=await this.http.get("/api/v1/checkout/config",{params:{storeId:this.storeId}});return e.config??e}async getEnabledMethods(e){let t=await this.getPaymentSetup(e);return Object.entries(t).filter(([,r])=>r.enabled).map(([r])=>r)}async tokenizeCard(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let s={cardNumber:e.cardNumber,expiryDate:e.expiryDate,cvc:e.cvc};e.cardholderName&&(s.cardholderName=e.cardholderName);let[i,o]=await Promise.all([r.tokenizeCard(s),r.tokenizeCardRaw(s)]);return{tagadaToken:i,rawToken:o}}async createInstrument(e){return this.http.post("/api/v1/payment/create-instrument-from-token",{tagadaToken:e.tagadaToken})}async create3dsSession(e){return this.http.post("/api/public/v1/threeds/create-session",{provider:e.provider??"basis_theory",storeId:this.storeId,paymentInstrumentId:e.paymentInstrumentId,sessionData:e.sessionData})}async pay(e){return e.tagadaToken&&!e.paymentInstrumentId?this.http.post("/api/v1/payment/pay-with-token",{tagadaToken:e.tagadaToken,checkoutSessionId:e.checkoutSessionId,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata}):this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId,storeId:this.storeId,paymentFlowId:e.paymentFlowId,threedsSessionId:e.threedsSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata})}async payDirect(e){return this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId??"",storeId:this.storeId,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,threedsSessionId:e.threedsSessionId})}async processApplePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeApplePay(e.applePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"apple_pay",isExpress:!0})}async processGooglePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeGooglePay(e.googlePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"google_pay",isExpress:!0})}async processApm(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,paymentMethod:e.paymentMethod,processorId:e.processorId,paymentFlowId:e.paymentFlowId})}async getPaymentStatus(e){return this.http.get(`/api/v1/payments/${e}`)}async pollPaymentStatus(e,t){let r=(t==null?void 0:t.intervalMs)??1500,s=(t==null?void 0:t.timeoutMs)??6e4,i=Date.now();for(;Date.now()-i<s;){let o=await this.getPaymentStatus(e);if(o.status==="succeeded"||o.status==="failed"||o.status==="declined")return o;await new Promise(a=>setTimeout(a,r))}throw new Error(`Payment ${e} did not reach terminal status within ${s}ms.`)}async completeAfter3ds(e){return this.http.post("/api/v1/payments/complete-after-3ds",{paymentId:e})}async loadCoreJs(){try{return await import("@tagadapay/core-js")}catch{throw new Error("This method requires @tagadapay/core-js. Install it: npm install @tagadapay/core-js")}}};var b=class{constructor(e,t){this.http=e;this.storeId=t}async getOffer(e){return this.http.get(`/api/v1/offers/${e}`)}async listOffers(e){var i;let t=`/api/v1/stores/${this.storeId}/offers`,r=[];if(e!=null&&e.type&&r.push(`type=${encodeURIComponent(e.type)}`),(i=e==null?void 0:e.ids)!=null&&i.length)for(let o of e.ids)r.push(`ids=${encodeURIComponent(o)}`);return r.length&&(t+=`?${r.join("&")}`),(await this.http.get(t)).offers??[]}async previewOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems})}async payPreviewedOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/pay-preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems,returnUrl:e.returnUrl??(typeof window<"u"?window.location.href:""),mainOrderId:e.mainOrderId,paymentInstrumentId:e.paymentInstrumentId})}async toggleOrderBump(e){return this.http.post(`/api/v1/checkout-sessions/${e.checkoutSessionId}/toggle-order-bump`,{orderBumpOfferId:e.orderBumpOfferId,selected:e.selected})}async listPostPurchaseOffers(e){let t=await this.http.get(`/api/v1/post-purchase/${e}/offers`);return Array.isArray(t)?t:[]}async acceptPostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/accept`,{items:e.items??[]})}async declinePostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/decline`)}};var R=class{constructor(e,t){this.http=e;this.storeId=t}async getProfile(e){return(await this.http.get(`/api/v1/customers/${e}`,{params:{storeId:this.storeId}})).customer}async getByEmail(e){try{return(await this.http.get("/api/v1/customers/by-email",{params:{email:e,storeId:this.storeId}})).customer}catch{return null}}async updateProfile(e,t){return(await this.http.patch(`/api/v1/customers/${e}`,{storeId:this.storeId,...t})).customer}async getOrders(e,t){return this.http.get(`/api/v1/customers/${e}/orders`,{params:{storeId:this.storeId,limit:t==null?void 0:t.limit,offset:t==null?void 0:t.offset}})}async getOrder(e){return(await this.http.get(`/api/v1/orders/${e}`,{params:{storeId:this.storeId}})).order}async getSubscriptions(e){return(await this.http.get(`/api/v1/customers/${e}/subscriptions`,{params:{storeId:this.storeId}})).subscriptions}async getSubscription(e){return(await this.http.get(`/api/v1/subscriptions/${e}`,{params:{storeId:this.storeId}})).subscription}};var L=class{constructor(e,t){this.http=e;this.storeId=t}async getProducts(e){var s,i;let t={storeId:this.storeId,includeVariants:!0,includePrices:!0};return(s=e==null?void 0:e.productIds)!=null&&s.length&&(t.productIds=e.productIds),(i=e==null?void 0:e.variantIds)!=null&&i.length&&(t.variantIds=e.variantIds),(await this.http.post("/api/v1/products",t)).items??[]}async getProduct(e){return(await this.getProducts({productIds:[e]}))[0]??null}};var O=class{constructor(e){let t=e.environment??"production",r=I.resolveBaseUrl(t,e.baseUrl);this.config={...e,environment:t,baseUrl:r,timeout:e.timeout??3e4},this.http=new I({baseUrl:r,timeout:this.config.timeout,apiKey:e.apiKey,getToken:()=>this._sessionToken});let s=i=>{this._sessionToken=i};this.checkout=new C(this.http,this.config.storeId,s),this.payment=new A(this.http,this.config.storeId,t),this.offers=new b(this.http,this.config.storeId),this.customer=new R(this.http,this.config.storeId),this.catalog=new L(this.http,this.config.storeId)}setSessionToken(e){this._sessionToken=e}};function Z(n){return new O(n)}var Q=!1,X=!1,K=[];function q(){X=!0;for(let n of K)n();K.length=0}function B(n,e={}){var t,r;return X||(r=(t=window.google)==null?void 0:t.maps)!=null&&r.places?(q(),Promise.resolve()):Q?new Promise(s=>K.push(s)):(Q=!0,new Promise((s,i)=>{if(K.push(s),document.querySelector('script[src*="maps.googleapis.com"]')){let l=()=>{var m,p;(p=(m=window.google)==null?void 0:m.maps)!=null&&p.places?q():setTimeout(l,100)};l();return}let a=new URLSearchParams({key:n,libraries:"places",v:e.version??"weekly"});e.language&&a.set("language",e.language),e.region&&a.set("region",e.region);let c=document.createElement("script");c.src=`https://maps.googleapis.com/maps/api/js?${a}`,c.async=!0,c.defer=!0,c.onload=()=>q(),c.onerror=()=>i(new Error("Failed to load Google Maps script")),document.head.appendChild(c)}))}var E=class n{static async searchPlaces(e,t={}){var s,i;if(!((i=(s=window.google)==null?void 0:s.maps)!=null&&i.places)||!e.trim())return[];let r=new window.google.maps.places.AutocompleteService;return new Promise(o=>{r.getPlacePredictions({input:e,types:t.types??["address"],componentRestrictions:t.componentRestrictions},(a,c)=>{var l,m,p;o(c===((p=(m=(l=window.google)==null?void 0:l.maps)==null?void 0:m.places)==null?void 0:p.PlacesServiceStatus.OK)&&a?a:[])})})}static async getPlaceDetails(e){var r,s;if(!((s=(r=window.google)==null?void 0:r.maps)!=null&&s.places))return null;let t=new window.google.maps.places.PlacesService(document.createElement("div"));return new Promise(i=>{t.getDetails({placeId:e,fields:["place_id","formatted_address","address_components","geometry"]},(o,a)=>{var c,l,m;i(a===((m=(l=(c=window.google)==null?void 0:c.maps)==null?void 0:l.places)==null?void 0:m.PlacesServiceStatus.OK)&&o?o:null)})})}static extractAddressComponents(e){let t={subpremise:"",streetNumber:"",route:"",locality:"",administrativeAreaLevel1:"",administrativeAreaLevel1Long:"",administrativeAreaLevel2:"",administrativeAreaLevel2Long:"",country:"",postalCode:"",fullStreetAddress:""},r="",s="",i="",o="",a="",c="",l="",m="";for(let d of e.address_components??[]){let u=d.types;u.includes("subpremise")&&(t.subpremise=d.long_name),u.includes("street_number")&&(t.streetNumber=d.long_name),u.includes("premise")&&(r=d.long_name),u.includes("route")&&(t.route=d.long_name),u.includes("neighborhood")&&(s=d.long_name),u.includes("sublocality_level_5")&&(i=d.long_name),u.includes("sublocality_level_4")&&(o=d.long_name),u.includes("sublocality_level_3")&&(a=d.long_name),u.includes("sublocality_level_2")&&(c=d.long_name),u.includes("sublocality_level_1")&&(l=d.long_name),u.includes("locality")&&(t.locality=d.long_name),u.includes("postal_town")&&(m=d.long_name),u.includes("administrative_area_level_2")&&(t.administrativeAreaLevel2=d.short_name,t.administrativeAreaLevel2Long=d.long_name),u.includes("administrative_area_level_1")&&(t.administrativeAreaLevel1=d.short_name,t.administrativeAreaLevel1Long=d.long_name),u.includes("country")&&(t.country=d.short_name),u.includes("postal_code")&&(t.postalCode=d.long_name)}t.locality||(t.locality=m||c||l||""),!t.administrativeAreaLevel1&&t.administrativeAreaLevel2&&(t.administrativeAreaLevel1=t.administrativeAreaLevel2Long||t.administrativeAreaLevel2,t.administrativeAreaLevel1Long=t.administrativeAreaLevel2Long);let p=t.streetNumber||r,h=t.route||i||o||a||s;if(t.subpremise&&p&&h)t.fullStreetAddress=`${t.subpremise}/${p} ${h}`;else if(p&&h)if(r&&o&&a){let d=`${a}-${o}-${r}`;c&&(d=`${d} ${c}`),t.fullStreetAddress=d}else t.fullStreetAddress=`${p} ${h}`;else h?t.fullStreetAddress=h:p&&(t.fullStreetAddress=p);return t.fullStreetAddress=t.fullStreetAddress.trim(),t}static extractFormattedAddress(e){let t=n.extractAddressComponents(e);return{address1:t.fullStreetAddress,city:t.locality,country:t.country,state:t.administrativeAreaLevel1,postal:t.postalCode}}};var ee="https://cvwnizdbugpz6jwk.public.blob.vercel-storage.com/geodata/v1",D=["en","ru","de","da","fr","es","zh","hi","pt","ja","ar","it","he"],$=new Map,F=new Map,j=new Map,z=new Map;async function le(n){let e=$.get(n);if(e)return e;let t=j.get(n);return t||(t=(async()=>{let r=`${ee}/${n}/countries.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let i=await s.json();return $.set(n,i),j.delete(n),i})(),j.set(n,t),t)}async function me(n){let e=F.get(n);if(e)return e;let t=z.get(n);return t||(t=(async()=>{let r=`${ee}/${n}/regions.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let i=await s.json();return F.set(n,i),z.delete(n),i})(),z.set(n,t),t)}function pe(n){return $.get(n)||$.get("en")||{}}function ge(n){return F.get(n)||F.get("en")||{}}async function N(n="en"){await Promise.all([le(n),me(n)])}var T=(n="en")=>{let e=pe(n);return Object.entries(e).map(([t,r])=>({code:t,name:r.n,iso3:r.i3,numeric:r.nu})).sort((t,r)=>t.name.localeCompare(r.name))},_=(n,e="en")=>{let r=ge(e)[n];return r?r.map(([s,i])=>({code:s,name:i,countryCode:n})).sort((s,i)=>s.name.localeCompare(i.name)):[]};function M(n){return $.has(n)}var U=class n{static ensureLoaded(e="en"){return N(e)}static getCountries(e="en"){let t=T(e),r={};for(let s of t)r[s.code]={iso:s.code,iso3:s.iso3??"",numeric:s.numeric??0,name:s.name};return r}static getCountryOptions(e="en"){return T(e).map(t=>({value:t.code,label:t.name}))}static getRegions(e,t="en"){return _(e,t).map(r=>({iso:r.code,name:r.name}))}static getRegionOptions(e,t="en"){return n.getRegions(e,t).map(r=>({value:r.iso,label:r.name}))}static findRegion(e,t,r="en"){return n.getRegions(e,r).find(s=>s.iso===t)??null}static mapGoogleToISO(e,t,r,s="en"){let i=n.getRegions(r,s);if(i.length===0)return null;let o=i.find(a=>a.iso===e);return o||(o=i.find(a=>a.name.toLowerCase()===e.toLowerCase()),o)||(o=i.find(a=>a.name.toLowerCase()===t.toLowerCase()),o)?o:(o=i.find(a=>a.name.toLowerCase().includes(t.toLowerCase())||t.toLowerCase().includes(a.name.toLowerCase())),o??null)}static isLanguageLoaded(e){return M(e)}static getAvailableLanguages(){return D}};var ye={USD:"$",EUR:"\u20AC",GBP:"\xA3",JPY:"\xA5",CAD:"C$",AUD:"A$",CHF:"CHF",CNY:"\xA5",SEK:"kr",NOK:"kr",DKK:"kr",PLN:"z\u0142",CZK:"K\u010D",HUF:"Ft",RON:"lei",BGN:"\u043B\u0432",HRK:"kn",RUB:"\u20BD",UAH:"\u20B4",TRY:"\u20BA",BRL:"R$",MXN:"$",ZAR:"R",INR:"\u20B9",KRW:"\u20A9",THB:"\u0E3F",VND:"\u20AB",IDR:"Rp",MYR:"RM",SGD:"S$",PHP:"\u20B1",TWD:"NT$",HKD:"HK$",ILS:"\u20AA",AED:"\u062F.\u0625",SAR:"\u0631.\u0633",QAR:"\u0631.\u0642",KWD:"\u062F.\u0643",BHD:"\u062F.\u0628",OMR:"\u0631.\u0639.",EGP:"\xA3",NGN:"\u20A6",KES:"KSh",GHS:"\u20B5",COP:"$",ARS:"$",CLP:"$",PEN:"S/",CRC:"\u20A1",DOP:"RD$",JMD:"J$",BOB:"Bs",PYG:"\u20B2",GTQ:"Q",NIO:"C$",PAB:"B/.",PKR:"\u20A8",BDT:"\u09F3",LKR:"\u20A8",NPR:"\u20A8",GEL:"\u20BE",AMD:"\u058F",AZN:"\u20BC",KZT:"\u20B8"},he={USD:"US Dollar",EUR:"Euro",GBP:"British Pound",JPY:"Japanese Yen",CAD:"Canadian Dollar",AUD:"Australian Dollar",CHF:"Swiss Franc",CNY:"Chinese Yuan",SEK:"Swedish Krona",NOK:"Norwegian Krone",DKK:"Danish Krone",PLN:"Polish Zloty",CZK:"Czech Koruna",HUF:"Hungarian Forint",BRL:"Brazilian Real",MXN:"Mexican Peso",INR:"Indian Rupee",KRW:"South Korean Won",THB:"Thai Baht",SGD:"Singapore Dollar",HKD:"Hong Kong Dollar",TWD:"Taiwan Dollar",ILS:"Israeli Shekel",AED:"UAE Dirham",SAR:"Saudi Riyal",ZAR:"South African Rand",TRY:"Turkish Lira",RUB:"Russian Ruble",NGN:"Nigerian Naira"},fe=new Set(["JPY","KRW","VND","IDR","LAK","KHR","MMK","PYG"]),w=class n{static getSymbol(e){return ye[e]??e}static getName(e){return he[e]??e}static getDecimalPlaces(e){return fe.has(e)?0:2}static getCurrency(e){return{code:e,symbol:n.getSymbol(e),name:n.getName(e),decimalPlaces:n.getDecimalPlaces(e)}}};function J(n,e="USD",t="en-US"){let r=w.getDecimalPlaces(e),s=n/(r===0?100:Math.pow(10,r));try{return new Intl.NumberFormat(t,{style:"currency",currency:e,minimumFractionDigits:r,maximumFractionDigits:r}).format(s)}catch{return`${w.getSymbol(e)}${s.toFixed(r)}`}}return ue(Ie);})();
|
|
6
|
+
"use strict";var TagadaHeadlessBundle=(()=>{var ne=Object.create;var q=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ae=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var Y=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var ue=(n,e)=>{for(var t in e)q(n,t,{get:e[t],enumerable:!0})},W=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of oe(e))!ce.call(n,s)&&s!==t&&q(n,s,{get:()=>e[s],enumerable:!(r=ie(e,s))||r.enumerable});return n};var Z=(n,e,t)=>(t=n!=null?ne(ae(n)):{},W(e||!n||!n.__esModule?q(t,"default",{value:n,enumerable:!0}):t,n)),de=n=>W(q({},"__esModule",{value:!0}),n);var we={};ue(we,{AVAILABLE_LANGUAGES:()=>N,CatalogModule:()=>T,CheckoutModule:()=>C,CurrencyUtils:()=>w,CustomerModule:()=>b,GoogleAutocompleteCore:()=>E,HeadlessClient:()=>O,HttpClient:()=>P,ISODataCore:()=>M,OffersModule:()=>R,PaymentModule:()=>A,TagadaAuthError:()=>I,TagadaError:()=>h,TagadaNetworkError:()=>f,TagadaNotFoundError:()=>k,TagadaPaymentError:()=>G,TagadaRateLimitError:()=>S,TagadaValidationError:()=>v,createHeadlessClient:()=>X,ensureGeoDataLoaded:()=>_,formatMoney:()=>J,getCountries:()=>L,getStatesForCountry:()=>$,isLanguageLoaded:()=>U,loadGoogleMapsScript:()=>B});var h=class extends Error{constructor(e,t,r,s){super(e),this.name="TagadaError",this.code=t,this.statusCode=r,this.details=s}},I=class extends h{constructor(e="Authentication failed. Check your API key or checkout token."){super(e,"auth_error",401),this.name="TagadaAuthError"}},v=class extends h{constructor(e,t=[]){super(e,"validation_error",422,{errors:t}),this.name="TagadaValidationError",this.errors=t}},k=class extends h{constructor(e,t){super(`${e} "${t}" not found.`,"not_found",404),this.name="TagadaNotFoundError"}},S=class extends h{constructor(e=1e3){super(`Rate limited. Retry after ${e}ms.`,"rate_limit",429),this.name="TagadaRateLimitError",this.retryAfterMs=e}},G=class extends h{constructor(e,t){super(e,"payment_error",void 0,t==null?void 0:t.details),this.name="TagadaPaymentError",this.paymentId=t==null?void 0:t.paymentId,this.requireAction=t==null?void 0:t.requireAction}},f=class extends h{constructor(e="Network request failed. Check your connection."){super(e,"network_error"),this.name="TagadaNetworkError"}};var Q={production:"https://app.tagadapay.com",development:"https://app.dev.tagadapay.com",local:"http://localhost:3000"},P=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.timeout=e.timeout,this.apiKey=e.apiKey,this.getToken=e.getToken}static resolveBaseUrl(e,t){return t??Q[e]??Q.production}async request(e,t={}){var d;let{method:r="GET",body:s,headers:o={},params:i,token:a,signal:c}=t,l=`${this.baseUrl}${e}`;if(i){let g=new URLSearchParams;for(let[se,V]of Object.entries(i))V!==void 0&&g.set(se,String(V));let x=g.toString();x&&(l+=`?${x}`)}let m={"Content-Type":"application/json",...o},p=a??this.apiKey??((d=this.getToken)==null?void 0:d.call(this));p&&(m["x-cms-token"]=p);let y=new AbortController,u=setTimeout(()=>y.abort(),this.timeout);try{let g=await fetch(l,{method:r,headers:m,body:s!=null?JSON.stringify(s):void 0,signal:c??y.signal});if(clearTimeout(u),g.ok){let x=await g.text();return x?JSON.parse(x):{}}throw await this.handleErrorResponse(g,e),new h("Unexpected error","unknown",g.status)}catch(g){throw clearTimeout(u),g instanceof h?g:g instanceof DOMException&&g.name==="AbortError"?new f(`Request to ${e} timed out after ${this.timeout}ms.`):new f(g instanceof Error?g.message:"Network request failed.")}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,r){return this.request(e,{...r,method:"POST",body:t})}patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t})}put(e,t,r){return this.request(e,{...r,method:"PUT",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}async handleErrorResponse(e,t){let r={};try{r=await e.json()}catch{}let s=r.message??r.error??`Request failed: ${e.status} ${e.statusText} on ${t}`;switch(e.status){case 401:case 403:throw new I(s);case 404:throw new k(t,"");case 422:{let o=Array.isArray(r.errors)?r.errors:[];throw new v(s,o)}case 429:{let o=Number(e.headers.get("Retry-After")??"1")*1e3;throw new S(o)}default:throw new h(s,"api_error",e.status,r)}}};var C=class{constructor(e,t,r){this.http=e;this.storeId=t;this.onTokenChange=r}async loadSession(e,t){var s;t&&(this.sessionToken=t,(s=this.onTokenChange)==null||s.call(this,t));let r=await this.http.get(`/api/v1/checkout-sessions/${e}/v2`,{params:{skipAsyncWait:"false"},token:this.sessionToken});return this.normalizeSession(r)}async createSession(e){var a;let t=e.items.map(c=>({variantId:c.variantId,priceId:c.priceId,quantity:c.quantity})),r={storeId:this.storeId,lineItems:t};e.currency&&(r.currency=e.currency),e.returnUrl&&(r.returnUrl=e.returnUrl),e.customerEmail&&(r.customer={email:e.customerEmail,firstName:e.customerFirstName,lastName:e.customerLastName,currency:e.currency});let s=await this.http.post("/api/v1/checkout/session/init",r),i=new URL(s.checkoutUrl).searchParams.get("token")??"";return this.sessionToken=i,i&&((a=this.onTokenChange)==null||a.call(this,i)),{checkoutUrl:s.checkoutUrl,checkoutToken:s.checkoutToken,sessionToken:i,customerId:s.customerId}}async updateCart(e,t){return this.http.post(`/api/v1/checkout-sessions/${e}/line-items`,{items:t},{token:this.sessionToken})}async updateCustomer(e,t){t.email&&(this.customerEmail=t.email),t.firstName&&(this.customerFirstName=t.firstName),t.lastName&&(this.customerLastName=t.lastName),t.phone&&(this.customerPhone=t.phone)}async updateAddress(e,t){let r=this.mapAddress(t.shippingAddress),s=this.mapAddress(t.billingAddress),o=r??s??{},i=s??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:o,billingAddress:i??{},differentBillingAddress:a},{token:this.sessionToken})}async updateCustomerAndAddress(e,t){t.customer.email&&(this.customerEmail=t.customer.email),t.customer.firstName&&(this.customerFirstName=t.customer.firstName),t.customer.lastName&&(this.customerLastName=t.customer.lastName),t.customer.phone&&(this.customerPhone=t.customer.phone);let r=this.mapAddress(t.shippingAddress),s=this.mapAddress(t.billingAddress),o=r??s??{},i=s??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:o,billingAddress:i??{},differentBillingAddress:a},{token:this.sessionToken})}mapAddress(e){if(e)return le({firstName:e.firstName??this.customerFirstName,lastName:e.lastName??this.customerLastName,phone:e.phone??this.customerPhone,address1:e.line1,address2:e.line2,city:e.city,state:e.state,postal:e.postalCode,country:e.country})}async applyPromoCode(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/promotions/apply`,{checkoutSessionId:e,code:t},{token:this.sessionToken})}async removePromoCode(e,t){let r=t??"default";await this.http.delete(`/api/v1/checkout-sessions/${e}/promotions/${r}`,{token:this.sessionToken})}async getShippingRates(e){return(await this.http.get(`/api/v1/checkout-sessions/${e}/shipping-rates`,{token:this.sessionToken})).rates??[]}async selectShippingRate(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/shipping-rate`,{checkoutSessionId:e,shippingRateId:t},{token:this.sessionToken})}normalizeSession(e){let t=e.checkoutSession,r=t.orderSummaries??[],s=e.summary??t.summary??r[0]??{},o=t.sessionLineItems??[],i=t.customer,a=o.map(l=>{let m=l.price,p=(m==null?void 0:m.variant)??{},y=p.product??{},u=(m==null?void 0:m.currencyOptions)??{},d=u.USD??u[Object.keys(u)[0]];return{id:l.id,variantId:l.variantId,priceId:l.priceId,productName:y.name??"",variantName:p.name??"",quantity:l.quantity??1,unitAmount:(d==null?void 0:d.amount)??0,totalAmount:((d==null?void 0:d.amount)??0)*(l.quantity??1),currency:t.selectedPresentmentCurrency??"USD",imageUrl:p.imageUrl??""}}),c=s.items??[];return{id:t.id,storeId:t.storeId,checkoutToken:t.checkoutToken,currency:t.selectedPresentmentCurrency??"USD",items:a,totals:{subtotal:s.subtotalAmount??0,discount:s.totalPromotionAmount??0,shipping:s.shippingCost??0,tax:s.totalTaxAmount??0,total:s.totalAmount??c.reduce((l,m)=>l+(m.amount??0),0),currency:s.currency??t.selectedPresentmentCurrency??"USD"},customer:i?{id:i.id,email:i.email,firstName:i.firstName,lastName:i.lastName}:void 0,shippingAddress:t.shippingAddress,billingAddress:t.billingAddress,metadata:t.metadata}}};function le(n){let e={};for(let[t,r]of Object.entries(n))r!=null&&r!==""&&(e[t]=r);return Object.keys(e).length>0?e:void 0}var A=class{constructor(e,t,r){this.http=e;this.storeId=t;this.environment=r}async getPaymentSetup(e){let t=await this.http.get("/api/v1/payment-methods",{params:{checkoutSessionId:e}}),r={};for(let s of t.methods??[]){let o=s.provider?`${s.method}:${s.provider}`:s.method;r[o]=s}return r}async getExpressMethods(e){var s,o;let t=await this.getPaymentSetup(e),r={};for(let[,i]of Object.entries(t)){if(!i.enabled||!i.express)continue;let a=i.method,c={type:a,available:!0,processorId:i.processorId,publishableKey:i.publishableKey,metadata:i.metadata};if(a==="apple_pay"||i.type==="apple_pay"){let l=typeof window<"u"&&"ApplePaySession"in window&&((o=(s=window.ApplePaySession)==null?void 0:s.canMakePayments)==null?void 0:o.call(s));r.applePay={...c,available:!!l}}else a==="google_pay"||i.type==="google_pay"?r.googlePay=c:a==="paypal"?r.paypal=c:a==="klarna"||a==="klarna_express"?r.klarna=c:a==="link"&&(r.link=c)}return r}async getStoreConfig(){let e=await this.http.get("/api/v1/checkout/config",{params:{storeId:this.storeId}});return e.config??e}async getEnabledMethods(e){let t=await this.getPaymentSetup(e);return Object.entries(t).filter(([,r])=>r.enabled).map(([r])=>r)}async tokenizeCard(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let s={cardNumber:e.cardNumber,expiryDate:e.expiryDate,cvc:e.cvc};e.cardholderName&&(s.cardholderName=e.cardholderName);let[o,i]=await Promise.all([r.tokenizeCard(s),r.tokenizeCardRaw(s)]);return{tagadaToken:o,rawToken:i}}async createInstrument(e){return this.http.post("/api/v1/payment/create-instrument-from-token",{tagadaToken:e.tagadaToken})}async create3dsSession(e){return this.http.post("/api/public/v1/threeds/create-session",{provider:e.provider??"basis_theory",storeId:this.storeId,paymentInstrumentId:e.paymentInstrumentId,sessionData:e.sessionData})}async pay(e){return e.tagadaToken&&!e.paymentInstrumentId?this.http.post("/api/v1/payment/pay-with-token",{tagadaToken:e.tagadaToken,checkoutSessionId:e.checkoutSessionId,returnUrl:e.returnUrl,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata}):this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId,storeId:this.storeId,paymentFlowId:e.paymentFlowId,threedsSessionId:e.threedsSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata})}async payDirect(e){return this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId??"",storeId:this.storeId,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,threedsSessionId:e.threedsSessionId})}async processApplePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeApplePay(e.applePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"apple_pay",isExpress:!0})}async processGooglePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeGooglePay(e.googlePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"google_pay",isExpress:!0})}async processApm(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,paymentMethod:e.paymentMethod,processorId:e.processorId,paymentFlowId:e.paymentFlowId})}async processPayment(e){var s,o;!e.returnUrl&&typeof window<"u"&&(e={...e,returnUrl:window.location.href});let t=await this.pay(e),r=t.payment;return r.status==="succeeded"?{status:"succeeded",payment:r,order:t.order}:r.status==="failed"||r.status==="declined"?{status:"failed",error:((s=r.requireActionData)==null?void 0:s.message)||((o=r.requireActionData)==null?void 0:o.errorCode)||`Payment ${r.status}`,payment:r}:r.requireAction&&r.requireAction!=="none"&&r.requireActionData?this.handlePaymentAction(r,e):this.pollUntilDone(r.id)}async resumeAfterRedirect(e){return this.pollUntilDone(e)}async getPaymentStatus(e){return this.http.get(`/api/v1/payments/${e}`)}async pollPaymentStatus(e,t){let r=(t==null?void 0:t.intervalMs)??1500,s=(t==null?void 0:t.timeoutMs)??6e4,o=Date.now();for(;Date.now()-o<s;){let i=await this.getPaymentStatus(e);if(i.status==="succeeded"||i.status==="failed"||i.status==="declined")return i;await new Promise(a=>setTimeout(a,r))}throw new Error(`Payment ${e} did not reach terminal status within ${s}ms.`)}async completeAfter3ds(e){return this.http.post("/api/v1/payments/complete-after-3ds",{paymentId:e})}async markActionProcessed(e){try{await this.http.post("/api/v1/payments/require-action/processed",{paymentId:e})}catch{}}async handlePaymentAction(e,t){let r=e.requireActionData;switch(await this.markActionProcessed(e.id),r.type){case"threeds_auth":return this.handleThreedsAuth(e,t);case"processor_auth":case"redirect_to_payment":return this.extractRedirect(e,r);case"redirect":return this.extractRedirect(e,r);case"error":return{status:"failed",error:r.message||r.errorCode||"Payment failed",payment:e};default:return this.extractRedirect(e,r)}}extractRedirect(e,t){var o,i;let r=(o=t.metadata)==null?void 0:o.redirect,s=(r==null?void 0:r.redirectUrl)||t.redirectUrl;return s?{status:"requires_redirect",redirectUrl:s,method:((i=r==null?void 0:r.method)==null?void 0:i.toUpperCase())||"GET",postData:r==null?void 0:r.data,paymentId:e.id}:{status:"failed",error:`Payment requires action (${t.type}) but no redirect URL was provided`,payment:e}}async handleThreedsAuth(e,t){var o,i;let r=(i=(o=e.requireActionData)==null?void 0:o.metadata)==null?void 0:i.threedsSession;if(!(r!=null&&r.externalSessionId))return this.extractRedirect(e,e.requireActionData);let s;try{s=await import("@tagadapay/core-js")}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:this.extractRedirect(e,e.requireActionData)}try{let a=new s.ThreedsManager({provider:"basis_theory"});return await a.initialize({apiKey:void 0}),await a.startChallenge({sessionId:r.externalSessionId,acsChallengeUrl:r.acsChallengeUrl,acsTransactionId:r.acsTransID,threeDSVersion:r.messageVersion}),await this.completeAfter3ds(e.id),this.pollUntilDone(e.id)}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:{status:"failed",error:"3D Secure authentication failed",payment:e}}}async pollUntilDone(e,t){let r=(t==null?void 0:t.intervalMs)??1500,s=(t==null?void 0:t.timeoutMs)??6e4,o=Date.now(),i=0;for(;Date.now()-o<s;){let a;try{a=await this.getPaymentStatus(e),i=0}catch{if(i++,i>=3)return{status:"failed",error:"Payment verification failed due to network errors"};await new Promise(c=>setTimeout(c,r));continue}if(a.status==="succeeded"||a.status==="pending"&&a.subStatus==="authorized")return{status:"succeeded",payment:a,order:a.order};if(a.status==="failed"||a.status==="declined")return{status:"failed",error:a.status,payment:a};if(a.requireAction&&a.requireAction!=="none"&&a.requireActionData&&!a.requireActionData.processed)return this.handlePaymentAction(a,{});await new Promise(c=>setTimeout(c,r))}return{status:"pending",paymentId:e}}async loadCoreJs(){try{return await import("@tagadapay/core-js")}catch{throw new Error("This method requires @tagadapay/core-js. Install it: npm install @tagadapay/core-js")}}};var R=class{constructor(e,t){this.http=e;this.storeId=t}async getOffer(e){return this.http.get(`/api/v1/offers/${e}`)}async listOffers(e){var o;let t=`/api/v1/stores/${this.storeId}/offers`,r=[];if(e!=null&&e.type&&r.push(`type=${encodeURIComponent(e.type)}`),(o=e==null?void 0:e.ids)!=null&&o.length)for(let i of e.ids)r.push(`ids=${encodeURIComponent(i)}`);return r.length&&(t+=`?${r.join("&")}`),(await this.http.get(t)).offers??[]}async previewOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems})}async payPreviewedOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/pay-preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems,returnUrl:e.returnUrl??(typeof window<"u"?window.location.href:""),mainOrderId:e.mainOrderId,paymentInstrumentId:e.paymentInstrumentId})}async toggleOrderBump(e){return this.http.post(`/api/v1/checkout-sessions/${e.checkoutSessionId}/toggle-order-bump`,{orderBumpOfferId:e.orderBumpOfferId,selected:e.selected})}async listPostPurchaseOffers(e){let t=await this.http.get(`/api/v1/post-purchase/${e}/offers`);return Array.isArray(t)?t:[]}async acceptPostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/accept`,{items:e.items??[]})}async declinePostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/decline`)}};var b=class{constructor(e,t){this.http=e;this.storeId=t}async getProfile(e){return(await this.http.get(`/api/v1/customers/${e}`,{params:{storeId:this.storeId}})).customer}async getByEmail(e){try{return(await this.http.get("/api/v1/customers/by-email",{params:{email:e,storeId:this.storeId}})).customer}catch{return null}}async updateProfile(e,t){return(await this.http.patch(`/api/v1/customers/${e}`,{storeId:this.storeId,...t})).customer}async getOrders(e,t){return this.http.get(`/api/v1/customers/${e}/orders`,{params:{storeId:this.storeId,limit:t==null?void 0:t.limit,offset:t==null?void 0:t.offset}})}async getOrder(e){return(await this.http.get(`/api/v1/orders/${e}`,{params:{storeId:this.storeId}})).order}async getSubscriptions(e){return(await this.http.get(`/api/v1/customers/${e}/subscriptions`,{params:{storeId:this.storeId}})).subscriptions}async getSubscription(e){return(await this.http.get(`/api/v1/subscriptions/${e}`,{params:{storeId:this.storeId}})).subscription}};var T=class{constructor(e,t){this.http=e;this.storeId=t}async getProducts(e){var s,o;let t={storeId:this.storeId,includeVariants:!0,includePrices:!0};return(s=e==null?void 0:e.productIds)!=null&&s.length&&(t.productIds=e.productIds),(o=e==null?void 0:e.variantIds)!=null&&o.length&&(t.variantIds=e.variantIds),(await this.http.post("/api/v1/products",t)).items??[]}async getProduct(e){return(await this.getProducts({productIds:[e]}))[0]??null}};var O=class{constructor(e){let t=e.environment??"production",r=P.resolveBaseUrl(t,e.baseUrl);this.config={...e,environment:t,baseUrl:r,timeout:e.timeout??3e4},this.http=new P({baseUrl:r,timeout:this.config.timeout,apiKey:e.apiKey,getToken:()=>this._sessionToken});let s=o=>{this._sessionToken=o};this.checkout=new C(this.http,this.config.storeId,s),this.payment=new A(this.http,this.config.storeId,t),this.offers=new R(this.http,this.config.storeId),this.customer=new b(this.http,this.config.storeId),this.catalog=new T(this.http,this.config.storeId)}setSessionToken(e){this._sessionToken=e}};function X(n){return new O(n)}var ee=!1,te=!1,H=[];function F(){te=!0;for(let n of H)n();H.length=0}function B(n,e={}){var t,r;return te||(r=(t=window.google)==null?void 0:t.maps)!=null&&r.places?(F(),Promise.resolve()):ee?new Promise(s=>H.push(s)):(ee=!0,new Promise((s,o)=>{if(H.push(s),document.querySelector('script[src*="maps.googleapis.com"]')){let l=()=>{var m,p;(p=(m=window.google)==null?void 0:m.maps)!=null&&p.places?F():setTimeout(l,100)};l();return}let a=new URLSearchParams({key:n,libraries:"places",v:e.version??"weekly"});e.language&&a.set("language",e.language),e.region&&a.set("region",e.region);let c=document.createElement("script");c.src=`https://maps.googleapis.com/maps/api/js?${a}`,c.async=!0,c.defer=!0,c.onload=()=>F(),c.onerror=()=>o(new Error("Failed to load Google Maps script")),document.head.appendChild(c)}))}var E=class n{static async searchPlaces(e,t={}){var s,o;if(!((o=(s=window.google)==null?void 0:s.maps)!=null&&o.places)||!e.trim())return[];let r=new window.google.maps.places.AutocompleteService;return new Promise(i=>{r.getPlacePredictions({input:e,types:t.types??["address"],componentRestrictions:t.componentRestrictions},(a,c)=>{var l,m,p;i(c===((p=(m=(l=window.google)==null?void 0:l.maps)==null?void 0:m.places)==null?void 0:p.PlacesServiceStatus.OK)&&a?a:[])})})}static async getPlaceDetails(e){var r,s;if(!((s=(r=window.google)==null?void 0:r.maps)!=null&&s.places))return null;let t=new window.google.maps.places.PlacesService(document.createElement("div"));return new Promise(o=>{t.getDetails({placeId:e,fields:["place_id","formatted_address","address_components","geometry"]},(i,a)=>{var c,l,m;o(a===((m=(l=(c=window.google)==null?void 0:c.maps)==null?void 0:l.places)==null?void 0:m.PlacesServiceStatus.OK)&&i?i:null)})})}static extractAddressComponents(e){let t={subpremise:"",streetNumber:"",route:"",locality:"",administrativeAreaLevel1:"",administrativeAreaLevel1Long:"",administrativeAreaLevel2:"",administrativeAreaLevel2Long:"",country:"",postalCode:"",fullStreetAddress:""},r="",s="",o="",i="",a="",c="",l="",m="";for(let u of e.address_components??[]){let d=u.types;d.includes("subpremise")&&(t.subpremise=u.long_name),d.includes("street_number")&&(t.streetNumber=u.long_name),d.includes("premise")&&(r=u.long_name),d.includes("route")&&(t.route=u.long_name),d.includes("neighborhood")&&(s=u.long_name),d.includes("sublocality_level_5")&&(o=u.long_name),d.includes("sublocality_level_4")&&(i=u.long_name),d.includes("sublocality_level_3")&&(a=u.long_name),d.includes("sublocality_level_2")&&(c=u.long_name),d.includes("sublocality_level_1")&&(l=u.long_name),d.includes("locality")&&(t.locality=u.long_name),d.includes("postal_town")&&(m=u.long_name),d.includes("administrative_area_level_2")&&(t.administrativeAreaLevel2=u.short_name,t.administrativeAreaLevel2Long=u.long_name),d.includes("administrative_area_level_1")&&(t.administrativeAreaLevel1=u.short_name,t.administrativeAreaLevel1Long=u.long_name),d.includes("country")&&(t.country=u.short_name),d.includes("postal_code")&&(t.postalCode=u.long_name)}t.locality||(t.locality=m||c||l||""),!t.administrativeAreaLevel1&&t.administrativeAreaLevel2&&(t.administrativeAreaLevel1=t.administrativeAreaLevel2Long||t.administrativeAreaLevel2,t.administrativeAreaLevel1Long=t.administrativeAreaLevel2Long);let p=t.streetNumber||r,y=t.route||o||i||a||s;if(t.subpremise&&p&&y)t.fullStreetAddress=`${t.subpremise}/${p} ${y}`;else if(p&&y)if(r&&i&&a){let u=`${a}-${i}-${r}`;c&&(u=`${u} ${c}`),t.fullStreetAddress=u}else t.fullStreetAddress=`${p} ${y}`;else y?t.fullStreetAddress=y:p&&(t.fullStreetAddress=p);return t.fullStreetAddress=t.fullStreetAddress.trim(),t}static extractFormattedAddress(e){let t=n.extractAddressComponents(e);return{address1:t.fullStreetAddress,city:t.locality,country:t.country,state:t.administrativeAreaLevel1,postal:t.postalCode}}};var re="https://cvwnizdbugpz6jwk.public.blob.vercel-storage.com/geodata/v1",N=["en","ru","de","da","fr","es","zh","hi","pt","ja","ar","it","he"],D=new Map,K=new Map,j=new Map,z=new Map;async function me(n){let e=D.get(n);if(e)return e;let t=j.get(n);return t||(t=(async()=>{let r=`${re}/${n}/countries.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let o=await s.json();return D.set(n,o),j.delete(n),o})(),j.set(n,t),t)}async function pe(n){let e=K.get(n);if(e)return e;let t=z.get(n);return t||(t=(async()=>{let r=`${re}/${n}/regions.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let o=await s.json();return K.set(n,o),z.delete(n),o})(),z.set(n,t),t)}function ge(n){return D.get(n)||D.get("en")||{}}function he(n){return K.get(n)||K.get("en")||{}}async function _(n="en"){await Promise.all([me(n),pe(n)])}var L=(n="en")=>{let e=ge(n);return Object.entries(e).map(([t,r])=>({code:t,name:r.n,iso3:r.i3,numeric:r.nu})).sort((t,r)=>t.name.localeCompare(r.name))},$=(n,e="en")=>{let r=he(e)[n];return r?r.map(([s,o])=>({code:s,name:o,countryCode:n})).sort((s,o)=>s.name.localeCompare(o.name)):[]};function U(n){return D.has(n)}var M=class n{static ensureLoaded(e="en"){return _(e)}static getCountries(e="en"){let t=L(e),r={};for(let s of t)r[s.code]={iso:s.code,iso3:s.iso3??"",numeric:s.numeric??0,name:s.name};return r}static getCountryOptions(e="en"){return L(e).map(t=>({value:t.code,label:t.name}))}static getRegions(e,t="en"){return $(e,t).map(r=>({iso:r.code,name:r.name}))}static getRegionOptions(e,t="en"){return n.getRegions(e,t).map(r=>({value:r.iso,label:r.name}))}static findRegion(e,t,r="en"){return n.getRegions(e,r).find(s=>s.iso===t)??null}static mapGoogleToISO(e,t,r,s="en"){let o=n.getRegions(r,s);if(o.length===0)return null;let i=o.find(a=>a.iso===e);return i||(i=o.find(a=>a.name.toLowerCase()===e.toLowerCase()),i)||(i=o.find(a=>a.name.toLowerCase()===t.toLowerCase()),i)?i:(i=o.find(a=>a.name.toLowerCase().includes(t.toLowerCase())||t.toLowerCase().includes(a.name.toLowerCase())),i??null)}static isLanguageLoaded(e){return U(e)}static getAvailableLanguages(){return N}};var ye={USD:"$",EUR:"\u20AC",GBP:"\xA3",JPY:"\xA5",CAD:"C$",AUD:"A$",CHF:"CHF",CNY:"\xA5",SEK:"kr",NOK:"kr",DKK:"kr",PLN:"z\u0142",CZK:"K\u010D",HUF:"Ft",RON:"lei",BGN:"\u043B\u0432",HRK:"kn",RUB:"\u20BD",UAH:"\u20B4",TRY:"\u20BA",BRL:"R$",MXN:"$",ZAR:"R",INR:"\u20B9",KRW:"\u20A9",THB:"\u0E3F",VND:"\u20AB",IDR:"Rp",MYR:"RM",SGD:"S$",PHP:"\u20B1",TWD:"NT$",HKD:"HK$",ILS:"\u20AA",AED:"\u062F.\u0625",SAR:"\u0631.\u0633",QAR:"\u0631.\u0642",KWD:"\u062F.\u0643",BHD:"\u062F.\u0628",OMR:"\u0631.\u0639.",EGP:"\xA3",NGN:"\u20A6",KES:"KSh",GHS:"\u20B5",COP:"$",ARS:"$",CLP:"$",PEN:"S/",CRC:"\u20A1",DOP:"RD$",JMD:"J$",BOB:"Bs",PYG:"\u20B2",GTQ:"Q",NIO:"C$",PAB:"B/.",PKR:"\u20A8",BDT:"\u09F3",LKR:"\u20A8",NPR:"\u20A8",GEL:"\u20BE",AMD:"\u058F",AZN:"\u20BC",KZT:"\u20B8"},fe={USD:"US Dollar",EUR:"Euro",GBP:"British Pound",JPY:"Japanese Yen",CAD:"Canadian Dollar",AUD:"Australian Dollar",CHF:"Swiss Franc",CNY:"Chinese Yuan",SEK:"Swedish Krona",NOK:"Norwegian Krone",DKK:"Danish Krone",PLN:"Polish Zloty",CZK:"Czech Koruna",HUF:"Hungarian Forint",BRL:"Brazilian Real",MXN:"Mexican Peso",INR:"Indian Rupee",KRW:"South Korean Won",THB:"Thai Baht",SGD:"Singapore Dollar",HKD:"Hong Kong Dollar",TWD:"Taiwan Dollar",ILS:"Israeli Shekel",AED:"UAE Dirham",SAR:"Saudi Riyal",ZAR:"South African Rand",TRY:"Turkish Lira",RUB:"Russian Ruble",NGN:"Nigerian Naira"},Pe=new Set(["JPY","KRW","VND","IDR","LAK","KHR","MMK","PYG"]),w=class n{static getSymbol(e){return ye[e]??e}static getName(e){return fe[e]??e}static getDecimalPlaces(e){return Pe.has(e)?0:2}static getCurrency(e){return{code:e,symbol:n.getSymbol(e),name:n.getName(e),decimalPlaces:n.getDecimalPlaces(e)}}};function J(n,e="USD",t="en-US"){let r=w.getDecimalPlaces(e),s=n/(r===0?100:Math.pow(10,r));try{return new Intl.NumberFormat(t,{style:"currency",currency:e,minimumFractionDigits:r,maximumFractionDigits:r}).format(s)}catch{return`${w.getSymbol(e)}${s.toFixed(r)}`}}return de(we);})();
|
|
7
7
|
if(typeof window!=="undefined"&&TagadaHeadlessBundle){ window.TagadaHeadless=TagadaHeadlessBundle; window.TagadaHeadless.create=TagadaHeadlessBundle.createHeadlessClient;}
|
|
8
8
|
//# sourceMappingURL=tagada-headless.min.js.map
|