@miden-npm/react 2.1.1 → 2.1.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.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");
@@ -3164,7 +3289,15 @@ function PayByCard({
3164
3289
  setPhoneCodeOptions(codeOptions);
3165
3290
  })();
3166
3291
  }, []);
3167
- 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: [
3168
3301
  formIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "grid grid-cols-2 gap-6 overflow-y-auto", children: [
3169
3302
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3170
3303
  BaseInput,
@@ -3484,7 +3617,7 @@ var PayByTransfer = ({
3484
3617
  caller
3485
3618
  );
3486
3619
  if (response?.isSuccessful) {
3487
- setPaymentAccountDetails(response.data);
3620
+ setPaymentAccountDetails(response);
3488
3621
  startTimer();
3489
3622
  setMessage("Virtual account generated successfully for payment.");
3490
3623
  setIsMakingPayment(true);
@@ -3687,7 +3820,14 @@ var PayByTransfer = ({
3687
3820
  BaseLabelInfo,
3688
3821
  {
3689
3822
  label: "Bank Name",
3690
- value: `${paymentAccountDetails?.bank} ${paymentAccountDetails?.accountName}`
3823
+ value: paymentAccountDetails?.bank
3824
+ }
3825
+ ),
3826
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3827
+ BaseLabelInfo,
3828
+ {
3829
+ label: "Account Name",
3830
+ value: paymentAccountDetails?.accountName
3691
3831
  }
3692
3832
  ),
3693
3833
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between", children: [
@@ -4196,7 +4336,7 @@ var PayByStableCoin = ({
4196
4336
  };
4197
4337
 
4198
4338
  // src/buzapay-checkout/checkout-card.tsx
4199
- var import_react_hot_toast = __toESM(require("react-hot-toast"), 1);
4339
+ var import_react_hot_toast2 = __toESM(require("react-hot-toast"), 1);
4200
4340
  var import_jsx_runtime39 = require("react/jsx-runtime");
4201
4341
  function BzpCheckoutCard({
4202
4342
  secretKey,
@@ -4232,25 +4372,23 @@ function BzpCheckoutCard({
4232
4372
  setSuccessObject({ ...event });
4233
4373
  if (event.paymentStatus === "authorized") {
4234
4374
  setCheckoutState("SUCCESS");
4235
- console.log("checkout state", checkoutState);
4236
- debugger;
4237
- import_react_hot_toast.default.success("Payment authorization successful.", toastConfig);
4375
+ import_react_hot_toast2.default.success("Payment authorization successful.", toastConfig);
4238
4376
  } else if (event.paymentStatus === "confirmed") {
4239
4377
  setCheckoutState("SUCCESS");
4240
- import_react_hot_toast.default.success("Payment confirmed.", toastConfig);
4378
+ import_react_hot_toast2.default.success("Payment confirmed.", toastConfig);
4241
4379
  } else if (event.paymentStatus === "payment failed") {
4242
4380
  setCheckoutState("PENDING");
4243
- import_react_hot_toast.default.error("Payment pending.", toastConfig);
4381
+ import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4244
4382
  } else if (event.paymentStatus === "used") {
4245
4383
  setCheckoutState("USED");
4246
4384
  } else {
4247
4385
  setCheckoutState("PENDING");
4248
- import_react_hot_toast.default.error("Payment pending.", toastConfig);
4386
+ import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4249
4387
  }
4250
4388
  onPaymentAuthorized?.(event);
4251
4389
  };
4252
4390
  const onErrorHandler = (error) => {
4253
- import_react_hot_toast.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4391
+ import_react_hot_toast2.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4254
4392
  onError?.(error);
4255
4393
  };
4256
4394
  (0, import_react13.useEffect)(() => {
@@ -4278,7 +4416,7 @@ function BzpCheckoutCard({
4278
4416
  }
4279
4417
  }, [filteredPaymentTypeOptions]);
4280
4418
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(BaseCard, { children: [
4281
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_hot_toast.Toaster, {}),
4419
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_hot_toast2.Toaster, {}),
4282
4420
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "grid grid-cols-3", children: [
4283
4421
  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: [
4284
4422
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-heading-text text-body-xs font-semibold", children: "Pay with" }),
@@ -4548,7 +4686,7 @@ function MidenCheckoutButton({
4548
4686
 
4549
4687
  // src/miden-checkout/checkout-card.tsx
4550
4688
  var import_react16 = require("react");
4551
- var import_react_hot_toast2 = __toESM(require("react-hot-toast"), 1);
4689
+ var import_react_hot_toast3 = __toESM(require("react-hot-toast"), 1);
4552
4690
  var import_jsx_runtime42 = require("react/jsx-runtime");
4553
4691
  function MidenCheckoutCard({
4554
4692
  secretKey,
@@ -4585,23 +4723,23 @@ function MidenCheckoutCard({
4585
4723
  setSuccessObject({ ...event });
4586
4724
  if (event.paymentStatus === "authorized") {
4587
4725
  setCheckoutState("SUCCESS");
4588
- import_react_hot_toast2.default.success("Payment authorization successful.", toastConfig);
4726
+ import_react_hot_toast3.default.success("Payment authorization successful.", toastConfig);
4589
4727
  } else if (event.paymentStatus === "confirmed") {
4590
4728
  setCheckoutState("SUCCESS");
4591
- import_react_hot_toast2.default.success("Payment confirmed.", toastConfig);
4729
+ import_react_hot_toast3.default.success("Payment confirmed.", toastConfig);
4592
4730
  } else if (event.paymentStatus === "payment failed") {
4593
4731
  setCheckoutState("PENDING");
4594
- import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4732
+ import_react_hot_toast3.default.error("Payment pending.", toastConfig);
4595
4733
  } else if (event.paymentStatus === "used") {
4596
4734
  setCheckoutState("USED");
4597
4735
  } else {
4598
4736
  setCheckoutState("PENDING");
4599
- import_react_hot_toast2.default.error("Payment pending.", toastConfig);
4737
+ import_react_hot_toast3.default.error("Payment pending.", toastConfig);
4600
4738
  }
4601
4739
  onPaymentAuthorized?.(event);
4602
4740
  };
4603
4741
  const onErrorHandler = (error) => {
4604
- import_react_hot_toast2.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4742
+ import_react_hot_toast3.default.error(error.errorMessage ?? "Payment failed.", toastConfig);
4605
4743
  onError?.(error);
4606
4744
  };
4607
4745
  const formatAmountHandler = () => {
@@ -4635,7 +4773,7 @@ function MidenCheckoutCard({
4635
4773
  }
4636
4774
  }, [filteredPaymentTypeOptions]);
4637
4775
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(BaseCard, { caller: "miden", children: [
4638
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_hot_toast2.Toaster, {}),
4776
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_hot_toast3.Toaster, {}),
4639
4777
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "grid grid-cols-3", children: [
4640
4778
  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: [
4641
4779
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-white text-body-xs font-semibold px-6", children: "Pay with" }),