azirid-react 0.9.4 → 0.9.7

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.cjs CHANGED
@@ -2256,8 +2256,9 @@ function usePaymentProviders() {
2256
2256
  }
2257
2257
 
2258
2258
  // src/utils/payphone-loader.ts
2259
- var PAYPHONE_CSS_URL = "https://cdn.payphonetodoesposible.com/box/v1.1/payphone-payment-box.css";
2260
- var PAYPHONE_JS_URL = "https://cdn.payphonetodoesposible.com/box/v1.1/payphone-payment-box.js";
2259
+ var PAYPHONE_CDN = "https://cdn.payphonetodoesposible.com";
2260
+ var PAYPHONE_CSS_URL = `${PAYPHONE_CDN}/box/v1.1/payphone-payment-box.css`;
2261
+ var PAYPHONE_JS_URL = `${PAYPHONE_CDN}/box/v1.1/payphone-payment-box.js`;
2261
2262
  var loadPromise = null;
2262
2263
  function loadCss(href) {
2263
2264
  if (document.querySelector(`link[href="${href}"]`)) return;
@@ -2275,7 +2276,11 @@ function loadScript(src) {
2275
2276
  const script = document.createElement("script");
2276
2277
  script.src = src;
2277
2278
  script.onload = () => resolve();
2278
- script.onerror = () => reject(new Error(`Failed to load Payphone SDK: ${src}`));
2279
+ script.onerror = () => reject(
2280
+ new Error(
2281
+ `Failed to load Payphone SDK from ${src}. If your app uses a Content-Security-Policy, add "${PAYPHONE_CDN}" to both script-src and style-src directives.`
2282
+ )
2283
+ );
2279
2284
  document.head.appendChild(script);
2280
2285
  });
2281
2286
  }
@@ -2284,21 +2289,27 @@ function loadPayphoneSdk() {
2284
2289
  loadPromise = (async () => {
2285
2290
  loadCss(PAYPHONE_CSS_URL);
2286
2291
  await loadScript(PAYPHONE_JS_URL);
2287
- })();
2292
+ })().catch((err) => {
2293
+ loadPromise = null;
2294
+ throw err;
2295
+ });
2288
2296
  return loadPromise;
2289
2297
  }
2290
- function PayphoneModal({ config, successUrl, onClose }) {
2291
- const [loading, setLoading] = react.useState(true);
2292
- const [error, setError] = react.useState(null);
2298
+ function PayphoneWidgetRenderer({
2299
+ config,
2300
+ responseUrl,
2301
+ containerId,
2302
+ onReady,
2303
+ onError
2304
+ }) {
2293
2305
  const initialized = react.useRef(false);
2294
2306
  react.useEffect(() => {
2295
2307
  if (initialized.current) return;
2296
2308
  initialized.current = true;
2297
2309
  loadPayphoneSdk().then(() => {
2298
- setLoading(false);
2299
2310
  requestAnimationFrame(() => {
2300
2311
  if (typeof window.PPaymentButtonBox === "undefined") {
2301
- setError("Payphone SDK failed to initialize");
2312
+ onError?.(new Error("Payphone SDK failed to initialize"));
2302
2313
  return;
2303
2314
  }
2304
2315
  new window.PPaymentButtonBox({
@@ -2309,19 +2320,30 @@ function PayphoneModal({ config, successUrl, onClose }) {
2309
2320
  currency: config.currency,
2310
2321
  storeId: config.storeId,
2311
2322
  reference: config.reference,
2312
- responseUrl: successUrl
2313
- }).render("pp-button-azirid");
2323
+ responseUrl
2324
+ }).render(containerId);
2325
+ onReady?.();
2314
2326
  });
2315
- }).catch(() => {
2316
- setLoading(false);
2317
- setError("Failed to load Payphone payment widget");
2327
+ }).catch((err) => {
2328
+ onError?.(new Error(err instanceof Error ? err.message : "Failed to load Payphone SDK"));
2318
2329
  });
2319
- }, [config, successUrl]);
2330
+ }, [config, responseUrl, containerId, onReady, onError]);
2331
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { id: containerId });
2332
+ }
2333
+ function PayphoneModal({ config, successUrl, onClose }) {
2334
+ const [error, setError] = react.useState(null);
2320
2335
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, onClick: (e) => e.stopPropagation(), children: [
2321
2336
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: "Payphone" }),
2322
- loading && /* @__PURE__ */ jsxRuntime.jsx("p", { style: messageStyle, children: "Loading payment widget..." }),
2323
2337
  error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...messageStyle, color: "#ef4444" }, children: error }),
2324
- /* @__PURE__ */ jsxRuntime.jsx("div", { id: "pp-button-azirid", style: { minHeight: "80px" } }),
2338
+ /* @__PURE__ */ jsxRuntime.jsx(
2339
+ PayphoneWidgetRenderer,
2340
+ {
2341
+ config,
2342
+ responseUrl: successUrl,
2343
+ containerId: "pp-button-azirid",
2344
+ onError: (err) => setError(err.message)
2345
+ }
2346
+ ),
2325
2347
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: warningStyle, children: "Do not close this window until the payment is complete." }),
2326
2348
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: cancelStyle, onClick: onClose, children: "Cancel" })
2327
2349
  ] }) });
@@ -2887,14 +2909,274 @@ function CheckoutButton({
2887
2909
  );
2888
2910
  }
2889
2911
  CheckoutButton.displayName = "CheckoutButton";
2912
+ function usePayphoneConfirm(options) {
2913
+ const client = useAccessClient();
2914
+ return reactQuery.useMutation({
2915
+ mutationFn: (params) => client.post(client.paths.payphoneConfirm, params),
2916
+ onSuccess: options?.onSuccess,
2917
+ onError: options?.onError
2918
+ });
2919
+ }
2890
2920
  var PROVIDER_LABELS2 = {
2921
+ STRIPE: "Credit/Debit Card",
2922
+ PAYPAL: "PayPal",
2923
+ PAYPHONE: "Payphone",
2924
+ NUVEI: "Nuvei",
2925
+ MANUAL_TRANSFER: "Bank Transfer"
2926
+ };
2927
+ var PROVIDER_ICONS2 = {
2928
+ STRIPE: "\u{1F4B3}",
2929
+ PAYPAL: "\u{1F17F}\uFE0F",
2930
+ PAYPHONE: "\u{1F4F1}",
2931
+ NUVEI: "\u{1F4B3}",
2932
+ MANUAL_TRANSFER: "\u{1F3E6}"
2933
+ };
2934
+ var PP_CONTAINER_ID = "pp-paybtn-azirid";
2935
+ function usePayButton({
2936
+ intentId,
2937
+ planId,
2938
+ onSuccess,
2939
+ onError
2940
+ }) {
2941
+ const [status, setStatus] = react.useState("idle");
2942
+ const [selectedProvider, setSelectedProvider] = react.useState(null);
2943
+ const [checkoutData, setCheckoutData] = react.useState(null);
2944
+ const [payphoneConfig, setPayphoneConfig] = react.useState(null);
2945
+ const [currentError, setCurrentError] = react.useState(null);
2946
+ const payphoneConfirmTriggered = react.useRef(false);
2947
+ const responseUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
2948
+ const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
2949
+ const callbackId = params.get("id");
2950
+ const callbackClientTxId = params.get("clientTransactionId");
2951
+ const isPayphoneCallback = !!(callbackId && callbackClientTxId);
2952
+ const {
2953
+ data: providerList,
2954
+ isLoading: providersLoading
2955
+ } = usePaymentProviders();
2956
+ const providers = providerList ?? [];
2957
+ react.useEffect(() => {
2958
+ if (isPayphoneCallback) return;
2959
+ if (providersLoading) {
2960
+ setStatus("loading_providers");
2961
+ } else if (providers.length > 0 && status === "loading_providers") {
2962
+ setStatus("ready");
2963
+ }
2964
+ }, [providersLoading, providers.length, status, isPayphoneCallback]);
2965
+ const { checkout: doCheckout, isPending } = useCheckout({
2966
+ redirectOnSuccess: false,
2967
+ onSuccess: (data) => {
2968
+ setCheckoutData(data);
2969
+ if (data.provider === "PAYPHONE" && data.widgetConfig) {
2970
+ setPayphoneConfig(data.widgetConfig);
2971
+ setStatus("processing");
2972
+ return;
2973
+ }
2974
+ if (data.provider === "MANUAL_TRANSFER") {
2975
+ setStatus("success");
2976
+ onSuccess?.(data);
2977
+ return;
2978
+ }
2979
+ if (data.url) {
2980
+ setStatus("redirecting");
2981
+ window.location.href = data.url;
2982
+ return;
2983
+ }
2984
+ setStatus("success");
2985
+ onSuccess?.(data);
2986
+ },
2987
+ onError: (err) => {
2988
+ setCurrentError(err);
2989
+ setStatus("error");
2990
+ onError?.(err);
2991
+ }
2992
+ });
2993
+ const checkout = react.useCallback(
2994
+ (provider) => {
2995
+ setSelectedProvider(provider);
2996
+ setStatus("processing");
2997
+ setCurrentError(null);
2998
+ doCheckout({
2999
+ intentId,
3000
+ planId,
3001
+ provider,
3002
+ successUrl: responseUrl,
3003
+ cancelUrl: responseUrl
3004
+ });
3005
+ },
3006
+ [doCheckout, intentId, planId, responseUrl]
3007
+ );
3008
+ const { mutate: confirmPayphone } = usePayphoneConfirm({
3009
+ onSuccess: (data) => {
3010
+ const isConfirmed = data.status === "confirmed" || data.status === "already_confirmed";
3011
+ setStatus(isConfirmed ? "success" : "error");
3012
+ const response = {
3013
+ provider: "PAYPHONE",
3014
+ ...checkoutData ?? {}
3015
+ };
3016
+ if (isConfirmed) {
3017
+ onSuccess?.(response);
3018
+ } else {
3019
+ onError?.(new Error("Payment was cancelled"));
3020
+ }
3021
+ },
3022
+ onError: (err) => {
3023
+ setCurrentError(err);
3024
+ setStatus("error");
3025
+ onError?.(err);
3026
+ }
3027
+ });
3028
+ react.useEffect(() => {
3029
+ if (!isPayphoneCallback || payphoneConfirmTriggered.current) return;
3030
+ payphoneConfirmTriggered.current = true;
3031
+ setSelectedProvider("PAYPHONE");
3032
+ setStatus("processing");
3033
+ confirmPayphone({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
3034
+ }, [isPayphoneCallback, callbackId, callbackClientTxId, confirmPayphone]);
3035
+ const handleSdkError = react.useCallback(
3036
+ (err) => {
3037
+ setCurrentError(err);
3038
+ setStatus("error");
3039
+ onError?.(err);
3040
+ },
3041
+ [onError]
3042
+ );
3043
+ const ProviderSelector = react.useMemo(() => {
3044
+ return function ProviderSelectorInner() {
3045
+ if (providers.length === 0 || isPayphoneCallback) return null;
3046
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(
3047
+ "button",
3048
+ {
3049
+ type: "button",
3050
+ style: {
3051
+ display: "flex",
3052
+ alignItems: "center",
3053
+ width: "100%",
3054
+ padding: "12px 16px",
3055
+ border: "1px solid #e5e7eb",
3056
+ borderRadius: "8px",
3057
+ backgroundColor: selectedProvider === p.provider ? "#f3f4f6" : "#fff",
3058
+ cursor: isPending ? "not-allowed" : "pointer",
3059
+ fontSize: "14px",
3060
+ fontWeight: 500,
3061
+ color: "#111827",
3062
+ fontFamily: "inherit"
3063
+ },
3064
+ onClick: () => checkout(p.provider),
3065
+ disabled: isPending,
3066
+ children: [
3067
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "20px", marginRight: "12px" }, children: PROVIDER_ICONS2[p.provider] }),
3068
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: PROVIDER_LABELS2[p.provider] })
3069
+ ]
3070
+ },
3071
+ p.provider
3072
+ )) });
3073
+ };
3074
+ }, [providers, selectedProvider, isPending, checkout, isPayphoneCallback]);
3075
+ const TransferDetails = react.useMemo(() => {
3076
+ return function TransferDetailsInner() {
3077
+ if (!checkoutData || checkoutData.provider !== "MANUAL_TRANSFER") return null;
3078
+ const bankDetails = checkoutData.bankDetails;
3079
+ const plan = checkoutData.plan;
3080
+ const intent = checkoutData.intent;
3081
+ const displayAmount = plan ? formatAmount(plan.amount, plan.currency) : intent ? formatAmount(intent.amount, intent.currency) : "";
3082
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3083
+ displayAmount && /* @__PURE__ */ jsxRuntime.jsxs(
3084
+ "div",
3085
+ {
3086
+ style: {
3087
+ textAlign: "center",
3088
+ padding: "16px",
3089
+ backgroundColor: "#f9fafb",
3090
+ borderRadius: "8px",
3091
+ marginBottom: "20px"
3092
+ },
3093
+ children: [
3094
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "32px", fontWeight: 700, color: "#111827" }, children: displayAmount }),
3095
+ plan?.name && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "14px", color: "#6b7280" }, children: plan.name }),
3096
+ intent?.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "14px", color: "#6b7280" }, children: intent.description })
3097
+ ]
3098
+ }
3099
+ ),
3100
+ bankDetails && Object.keys(bankDetails).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "16px" }, children: [
3101
+ /* @__PURE__ */ jsxRuntime.jsx(
3102
+ "div",
3103
+ {
3104
+ style: {
3105
+ fontSize: "14px",
3106
+ fontWeight: 600,
3107
+ color: "#111827",
3108
+ marginBottom: "8px"
3109
+ },
3110
+ children: "Bank Details"
3111
+ }
3112
+ ),
3113
+ Object.entries(bankDetails).filter(([, v]) => v).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs(
3114
+ "div",
3115
+ {
3116
+ style: {
3117
+ display: "flex",
3118
+ justifyContent: "space-between",
3119
+ padding: "6px 0",
3120
+ borderBottom: "1px solid #f3f4f6",
3121
+ fontSize: "13px"
3122
+ },
3123
+ children: [
3124
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#6b7280" }, children: key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()) }),
3125
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#111827", fontWeight: 500 }, children: value })
3126
+ ]
3127
+ },
3128
+ key
3129
+ ))
3130
+ ] }),
3131
+ checkoutData.transferInstructions && /* @__PURE__ */ jsxRuntime.jsx(
3132
+ "div",
3133
+ {
3134
+ style: {
3135
+ padding: "12px",
3136
+ backgroundColor: "#eff6ff",
3137
+ borderRadius: "6px",
3138
+ fontSize: "13px",
3139
+ color: "#1e40af",
3140
+ lineHeight: 1.5
3141
+ },
3142
+ children: checkoutData.transferInstructions
3143
+ }
3144
+ )
3145
+ ] });
3146
+ };
3147
+ }, [checkoutData]);
3148
+ const PayphoneWidget = react.useMemo(() => {
3149
+ return function PayphoneWidgetInner() {
3150
+ if (!payphoneConfig || isPayphoneCallback) return null;
3151
+ return PayphoneWidgetRenderer({
3152
+ config: payphoneConfig,
3153
+ responseUrl,
3154
+ containerId: PP_CONTAINER_ID,
3155
+ onError: handleSdkError
3156
+ });
3157
+ };
3158
+ }, [payphoneConfig, responseUrl, isPayphoneCallback, handleSdkError]);
3159
+ return {
3160
+ providers,
3161
+ checkout,
3162
+ ProviderSelector,
3163
+ TransferDetails,
3164
+ PayphoneWidget,
3165
+ status,
3166
+ selectedProvider,
3167
+ checkoutData,
3168
+ isPending,
3169
+ error: currentError
3170
+ };
3171
+ }
3172
+ var PROVIDER_LABELS3 = {
2891
3173
  STRIPE: { en: "Credit/Debit Card", es: "Tarjeta de cr\xE9dito/d\xE9bito" },
2892
3174
  PAYPAL: { en: "PayPal", es: "PayPal" },
2893
3175
  PAYPHONE: { en: "Payphone", es: "Payphone" },
2894
3176
  NUVEI: { en: "Nuvei", es: "Nuvei" },
2895
3177
  MANUAL_TRANSFER: { en: "Bank Transfer", es: "Transferencia bancaria" }
2896
3178
  };
2897
- var PROVIDER_ICONS2 = {
3179
+ var PROVIDER_ICONS3 = {
2898
3180
  STRIPE: "\u{1F4B3}",
2899
3181
  PAYPAL: "\u{1F17F}\uFE0F",
2900
3182
  PAYPHONE: "\u{1F4F1}",
@@ -2967,7 +3249,7 @@ function ProviderModal({
2967
3249
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: modalStyles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalStyles.card, onClick: (e) => e.stopPropagation(), children: [
2968
3250
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: modalStyles.title, children: labels?.selectPaymentMethod ?? "Select payment method" }),
2969
3251
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: providers.map((p) => {
2970
- const label = PROVIDER_LABELS2[p.provider];
3252
+ const label = PROVIDER_LABELS3[p.provider];
2971
3253
  return /* @__PURE__ */ jsxRuntime.jsxs(
2972
3254
  "button",
2973
3255
  {
@@ -2976,7 +3258,7 @@ function ProviderModal({
2976
3258
  onClick: () => onSelect(p.provider),
2977
3259
  disabled: isPending,
2978
3260
  children: [
2979
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "20px", marginRight: "12px" }, children: PROVIDER_ICONS2[p.provider] }),
3261
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "20px", marginRight: "12px" }, children: PROVIDER_ICONS3[p.provider] }),
2980
3262
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: label?.en ?? p.provider })
2981
3263
  ]
2982
3264
  },
@@ -3087,20 +3369,23 @@ function PayButton({
3087
3369
  const billing = messages?.billing;
3088
3370
  const [showProviderModal, setShowProviderModal] = react.useState(false);
3089
3371
  const [showTransferModal, setShowTransferModal] = react.useState(false);
3090
- const [transferData, setTransferData] = react.useState(null);
3091
- const [payphoneData, setPayphoneData] = react.useState(null);
3092
- const { data: providers, isLoading: providersLoading } = usePaymentProviders();
3093
- const { checkout, isPending } = useCheckout({
3094
- redirectOnSuccess: true,
3372
+ const {
3373
+ providers,
3374
+ checkout,
3375
+ checkoutData,
3376
+ PayphoneWidget,
3377
+ isPending,
3378
+ status
3379
+ } = usePayButton({
3380
+ intentId,
3381
+ planId,
3095
3382
  onSuccess: (data) => {
3096
3383
  if (data.provider === "MANUAL_TRANSFER") {
3097
- setTransferData(data);
3098
3384
  setShowTransferModal(true);
3099
3385
  setShowProviderModal(false);
3100
3386
  return;
3101
3387
  }
3102
- if (data.provider === "PAYPHONE" && data.widgetConfig) {
3103
- setPayphoneData(data);
3388
+ if (data.provider === "PAYPHONE") {
3104
3389
  setShowProviderModal(false);
3105
3390
  return;
3106
3391
  }
@@ -3118,15 +3403,9 @@ function PayButton({
3118
3403
  };
3119
3404
  const doCheckout = (provider) => {
3120
3405
  onProviderSelect?.(provider);
3121
- checkout({
3122
- planId,
3123
- intentId,
3124
- provider,
3125
- successUrl,
3126
- cancelUrl
3127
- });
3406
+ checkout(provider);
3128
3407
  };
3129
- const isDisabled = disabled || isPending || providersLoading || !planId && !intentId;
3408
+ const isDisabled = disabled || isPending || status === "loading_providers" || !planId && !intentId;
3130
3409
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3131
3410
  /* @__PURE__ */ jsxRuntime.jsx(
3132
3411
  "button",
@@ -3160,39 +3439,29 @@ function PayButton({
3160
3439
  labels: billing
3161
3440
  }
3162
3441
  ),
3163
- showTransferModal && transferData && /* @__PURE__ */ jsxRuntime.jsx(
3442
+ showTransferModal && checkoutData && checkoutData.provider === "MANUAL_TRANSFER" && /* @__PURE__ */ jsxRuntime.jsx(
3164
3443
  TransferModal2,
3165
3444
  {
3166
- data: transferData,
3445
+ data: checkoutData,
3167
3446
  onClose: () => {
3168
3447
  setShowTransferModal(false);
3169
- onSuccess?.(transferData);
3170
- setTransferData(null);
3448
+ onSuccess?.(checkoutData);
3171
3449
  },
3172
3450
  labels: billing
3173
3451
  }
3174
3452
  ),
3175
- payphoneData?.widgetConfig && /* @__PURE__ */ jsxRuntime.jsx(
3453
+ status === "processing" && checkoutData?.provider === "PAYPHONE" && checkoutData.widgetConfig && /* @__PURE__ */ jsxRuntime.jsx(
3176
3454
  PayphoneModal,
3177
3455
  {
3178
- config: payphoneData.widgetConfig,
3456
+ config: checkoutData.widgetConfig,
3179
3457
  successUrl,
3180
3458
  onClose: () => {
3181
- onSuccess?.(payphoneData);
3182
- setPayphoneData(null);
3459
+ onSuccess?.(checkoutData);
3183
3460
  }
3184
3461
  }
3185
3462
  )
3186
3463
  ] });
3187
3464
  }
3188
- function usePayphoneConfirm(options) {
3189
- const client = useAccessClient();
3190
- return reactQuery.useMutation({
3191
- mutationFn: (params) => client.post(client.paths.payphoneConfirm, params),
3192
- onSuccess: options?.onSuccess,
3193
- onError: options?.onError
3194
- });
3195
- }
3196
3465
  function PayphoneCallback({ onSuccess, onError, className, style }) {
3197
3466
  const { mutate, isPending, isSuccess, isError, error, data } = usePayphoneConfirm({
3198
3467
  onSuccess,
@@ -3698,6 +3967,230 @@ function useTransferProofs() {
3698
3967
  queryFn: () => client.get(client.paths.transferProofs)
3699
3968
  });
3700
3969
  }
3970
+ var CONTAINER_ID = "pp-checkout-azirid";
3971
+ function usePayphoneCheckout({
3972
+ intentId,
3973
+ onSuccess,
3974
+ onError
3975
+ }) {
3976
+ const [status, setStatus] = react.useState("idle");
3977
+ const [widgetConfig, setWidgetConfig] = react.useState(null);
3978
+ const [currentError, setCurrentError] = react.useState(null);
3979
+ const checkoutTriggered = react.useRef(false);
3980
+ const confirmTriggered = react.useRef(false);
3981
+ const responseUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
3982
+ const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
3983
+ const callbackId = params.get("id");
3984
+ const callbackClientTxId = params.get("clientTransactionId");
3985
+ const isCallback = !!(callbackId && callbackClientTxId);
3986
+ const { checkout } = useCheckout({
3987
+ redirectOnSuccess: false,
3988
+ onSuccess: (data) => {
3989
+ if (data.provider === "PAYPHONE" && data.widgetConfig) {
3990
+ setWidgetConfig(data.widgetConfig);
3991
+ setStatus("ready");
3992
+ }
3993
+ },
3994
+ onError: (err) => {
3995
+ setCurrentError(err);
3996
+ setStatus("error");
3997
+ onError?.(err);
3998
+ }
3999
+ });
4000
+ react.useEffect(() => {
4001
+ if (isCallback || checkoutTriggered.current) return;
4002
+ checkoutTriggered.current = true;
4003
+ setStatus("loading");
4004
+ checkout({
4005
+ intentId,
4006
+ provider: "PAYPHONE",
4007
+ successUrl: responseUrl,
4008
+ cancelUrl: responseUrl
4009
+ });
4010
+ }, [checkout, intentId, responseUrl, isCallback]);
4011
+ const { mutate: confirm } = usePayphoneConfirm({
4012
+ onSuccess: (data) => {
4013
+ setStatus(data.status === "confirmed" || data.status === "already_confirmed" ? "confirmed" : "cancelled");
4014
+ onSuccess?.(data);
4015
+ },
4016
+ onError: (err) => {
4017
+ setCurrentError(err);
4018
+ setStatus("error");
4019
+ onError?.(err);
4020
+ }
4021
+ });
4022
+ react.useEffect(() => {
4023
+ if (!isCallback || confirmTriggered.current) return;
4024
+ confirmTriggered.current = true;
4025
+ setStatus("confirming");
4026
+ confirm({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
4027
+ }, [isCallback, callbackId, callbackClientTxId, confirm]);
4028
+ const handleSdkError = react.useCallback(
4029
+ (err) => {
4030
+ setCurrentError(err);
4031
+ setStatus("error");
4032
+ onError?.(err);
4033
+ },
4034
+ [onError]
4035
+ );
4036
+ const PayphoneWidget = react.useMemo(() => {
4037
+ return function PayphoneWidgetInner() {
4038
+ if (!widgetConfig || isCallback) return null;
4039
+ return PayphoneWidgetRenderer({
4040
+ config: widgetConfig,
4041
+ responseUrl,
4042
+ containerId: CONTAINER_ID,
4043
+ onError: handleSdkError
4044
+ });
4045
+ };
4046
+ }, [widgetConfig, responseUrl, isCallback, handleSdkError]);
4047
+ return { PayphoneWidget, status, intentId, error: currentError };
4048
+ }
4049
+ function useTransferPayment({
4050
+ intentId,
4051
+ onSuccess,
4052
+ onProofSubmitted,
4053
+ onError
4054
+ }) {
4055
+ const [status, setStatus] = react.useState("idle");
4056
+ const [checkoutData, setCheckoutData] = react.useState(null);
4057
+ const [currentError, setCurrentError] = react.useState(null);
4058
+ const checkoutTriggered = react.useRef(false);
4059
+ const responseUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
4060
+ const { checkout } = useCheckout({
4061
+ redirectOnSuccess: false,
4062
+ onSuccess: (data) => {
4063
+ setCheckoutData(data);
4064
+ setStatus("ready");
4065
+ onSuccess?.(data);
4066
+ },
4067
+ onError: (err) => {
4068
+ setCurrentError(err);
4069
+ setStatus("error");
4070
+ onError?.(err);
4071
+ }
4072
+ });
4073
+ react.useEffect(() => {
4074
+ if (checkoutTriggered.current) return;
4075
+ checkoutTriggered.current = true;
4076
+ setStatus("loading");
4077
+ checkout({
4078
+ intentId,
4079
+ provider: "MANUAL_TRANSFER",
4080
+ successUrl: responseUrl,
4081
+ cancelUrl: responseUrl
4082
+ });
4083
+ }, [checkout, intentId, responseUrl]);
4084
+ const { submit, isPending: isSubmitting } = useSubmitTransferProof({
4085
+ onSuccess: (proof) => {
4086
+ setStatus("submitted");
4087
+ onProofSubmitted?.(proof);
4088
+ },
4089
+ onError: (err) => {
4090
+ setCurrentError(err);
4091
+ setStatus("error");
4092
+ onError?.(err);
4093
+ }
4094
+ });
4095
+ const submitProof = react.useCallback(
4096
+ (data) => {
4097
+ if (!checkoutData?.intent) return;
4098
+ setStatus("submitting");
4099
+ setCurrentError(null);
4100
+ submit({
4101
+ planId: checkoutData.intent.id,
4102
+ fileUrl: data.fileUrl,
4103
+ fileName: data.fileName,
4104
+ fileType: data.fileType,
4105
+ amount: data.amount,
4106
+ currency: data.currency,
4107
+ notes: data.notes
4108
+ });
4109
+ },
4110
+ [submit, checkoutData]
4111
+ );
4112
+ const TransferDetails = react.useMemo(() => {
4113
+ return function TransferDetailsInner() {
4114
+ if (!checkoutData) return null;
4115
+ const bankDetails = checkoutData.bankDetails;
4116
+ const plan = checkoutData.plan;
4117
+ const intent = checkoutData.intent;
4118
+ const displayAmount = plan ? formatAmount(plan.amount, plan.currency) : intent ? formatAmount(intent.amount, intent.currency) : "";
4119
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4120
+ displayAmount && /* @__PURE__ */ jsxRuntime.jsxs(
4121
+ "div",
4122
+ {
4123
+ style: {
4124
+ textAlign: "center",
4125
+ padding: "16px",
4126
+ backgroundColor: "#f9fafb",
4127
+ borderRadius: "8px",
4128
+ marginBottom: "20px"
4129
+ },
4130
+ children: [
4131
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "32px", fontWeight: 700, color: "#111827" }, children: displayAmount }),
4132
+ plan?.name && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "14px", color: "#6b7280" }, children: plan.name }),
4133
+ intent?.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "14px", color: "#6b7280" }, children: intent.description })
4134
+ ]
4135
+ }
4136
+ ),
4137
+ bankDetails && Object.keys(bankDetails).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "16px" }, children: [
4138
+ /* @__PURE__ */ jsxRuntime.jsx(
4139
+ "div",
4140
+ {
4141
+ style: {
4142
+ fontSize: "14px",
4143
+ fontWeight: 600,
4144
+ color: "#111827",
4145
+ marginBottom: "8px"
4146
+ },
4147
+ children: "Bank Details"
4148
+ }
4149
+ ),
4150
+ Object.entries(bankDetails).filter(([, v]) => v).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs(
4151
+ "div",
4152
+ {
4153
+ style: {
4154
+ display: "flex",
4155
+ justifyContent: "space-between",
4156
+ padding: "6px 0",
4157
+ borderBottom: "1px solid #f3f4f6",
4158
+ fontSize: "13px"
4159
+ },
4160
+ children: [
4161
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#6b7280" }, children: key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()) }),
4162
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#111827", fontWeight: 500 }, children: value })
4163
+ ]
4164
+ },
4165
+ key
4166
+ ))
4167
+ ] }),
4168
+ checkoutData.transferInstructions && /* @__PURE__ */ jsxRuntime.jsx(
4169
+ "div",
4170
+ {
4171
+ style: {
4172
+ padding: "12px",
4173
+ backgroundColor: "#eff6ff",
4174
+ borderRadius: "6px",
4175
+ fontSize: "13px",
4176
+ color: "#1e40af",
4177
+ lineHeight: 1.5
4178
+ },
4179
+ children: checkoutData.transferInstructions
4180
+ }
4181
+ )
4182
+ ] });
4183
+ };
4184
+ }, [checkoutData]);
4185
+ return {
4186
+ TransferDetails,
4187
+ submitProof,
4188
+ status,
4189
+ checkoutData,
4190
+ isSubmitting,
4191
+ error: currentError
4192
+ };
4193
+ }
3701
4194
  function useTenants() {
3702
4195
  const client = useAccessClient();
3703
4196
  return reactQuery.useQuery({
@@ -3790,7 +4283,7 @@ function usePasswordToggle() {
3790
4283
  }
3791
4284
 
3792
4285
  // src/index.ts
3793
- var SDK_VERSION = "0.9.4";
4286
+ var SDK_VERSION = "0.9.7";
3794
4287
 
3795
4288
  exports.AuthForm = AuthForm;
3796
4289
  exports.AziridProvider = AziridProvider;
@@ -3802,6 +4295,7 @@ exports.LoginForm = LoginForm;
3802
4295
  exports.PATHS = PATHS;
3803
4296
  exports.PayButton = PayButton;
3804
4297
  exports.PayphoneCallback = PayphoneCallback;
4298
+ exports.PayphoneWidgetRenderer = PayphoneWidgetRenderer;
3805
4299
  exports.PricingTable = PricingTable;
3806
4300
  exports.ReferralCard = ReferralCard;
3807
4301
  exports.ReferralStats = ReferralStats;
@@ -3846,7 +4340,9 @@ exports.useMessages = useMessages;
3846
4340
  exports.usePasskeys = usePasskeys;
3847
4341
  exports.usePasswordReset = usePasswordReset;
3848
4342
  exports.usePasswordToggle = usePasswordToggle;
4343
+ exports.usePayButton = usePayButton;
3849
4344
  exports.usePaymentProviders = usePaymentProviders;
4345
+ exports.usePayphoneCheckout = usePayphoneCheckout;
3850
4346
  exports.usePayphoneConfirm = usePayphoneConfirm;
3851
4347
  exports.usePlans = usePlans;
3852
4348
  exports.useReferral = useReferral;
@@ -3860,6 +4356,7 @@ exports.useSubscription = useSubscription;
3860
4356
  exports.useSwitchTenant = useSwitchTenant;
3861
4357
  exports.useTenantMembers = useTenantMembers;
3862
4358
  exports.useTenants = useTenants;
4359
+ exports.useTransferPayment = useTransferPayment;
3863
4360
  exports.useTransferProofs = useTransferProofs;
3864
4361
  //# sourceMappingURL=index.cjs.map
3865
4362
  //# sourceMappingURL=index.cjs.map