@miden-npm/react 2.1.0 → 2.1.2

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
@@ -154,7 +154,15 @@ var getBaseUrl = (mode, caller) => {
154
154
  if (mode === "sandbox") {
155
155
  return caller === "buzapay" ? "https://sandbox-api.buzapay.com/payment-gateway-api" : "https://sandbox-api.midencards.io/miden-web";
156
156
  } else if (mode === "prod") {
157
- return caller === "buzapay" ? "https://api.buzapay.com/payment-gateway-api" : "https://sandbox-api.midencards.io/miden-web";
157
+ return caller === "buzapay" ? "https://api.buzapay.com/payment-gateway-api" : "https://api.midencards.io/miden-web";
158
+ }
159
+ return "";
160
+ };
161
+ var getBaseAppUrl = (mode, caller) => {
162
+ if (mode === "sandbox") {
163
+ return caller === "buzapay" ? "https://sandbox-merchant.buzapay.com" : "https://sandbox.midencards.io";
164
+ } else if (mode === "prod") {
165
+ return caller === "buzapay" ? "https://merchant.buzapay.com" : "https://midencards.io";
158
166
  }
159
167
  return "";
160
168
  };
@@ -802,6 +810,24 @@ async function generateStableCoinAddress(environment, { merchantId, ...rest }, c
802
810
  } catch (error) {
803
811
  }
804
812
  }
813
+ async function midenConfirmPayment(environment, reference, merchantId, caller) {
814
+ try {
815
+ const baseUrl = getBaseUrl(environment, caller);
816
+ const apiKey = {
817
+ miden: `api/v1/accrual/checkout/confirm-payment/${reference}`
818
+ };
819
+ const res = await fetch(`${baseUrl}/${apiKey[caller]}`, {
820
+ method: "GET",
821
+ headers: {
822
+ "Content-Type": "application/json",
823
+ Accept: "application/json",
824
+ uniqueKey: merchantId
825
+ }
826
+ });
827
+ return await res.json();
828
+ } catch (error) {
829
+ }
830
+ }
805
831
 
806
832
  // src/apis/encrypt.api.ts
807
833
  var import_crypto_js = __toESM(require("crypto-js"), 1);
@@ -2805,6 +2831,7 @@ var BasePhoneNumberInput = ({
2805
2831
  };
2806
2832
 
2807
2833
  // src/components/pay-by-card.tsx
2834
+ var import_react_hot_toast = __toESM(require("react-hot-toast"), 1);
2808
2835
  var import_jsx_runtime36 = require("react/jsx-runtime");
2809
2836
  function PayByCard({
2810
2837
  secretKey,
@@ -2829,6 +2856,7 @@ function PayByCard({
2829
2856
  const [phoneCodeOptions, setPhoneCodeOptions] = (0, import_react10.useState)(
2830
2857
  []
2831
2858
  );
2859
+ const baseAppUrl = getBaseAppUrl(environment, caller);
2832
2860
  const [billingForm, setBillingForm] = (0, import_react10.useState)({
2833
2861
  address1: "",
2834
2862
  address2: "",
@@ -2892,6 +2920,99 @@ function PayByCard({
2892
2920
  cvv: "CVV",
2893
2921
  cardPin: "Card PIN"
2894
2922
  };
2923
+ const [threeDSOpen, setThreeDSOpen] = (0, import_react10.useState)(false);
2924
+ const [threeDSIframeSrc, setThreeDSIframeSrc] = (0, import_react10.useState)("");
2925
+ const messageListenerRef = (0, import_react10.useRef)();
2926
+ const midenThreeDSChallenge = (url, value) => {
2927
+ if (!url || !value) {
2928
+ setMessage("3DS challenge could not be started (missing stepUpUrl/JWT).");
2929
+ return;
2930
+ }
2931
+ const html = `<!doctype html>
2932
+ <html>
2933
+ <head><meta charset="utf-8" /></head>
2934
+ <body onload="document.forms[0].submit()">
2935
+ <form method="POST" action="${url}">
2936
+ <input type="hidden" name="JWT" value="${value}" />
2937
+ </form>
2938
+ </body>
2939
+ </html>`;
2940
+ const dataUrl = `data:text/html;charset=utf-8,${encodeURIComponent(html)}`;
2941
+ setThreeDSIframeSrc(dataUrl);
2942
+ setThreeDSOpen(true);
2943
+ const listener = (event) => {
2944
+ if (event?.data === "challenge_success" || event?.data?.status === "success") {
2945
+ setThreeDSOpen(false);
2946
+ setThreeDSIframeSrc("");
2947
+ handleMidenProceed();
2948
+ }
2949
+ if (event?.data === "challenge_failed" || event?.data?.status === "failed") {
2950
+ setThreeDSOpen(false);
2951
+ setThreeDSIframeSrc("");
2952
+ setMessage("3D Secure verification failed.");
2953
+ setIsMakingPayment(false);
2954
+ }
2955
+ };
2956
+ if (messageListenerRef.current) {
2957
+ window.removeEventListener("message", messageListenerRef.current);
2958
+ }
2959
+ messageListenerRef.current = listener;
2960
+ window.addEventListener("message", listener);
2961
+ };
2962
+ (0, import_react10.useEffect)(() => {
2963
+ return () => {
2964
+ if (messageListenerRef.current) {
2965
+ window.removeEventListener("message", messageListenerRef.current);
2966
+ }
2967
+ };
2968
+ }, []);
2969
+ const handleMidenProceed = async () => {
2970
+ try {
2971
+ setIsMakingPayment(true);
2972
+ const result = await await midenConfirmPayment(
2973
+ environment,
2974
+ transactionReference,
2975
+ secretKey,
2976
+ "miden"
2977
+ );
2978
+ if (result?.isSuccessful) {
2979
+ setMessage("Payment authorization successful.");
2980
+ import_react_hot_toast.default.success("Payment authorization successful.");
2981
+ setIsMakingPayment(false);
2982
+ onPaymentAuthorized?.({
2983
+ paymentId: transactionReference,
2984
+ paymentDate: (/* @__PURE__ */ new Date()).toISOString(),
2985
+ paymentStatus: "authorized",
2986
+ message: "Payment authorization successful."
2987
+ });
2988
+ } else {
2989
+ import_react_hot_toast.default.success("Payment authorization successful.");
2990
+ setIsMakingPayment(false);
2991
+ }
2992
+ } catch (err) {
2993
+ const status = err?.status ?? err?.response?.status;
2994
+ if ([500, 501, 502, 503].includes(status)) {
2995
+ setIsMakingPayment(false);
2996
+ setMessage("Temporary server error. Please try again.");
2997
+ return;
2998
+ }
2999
+ const responseMessage = err?.error?.responseMessage || err?.responseMessage || err?.message || "Payment confirmation failed.";
3000
+ setIsMakingPayment(false);
3001
+ setMessage(responseMessage);
3002
+ import_react_hot_toast.default.error(responseMessage);
3003
+ onError?.({ errorMessage: responseMessage });
3004
+ }
3005
+ };
3006
+ const handleMidenCard = (data) => {
3007
+ const threeDsRequired = data?.threeDsInteractionRequired;
3008
+ if (threeDsRequired) {
3009
+ const url = data?.threeDsHtml?.stepUpUrl;
3010
+ const cred = data?.threeDsHtml?.accessToken;
3011
+ midenThreeDSChallenge(url, cred);
3012
+ } else {
3013
+ handleMidenProceed();
3014
+ }
3015
+ };
2895
3016
  const proceedHandler = async () => {
2896
3017
  if (formIndex === 0) {
2897
3018
  const errs = validateGroup(billingForm, billingRules, billingLabels);
@@ -2939,7 +3060,7 @@ function PayByCard({
2939
3060
  narration: paymentObject?.narration || "Test transaction",
2940
3061
  encryptedCardDetails: encryptedCardDetails.requestParam,
2941
3062
  billingDetails,
2942
- redirectUrl: paymentObject?.redirectUrl || "https://sandbox-merchant.buzapay.com/account/three-ds-status",
3063
+ redirectUrl: paymentObject?.redirectUrl || `${baseAppUrl}/account/three-ds-status`,
2943
3064
  paymentReference: transactionReference,
2944
3065
  isCheckout: true
2945
3066
  };
@@ -2952,7 +3073,7 @@ function PayByCard({
2952
3073
  narration: paymentObject?.narration || "Test transaction",
2953
3074
  encryptedCardDetails: encryptedCardDetails.requestParam,
2954
3075
  billingDetails,
2955
- redirectUrl: paymentObject?.redirectUrl || "",
3076
+ redirectUrl: paymentObject?.redirectUrl || `${baseAppUrl}/pay/verification`,
2956
3077
  paymentReference: transactionReference,
2957
3078
  isCheckout: true,
2958
3079
  postBackUrl: "",
@@ -2966,6 +3087,10 @@ function PayByCard({
2966
3087
  response = decryptPayload(environment, response.responseParam);
2967
3088
  }
2968
3089
  if (response?.isSuccessful) {
3090
+ if (caller === "miden") {
3091
+ handleMidenCard(response);
3092
+ return;
3093
+ }
2969
3094
  if (response.threeDsInteractionRequired === true) {
2970
3095
  const threeDsData = {
2971
3096
  transactionReference: response.transactionReference,
@@ -2979,7 +3104,7 @@ function PayByCard({
2979
3104
  md: response.threeDsHtml?.md
2980
3105
  };
2981
3106
  const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2982
- const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(
3107
+ const threeDsUrl = `${baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(
2983
3108
  stringifiedThreeDsData
2984
3109
  )}&paymentReference=${response.transactionReference}`;
2985
3110
  window.open(threeDsUrl, "_self", "noopener,noreferrer");
@@ -3002,7 +3127,7 @@ function PayByCard({
3002
3127
  md: response.threeDsHtml?.md
3003
3128
  };
3004
3129
  const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
3005
- const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(
3130
+ const threeDsUrl = `${baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(
3006
3131
  stringifiedThreeDsData
3007
3132
  )}&paymentReference=${response.transactionReference}`;
3008
3133
  window.open(threeDsUrl, "_self", "noopener,noreferrer");
@@ -3016,7 +3141,6 @@ function PayByCard({
3016
3141
  onPaymentAuthorized?.({
3017
3142
  paymentId: response.transactionReference,
3018
3143
  paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3019
- // optional if present
3020
3144
  paymentStatus: "authorized",
3021
3145
  message
3022
3146
  });
@@ -3165,7 +3289,15 @@ function PayByCard({
3165
3289
  setPhoneCodeOptions(codeOptions);
3166
3290
  })();
3167
3291
  }, []);
3168
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col gap-6", children: [
3292
+ return threeDSOpen ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-white p-4", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3293
+ "iframe",
3294
+ {
3295
+ title: "Miden 3DS",
3296
+ src: threeDSIframeSrc,
3297
+ className: "w-full h-full",
3298
+ sandbox: "allow-forms allow-scripts allow-same-origin allow-top-navigation"
3299
+ }
3300
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col gap-6", children: [
3169
3301
  formIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "grid grid-cols-2 gap-6 overflow-y-auto", children: [
3170
3302
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3171
3303
  BaseInput,
@@ -3523,7 +3655,7 @@ var PayByTransfer = ({
3523
3655
  setPaymentReferenceStatus("pending");
3524
3656
  onPaymentAuthorized?.({
3525
3657
  paymentId: transactionReference,
3526
- paymentDate: response.data?.updatedAt,
3658
+ paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3527
3659
  paymentStatus: "pending",
3528
3660
  message
3529
3661
  });
@@ -3531,7 +3663,7 @@ var PayByTransfer = ({
3531
3663
  setPaymentReferenceStatus("confirmed");
3532
3664
  onPaymentAuthorized?.({
3533
3665
  paymentId: transactionReference,
3534
- paymentDate: response.data?.updatedAt,
3666
+ paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3535
3667
  paymentStatus: "confirmed",
3536
3668
  message
3537
3669
  });
@@ -3542,7 +3674,7 @@ var PayByTransfer = ({
3542
3674
  setMessage("Transaction confirmed !!");
3543
3675
  onPaymentAuthorized?.({
3544
3676
  paymentId: transactionReference,
3545
- paymentDate: response.data?.updatedAt,
3677
+ paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3546
3678
  paymentStatus: "confirmed",
3547
3679
  message
3548
3680
  });
@@ -3924,7 +4056,7 @@ var PayByStableCoin = ({
3924
4056
  setPaymentReferenceStatus("pending");
3925
4057
  onPaymentAuthorized?.({
3926
4058
  paymentId: transactionReference,
3927
- paymentDate: response.data?.updatedAt ?? "",
4059
+ paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3928
4060
  paymentStatus: "pending",
3929
4061
  message
3930
4062
  });
@@ -3933,7 +4065,7 @@ var PayByStableCoin = ({
3933
4065
  setPaymentReferenceStatus("confirmed");
3934
4066
  onPaymentAuthorized?.({
3935
4067
  paymentId: transactionReference,
3936
- paymentDate: response.data?.updatedAt,
4068
+ paymentDate: response?.data?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3937
4069
  paymentStatus: "confirmed",
3938
4070
  message
3939
4071
  });
@@ -4197,7 +4329,7 @@ var PayByStableCoin = ({
4197
4329
  };
4198
4330
 
4199
4331
  // src/buzapay-checkout/checkout-card.tsx
4200
- var import_react_hot_toast = __toESM(require("react-hot-toast"), 1);
4332
+ var import_react_hot_toast2 = __toESM(require("react-hot-toast"), 1);
4201
4333
  var import_jsx_runtime39 = require("react/jsx-runtime");
4202
4334
  function BzpCheckoutCard({
4203
4335
  secretKey,
@@ -4233,25 +4365,23 @@ function BzpCheckoutCard({
4233
4365
  setSuccessObject({ ...event });
4234
4366
  if (event.paymentStatus === "authorized") {
4235
4367
  setCheckoutState("SUCCESS");
4236
- console.log("checkout state", checkoutState);
4237
- debugger;
4238
- import_react_hot_toast.default.success("Payment authorization successful.", toastConfig);
4368
+ import_react_hot_toast2.default.success("Payment authorization successful.", toastConfig);
4239
4369
  } else if (event.paymentStatus === "confirmed") {
4240
4370
  setCheckoutState("SUCCESS");
4241
- import_react_hot_toast.default.success("Payment confirmed.", toastConfig);
4371
+ import_react_hot_toast2.default.success("Payment confirmed.", toastConfig);
4242
4372
  } else if (event.paymentStatus === "payment failed") {
4243
4373
  setCheckoutState("PENDING");
4244
- import_react_hot_toast.default.error("Payment pending.", toastConfig);
4374
+ import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4245
4375
  } else if (event.paymentStatus === "used") {
4246
4376
  setCheckoutState("USED");
4247
4377
  } else {
4248
4378
  setCheckoutState("PENDING");
4249
- import_react_hot_toast.default.error("Payment pending.", toastConfig);
4379
+ import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4250
4380
  }
4251
4381
  onPaymentAuthorized?.(event);
4252
4382
  };
4253
4383
  const onErrorHandler = (error) => {
4254
- import_react_hot_toast.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4384
+ import_react_hot_toast2.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4255
4385
  onError?.(error);
4256
4386
  };
4257
4387
  (0, import_react13.useEffect)(() => {
@@ -4279,7 +4409,7 @@ function BzpCheckoutCard({
4279
4409
  }
4280
4410
  }, [filteredPaymentTypeOptions]);
4281
4411
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(BaseCard, { children: [
4282
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_hot_toast.Toaster, {}),
4412
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_hot_toast2.Toaster, {}),
4283
4413
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "grid grid-cols-3", children: [
4284
4414
  checkoutState === "PENDING" && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl", children: [
4285
4415
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-heading-text text-body-xs font-semibold", children: "Pay with" }),
@@ -4549,7 +4679,7 @@ function MidenCheckoutButton({
4549
4679
 
4550
4680
  // src/miden-checkout/checkout-card.tsx
4551
4681
  var import_react16 = require("react");
4552
- var import_react_hot_toast2 = __toESM(require("react-hot-toast"), 1);
4682
+ var import_react_hot_toast3 = __toESM(require("react-hot-toast"), 1);
4553
4683
  var import_jsx_runtime42 = require("react/jsx-runtime");
4554
4684
  function MidenCheckoutCard({
4555
4685
  secretKey,
@@ -4586,23 +4716,23 @@ function MidenCheckoutCard({
4586
4716
  setSuccessObject({ ...event });
4587
4717
  if (event.paymentStatus === "authorized") {
4588
4718
  setCheckoutState("SUCCESS");
4589
- import_react_hot_toast2.default.success("Payment authorization successful.", toastConfig);
4719
+ import_react_hot_toast3.default.success("Payment authorization successful.", toastConfig);
4590
4720
  } else if (event.paymentStatus === "confirmed") {
4591
4721
  setCheckoutState("SUCCESS");
4592
- import_react_hot_toast2.default.success("Payment confirmed.", toastConfig);
4722
+ import_react_hot_toast3.default.success("Payment confirmed.", toastConfig);
4593
4723
  } else if (event.paymentStatus === "payment failed") {
4594
4724
  setCheckoutState("PENDING");
4595
- import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4725
+ import_react_hot_toast3.default.error("Payment pending.", toastConfig);
4596
4726
  } else if (event.paymentStatus === "used") {
4597
4727
  setCheckoutState("USED");
4598
4728
  } else {
4599
4729
  setCheckoutState("PENDING");
4600
- import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4730
+ import_react_hot_toast3.default.error("Payment pending.", toastConfig);
4601
4731
  }
4602
4732
  onPaymentAuthorized?.(event);
4603
4733
  };
4604
4734
  const onErrorHandler = (error) => {
4605
- import_react_hot_toast2.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4735
+ import_react_hot_toast3.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4606
4736
  onError?.(error);
4607
4737
  };
4608
4738
  const formatAmountHandler = () => {
@@ -4636,7 +4766,7 @@ function MidenCheckoutCard({
4636
4766
  }
4637
4767
  }, [filteredPaymentTypeOptions]);
4638
4768
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(BaseCard, { caller: "miden", children: [
4639
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_hot_toast2.Toaster, {}),
4769
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_hot_toast3.Toaster, {}),
4640
4770
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "grid grid-cols-3", children: [
4641
4771
  checkoutState === "PENDING" && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "bg-[#0A0032] py-6 flex flex-col gap-5 col-span-1 rounded-l-xl", children: [
4642
4772
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-white text-body-xs font-semibold px-6", children: "Pay with" }),