@cimplify/sdk 0.7.10 → 0.7.12

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/react.mjs CHANGED
@@ -337,6 +337,18 @@ function Ad({
337
337
  }
338
338
  );
339
339
  }
340
+ var SPACE = { sm: 8, md: 12, lg: 16, xl: 24 };
341
+ function shellColors(isDark, primaryColor) {
342
+ return {
343
+ text: isDark ? "#f4f4f5" : "#1a1a1a",
344
+ textSecondary: isDark ? "#a1a1aa" : "#52525b",
345
+ textMuted: isDark ? "#71717a" : "#a1a1aa",
346
+ border: isDark ? "#27272a" : "#e4e4e7",
347
+ surface: isDark ? "#18181b" : "#fafafa",
348
+ error: "#dc2626",
349
+ primary: primaryColor
350
+ };
351
+ }
340
352
  function labelForOrderType(orderType) {
341
353
  if (orderType === "dine_in") {
342
354
  return "Dine In";
@@ -629,11 +641,12 @@ function CimplifyCheckout({
629
641
  onError,
630
642
  orderType
631
643
  ]);
644
+ const colors = shellColors(isDark ?? false, primaryColor);
632
645
  if (isInitializing) {
633
- return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { fontSize: "14px", color: "#52525b" }, children: "Preparing checkout..." }) });
646
+ return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
634
647
  }
635
648
  if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
636
- return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { fontSize: "14px", color: "#b91c1c" }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
649
+ return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
637
650
  }
638
651
  return /* @__PURE__ */ jsxs("div", { className, "data-cimplify-checkout": "", children: [
639
652
  isTestMode && !isDemoCheckout && /* @__PURE__ */ jsx(
@@ -650,38 +663,47 @@ function CimplifyCheckout({
650
663
  }
651
664
  ),
652
665
  /* @__PURE__ */ jsx("div", { "data-cimplify-section": "payment", children: /* @__PURE__ */ jsx("div", { ref: isDemoCheckout ? void 0 : paymentMountRef }) }),
653
- /* @__PURE__ */ jsxs("div", { "data-cimplify-section": "order-type", style: { marginTop: "20px" }, children: [
654
- /* @__PURE__ */ jsx("p", { style: { fontSize: "13px", fontWeight: 500, color: isDark ? "#a1a1aa" : "#71717a", marginBottom: "8px" }, children: "Order type" }),
666
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-section": "order-type", style: { marginTop: SPACE.xl }, children: [
667
+ /* @__PURE__ */ jsx("p", { style: { fontSize: 13, fontWeight: 500, color: colors.textMuted, marginBottom: SPACE.sm }, children: "Order type" }),
655
668
  /* @__PURE__ */ jsx(
656
669
  "div",
657
670
  {
658
671
  role: "group",
659
672
  "aria-label": "Order type",
660
- style: { display: "flex", gap: "8px", flexWrap: "wrap" },
661
- children: resolvedOrderTypes.map((type) => /* @__PURE__ */ jsx(
662
- "button",
663
- {
664
- type: "button",
665
- onClick: () => setOrderType(type),
666
- disabled: isSubmitting,
667
- "data-selected": orderType === type ? "true" : "false",
668
- style: {
669
- padding: "10px 18px",
670
- borderRadius: "8px",
671
- border: orderType === type ? "1px solid transparent" : `1px solid ${isDark ? "#3f3f46" : "#d4d4d8"}`,
672
- background: orderType === type ? primaryColor : "transparent",
673
- color: orderType === type ? "#ffffff" : isDark ? "#e4e4e7" : "#3f3f46",
674
- cursor: isSubmitting ? "not-allowed" : "pointer",
675
- opacity: isSubmitting ? 0.6 : 1,
676
- fontSize: "15px",
677
- fontWeight: 500,
678
- transition: "all 150ms ease",
679
- WebkitTapHighlightColor: "transparent"
673
+ style: {
674
+ display: "inline-flex",
675
+ border: `1px solid ${colors.border}`,
676
+ borderRadius: 8,
677
+ padding: 3,
678
+ background: colors.surface
679
+ },
680
+ children: resolvedOrderTypes.map((type) => {
681
+ const active = orderType === type;
682
+ return /* @__PURE__ */ jsx(
683
+ "button",
684
+ {
685
+ type: "button",
686
+ onClick: () => setOrderType(type),
687
+ disabled: isSubmitting,
688
+ "data-selected": active ? "true" : "false",
689
+ style: {
690
+ padding: `${SPACE.sm}px ${SPACE.lg}px`,
691
+ borderRadius: 6,
692
+ border: "none",
693
+ background: active ? primaryColor : "transparent",
694
+ color: active ? "#ffffff" : colors.textSecondary,
695
+ cursor: isSubmitting ? "not-allowed" : "pointer",
696
+ opacity: isSubmitting ? 0.6 : 1,
697
+ fontSize: 14,
698
+ fontWeight: 500,
699
+ transition: "all 150ms ease",
700
+ WebkitTapHighlightColor: "transparent"
701
+ },
702
+ children: labelForOrderType(type)
680
703
  },
681
- children: labelForOrderType(type)
682
- },
683
- type
684
- ))
704
+ type
705
+ );
706
+ })
685
707
  }
686
708
  )
687
709
  ] }),
@@ -689,11 +711,11 @@ function CimplifyCheckout({
689
711
  "div",
690
712
  {
691
713
  "data-cimplify-section": "address",
692
- style: { marginTop: "16px", display: orderType === "delivery" ? "block" : "none" },
714
+ style: { marginTop: SPACE.lg, display: orderType === "delivery" ? "block" : "none" },
693
715
  children: /* @__PURE__ */ jsx("div", { ref: isDemoCheckout ? void 0 : addressMountRef })
694
716
  }
695
717
  ),
696
- /* @__PURE__ */ jsx("div", { style: { marginTop: "24px" }, children: /* @__PURE__ */ jsx(
718
+ /* @__PURE__ */ jsx("div", { style: { marginTop: SPACE.xl }, children: /* @__PURE__ */ jsx(
697
719
  "button",
698
720
  {
699
721
  type: "button",
@@ -701,23 +723,22 @@ function CimplifyCheckout({
701
723
  disabled: isSubmitting,
702
724
  style: {
703
725
  width: "100%",
704
- padding: "14px 16px",
705
- borderRadius: "10px",
726
+ padding: `${SPACE.md}px ${SPACE.lg}px`,
727
+ borderRadius: 8,
706
728
  border: "none",
707
- background: isSubmitting ? "#a1a1aa" : primaryColor,
729
+ background: isSubmitting ? colors.textMuted : primaryColor,
708
730
  color: "#ffffff",
709
731
  cursor: isSubmitting ? "not-allowed" : "pointer",
710
732
  fontWeight: 600,
711
- fontSize: "16px",
712
- boxShadow: isSubmitting ? "none" : "0 1px 3px 0 rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1)",
733
+ fontSize: 16,
713
734
  transition: "all 150ms ease",
714
735
  WebkitTapHighlightColor: "transparent"
715
736
  },
716
737
  children: isSubmitting ? "Processing..." : "Complete Order"
717
738
  }
718
739
  ) }),
719
- status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: "10px", fontSize: "14px", color: "#52525b" }, children: statusText || statusToLabel(status) }),
720
- errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: "8px", fontSize: "14px", color: "#b91c1c" }, children: errorMessage })
740
+ status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
741
+ errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
721
742
  ] });
722
743
  }
723
744
 
@@ -2946,6 +2967,12 @@ var CimplifyElements = class {
2946
2967
  getElement(type) {
2947
2968
  return this.elements.get(type);
2948
2969
  }
2970
+ _removeElement(type, instance) {
2971
+ const current = this.elements.get(type);
2972
+ if (current === instance) {
2973
+ this.elements.delete(type);
2974
+ }
2975
+ }
2949
2976
  destroy() {
2950
2977
  this.elements.forEach((element) => element.destroy());
2951
2978
  this.elements.clear();
@@ -2984,7 +3011,9 @@ var CimplifyElements = class {
2984
3011
  processCheckout(options) {
2985
3012
  let abortFn = null;
2986
3013
  const task = (async () => {
3014
+ console.debug("[cimplify:checkout] processCheckout called", { cart_id: options.cart_id, order_type: options.order_type, location_id: options.location_id });
2987
3015
  if (this.checkoutInProgress) {
3016
+ console.debug("[cimplify:checkout] BLOCKED: already processing");
2988
3017
  return toCheckoutError(
2989
3018
  "ALREADY_PROCESSING",
2990
3019
  "Checkout is already in progress.",
@@ -2992,6 +3021,7 @@ var CimplifyElements = class {
2992
3021
  );
2993
3022
  }
2994
3023
  if (!options.cart_id) {
3024
+ console.debug("[cimplify:checkout] BLOCKED: no cart_id");
2995
3025
  return toCheckoutError(
2996
3026
  "INVALID_CART",
2997
3027
  "A valid cart is required before checkout can start.",
@@ -2999,6 +3029,7 @@ var CimplifyElements = class {
2999
3029
  );
3000
3030
  }
3001
3031
  if (!options.order_type) {
3032
+ console.debug("[cimplify:checkout] BLOCKED: no order_type");
3002
3033
  return toCheckoutError(
3003
3034
  "ORDER_TYPE_REQUIRED",
3004
3035
  "Order type is required before checkout can start.",
@@ -3007,6 +3038,7 @@ var CimplifyElements = class {
3007
3038
  }
3008
3039
  const paymentElement = this.elements.get(ELEMENT_TYPES.PAYMENT);
3009
3040
  if (!paymentElement) {
3041
+ console.debug("[cimplify:checkout] BLOCKED: no payment element");
3010
3042
  return toCheckoutError(
3011
3043
  "NO_PAYMENT_ELEMENT",
3012
3044
  "Payment element must be mounted before checkout.",
@@ -3014,6 +3046,7 @@ var CimplifyElements = class {
3014
3046
  );
3015
3047
  }
3016
3048
  if (!paymentElement.isMounted()) {
3049
+ console.debug("[cimplify:checkout] BLOCKED: payment element not mounted");
3017
3050
  return toCheckoutError(
3018
3051
  "PAYMENT_NOT_MOUNTED",
3019
3052
  "Payment element must be mounted before checkout.",
@@ -3022,6 +3055,7 @@ var CimplifyElements = class {
3022
3055
  }
3023
3056
  const authElement = this.elements.get(ELEMENT_TYPES.AUTH);
3024
3057
  if (authElement && !this.accessToken) {
3058
+ console.debug("[cimplify:checkout] BLOCKED: auth incomplete");
3025
3059
  return toCheckoutError(
3026
3060
  "AUTH_INCOMPLETE",
3027
3061
  "Authentication must complete before checkout can start.",
@@ -3030,9 +3064,12 @@ var CimplifyElements = class {
3030
3064
  }
3031
3065
  const addressElement = this.elements.get(ELEMENT_TYPES.ADDRESS);
3032
3066
  if (addressElement) {
3067
+ console.debug("[cimplify:checkout] getting address data...");
3033
3068
  await addressElement.getData();
3069
+ console.debug("[cimplify:checkout] address data resolved", this.addressData);
3034
3070
  }
3035
3071
  await this.hydrateCustomerData();
3072
+ console.debug("[cimplify:checkout] customer data hydrated", { customerData: this.customerData, accountId: this.accountId });
3036
3073
  const processMessage = {
3037
3074
  type: MESSAGE_TYPES.PROCESS_CHECKOUT,
3038
3075
  cart_id: options.cart_id,
@@ -3109,6 +3146,7 @@ var CimplifyElements = class {
3109
3146
  return;
3110
3147
  }
3111
3148
  if (message.type === MESSAGE_TYPES.CHECKOUT_COMPLETE) {
3149
+ console.debug("[cimplify:checkout] received checkout_complete", { success: message.success, error: message.error });
3112
3150
  settle({
3113
3151
  success: message.success,
3114
3152
  order: message.order,
@@ -3131,7 +3169,9 @@ var CimplifyElements = class {
3131
3169
  );
3132
3170
  };
3133
3171
  this.activeCheckoutAbort = abortFn;
3172
+ console.debug("[cimplify:checkout] sending process_checkout to payment iframe", { cart_id: processMessage.cart_id, order_type: processMessage.order_type, hasCustomer: !!processMessage.customer, hasAddress: !!processMessage.address });
3134
3173
  paymentElement.sendMessage(processMessage);
3174
+ console.debug("[cimplify:checkout] postMessage sent, waiting for checkout_complete...");
3135
3175
  });
3136
3176
  })();
3137
3177
  const abortable = task;
@@ -3272,6 +3312,7 @@ var CimplifyElement = class {
3272
3312
  this.mounted = false;
3273
3313
  this.eventHandlers = /* @__PURE__ */ new Map();
3274
3314
  this.resolvers = /* @__PURE__ */ new Map();
3315
+ this.listening = false;
3275
3316
  this.type = type;
3276
3317
  this.businessId = businessId;
3277
3318
  this.linkUrl = linkUrl;
@@ -3281,6 +3322,7 @@ var CimplifyElement = class {
3281
3322
  this.boundHandleMessage = this.handleMessage.bind(this);
3282
3323
  if (typeof window !== "undefined") {
3283
3324
  window.addEventListener("message", this.boundHandleMessage);
3325
+ this.listening = true;
3284
3326
  }
3285
3327
  }
3286
3328
  mount(container) {
@@ -3295,6 +3337,10 @@ var CimplifyElement = class {
3295
3337
  }
3296
3338
  this.container = target;
3297
3339
  this.mounted = true;
3340
+ if (!this.listening && typeof window !== "undefined") {
3341
+ window.addEventListener("message", this.boundHandleMessage);
3342
+ this.listening = true;
3343
+ }
3298
3344
  void this.createIframe();
3299
3345
  }
3300
3346
  destroy() {
@@ -3307,9 +3353,11 @@ var CimplifyElement = class {
3307
3353
  this.eventHandlers.clear();
3308
3354
  this.resolvers.forEach((entry) => clearTimeout(entry.timeoutId));
3309
3355
  this.resolvers.clear();
3310
- if (typeof window !== "undefined") {
3356
+ if (this.listening && typeof window !== "undefined") {
3311
3357
  window.removeEventListener("message", this.boundHandleMessage);
3358
+ this.listening = false;
3312
3359
  }
3360
+ this.parent._removeElement(this.type, this);
3313
3361
  }
3314
3362
  on(event, handler) {
3315
3363
  if (!this.eventHandlers.has(event)) {
@@ -6104,17 +6152,36 @@ function AuthElement({
6104
6152
  const containerRef = useRef(null);
6105
6153
  const elementRef = useRef(null);
6106
6154
  const elements = useElements();
6155
+ const onReadyRef = useRef(onReady);
6156
+ const onAuthenticatedRef = useRef(onAuthenticated);
6157
+ const onRequiresOtpRef = useRef(onRequiresOtp);
6158
+ const onErrorRef = useRef(onError);
6159
+ useEffect(() => {
6160
+ onReadyRef.current = onReady;
6161
+ onAuthenticatedRef.current = onAuthenticated;
6162
+ onRequiresOtpRef.current = onRequiresOtp;
6163
+ onErrorRef.current = onError;
6164
+ }, [onReady, onAuthenticated, onRequiresOtp, onError]);
6107
6165
  useEffect(() => {
6108
6166
  if (!elements || !containerRef.current) return;
6109
6167
  const element = elements.create(ELEMENT_TYPES.AUTH, { prefillEmail });
6110
6168
  elementRef.current = element;
6111
- element.on(EVENT_TYPES.READY, () => onReady?.());
6112
- element.on(EVENT_TYPES.AUTHENTICATED, (data) => onAuthenticated?.(data));
6113
- element.on(EVENT_TYPES.REQUIRES_OTP, (data) => onRequiresOtp?.(data));
6114
- element.on(EVENT_TYPES.ERROR, (data) => onError?.(data));
6169
+ element.on(EVENT_TYPES.READY, () => onReadyRef.current?.());
6170
+ element.on(
6171
+ EVENT_TYPES.AUTHENTICATED,
6172
+ (data) => onAuthenticatedRef.current?.(data)
6173
+ );
6174
+ element.on(
6175
+ EVENT_TYPES.REQUIRES_OTP,
6176
+ (data) => onRequiresOtpRef.current?.(data)
6177
+ );
6178
+ element.on(
6179
+ EVENT_TYPES.ERROR,
6180
+ (data) => onErrorRef.current?.(data)
6181
+ );
6115
6182
  element.mount(containerRef.current);
6116
6183
  return () => element.destroy();
6117
- }, [elements, prefillEmail, onReady, onAuthenticated, onRequiresOtp, onError]);
6184
+ }, [elements, prefillEmail]);
6118
6185
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className, style });
6119
6186
  }
6120
6187
  function AddressElement({
@@ -6128,16 +6195,30 @@ function AddressElement({
6128
6195
  const containerRef = useRef(null);
6129
6196
  const elementRef = useRef(null);
6130
6197
  const elements = useElements();
6198
+ const onReadyRef = useRef(onReady);
6199
+ const onChangeRef = useRef(onChange);
6200
+ const onErrorRef = useRef(onError);
6201
+ useEffect(() => {
6202
+ onReadyRef.current = onReady;
6203
+ onChangeRef.current = onChange;
6204
+ onErrorRef.current = onError;
6205
+ }, [onReady, onChange, onError]);
6131
6206
  useEffect(() => {
6132
6207
  if (!elements || !containerRef.current) return;
6133
6208
  const element = elements.create(ELEMENT_TYPES.ADDRESS, { mode });
6134
6209
  elementRef.current = element;
6135
- element.on(EVENT_TYPES.READY, () => onReady?.());
6136
- element.on(EVENT_TYPES.CHANGE, (data) => onChange?.(data));
6137
- element.on(EVENT_TYPES.ERROR, (data) => onError?.(data));
6210
+ element.on(EVENT_TYPES.READY, () => onReadyRef.current?.());
6211
+ element.on(
6212
+ EVENT_TYPES.CHANGE,
6213
+ (data) => onChangeRef.current?.(data)
6214
+ );
6215
+ element.on(
6216
+ EVENT_TYPES.ERROR,
6217
+ (data) => onErrorRef.current?.(data)
6218
+ );
6138
6219
  element.mount(containerRef.current);
6139
6220
  return () => element.destroy();
6140
- }, [elements, mode, onReady, onChange, onError]);
6221
+ }, [elements, mode]);
6141
6222
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className, style });
6142
6223
  }
6143
6224
  function PaymentElement({
@@ -6152,16 +6233,30 @@ function PaymentElement({
6152
6233
  const containerRef = useRef(null);
6153
6234
  const elementRef = useRef(null);
6154
6235
  const elements = useElements();
6236
+ const onReadyRef = useRef(onReady);
6237
+ const onChangeRef = useRef(onChange);
6238
+ const onErrorRef = useRef(onError);
6239
+ useEffect(() => {
6240
+ onReadyRef.current = onReady;
6241
+ onChangeRef.current = onChange;
6242
+ onErrorRef.current = onError;
6243
+ }, [onReady, onChange, onError]);
6155
6244
  useEffect(() => {
6156
6245
  if (!elements || !containerRef.current) return;
6157
6246
  const element = elements.create(ELEMENT_TYPES.PAYMENT, { amount, currency });
6158
6247
  elementRef.current = element;
6159
- element.on(EVENT_TYPES.READY, () => onReady?.());
6160
- element.on(EVENT_TYPES.CHANGE, (data) => onChange?.(data));
6161
- element.on(EVENT_TYPES.ERROR, (data) => onError?.(data));
6248
+ element.on(EVENT_TYPES.READY, () => onReadyRef.current?.());
6249
+ element.on(
6250
+ EVENT_TYPES.CHANGE,
6251
+ (data) => onChangeRef.current?.(data)
6252
+ );
6253
+ element.on(
6254
+ EVENT_TYPES.ERROR,
6255
+ (data) => onErrorRef.current?.(data)
6256
+ );
6162
6257
  element.mount(containerRef.current);
6163
6258
  return () => element.destroy();
6164
- }, [elements, amount, currency, onReady, onChange, onError]);
6259
+ }, [elements, amount, currency]);
6165
6260
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className, style });
6166
6261
  }
6167
6262
  function useCheckout() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cimplify/sdk",
3
- "version": "0.7.10",
3
+ "version": "0.7.12",
4
4
  "description": "Cimplify Commerce SDK for storefronts",
5
5
  "keywords": [
6
6
  "cimplify",