@cimplify/sdk 0.8.1 → 0.8.3

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/index.js CHANGED
@@ -717,6 +717,105 @@ var CartOperations = class {
717
717
  }
718
718
  };
719
719
 
720
+ // src/constants.ts
721
+ var CHECKOUT_MODE = {
722
+ LINK: "link",
723
+ GUEST: "guest"
724
+ };
725
+ var ORDER_TYPE = {
726
+ DELIVERY: "delivery",
727
+ PICKUP: "pickup",
728
+ DINE_IN: "dine-in",
729
+ WALK_IN: "walk-in"
730
+ };
731
+ var PAYMENT_METHOD = {
732
+ MOBILE_MONEY: "mobile_money",
733
+ CARD: "card"
734
+ };
735
+ var CHECKOUT_STEP = {
736
+ AUTHENTICATION: "authentication",
737
+ ORDER_DETAILS: "order_details",
738
+ PAYMENT_METHOD: "payment_method",
739
+ PAYMENT: "payment",
740
+ CONFIRMATION: "confirmation"
741
+ };
742
+ var PAYMENT_STATE = {
743
+ INITIAL: "initial",
744
+ PREPARING: "preparing",
745
+ PROCESSING: "processing",
746
+ VERIFYING: "verifying",
747
+ AWAITING_AUTHORIZATION: "awaiting_authorization",
748
+ SUCCESS: "success",
749
+ ERROR: "error",
750
+ TIMEOUT: "timeout"
751
+ };
752
+ var PICKUP_TIME_TYPE = {
753
+ ASAP: "asap",
754
+ SCHEDULED: "scheduled"
755
+ };
756
+ var MOBILE_MONEY_PROVIDER = {
757
+ MTN: "mtn",
758
+ VODAFONE: "vodafone",
759
+ AIRTEL: "airtel"
760
+ };
761
+ var AUTHORIZATION_TYPE = {
762
+ OTP: "otp",
763
+ PIN: "pin",
764
+ PHONE: "phone",
765
+ BIRTHDAY: "birthday",
766
+ ADDRESS: "address"
767
+ };
768
+ var DEVICE_TYPE = {
769
+ MOBILE: "mobile",
770
+ DESKTOP: "desktop",
771
+ TABLET: "tablet"
772
+ };
773
+ var CONTACT_TYPE = {
774
+ PHONE: "phone",
775
+ EMAIL: "email"
776
+ };
777
+ var LINK_QUERY = {
778
+ DATA: "link.data",
779
+ ADDRESSES: "link.addresses",
780
+ MOBILE_MONEY: "link.mobile_money",
781
+ PREFERENCES: "link.preferences",
782
+ SESSIONS: "link.sessions"
783
+ };
784
+ var LINK_MUTATION = {
785
+ CHECK_STATUS: "link.check_status",
786
+ ENROLL: "link.enroll",
787
+ ENROLL_AND_LINK_ORDER: "link.enroll_and_link_order",
788
+ UPDATE_PREFERENCES: "link.update_preferences",
789
+ CREATE_ADDRESS: "link.create_address",
790
+ UPDATE_ADDRESS: "link.update_address",
791
+ DELETE_ADDRESS: "link.delete_address",
792
+ SET_DEFAULT_ADDRESS: "link.set_default_address",
793
+ TRACK_ADDRESS_USAGE: "link.track_address_usage",
794
+ CREATE_MOBILE_MONEY: "link.create_mobile_money",
795
+ DELETE_MOBILE_MONEY: "link.delete_mobile_money",
796
+ SET_DEFAULT_MOBILE_MONEY: "link.set_default_mobile_money",
797
+ TRACK_MOBILE_MONEY_USAGE: "link.track_mobile_money_usage",
798
+ VERIFY_MOBILE_MONEY: "link.verify_mobile_money",
799
+ REVOKE_SESSION: "link.revoke_session",
800
+ REVOKE_ALL_SESSIONS: "link.revoke_all_sessions"
801
+ };
802
+ var AUTH_MUTATION = {
803
+ REQUEST_OTP: "auth.request_otp",
804
+ VERIFY_OTP: "auth.verify_otp"
805
+ };
806
+ var CHECKOUT_MUTATION = {
807
+ PROCESS: "checkout.process"
808
+ };
809
+ var PAYMENT_MUTATION = {
810
+ SUBMIT_AUTHORIZATION: "payment.submit_authorization",
811
+ CHECK_STATUS: "order.poll_payment_status"
812
+ };
813
+ var ORDER_MUTATION = {
814
+ UPDATE_CUSTOMER: "order.update_order_customer"
815
+ };
816
+ var DEFAULT_CURRENCY = "GHS";
817
+ var DEFAULT_COUNTRY = "GHA";
818
+
720
819
  // src/utils/price.ts
721
820
  var CURRENCY_SYMBOLS = {
722
821
  // Major world currencies
@@ -1274,6 +1373,10 @@ async function openCardPopup(provider, checkoutResult, email, currency, signal)
1274
1373
  }
1275
1374
  return { success: false, error: "PROVIDER_UNAVAILABLE" };
1276
1375
  }
1376
+ var VALID_MOBILE_MONEY_PROVIDERS = new Set(Object.values(MOBILE_MONEY_PROVIDER));
1377
+ function isValidMobileMoneyProvider(value) {
1378
+ return VALID_MOBILE_MONEY_PROVIDERS.has(value);
1379
+ }
1277
1380
  function normalizeAuthorizationType(value) {
1278
1381
  return value === "otp" || value === "pin" ? value : void 0;
1279
1382
  }
@@ -1506,6 +1609,16 @@ var CheckoutResolver = class {
1506
1609
  }
1507
1610
  await this.wait(this.pollIntervalMs);
1508
1611
  }
1612
+ try {
1613
+ const finalResult = await this.client.checkout.pollPaymentStatus(input.orderId);
1614
+ if (finalResult.ok) {
1615
+ const normalized = normalizeStatusResponse(finalResult.value);
1616
+ if (normalized.paid || isPaymentStatusSuccess(normalized.status)) {
1617
+ return this.finalizeSuccess(latestCheckoutResult);
1618
+ }
1619
+ }
1620
+ } catch {
1621
+ }
1509
1622
  return this.fail(
1510
1623
  "PAYMENT_TIMEOUT",
1511
1624
  "Payment confirmation timed out. Please retry checkout.",
@@ -1636,7 +1749,7 @@ var CheckoutResolver = class {
1636
1749
  };
1637
1750
  }
1638
1751
  getEnrollmentMobileMoney() {
1639
- if (this.paymentData?.type === "mobile_money" && this.paymentData.phone_number && this.paymentData.provider) {
1752
+ if (this.paymentData?.type === "mobile_money" && this.paymentData.phone_number && this.paymentData.provider && isValidMobileMoneyProvider(this.paymentData.provider)) {
1640
1753
  return {
1641
1754
  phone_number: this.paymentData.phone_number,
1642
1755
  provider: this.paymentData.provider,
@@ -2591,6 +2704,7 @@ var MESSAGE_TYPES = {
2591
2704
  // Parent → Iframe
2592
2705
  INIT: "init",
2593
2706
  SET_TOKEN: "set_token",
2707
+ SET_CART: "set_cart",
2594
2708
  GET_DATA: "get_data",
2595
2709
  REFRESH_TOKEN: "refresh_token",
2596
2710
  LOGOUT: "logout",
@@ -2755,8 +2869,10 @@ var CimplifyElements = class {
2755
2869
  false
2756
2870
  );
2757
2871
  }
2872
+ this.checkoutInProgress = true;
2758
2873
  if (!options.cart_id) {
2759
2874
  console.debug("[cimplify:checkout] BLOCKED: no cart_id");
2875
+ this.checkoutInProgress = false;
2760
2876
  return toCheckoutError(
2761
2877
  "INVALID_CART",
2762
2878
  "A valid cart is required before checkout can start.",
@@ -2765,6 +2881,7 @@ var CimplifyElements = class {
2765
2881
  }
2766
2882
  if (!options.order_type) {
2767
2883
  console.debug("[cimplify:checkout] BLOCKED: no order_type");
2884
+ this.checkoutInProgress = false;
2768
2885
  return toCheckoutError(
2769
2886
  "ORDER_TYPE_REQUIRED",
2770
2887
  "Order type is required before checkout can start.",
@@ -2774,6 +2891,7 @@ var CimplifyElements = class {
2774
2891
  const checkoutElement = this.elements.get(ELEMENT_TYPES.CHECKOUT) || this.elements.get(ELEMENT_TYPES.PAYMENT);
2775
2892
  if (!checkoutElement) {
2776
2893
  console.debug("[cimplify:checkout] BLOCKED: no checkout element");
2894
+ this.checkoutInProgress = false;
2777
2895
  return toCheckoutError(
2778
2896
  "NO_PAYMENT_ELEMENT",
2779
2897
  "Checkout element must be mounted before checkout.",
@@ -2782,6 +2900,7 @@ var CimplifyElements = class {
2782
2900
  }
2783
2901
  if (!checkoutElement.isMounted()) {
2784
2902
  console.debug("[cimplify:checkout] BLOCKED: checkout element not mounted");
2903
+ this.checkoutInProgress = false;
2785
2904
  return toCheckoutError(
2786
2905
  "PAYMENT_NOT_MOUNTED",
2787
2906
  "Checkout element must be mounted before checkout.",
@@ -2793,6 +2912,7 @@ var CimplifyElements = class {
2793
2912
  const authElement = this.elements.get(ELEMENT_TYPES.AUTH);
2794
2913
  if (authElement && !this.accessToken) {
2795
2914
  console.debug("[cimplify:checkout] BLOCKED: auth incomplete");
2915
+ this.checkoutInProgress = false;
2796
2916
  return toCheckoutError(
2797
2917
  "AUTH_INCOMPLETE",
2798
2918
  "Authentication must complete before checkout can start.",
@@ -2830,7 +2950,6 @@ var CimplifyElements = class {
2830
2950
  };
2831
2951
  const timeoutMs = options.timeout_ms ?? 18e4;
2832
2952
  const paymentWindow = checkoutElement.getContentWindow();
2833
- this.checkoutInProgress = true;
2834
2953
  return new Promise((resolve) => {
2835
2954
  let settled = false;
2836
2955
  const cleanup = () => {
@@ -3125,6 +3244,9 @@ var CimplifyElement = class {
3125
3244
  this.sendMessage({ type: MESSAGE_TYPES.GET_DATA });
3126
3245
  });
3127
3246
  }
3247
+ setCart(cart) {
3248
+ this.sendMessage({ type: MESSAGE_TYPES.SET_CART, cart });
3249
+ }
3128
3250
  sendMessage(message) {
3129
3251
  if (this.iframe?.contentWindow) {
3130
3252
  this.iframe.contentWindow.postMessage(message, this.linkUrl);
@@ -3273,6 +3395,7 @@ var ACCESS_TOKEN_STORAGE_KEY = "cimplify_access_token";
3273
3395
  var SESSION_TOKEN_STORAGE_KEY = "cimplify_session_token";
3274
3396
  var ORDER_TOKEN_PREFIX = "cimplify_ot_";
3275
3397
  var SESSION_TOKEN_HEADER = "x-session-token";
3398
+ var ORDER_TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
3276
3399
  var DEFAULT_TIMEOUT_MS = 3e4;
3277
3400
  var DEFAULT_MAX_RETRIES = 3;
3278
3401
  var DEFAULT_RETRY_DELAY_MS = 1e3;
@@ -3379,6 +3502,14 @@ var CimplifyClient = class {
3379
3502
  );
3380
3503
  }
3381
3504
  }
3505
+ /** Build a full URL, appending context params (e.g. location_id) as query parameters. */
3506
+ buildUrl(base, path) {
3507
+ const url = `${base}${path}`;
3508
+ const locationId = this.context.location_id;
3509
+ if (!locationId) return url;
3510
+ const separator = url.includes("?") ? "&" : "?";
3511
+ return `${url}${separator}location_id=${encodeURIComponent(locationId)}`;
3512
+ }
3382
3513
  /** @deprecated Use getAccessToken() instead */
3383
3514
  getSessionToken() {
3384
3515
  return this.accessToken;
@@ -3422,12 +3553,27 @@ var CimplifyClient = class {
3422
3553
  }
3423
3554
  setOrderToken(orderId, token) {
3424
3555
  if (typeof window !== "undefined" && window.localStorage) {
3425
- localStorage.setItem(`${ORDER_TOKEN_PREFIX}${orderId}`, token);
3556
+ try {
3557
+ const entry = JSON.stringify({ token, storedAt: Date.now() });
3558
+ localStorage.setItem(`${ORDER_TOKEN_PREFIX}${orderId}`, entry);
3559
+ } catch {
3560
+ }
3426
3561
  }
3427
3562
  }
3428
3563
  getOrderToken(orderId) {
3429
3564
  if (typeof window !== "undefined" && window.localStorage) {
3430
- return localStorage.getItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
3565
+ try {
3566
+ const raw = localStorage.getItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
3567
+ if (!raw) return null;
3568
+ const entry = JSON.parse(raw);
3569
+ if (Date.now() - entry.storedAt > ORDER_TOKEN_TTL_MS) {
3570
+ localStorage.removeItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
3571
+ return null;
3572
+ }
3573
+ return entry.token;
3574
+ } catch {
3575
+ return null;
3576
+ }
3431
3577
  }
3432
3578
  return null;
3433
3579
  }
@@ -3503,10 +3649,13 @@ var CimplifyClient = class {
3503
3649
  }
3504
3650
  saveAccessToken(token) {
3505
3651
  if (typeof window !== "undefined" && window.localStorage) {
3506
- if (token) {
3507
- localStorage.setItem(ACCESS_TOKEN_STORAGE_KEY, token);
3508
- } else {
3509
- localStorage.removeItem(ACCESS_TOKEN_STORAGE_KEY);
3652
+ try {
3653
+ if (token) {
3654
+ localStorage.setItem(ACCESS_TOKEN_STORAGE_KEY, token);
3655
+ } else {
3656
+ localStorage.removeItem(ACCESS_TOKEN_STORAGE_KEY);
3657
+ }
3658
+ } catch {
3510
3659
  }
3511
3660
  }
3512
3661
  }
@@ -3579,6 +3728,19 @@ var CimplifyClient = class {
3579
3728
  });
3580
3729
  return response;
3581
3730
  }
3731
+ if (response.status === 429 && attempt < this.maxRetries) {
3732
+ retryCount++;
3733
+ const retryAfter = response.headers.get("Retry-After");
3734
+ const delay = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, 3e4) || this.retryDelay * Math.pow(2, attempt) : this.retryDelay * Math.pow(2, attempt);
3735
+ this.hooks.onRetry?.({
3736
+ ...context,
3737
+ attempt: retryCount,
3738
+ delayMs: delay,
3739
+ error: new Error(`Rate limited: ${response.status}`)
3740
+ });
3741
+ await sleep(delay);
3742
+ continue;
3743
+ }
3582
3744
  if (response.status >= 400 && response.status < 500) {
3583
3745
  this.hooks.onRequestError?.({
3584
3746
  ...context,
@@ -3671,7 +3833,7 @@ var CimplifyClient = class {
3671
3833
  async get(path) {
3672
3834
  const key = this.getDedupeKey("get", path);
3673
3835
  return this.deduplicatedRequest(key, async () => {
3674
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
3836
+ const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
3675
3837
  method: "GET",
3676
3838
  credentials: this.credentials,
3677
3839
  headers: this.getHeaders()
@@ -3680,7 +3842,7 @@ var CimplifyClient = class {
3680
3842
  });
3681
3843
  }
3682
3844
  async post(path, body) {
3683
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
3845
+ const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
3684
3846
  method: "POST",
3685
3847
  credentials: this.credentials,
3686
3848
  headers: this.getHeaders(),
@@ -3689,7 +3851,7 @@ var CimplifyClient = class {
3689
3851
  return this.handleRestResponse(response);
3690
3852
  }
3691
3853
  async patch(path, body) {
3692
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
3854
+ const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
3693
3855
  method: "PATCH",
3694
3856
  credentials: this.credentials,
3695
3857
  headers: this.getHeaders(),
@@ -3698,7 +3860,7 @@ var CimplifyClient = class {
3698
3860
  return this.handleRestResponse(response);
3699
3861
  }
3700
3862
  async delete(path) {
3701
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
3863
+ const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
3702
3864
  method: "DELETE",
3703
3865
  credentials: this.credentials,
3704
3866
  headers: this.getHeaders()
@@ -3929,105 +4091,6 @@ function query(entity) {
3929
4091
  return new QueryBuilder(entity);
3930
4092
  }
3931
4093
 
3932
- // src/constants.ts
3933
- var CHECKOUT_MODE = {
3934
- LINK: "link",
3935
- GUEST: "guest"
3936
- };
3937
- var ORDER_TYPE = {
3938
- DELIVERY: "delivery",
3939
- PICKUP: "pickup",
3940
- DINE_IN: "dine-in",
3941
- WALK_IN: "walk-in"
3942
- };
3943
- var PAYMENT_METHOD = {
3944
- MOBILE_MONEY: "mobile_money",
3945
- CARD: "card"
3946
- };
3947
- var CHECKOUT_STEP = {
3948
- AUTHENTICATION: "authentication",
3949
- ORDER_DETAILS: "order_details",
3950
- PAYMENT_METHOD: "payment_method",
3951
- PAYMENT: "payment",
3952
- CONFIRMATION: "confirmation"
3953
- };
3954
- var PAYMENT_STATE = {
3955
- INITIAL: "initial",
3956
- PREPARING: "preparing",
3957
- PROCESSING: "processing",
3958
- VERIFYING: "verifying",
3959
- AWAITING_AUTHORIZATION: "awaiting_authorization",
3960
- SUCCESS: "success",
3961
- ERROR: "error",
3962
- TIMEOUT: "timeout"
3963
- };
3964
- var PICKUP_TIME_TYPE = {
3965
- ASAP: "asap",
3966
- SCHEDULED: "scheduled"
3967
- };
3968
- var MOBILE_MONEY_PROVIDER = {
3969
- MTN: "mtn",
3970
- VODAFONE: "vodafone",
3971
- AIRTEL: "airtel"
3972
- };
3973
- var AUTHORIZATION_TYPE = {
3974
- OTP: "otp",
3975
- PIN: "pin",
3976
- PHONE: "phone",
3977
- BIRTHDAY: "birthday",
3978
- ADDRESS: "address"
3979
- };
3980
- var DEVICE_TYPE = {
3981
- MOBILE: "mobile",
3982
- DESKTOP: "desktop",
3983
- TABLET: "tablet"
3984
- };
3985
- var CONTACT_TYPE = {
3986
- PHONE: "phone",
3987
- EMAIL: "email"
3988
- };
3989
- var LINK_QUERY = {
3990
- DATA: "link.data",
3991
- ADDRESSES: "link.addresses",
3992
- MOBILE_MONEY: "link.mobile_money",
3993
- PREFERENCES: "link.preferences",
3994
- SESSIONS: "link.sessions"
3995
- };
3996
- var LINK_MUTATION = {
3997
- CHECK_STATUS: "link.check_status",
3998
- ENROLL: "link.enroll",
3999
- ENROLL_AND_LINK_ORDER: "link.enroll_and_link_order",
4000
- UPDATE_PREFERENCES: "link.update_preferences",
4001
- CREATE_ADDRESS: "link.create_address",
4002
- UPDATE_ADDRESS: "link.update_address",
4003
- DELETE_ADDRESS: "link.delete_address",
4004
- SET_DEFAULT_ADDRESS: "link.set_default_address",
4005
- TRACK_ADDRESS_USAGE: "link.track_address_usage",
4006
- CREATE_MOBILE_MONEY: "link.create_mobile_money",
4007
- DELETE_MOBILE_MONEY: "link.delete_mobile_money",
4008
- SET_DEFAULT_MOBILE_MONEY: "link.set_default_mobile_money",
4009
- TRACK_MOBILE_MONEY_USAGE: "link.track_mobile_money_usage",
4010
- VERIFY_MOBILE_MONEY: "link.verify_mobile_money",
4011
- REVOKE_SESSION: "link.revoke_session",
4012
- REVOKE_ALL_SESSIONS: "link.revoke_all_sessions"
4013
- };
4014
- var AUTH_MUTATION = {
4015
- REQUEST_OTP: "auth.request_otp",
4016
- VERIFY_OTP: "auth.verify_otp"
4017
- };
4018
- var CHECKOUT_MUTATION = {
4019
- PROCESS: "checkout.process"
4020
- };
4021
- var PAYMENT_MUTATION = {
4022
- SUBMIT_AUTHORIZATION: "payment.submit_authorization",
4023
- CHECK_STATUS: "order.poll_payment_status"
4024
- };
4025
- var ORDER_MUTATION = {
4026
- UPDATE_CUSTOMER: "order.update_order_customer"
4027
- };
4028
- var DEFAULT_CURRENCY = "GHS";
4029
- var DEFAULT_COUNTRY = "GHA";
4030
-
4031
4094
  exports.AUTHORIZATION_TYPE = AUTHORIZATION_TYPE;
4032
4095
  exports.AUTH_MUTATION = AUTH_MUTATION;
4033
4096
  exports.AuthService = AuthService;