coinley-pay 0.26.0 → 0.28.0

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.
@@ -5,7 +5,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
5
5
  import { useState, useRef, useEffect, useCallback, useMemo } from "react";
6
6
  import { useConnect, useAccount, useSwitchChain, useSendTransaction, useWaitForTransactionReceipt, WagmiProvider, useDisconnect } from "wagmi";
7
7
  import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
8
- import { s as sdkAnalytics, c as clarityAnalytics, d as dist, a as Buffer2, B as Buffer$1, g as getCurrencyInfo, p as prefetchRates, i as isSupportedCurrency, b as convertToUSD, f as formatCurrency } from "./index-MRszoy4w.js";
8
+ import { s as sdkAnalytics, c as clarityAnalytics, d as dist, a as Buffer2, B as Buffer$1, g as getCurrencyInfo, p as prefetchRates, i as isSupportedCurrency, b as convertToUSD, f as formatCurrency } from "./index-B6XL-PMy.js";
9
9
  import { createConfig, fallback, http, getAccount as getAccount$1, getWalletClient, simulateContract, writeContract, readContract, waitForTransactionReceipt, estimateFeesPerGas as estimateFeesPerGas$1 } from "@wagmi/core";
10
10
  import { injected, metaMask, coinbaseWallet, walletConnect } from "@wagmi/connectors";
11
11
  import { defineChain as defineChain$1, erc20Abi, http as http$1, createPublicClient, fallback as fallback$1 } from "viem";
@@ -2896,6 +2896,7 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
2896
2896
  __coinleySelectionSnapshot: (attemptMeta == null ? void 0 : attemptMeta.selectionSnapshot) ?? null
2897
2897
  };
2898
2898
  setPaymentData(enrichedPayment);
2899
+ setPaymentType("deposit");
2899
2900
  sdkAnalytics.trackPaymentCreated(
2900
2901
  (_g = response.payment) == null ? void 0 : _g.id,
2901
2902
  config.amount,
@@ -20453,7 +20454,7 @@ const PaymentStatus = ({
20453
20454
  const networkName = (selectedNetwork == null ? void 0 : selectedNetwork.name) || (selectedNetwork == null ? void 0 : selectedNetwork.displayName) || (selectedNetwork == null ? void 0 : selectedNetwork.shortName) || "Network";
20454
20455
  const explorerUrl = getExplorerUrl(transactionHash, selectedNetwork);
20455
20456
  const explorerName = getExplorerName(selectedNetwork);
20456
- return /* @__PURE__ */ jsxs("div", { className: "relative flex h-full min-h-0 w-full flex-col justify-between px-3 pb-0 pt-12", children: [
20457
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-[500px] w-full flex-col px-3 pb-0 pt-12", children: [
20457
20458
  onClose && /* @__PURE__ */ jsx(
20458
20459
  "button",
20459
20460
  {
@@ -20478,7 +20479,7 @@ const PaymentStatus = ({
20478
20479
  ] })
20479
20480
  ] })
20480
20481
  ] }),
20481
- /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
20482
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
20482
20483
  /* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-medium text-[#4B5563]", children: "Transaction ID" }),
20483
20484
  /* @__PURE__ */ jsxs(
20484
20485
  "button",
@@ -21120,7 +21121,7 @@ const WalletSelector = ({
21120
21121
  try {
21121
21122
  setAppKitError(null);
21122
21123
  setWalletConnectAddress(solanaAccountState.address);
21123
- const { createWalletConnectAdapter } = await import("./appKitSolana-D38g1-Lm.js");
21124
+ const { createWalletConnectAdapter } = await import("./appKitSolana-BWdEszCH.js");
21124
21125
  const adapter = createWalletConnectAdapter(solanaAccountState.address);
21125
21126
  await solanaWallet.connectWalletConnect(adapter, solanaAccountState.address);
21126
21127
  console.log("✅ WalletConnect synced with SDK");
@@ -21225,7 +21226,7 @@ const WalletSelector = ({
21225
21226
  setAppKitLoading(true);
21226
21227
  setAppKitError(null);
21227
21228
  try {
21228
- const { initializeAppKitEVM, openAppKitModal } = await import("./appKitEVM-Bu9jo5n-.js");
21229
+ const { initializeAppKitEVM, openAppKitModal } = await import("./appKitEVM-BcM7Ftoe.js");
21229
21230
  await initializeAppKitEVM(wagmiConfig);
21230
21231
  await openAppKitModal();
21231
21232
  } catch (error) {
@@ -21245,7 +21246,7 @@ const WalletSelector = ({
21245
21246
  setAppKitError(null);
21246
21247
  try {
21247
21248
  console.log("📦 Loading AppKit Solana module...");
21248
- const { initializeAppKitSolana } = await import("./appKitSolana-D38g1-Lm.js");
21249
+ const { initializeAppKitSolana } = await import("./appKitSolana-BWdEszCH.js");
21249
21250
  console.log("✅ Module loaded, initializing...");
21250
21251
  const modal = await initializeAppKitSolana(solanaWallet);
21251
21252
  console.log("✅ AppKit Solana initialized successfully");
@@ -23282,6 +23283,11 @@ const CoinleyPaymentInternal = ({
23282
23283
  const [verifyingPayment, setVerifyingPayment] = useState(false);
23283
23284
  const [manualCheckStatus, setManualCheckStatus] = useState(null);
23284
23285
  const [processingStatusMessage, setProcessingStatusMessage] = useState("");
23286
+ const [underpaymentInfo, setUnderpaymentInfo] = useState(null);
23287
+ const [underpaymentChoice, setUnderpaymentChoice] = useState(null);
23288
+ const [underpaymentView, setUnderpaymentView] = useState("choice");
23289
+ const [refundAddress, setRefundAddress] = useState("");
23290
+ const [refundRequestSubmitted, setRefundRequestSubmitted] = useState(false);
23285
23291
  const manualCheckTimeout = useRef(null);
23286
23292
  const [copiedField, setCopiedField] = useState(null);
23287
23293
  const [expirationTime, setExpirationTime] = useState(null);
@@ -23421,6 +23427,62 @@ const CoinleyPaymentInternal = ({
23421
23427
  const hasCommittedTransaction = Boolean(
23422
23428
  currentTransactionHash || (solanaTransaction == null ? void 0 : solanaTransaction.txSignature) || (paymentData == null ? void 0 : paymentData.transactionHash)
23423
23429
  );
23430
+ const normalizeUnderpaymentInfo = useCallback((payment = {}) => {
23431
+ const raw = payment.underpayment || payment.underpaymentDetails || payment.shortPayment || payment.partialPayment || null;
23432
+ const statusText = String(payment.status || payment.depositStatus || (raw == null ? void 0 : raw.status) || "").toLowerCase();
23433
+ const paymentStateText = String(payment.paymentState || (raw == null ? void 0 : raw.paymentState) || "").toLowerCase();
23434
+ const hasUnderpaymentStatus = ["underpaid", "underpayment", "partial", "partial_payment", "short_paid", "shortfall"].includes(statusText) || ["underpaid", "partial", "short_paid", "shortfall"].includes(paymentStateText);
23435
+ const explicitUnderpayment = payment.isUnderpaid || payment.underpaid || (raw == null ? void 0 : raw.isUnderpaid) || (raw == null ? void 0 : raw.underpaid);
23436
+ if (!raw && !hasUnderpaymentStatus && !explicitUnderpayment) {
23437
+ return null;
23438
+ }
23439
+ const expected = Number(
23440
+ (raw == null ? void 0 : raw.expectedAmount) ?? payment.expectedAmount ?? payment.amount ?? payment.totalAmount ?? paymentAmount ?? 0
23441
+ );
23442
+ const received = Number(
23443
+ (raw == null ? void 0 : raw.receivedAmount) ?? (raw == null ? void 0 : raw.amountReceived) ?? payment.receivedAmount ?? payment.amountReceived ?? payment.depositAmount ?? payment.balance ?? 0
23444
+ );
23445
+ const shortfall = Number(
23446
+ (raw == null ? void 0 : raw.shortfallAmount) ?? (raw == null ? void 0 : raw.remainingAmount) ?? (raw == null ? void 0 : raw.amountRemaining) ?? (raw == null ? void 0 : raw.offsetAmount) ?? payment.shortfallAmount ?? payment.remainingAmount ?? payment.amountRemaining ?? payment.offsetAmount ?? Math.max(expected - received, 0)
23447
+ );
23448
+ if (!shortfall || shortfall <= 0) {
23449
+ return null;
23450
+ }
23451
+ return {
23452
+ expectedAmount: expected,
23453
+ receivedAmount: received,
23454
+ shortfallAmount: shortfall,
23455
+ tokenSymbol: (raw == null ? void 0 : raw.tokenSymbol) || (raw == null ? void 0 : raw.currency) || payment.currency || (selectedToken == null ? void 0 : selectedToken.symbol) || "Token",
23456
+ refundNetworkLabel: (raw == null ? void 0 : raw.refundNetworkLabel) || (raw == null ? void 0 : raw.refundNetwork) || payment.refundNetworkLabel || (selectedNetwork == null ? void 0 : selectedNetwork.displayName) || (selectedNetwork == null ? void 0 : selectedNetwork.name) || (selectedNetwork == null ? void 0 : selectedNetwork.shortName) || "selected network",
23457
+ paymentState: payment.paymentState || (raw == null ? void 0 : raw.paymentState) || statusText || "underpaid"
23458
+ };
23459
+ }, [paymentAmount, selectedNetwork, selectedToken]);
23460
+ const activateUnderpaymentFlow = useCallback((payment) => {
23461
+ const normalized = normalizeUnderpaymentInfo(payment);
23462
+ if (!normalized) return false;
23463
+ setUnderpaymentInfo(normalized);
23464
+ setUnderpaymentChoice(null);
23465
+ setUnderpaymentView("choice");
23466
+ setManualCheckStatus(null);
23467
+ setRefundRequestSubmitted(false);
23468
+ return true;
23469
+ }, [normalizeUnderpaymentInfo]);
23470
+ const activateUnderpaymentFromDepositBalance = useCallback((balanceResult) => {
23471
+ const received = Number((balanceResult == null ? void 0 : balanceResult.balance) ?? (balanceResult == null ? void 0 : balanceResult.balanceFormatted) ?? 0);
23472
+ const expected = Number((balanceResult == null ? void 0 : balanceResult.expectedAmount) ?? paymentAmount ?? 0);
23473
+ if (!received || !expected || received <= 0 || received >= expected) {
23474
+ return false;
23475
+ }
23476
+ return activateUnderpaymentFlow({
23477
+ status: "underpaid",
23478
+ paymentState: "underpaid",
23479
+ amount: expected,
23480
+ amountReceived: received,
23481
+ amountRemaining: Math.max(expected - received, 0),
23482
+ currency: (balanceResult == null ? void 0 : balanceResult.token) || (selectedToken == null ? void 0 : selectedToken.symbol),
23483
+ refundNetworkLabel: (selectedNetwork == null ? void 0 : selectedNetwork.displayName) || (selectedNetwork == null ? void 0 : selectedNetwork.name) || (selectedNetwork == null ? void 0 : selectedNetwork.shortName)
23484
+ });
23485
+ }, [activateUnderpaymentFlow, paymentAmount, selectedNetwork, selectedToken]);
23424
23486
  const selectedNetworkIsSolana = (selectedNetwork == null ? void 0 : selectedNetwork.chainType) === "solana" || (selectedNetwork == null ? void 0 : selectedNetwork.shortName) === "solana";
23425
23487
  const sourceNeedsMerchantBridge = Boolean(
23426
23488
  selectedNetwork && !selectedNetworkIsSolana && !isMerchantReceiveNetwork(selectedNetwork)
@@ -23873,6 +23935,11 @@ const CoinleyPaymentInternal = ({
23873
23935
  try {
23874
23936
  const statusResult = await paymentFlow.api.getDepositStatus(paymentData.id);
23875
23937
  if (statusResult.success && statusResult.payment) {
23938
+ if (activateUnderpaymentFlow(statusResult.payment)) {
23939
+ clearInterval(pollInterval);
23940
+ setCurrentStep(PAYMENT_STEPS.CONFIRM);
23941
+ return;
23942
+ }
23876
23943
  const status = statusResult.payment.status;
23877
23944
  const txHash = statusResult.payment.depositTxHash || statusResult.payment.sweepTxHash || statusResult.payment.transactionHash;
23878
23945
  if ((status === "completed" || status === "swept") && txHash) {
@@ -23929,9 +23996,9 @@ const CoinleyPaymentInternal = ({
23929
23996
  }
23930
23997
  }, 5e3);
23931
23998
  return () => clearInterval(pollInterval);
23932
- }, [currentStep, paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.depositAddress, selectedNetwork, selectedToken, onSuccess]);
23999
+ }, [currentStep, paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.depositAddress, selectedNetwork, selectedToken, onSuccess, activateUnderpaymentFlow]);
23933
24000
  useEffect(() => {
23934
- const shouldPoll = (paymentData == null ? void 0 : paymentData.id) && (activeTab === PAYMENT_TABS.QR || activeTab === PAYMENT_TABS.TRANSFER) && currentStep === PAYMENT_STEPS.CONFIRM && !verifyingPayment && paymentType !== PAYMENT_TYPES.DEPOSIT;
24001
+ const shouldPoll = (paymentData == null ? void 0 : paymentData.id) && (activeTab === PAYMENT_TABS.QR || activeTab === PAYMENT_TABS.TRANSFER) && currentStep === PAYMENT_STEPS.CONFIRM && !verifyingPayment && paymentType !== PAYMENT_TYPES.DEPOSIT && !(paymentData == null ? void 0 : paymentData.isDepositPayment) && !(paymentData == null ? void 0 : paymentData.depositAddress);
23935
24002
  if (!shouldPoll) {
23936
24003
  return;
23937
24004
  }
@@ -24011,7 +24078,7 @@ const CoinleyPaymentInternal = ({
24011
24078
  console.log("🛑 Stopping auto-detection polling");
24012
24079
  clearInterval(pollInterval);
24013
24080
  };
24014
- }, [paymentData == null ? void 0 : paymentData.id, activeTab, currentStep, verifyingPayment, paymentType, selectedNetwork, selectedToken, onSuccess, paymentFlow.api]);
24081
+ }, [paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.isDepositPayment, paymentData == null ? void 0 : paymentData.depositAddress, activeTab, currentStep, verifyingPayment, paymentType, selectedNetwork, selectedToken, onSuccess, paymentFlow.api]);
24015
24082
  const resetAllTransactionState = async () => {
24016
24083
  var _a2;
24017
24084
  invalidateCurrentAttempt("reset-all-transaction-state");
@@ -25457,6 +25524,10 @@ const CoinleyPaymentInternal = ({
25457
25524
  try {
25458
25525
  const statusResult = await paymentFlow.api.getDepositStatus(paymentData.id);
25459
25526
  if (statusResult.success && statusResult.payment) {
25527
+ if (activateUnderpaymentFlow(statusResult.payment)) {
25528
+ clearInterval(pollInterval);
25529
+ return;
25530
+ }
25460
25531
  const status = statusResult.payment.status;
25461
25532
  const txHash = statusResult.payment.depositTxHash || statusResult.payment.sweepTxHash || statusResult.payment.transactionHash;
25462
25533
  if ((status === "completed" || status === "swept") && txHash) {
@@ -25492,7 +25563,7 @@ const CoinleyPaymentInternal = ({
25492
25563
  console.log("🛑 Stopping deposit auto-detection polling");
25493
25564
  clearInterval(pollInterval);
25494
25565
  };
25495
- }, [paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.depositAddress, paymentType, currentStep, verifyingPayment, expirationTime == null ? void 0 : expirationTime.expired, selectedNetwork, selectedToken, onSuccess, paymentFlow.api]);
25566
+ }, [paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.depositAddress, paymentType, currentStep, verifyingPayment, expirationTime == null ? void 0 : expirationTime.expired, selectedNetwork, selectedToken, onSuccess, paymentFlow.api, activateUnderpaymentFlow]);
25496
25567
  useEffect(() => {
25497
25568
  return () => {
25498
25569
  if (manualCheckTimeout.current) {
@@ -25500,12 +25571,44 @@ const CoinleyPaymentInternal = ({
25500
25571
  }
25501
25572
  };
25502
25573
  }, []);
25574
+ useEffect(() => {
25575
+ setUnderpaymentInfo(null);
25576
+ setUnderpaymentChoice(null);
25577
+ setUnderpaymentView("choice");
25578
+ setRefundAddress("");
25579
+ setRefundRequestSubmitted(false);
25580
+ }, [paymentData == null ? void 0 : paymentData.id]);
25581
+ const handleRefundRequestSubmit = useCallback(() => {
25582
+ const trimmedAddress = refundAddress.trim();
25583
+ if (!trimmedAddress) return;
25584
+ setRefundRequestSubmitted(true);
25585
+ setManualCheckStatus(null);
25586
+ const refundPayload = {
25587
+ paymentId: paymentData == null ? void 0 : paymentData.id,
25588
+ refundAddress: trimmedAddress,
25589
+ amountReceived: underpaymentInfo == null ? void 0 : underpaymentInfo.receivedAmount,
25590
+ amountRemaining: underpaymentInfo == null ? void 0 : underpaymentInfo.shortfallAmount,
25591
+ network: selectedNetwork == null ? void 0 : selectedNetwork.shortName,
25592
+ currency: selectedToken == null ? void 0 : selectedToken.symbol
25593
+ };
25594
+ if (typeof (config == null ? void 0 : config.onRefundRequest) === "function") {
25595
+ config.onRefundRequest(refundPayload);
25596
+ }
25597
+ if (typeof window !== "undefined") {
25598
+ window.dispatchEvent(new CustomEvent("coinley:refund-requested", {
25599
+ detail: refundPayload
25600
+ }));
25601
+ }
25602
+ }, [config, refundAddress, paymentData == null ? void 0 : paymentData.id, selectedNetwork == null ? void 0 : selectedNetwork.shortName, selectedToken == null ? void 0 : selectedToken.symbol, underpaymentInfo]);
25503
25603
  const handleDepositManualCheck = useCallback(async () => {
25504
25604
  if (manualCheckStatus === "checking" || !(paymentData == null ? void 0 : paymentData.id)) return;
25505
25605
  setManualCheckStatus("checking");
25506
25606
  try {
25507
25607
  const statusResult = await paymentFlow.api.getDepositStatus(paymentData.id);
25508
25608
  if (statusResult.success && statusResult.payment) {
25609
+ if (activateUnderpaymentFlow(statusResult.payment)) {
25610
+ return;
25611
+ }
25509
25612
  const status = statusResult.payment.status;
25510
25613
  const txHash = statusResult.payment.depositTxHash || statusResult.payment.sweepTxHash || statusResult.payment.transactionHash;
25511
25614
  if ((status === "completed" || status === "swept") && txHash) {
@@ -25531,6 +25634,12 @@ const CoinleyPaymentInternal = ({
25531
25634
  return;
25532
25635
  }
25533
25636
  }
25637
+ if (paymentData == null ? void 0 : paymentData.depositAddress) {
25638
+ const balanceResult = await paymentFlow.api.getDepositBalance(paymentData.id);
25639
+ if ((balanceResult == null ? void 0 : balanceResult.success) && activateUnderpaymentFromDepositBalance(balanceResult)) {
25640
+ return;
25641
+ }
25642
+ }
25534
25643
  setManualCheckStatus("not_found");
25535
25644
  manualCheckTimeout.current = setTimeout(() => {
25536
25645
  setManualCheckStatus(null);
@@ -25542,7 +25651,7 @@ const CoinleyPaymentInternal = ({
25542
25651
  setManualCheckStatus(null);
25543
25652
  }, 1e4);
25544
25653
  }
25545
- }, [manualCheckStatus, paymentData == null ? void 0 : paymentData.id, paymentFlow.api, config == null ? void 0 : config.amount, selectedNetwork, selectedToken, onSuccess]);
25654
+ }, [manualCheckStatus, paymentData == null ? void 0 : paymentData.id, paymentData == null ? void 0 : paymentData.depositAddress, paymentFlow.api, config == null ? void 0 : config.amount, selectedNetwork, selectedToken, onSuccess, activateUnderpaymentFlow, activateUnderpaymentFromDepositBalance]);
25546
25655
  if (!isOpen) return null;
25547
25656
  if (currentStep === PAYMENT_STEPS.PROCESSING) {
25548
25657
  return /* @__PURE__ */ jsxs("div", { id: SDK_ROOT_ID, className: `${SDK_ROOT_CLASS} fixed inset-0 z-50`, style: { fontFamily: FONT_FAMILY }, children: [
@@ -25588,7 +25697,7 @@ const CoinleyPaymentInternal = ({
25588
25697
  if (currentStep === PAYMENT_STEPS.SUCCESS) {
25589
25698
  return /* @__PURE__ */ jsxs("div", { id: SDK_ROOT_ID, className: `${SDK_ROOT_CLASS} fixed inset-0 z-50`, style: { fontFamily: FONT_FAMILY }, children: [
25590
25699
  /* @__PURE__ */ jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50" }),
25591
- /* @__PURE__ */ jsx("div", { className: isMobile ? "fixed inset-0 flex items-end" : "fixed inset-0 flex items-center justify-center p-4", style: { zIndex: 51 }, children: /* @__PURE__ */ jsx("div", { className: isMobile ? "relative flex w-full max-h-[92vh] flex-col overflow-y-auto rounded-t-[28px] bg-white px-4 pb-5 pt-5 animate-slide-up-sheet" : "relative flex h-[553px] w-[450px] max-w-[calc(100vw-32px)] flex-col overflow-hidden rounded-[28px] bg-white px-4 pb-5 pt-5", children: /* @__PURE__ */ jsx(
25700
+ /* @__PURE__ */ jsx("div", { className: isMobile ? "fixed inset-0 flex items-end" : "fixed inset-0 flex items-center justify-center p-4", style: { zIndex: 51 }, children: /* @__PURE__ */ jsx("div", { className: isMobile ? "relative flex w-full max-h-[92vh] flex-col overflow-y-auto rounded-t-[28px] bg-white px-4 pb-5 pt-5 animate-slide-up-sheet" : "relative flex max-h-[calc(100vh-32px)] min-h-0 w-[450px] max-w-[calc(100vw-32px)] flex-col overflow-y-auto rounded-[28px] bg-white px-4 pb-5 pt-5", children: /* @__PURE__ */ jsx(
25592
25701
  PaymentStatus,
25593
25702
  {
25594
25703
  status: "success",
@@ -25605,6 +25714,8 @@ const CoinleyPaymentInternal = ({
25605
25714
  ] });
25606
25715
  }
25607
25716
  const paymentAmountLabel = isConverting ? "..." : `$${formatAmount(paymentAmount || (config == null ? void 0 : config.amount) || 0)}`;
25717
+ const underpaymentOffsetAmountLabel = underpaymentInfo ? `$${formatAmount(underpaymentInfo.shortfallAmount || 0)}` : paymentAmountLabel;
25718
+ const summaryPaymentAmountLabel = underpaymentInfo && (underpaymentView === "offset" || underpaymentView === "refund") ? underpaymentOffsetAmountLabel : paymentAmountLabel;
25608
25719
  const getTokenDisplaySymbol = (token) => (token == null ? void 0 : token.symbol) || (token == null ? void 0 : token.tokenSymbol) || (token == null ? void 0 : token.currency) || (token == null ? void 0 : token.ticker) || (token == null ? void 0 : token.name) || "Token";
25609
25720
  const getLogoFallbackUrl = (label = "?", background = "7042D2") => {
25610
25721
  const safeLabel = String(label || "?").slice(0, 2).toUpperCase();
@@ -25639,7 +25750,7 @@ const CoinleyPaymentInternal = ({
25639
25750
  /* @__PURE__ */ jsx("div", { className: "flex-1 pt-[13px] border-t border-dashed border-[#DFE1E7]" }),
25640
25751
  /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
25641
25752
  /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-none text-[#9EA0A8] mb-1", children: "To Pay:" }),
25642
- /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-[#1F2430]", children: paymentAmountLabel })
25753
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-[#1F2430]", children: summaryPaymentAmountLabel })
25643
25754
  ] })
25644
25755
  ] }),
25645
25756
  merchantCurrency !== "USD" && currencyInfo && exchangeRate && !isConverting && /* @__PURE__ */ jsxs("p", { className: "text-[11px] text-[#9EA0A8] mt-2", children: [
@@ -25665,6 +25776,141 @@ const CoinleyPaymentInternal = ({
25665
25776
  method.tab
25666
25777
  )) })
25667
25778
  ] });
25779
+ const renderUnderpaymentWarning = (title = "Amount received is less than expected", description = null) => /* @__PURE__ */ jsxs("div", { className: "mb-5 rounded-lg border border-[#F5E5B8] bg-[#FFF9E8] px-3 py-2", children: [
25780
+ /* @__PURE__ */ jsxs("div", { className: `flex items-start gap-2 text-[#B54708] ${title && description ? "mb-1" : ""}`, children: [
25781
+ /* @__PURE__ */ jsx("svg", { className: "mt-0.5 h-4 w-4 flex-shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v4m0 4h.01M12 3a9 9 0 110 18 9 9 0 010-18z" }) }),
25782
+ title ? /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: title }) : /* @__PURE__ */ jsx("p", { className: "text-xs leading-5 text-[#B54708]", children: description })
25783
+ ] }),
25784
+ title && description && /* @__PURE__ */ jsx("p", { className: "pl-6 text-xs leading-5 text-[#B54708]", children: description })
25785
+ ] });
25786
+ const renderUnderpaymentOptionCard = ({ choice, icon, title, description }) => {
25787
+ const selected = underpaymentChoice === choice;
25788
+ return /* @__PURE__ */ jsxs(
25789
+ "button",
25790
+ {
25791
+ type: "button",
25792
+ onClick: () => {
25793
+ setUnderpaymentChoice(choice);
25794
+ setRefundRequestSubmitted(false);
25795
+ },
25796
+ className: `relative flex min-h-[118px] flex-1 flex-col items-start rounded-xl border p-3 text-left transition-colors ${selected ? "border-[#8B5CF6] bg-[#F4EEFF]" : "border-[#ECEEF2] bg-white hover:border-[#D7C5FF]"}`,
25797
+ children: [
25798
+ selected && /* @__PURE__ */ jsx("span", { className: "absolute right-[-7px] top-[-9px] flex h-5 w-5 items-center justify-center rounded-full border border-[#8B5CF6] bg-white text-[#7042D2]", children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M5 13l4 4L19 7" }) }) }),
25799
+ /* @__PURE__ */ jsx("div", { className: "mb-3 flex h-6 w-6 items-center justify-center text-[#111827]", children: icon }),
25800
+ /* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-semibold text-[#111827]", children: title }),
25801
+ /* @__PURE__ */ jsx("p", { className: "text-xs leading-4 text-[#A3A5AC]", children: description })
25802
+ ]
25803
+ }
25804
+ );
25805
+ };
25806
+ const renderUnderpaymentChoicePanel = () => /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
25807
+ renderUnderpaymentWarning(
25808
+ "Amount received is less than expected",
25809
+ `We received $${formatAmount(underpaymentInfo.receivedAmount || 0)} but expected $${formatAmount(underpaymentInfo.expectedAmount || paymentAmount || 0)}. Your transaction is on hold, please choose how to proceed.`
25810
+ ),
25811
+ /* @__PURE__ */ jsxs("div", { className: "mb-5 flex gap-2", children: [
25812
+ renderUnderpaymentOptionCard({
25813
+ choice: "offset",
25814
+ title: "Send offset",
25815
+ description: underpaymentChoice === "offset" ? "Top up the shortfall and complete this transfer with extended time" : "Top up the shortfall with extended time",
25816
+ icon: /* @__PURE__ */ jsx("svg", { className: "h-6 w-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.8, d: "M4 4v6h6M20 20v-6h-6M5.5 15.5A7 7 0 0017.7 18M18.5 8.5A7 7 0 006.3 6" }) })
25817
+ }),
25818
+ renderUnderpaymentOptionCard({
25819
+ choice: "refund",
25820
+ title: "Cancel & refund",
25821
+ description: "Cancel my transaction so i get refunded",
25822
+ icon: /* @__PURE__ */ jsxs("svg", { className: "h-6 w-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
25823
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", strokeWidth: 1.8 }),
25824
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.8, d: "M9 9l6 6m0-6l-6 6" })
25825
+ ] })
25826
+ })
25827
+ ] }),
25828
+ /* @__PURE__ */ jsx(
25829
+ "button",
25830
+ {
25831
+ type: "button",
25832
+ disabled: !underpaymentChoice,
25833
+ onClick: () => {
25834
+ setRefundRequestSubmitted(false);
25835
+ if (underpaymentChoice === "offset") {
25836
+ modalOpenedAtRef.current = Date.now();
25837
+ setTimeRemaining(paymentTimeoutMs);
25838
+ }
25839
+ setUnderpaymentView(underpaymentChoice === "refund" ? "refund" : "offset");
25840
+ },
25841
+ className: `h-11 w-full rounded-xl px-4 text-sm font-semibold text-white transition-colors ${underpaymentChoice ? "bg-[#7042D2] hover:bg-[#5b34b1]" : "cursor-not-allowed bg-[#B59AE9]"}`,
25842
+ children: "Continue"
25843
+ }
25844
+ )
25845
+ ] });
25846
+ const renderUnderpaymentOffsetPanel = () => /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
25847
+ /* @__PURE__ */ jsxs("div", { className: "mb-5 flex items-start gap-3", children: [
25848
+ /* @__PURE__ */ jsx("div", { className: "h-[92px] w-[92px] flex-shrink-0 bg-white", children: depositQrCode ? /* @__PURE__ */ jsx("img", { src: depositQrCode, alt: "Deposit Address QR Code", className: "h-full w-full" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center rounded-lg bg-gray-100", children: /* @__PURE__ */ jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[#E5E7EB] border-t-[#7042D2]" }) }) }),
25849
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 pt-1", children: [
25850
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-[#1F2430]", children: "Same Wallet address" }),
25851
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-[58px] items-center gap-2 rounded-xl border border-[#EEF0F4] bg-[#FAFAFB] px-3 py-2", children: [
25852
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 break-all text-sm leading-5 text-[#1F2430]", children: paymentData.depositAddress }),
25853
+ /* @__PURE__ */ jsx(
25854
+ "button",
25855
+ {
25856
+ onClick: () => copyToClipboard(paymentData.depositAddress, "depositAddress"),
25857
+ className: `flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg transition-colors ${copiedField === "depositAddress" ? "bg-green-100 text-green-600" : "text-[#7042D2] hover:bg-purple-50"}`,
25858
+ "aria-label": "Copy wallet address",
25859
+ children: copiedField === "depositAddress" ? /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
25860
+ }
25861
+ )
25862
+ ] })
25863
+ ] })
25864
+ ] }),
25865
+ renderUnderpaymentWarning(
25866
+ null,
25867
+ "Send only the offset amount to the same address. Make sure to add network fees on top of this amount."
25868
+ ),
25869
+ /* @__PURE__ */ jsx(
25870
+ "button",
25871
+ {
25872
+ type: "button",
25873
+ onClick: handleDepositManualCheck,
25874
+ disabled: manualCheckStatus === "checking",
25875
+ className: `h-11 w-full rounded-xl px-4 text-sm font-semibold text-white transition-colors ${manualCheckStatus === "checking" ? "cursor-not-allowed bg-purple-400" : "bg-[#7042D2] hover:bg-[#5b34b1]"}`,
25876
+ children: manualCheckStatus === "checking" ? "Checking for your payment..." : "I've sent the offset"
25877
+ }
25878
+ )
25879
+ ] });
25880
+ const renderUnderpaymentRefundPanel = () => /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
25881
+ renderUnderpaymentWarning(
25882
+ `Refund of $${formatAmount(underpaymentInfo.receivedAmount || 0)} ${underpaymentInfo.tokenSymbol}`,
25883
+ `Provide a ${underpaymentInfo.tokenSymbol} wallet address on the same network (${underpaymentInfo.refundNetworkLabel}) to receive your refund. Network fees will be deducted.`
25884
+ ),
25885
+ /* @__PURE__ */ jsxs("label", { className: "mb-2 block text-xs font-medium text-[#111827]", children: [
25886
+ "Your ",
25887
+ underpaymentInfo.tokenSymbol,
25888
+ " (",
25889
+ underpaymentInfo.refundNetworkLabel,
25890
+ ") receiving wallet address"
25891
+ ] }),
25892
+ /* @__PURE__ */ jsx(
25893
+ "input",
25894
+ {
25895
+ type: "text",
25896
+ value: refundAddress,
25897
+ onChange: (event) => setRefundAddress(event.target.value),
25898
+ placeholder: "Paste your wallet address here",
25899
+ className: "mb-5 h-11 w-full rounded-xl border border-[#E4E6EB] bg-white px-3 text-sm text-[#1F2430] outline-none transition-colors placeholder:text-[#8B8E98] focus:border-[#B49AF0]"
25900
+ }
25901
+ ),
25902
+ /* @__PURE__ */ jsx(
25903
+ "button",
25904
+ {
25905
+ type: "button",
25906
+ disabled: !refundAddress.trim(),
25907
+ onClick: handleRefundRequestSubmit,
25908
+ className: `h-11 w-full rounded-xl px-4 text-sm font-semibold text-white transition-colors ${refundAddress.trim() ? "bg-[#7042D2] hover:bg-[#5b34b1]" : "cursor-not-allowed bg-[#B59AE9]"}`,
25909
+ children: refundRequestSubmitted ? "Refund request submitted" : "Submit refund request"
25910
+ }
25911
+ ),
25912
+ refundRequestSubmitted && /* @__PURE__ */ jsx("p", { className: "mt-2 text-center text-xs leading-5 text-[#8B8E98]", children: "Keep this screen open while we continue checking the payment status." })
25913
+ ] });
25668
25914
  const transferNetworks = networks.filter((network) => {
25669
25915
  const chainId = parseInt(network.chainId);
25670
25916
  const supportedChains = [8453, 56, 42161, 137, 10, 43114, 143, 59144, 534352, 130];
@@ -26564,20 +26810,13 @@ const CoinleyPaymentInternal = ({
26564
26810
  activeTab === PAYMENT_TABS.QR && /* @__PURE__ */ jsx(Fragment, { children: qrWalletChoiceConfirmed ? renderQrPaymentPanel() : renderQrWalletChoicePanel() }),
26565
26811
  activeTab === PAYMENT_TABS.TRANSFER && /* @__PURE__ */ jsxs(Fragment, { children: [
26566
26812
  (!selectedNetwork || !selectedToken || !(paymentData == null ? void 0 : paymentData.depositAddress)) && renderTransferSetupPanel(),
26567
- selectedNetwork && selectedToken && (paymentData == null ? void 0 : paymentData.depositAddress) && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
26568
- expirationTime && !expirationTime.expired && /* @__PURE__ */ jsxs("div", { className: "mb-4 rounded-lg border border-[#F2E8C8] bg-[#FFF9E8] px-3 py-2 text-xs font-medium text-[#C56416]", children: [
26569
- "Address expires in ",
26570
- String(expirationTime.minutes).padStart(2, "0"),
26571
- ":",
26572
- String(expirationTime.seconds).padStart(2, "0")
26573
- ] }),
26813
+ selectedNetwork && selectedToken && (paymentData == null ? void 0 : paymentData.depositAddress) && (underpaymentInfo ? /* @__PURE__ */ jsx(Fragment, { children: underpaymentView === "offset" ? renderUnderpaymentOffsetPanel() : underpaymentView === "refund" ? renderUnderpaymentRefundPanel() : renderUnderpaymentChoicePanel() }) : /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
26574
26814
  (expirationTime == null ? void 0 : expirationTime.expired) && /* @__PURE__ */ jsx("div", { className: "mb-4 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs font-medium text-red-600", children: "Timer exhausted - No transaction detected. Please generate a new address." }),
26575
- /* @__PURE__ */ jsx("p", { className: "mb-4 text-xs leading-5 text-[#9EA0A8]", children: "Simply scan the QR code which holds just the address, input the amount, and transfer the funds" }),
26576
- /* @__PURE__ */ jsxs("div", { className: "mb-5 flex items-center gap-4", children: [
26815
+ /* @__PURE__ */ jsxs("div", { className: "mb-5 flex items-start gap-3", children: [
26577
26816
  /* @__PURE__ */ jsx("div", { className: "h-[92px] w-[92px] flex-shrink-0 bg-white", children: depositQrCode ? /* @__PURE__ */ jsx("img", { src: depositQrCode, alt: "Deposit Address QR Code", className: "h-full w-full" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center rounded-lg bg-gray-100", children: /* @__PURE__ */ jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[#E5E7EB] border-t-[#7042D2]" }) }) }),
26578
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
26817
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 pt-1", children: [
26579
26818
  /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-[#1F2430]", children: "Wallet address" }),
26580
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-[60px] items-center gap-2 rounded-xl border border-[#EEF0F4] bg-[#FAFAFB] px-3 py-2", children: [
26819
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-[58px] items-center gap-2 rounded-xl border border-[#EEF0F4] bg-[#FAFAFB] px-3 py-2", children: [
26581
26820
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 break-all text-sm leading-5 text-[#1F2430]", children: paymentData.depositAddress }),
26582
26821
  /* @__PURE__ */ jsx(
26583
26822
  "button",
@@ -26591,6 +26830,13 @@ const CoinleyPaymentInternal = ({
26591
26830
  ] })
26592
26831
  ] })
26593
26832
  ] }),
26833
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 rounded-lg border border-[#F5E5B8] bg-[#FFF9E8] px-3 py-2.5", children: [
26834
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-2 text-[#C55A11]", children: [
26835
+ /* @__PURE__ */ jsx("svg", { className: "h-4 w-4 flex-shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v4m0 4h.01M12 3a9 9 0 110 18 9 9 0 010-18z" }) }),
26836
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold", children: "Important!" })
26837
+ ] }),
26838
+ /* @__PURE__ */ jsx("p", { className: "pl-6 text-xs leading-5 text-[#C55A11]", children: "We must receive the exact amount shown. If your exchange charges a withdrawal fee, add it on top of this amount before sending." })
26839
+ ] }),
26594
26840
  !(expirationTime == null ? void 0 : expirationTime.expired) && /* @__PURE__ */ jsx("div", { className: "mt-2", children: manualCheckStatus === "not_found" ? /* @__PURE__ */ jsxs("div", { className: "p-3 bg-amber-50 border border-amber-200 rounded-xl mb-3", children: [
26595
26841
  /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-700", children: "We haven't received your payment yet. It may take a few moments for the transaction to appear on the blockchain. We'll keep checking automatically." }),
26596
26842
  /* @__PURE__ */ jsx(
@@ -26615,15 +26861,8 @@ const CoinleyPaymentInternal = ({
26615
26861
  "Checking for your payment..."
26616
26862
  ] }) : "I've made this transfer"
26617
26863
  }
26618
- ) }),
26619
- paymentData && !verifyingPayment && !(expirationTime == null ? void 0 : expirationTime.expired) && manualCheckStatus !== "not_found" && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center justify-center gap-2 text-xs text-[#A3A5AC]", children: [
26620
- /* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
26621
- /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
26622
- /* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
26623
- ] }),
26624
- "Checking automatically every few seconds..."
26625
- ] })
26626
- ] })
26864
+ ) })
26865
+ ] }))
26627
26866
  ] }),
26628
26867
  (error || transactionError) && /* @__PURE__ */ jsxs("div", { className: "mt-4 p-4 bg-red-50 border border-red-200 rounded-xl", children: [
26629
26868
  /* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: error || transactionError }),
@@ -26663,6 +26902,10 @@ const CoinleyPaymentInternal = ({
26663
26902
  const isWalletTokenSelectionView = activeTab === PAYMENT_TABS.WALLET && selectedNetwork && !selectedToken && !showWalletConfirm && !(showMobileWalletPicker && isMobile);
26664
26903
  const isQrPaymentActiveView = activeTab === PAYMENT_TABS.QR && qrWalletChoiceConfirmed;
26665
26904
  const handleTransferAddressBack = async () => {
26905
+ if (underpaymentInfo && underpaymentView !== "choice") {
26906
+ setUnderpaymentView("choice");
26907
+ return;
26908
+ }
26666
26909
  setPaymentData((prev) => {
26667
26910
  if (!prev) return prev;
26668
26911
  return {
@@ -26674,6 +26917,11 @@ const CoinleyPaymentInternal = ({
26674
26917
  };
26675
26918
  });
26676
26919
  setExpirationTime(null);
26920
+ setUnderpaymentInfo(null);
26921
+ setUnderpaymentChoice(null);
26922
+ setUnderpaymentView("choice");
26923
+ setRefundAddress("");
26924
+ setRefundRequestSubmitted(false);
26677
26925
  await resetAllTransactionState();
26678
26926
  setActiveTab(PAYMENT_TABS.TRANSFER);
26679
26927
  };
@@ -26768,4 +27016,4 @@ export {
26768
27016
  isFeatureEnabled as i,
26769
27017
  logo as l
26770
27018
  };
26771
- //# sourceMappingURL=CoinleyPayment-tHjB69By.js.map
27019
+ //# sourceMappingURL=CoinleyPayment-Bql8B8cV.js.map
@@ -1,4 +1,4 @@
1
- import { i as isFeatureEnabled, F as FEATURES, c as chainTransports, W as WALLETCONNECT_PROJECT_ID, l as logo } from "./CoinleyPayment-tHjB69By.js";
1
+ import { i as isFeatureEnabled, F as FEATURES, c as chainTransports, W as WALLETCONNECT_PROJECT_ID, l as logo } from "./CoinleyPayment-Bql8B8cV.js";
2
2
  let appKitInstance = null;
3
3
  let isInitializing = false;
4
4
  let initializationPromise = null;
@@ -112,4 +112,4 @@ export {
112
112
  initializeAppKitEVM,
113
113
  openAppKitModal
114
114
  };
115
- //# sourceMappingURL=appKitEVM-Bu9jo5n-.js.map
115
+ //# sourceMappingURL=appKitEVM-BcM7Ftoe.js.map
@@ -1,4 +1,4 @@
1
- import { F as FEATURES, l as logo, W as WALLETCONNECT_PROJECT_ID } from "./CoinleyPayment-tHjB69By.js";
1
+ import { F as FEATURES, l as logo, W as WALLETCONNECT_PROJECT_ID } from "./CoinleyPayment-Bql8B8cV.js";
2
2
  let appKitInstance = null;
3
3
  let isInitializing = false;
4
4
  let initializationPromise = null;
@@ -242,4 +242,4 @@ export {
242
242
  disconnectWalletConnect,
243
243
  initializeAppKitSolana
244
244
  };
245
- //# sourceMappingURL=appKitSolana-D38g1-Lm.js.map
245
+ //# sourceMappingURL=appKitSolana-BWdEszCH.js.map