coinley-checkout 0.6.1 → 0.6.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.
@@ -20596,10 +20596,37 @@ const PaymentStatus = ({
20596
20596
  transactionHash = null,
20597
20597
  selectedPaymentMethod = null,
20598
20598
  merchantName = "Merchant",
20599
- onClose = null
20599
+ onClose = null,
20600
20600
  // The onClose prop for the close button
20601
+ // New props for enhanced processing feedback
20602
+ processingStartTime = null,
20603
+ // Time when processing started
20604
+ paymentNetwork = null
20605
+ // Current payment network
20601
20606
  }) => {
20602
20607
  const [copiedHash, setCopiedHash] = useState(false);
20608
+ const [processingSeconds, setProcessingSeconds] = useState(0);
20609
+ const [showEarlySuccessOption, setShowEarlySuccessOption] = useState(false);
20610
+ const [progressStage, setProgressStage] = useState(1);
20611
+ useEffect(() => {
20612
+ let timer;
20613
+ if (status === "processing" && processingStartTime) {
20614
+ timer = setInterval(() => {
20615
+ const elapsed = Math.floor((Date.now() - processingStartTime) / 1e3);
20616
+ setProcessingSeconds(elapsed);
20617
+ if (elapsed >= 5 && progressStage === 1) {
20618
+ setProgressStage(2);
20619
+ }
20620
+ if (elapsed >= 15 && progressStage === 2) {
20621
+ setProgressStage(3);
20622
+ }
20623
+ if (elapsed >= 30 && !showEarlySuccessOption) {
20624
+ setShowEarlySuccessOption(true);
20625
+ }
20626
+ }, 1e3);
20627
+ }
20628
+ return () => clearInterval(timer);
20629
+ }, [status, processingStartTime, progressStage, showEarlySuccessOption]);
20603
20630
  const copyTransactionHash = () => __async(void 0, null, function* () {
20604
20631
  if (transactionHash) {
20605
20632
  try {
@@ -20617,6 +20644,11 @@ const PaymentStatus = ({
20617
20644
  onClose();
20618
20645
  }
20619
20646
  };
20647
+ const handleEarlySuccess = () => {
20648
+ if (onClose) {
20649
+ onClose();
20650
+ }
20651
+ };
20620
20652
  const formatTransactionHash = (hash2) => {
20621
20653
  if (!hash2)
20622
20654
  return "";
@@ -20633,6 +20665,16 @@ const PaymentStatus = ({
20633
20665
  };
20634
20666
  return names2[network] || network;
20635
20667
  };
20668
+ const getEstimatedConfirmationTime = (network) => {
20669
+ const times = {
20670
+ ethereum: "1-2 minutes",
20671
+ bsc: "15-30 seconds",
20672
+ tron: "30-60 seconds",
20673
+ algorand: "5-10 seconds",
20674
+ solana: "10-15 seconds"
20675
+ };
20676
+ return times[network] || "1-2 minutes";
20677
+ };
20636
20678
  const formatRecipientAddress = (address) => {
20637
20679
  if (!address)
20638
20680
  return "N/A";
@@ -20640,6 +20682,11 @@ const PaymentStatus = ({
20640
20682
  return address;
20641
20683
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
20642
20684
  };
20685
+ const formatTime = (seconds) => {
20686
+ const mins = Math.floor(seconds / 60);
20687
+ const secs = seconds % 60;
20688
+ return `${mins}:${secs < 10 ? "0" : ""}${secs}`;
20689
+ };
20643
20690
  const renderIcon = () => {
20644
20691
  switch (status) {
20645
20692
  case "processing":
@@ -20761,12 +20808,66 @@ const PaymentStatus = ({
20761
20808
  )
20762
20809
  ] });
20763
20810
  }
20811
+ if (status === "processing") {
20812
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6", children: [
20813
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: renderIcon() }),
20814
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: `text-xl font-bold mb-2 ${theme2 === "dark" ? "text-white" : "text-gray-900"}`, children: getStatusTitle() }),
20815
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-center ${getMessageClasses()}`, children: message }),
20816
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full mt-6 mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full bg-gray-200 rounded-full h-2.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
20817
+ "div",
20818
+ {
20819
+ className: "bg-blue-600 h-2.5 rounded-full transition-all duration-500",
20820
+ style: {
20821
+ width: `${Math.min(100, progressStage / 3 * 100)}%`
20822
+ }
20823
+ }
20824
+ ) }) }),
20825
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full grid grid-cols-3 gap-1 mb-4", children: [
20826
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-xs text-center ${progressStage >= 1 ? "text-blue-600 font-medium" : "text-gray-400"}`, children: "Submitted" }),
20827
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-xs text-center ${progressStage >= 2 ? "text-blue-600 font-medium" : "text-gray-400"}`, children: "Detected" }),
20828
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-xs text-center ${progressStage >= 3 ? "text-blue-600 font-medium" : "text-gray-400"}`, children: "Confirming" })
20829
+ ] }),
20830
+ transactionHash && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full my-3 px-4", children: [
20831
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-center text-gray-600 mb-2", children: "Transaction ID:" }),
20832
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-md p-2 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-gray-700", children: formatTransactionHash(transactionHash) }) })
20833
+ ] }),
20834
+ paymentNetwork && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mt-4 mb-2 p-3 bg-blue-50 rounded-md text-center", children: [
20835
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-blue-800", children: [
20836
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Estimated confirmation time:" }),
20837
+ " ",
20838
+ getEstimatedConfirmationTime(paymentNetwork)
20839
+ ] }),
20840
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-blue-600 mt-1", children: [
20841
+ "Processing time: ",
20842
+ formatTime(processingSeconds)
20843
+ ] })
20844
+ ] }),
20845
+ showEarlySuccessOption && onClose && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mt-4", children: [
20846
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2 p-3 bg-yellow-50 rounded-md", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-center text-yellow-800", children: "Taking longer than expected? Your payment may already be complete. You can proceed now or continue waiting for confirmation." }) }),
20847
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
20848
+ "button",
20849
+ {
20850
+ onClick: handleEarlySuccess,
20851
+ className: "w-full py-2 px-4 bg-gray-200 text-purple-600 font-medium rounded-md hover:bg-gray-300 transition-colors",
20852
+ children: "Continue to Order Confirmation"
20853
+ }
20854
+ )
20855
+ ] }),
20856
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 text-xs ${theme2 === "dark" ? "text-gray-400" : "text-gray-500"}`, children: "Blockchain transactions can take a few moments to confirm. Please wait..." })
20857
+ ] });
20858
+ }
20859
+ if (status === "error") {
20860
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6", children: [
20861
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: renderIcon() }),
20862
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: `text-xl font-bold mb-2 ${theme2 === "dark" ? "text-white" : "text-gray-900"}`, children: "Payment Failed" }),
20863
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-center ${getMessageClasses()}`, children: message }),
20864
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 p-2 rounded ${theme2 === "dark" ? "bg-gray-700" : "bg-gray-100"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs ${theme2 === "dark" ? "text-gray-300" : "text-gray-600"}`, children: "Please try again or contact support if the problem persists." }) })
20865
+ ] });
20866
+ }
20764
20867
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6", children: [
20765
20868
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: renderIcon() }),
20766
20869
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: `text-xl font-bold mb-2 ${theme2 === "dark" ? "text-white" : "text-gray-900"}`, children: getStatusTitle() }),
20767
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-center ${getMessageClasses()}`, children: message }),
20768
- status === "processing" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 text-xs ${theme2 === "dark" ? "text-gray-400" : "text-gray-500"}`, children: "This may take a few moments. Please do not close this window." }),
20769
- status === "error" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 p-2 rounded ${theme2 === "dark" ? "bg-gray-700" : "bg-gray-100"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs ${theme2 === "dark" ? "text-gray-300" : "text-gray-600"}`, children: "Please try again or contact support if the problem persists." }) })
20870
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-center ${getMessageClasses()}`, children: message })
20770
20871
  ] });
20771
20872
  };
20772
20873
  const PaymentMethods = ({ onSelect, selected, theme: theme2 = "light", supportedNetworks = [] }) => {
@@ -21142,7 +21243,12 @@ const CoinleyModal = ({
21142
21243
  supportedWallets = [],
21143
21244
  step = "select-currency",
21144
21245
  merchantWalletAddresses = {},
21145
- debug = false
21246
+ debug = false,
21247
+ // New props for enhanced processing feedback
21248
+ processingStartTime = null,
21249
+ transactionDetected = false,
21250
+ paymentNetwork = null,
21251
+ onEarlySuccess = null
21146
21252
  }) => {
21147
21253
  const [paymentType, setPaymentType] = useState("wallet");
21148
21254
  const getWalletAddressForNetwork = () => {
@@ -21163,6 +21269,12 @@ const CoinleyModal = ({
21163
21269
  onClose();
21164
21270
  }
21165
21271
  };
21272
+ const handleEarlySuccess = () => {
21273
+ console.log("Early success button clicked");
21274
+ if (onEarlySuccess) {
21275
+ onEarlySuccess();
21276
+ }
21277
+ };
21166
21278
  const formatAmount = (amount) => {
21167
21279
  return parseFloat(amount).toFixed(2);
21168
21280
  };
@@ -21210,7 +21322,7 @@ const CoinleyModal = ({
21210
21322
  /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: logo, className: "w-auto h-auto", alt: "Coinley Logo" }),
21211
21323
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-lg font-semibold text-gray-800", children: "Payment Details" })
21212
21324
  ] }),
21213
- step !== "success" && /* @__PURE__ */ jsxRuntimeExports.jsx(
21325
+ step !== "success" && step !== "processing" && /* @__PURE__ */ jsxRuntimeExports.jsx(
21214
21326
  "button",
21215
21327
  {
21216
21328
  onClick: onClose,
@@ -21389,7 +21501,11 @@ const CoinleyModal = ({
21389
21501
  {
21390
21502
  status: "processing",
21391
21503
  theme: theme2,
21392
- message: "Processing your payment..."
21504
+ message: transactionDetected ? "Transaction detected! Waiting for blockchain confirmation..." : "Processing your payment...",
21505
+ processingStartTime,
21506
+ paymentNetwork: paymentNetwork || (selectedPaymentMethod == null ? void 0 : selectedPaymentMethod.network),
21507
+ transactionHash,
21508
+ onEarlySuccess: handleEarlySuccess
21393
21509
  }
21394
21510
  ),
21395
21511
  step === "success" && /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -21456,7 +21572,12 @@ const CoinleyCheckout = forwardRef(({
21456
21572
  testMode = false,
21457
21573
  supportedNetworks = [],
21458
21574
  preferredNetwork = NETWORK_TYPES.ETHEREUM,
21459
- preferredWallet = WALLET_TYPES.METAMASK
21575
+ preferredWallet = WALLET_TYPES.METAMASK,
21576
+ // New props for payment processing
21577
+ confirmations = 1,
21578
+ // Minimum confirmations required (lower = faster)
21579
+ fastMode = false
21580
+ // When true, will show success screen faster with fewer confirmations
21460
21581
  }, ref) => {
21461
21582
  const coinleyContext = useCoinley();
21462
21583
  const { theme: contextTheme } = useTheme();
@@ -21470,6 +21591,10 @@ const CoinleyCheckout = forwardRef(({
21470
21591
  const [availableWallets, setAvailableWallets] = useState({});
21471
21592
  const [step, setStep] = useState("select-currency");
21472
21593
  const [actualMerchantWallets, setActualMerchantWallets] = useState({});
21594
+ const [processingStartTime, setProcessingStartTime] = useState(null);
21595
+ const [transactionDetected, setTransactionDetected] = useState(false);
21596
+ const [checkingInterval, setCheckingInterval] = useState(null);
21597
+ const processingTimerRef = useRef(null);
21473
21598
  const effectiveApiKey = apiKey || (coinleyContext == null ? void 0 : coinleyContext.apiKey);
21474
21599
  const effectiveApiSecret = apiSecret || (coinleyContext == null ? void 0 : coinleyContext.apiSecret);
21475
21600
  apiUrl || (coinleyContext == null ? void 0 : coinleyContext.apiUrl);
@@ -21507,6 +21632,86 @@ const CoinleyCheckout = forwardRef(({
21507
21632
  detectWalletsAsync();
21508
21633
  }
21509
21634
  }, [effectiveDebug]);
21635
+ useEffect(() => {
21636
+ return () => {
21637
+ if (processingTimerRef.current) {
21638
+ clearTimeout(processingTimerRef.current);
21639
+ }
21640
+ if (checkingInterval) {
21641
+ clearInterval(checkingInterval);
21642
+ }
21643
+ };
21644
+ }, [checkingInterval]);
21645
+ useEffect(() => {
21646
+ if (transactionHash && paymentStatus === "loading" && step === "processing" && !checkingInterval) {
21647
+ setTransactionDetected(true);
21648
+ if (!testMode) {
21649
+ const interval = setInterval(() => __async(void 0, null, function* () {
21650
+ try {
21651
+ const processingTime = Date.now() - processingStartTime;
21652
+ if (fastMode && processingTime > getMinimumProcessingTime()) {
21653
+ log("Fast mode: Moving to success state early");
21654
+ clearInterval(interval);
21655
+ setCheckingInterval(null);
21656
+ handleEarlySuccess();
21657
+ return;
21658
+ }
21659
+ } catch (err) {
21660
+ log("Error checking transaction status:", err);
21661
+ }
21662
+ }), 5e3);
21663
+ setCheckingInterval(interval);
21664
+ }
21665
+ }
21666
+ return () => {
21667
+ if (checkingInterval) {
21668
+ clearInterval(checkingInterval);
21669
+ }
21670
+ };
21671
+ }, [transactionHash, paymentStatus, step, testMode, processingStartTime, fastMode]);
21672
+ const getMinimumProcessingTime = () => {
21673
+ if (!selectedPaymentMethod)
21674
+ return 2e4;
21675
+ const times = {
21676
+ [NETWORK_TYPES.ETHEREUM]: 15e3,
21677
+ // 15 seconds for Ethereum
21678
+ [NETWORK_TYPES.BSC]: 1e4,
21679
+ // 10 seconds for BSC
21680
+ [NETWORK_TYPES.TRON]: 8e3,
21681
+ // 8 seconds for Tron
21682
+ [NETWORK_TYPES.ALGORAND]: 5e3
21683
+ // 5 seconds for Algorand
21684
+ };
21685
+ return times[selectedPaymentMethod.network] || 15e3;
21686
+ };
21687
+ const handleEarlySuccess = () => __async(void 0, null, function* () {
21688
+ if (!payment || !selectedPaymentMethod || !transactionHash) {
21689
+ return;
21690
+ }
21691
+ log("Moving to early success state with transaction:", transactionHash);
21692
+ try {
21693
+ const processResponse = yield processPayment({
21694
+ paymentId: payment.id,
21695
+ transactionHash,
21696
+ network: selectedPaymentMethod.network,
21697
+ currency: selectedPaymentMethod.currency,
21698
+ senderAddress: walletConnection == null ? void 0 : walletConnection.address,
21699
+ early: true
21700
+ });
21701
+ log("Early payment processed:", processResponse);
21702
+ setPaymentStatus("success");
21703
+ setStep("success");
21704
+ if (onSuccess) {
21705
+ onSuccess(payment.id, transactionHash, {
21706
+ network: selectedPaymentMethod.network,
21707
+ currency: selectedPaymentMethod.currency,
21708
+ amount: payment.totalAmount || payment.amount
21709
+ });
21710
+ }
21711
+ } catch (err) {
21712
+ log("Early success processing error:", err);
21713
+ }
21714
+ });
21510
21715
  useImperativeHandle(ref, () => ({
21511
21716
  open: (paymentDetails) => {
21512
21717
  handleOpen(paymentDetails);
@@ -21563,11 +21768,21 @@ const CoinleyCheckout = forwardRef(({
21563
21768
  }
21564
21769
  });
21565
21770
  const handleClose = () => {
21771
+ if (checkingInterval) {
21772
+ clearInterval(checkingInterval);
21773
+ setCheckingInterval(null);
21774
+ }
21775
+ if (processingTimerRef.current) {
21776
+ clearTimeout(processingTimerRef.current);
21777
+ processingTimerRef.current = null;
21778
+ }
21566
21779
  setIsOpen(false);
21567
21780
  setTransactionHash(null);
21568
21781
  setWalletConnection(null);
21569
21782
  setSelectedPaymentMethod(null);
21570
21783
  setStep("select-currency");
21784
+ setProcessingStartTime(null);
21785
+ setTransactionDetected(false);
21571
21786
  if (onClose)
21572
21787
  onClose();
21573
21788
  };
@@ -21630,11 +21845,14 @@ const CoinleyCheckout = forwardRef(({
21630
21845
  setPaymentStatus("loading");
21631
21846
  setTransactionHash(null);
21632
21847
  setStep("processing");
21848
+ setProcessingStartTime(Date.now());
21849
+ setTransactionDetected(false);
21633
21850
  try {
21634
21851
  let txHash;
21635
21852
  if (testMode) {
21636
21853
  log("Test mode: Generating mock transaction...");
21637
21854
  txHash = `test_${Date.now().toString(16)}_${Math.random().toString(16).substring(2, 10)}`;
21855
+ yield new Promise((resolve) => setTimeout(resolve, 2e3));
21638
21856
  } else {
21639
21857
  let merchantAddress;
21640
21858
  if (payment.recipientWallet) {
@@ -21657,24 +21875,46 @@ const CoinleyCheckout = forwardRef(({
21657
21875
  }
21658
21876
  log("Transaction hash:", txHash);
21659
21877
  setTransactionHash(txHash);
21660
- log("Processing payment with backend...");
21661
- const processResponse = yield processPayment({
21662
- paymentId: payment.id,
21663
- transactionHash: txHash,
21664
- network: selectedPaymentMethod.network,
21665
- currency: selectedPaymentMethod.currency,
21666
- senderAddress: walletConnection == null ? void 0 : walletConnection.address
21667
- });
21668
- log("Payment processed successfully:", processResponse);
21669
- setPaymentStatus("success");
21670
- setStep("success");
21671
- if (onSuccess) {
21672
- log("Calling onSuccess callback...");
21673
- onSuccess(payment.id, txHash, {
21878
+ if (testMode) {
21879
+ processingTimerRef.current = setTimeout(() => {
21880
+ log("Test mode: Moving to success state");
21881
+ setPaymentStatus("success");
21882
+ setStep("success");
21883
+ if (onSuccess) {
21884
+ log("Calling onSuccess callback...");
21885
+ onSuccess(payment.id, txHash, {
21886
+ network: selectedPaymentMethod.network,
21887
+ currency: selectedPaymentMethod.currency,
21888
+ amount: payment.totalAmount || payment.amount
21889
+ });
21890
+ }
21891
+ }, 2e3);
21892
+ return;
21893
+ }
21894
+ try {
21895
+ log("Processing payment with backend...");
21896
+ const processResponse = yield processPayment({
21897
+ paymentId: payment.id,
21898
+ transactionHash: txHash,
21674
21899
  network: selectedPaymentMethod.network,
21675
21900
  currency: selectedPaymentMethod.currency,
21676
- amount: payment.totalAmount || payment.amount
21901
+ senderAddress: walletConnection == null ? void 0 : walletConnection.address,
21902
+ confirmations
21903
+ // Use specified confirmation level
21677
21904
  });
21905
+ log("Payment processed successfully:", processResponse);
21906
+ setPaymentStatus("success");
21907
+ setStep("success");
21908
+ if (onSuccess) {
21909
+ log("Calling onSuccess callback...");
21910
+ onSuccess(payment.id, txHash, {
21911
+ network: selectedPaymentMethod.network,
21912
+ currency: selectedPaymentMethod.currency,
21913
+ amount: payment.totalAmount || payment.amount
21914
+ });
21915
+ }
21916
+ } catch (processError) {
21917
+ log("Payment processing error, but transaction was sent:", processError);
21678
21918
  }
21679
21919
  } catch (err) {
21680
21920
  log("Payment error:", err);
@@ -21713,7 +21953,11 @@ const CoinleyCheckout = forwardRef(({
21713
21953
  supportedWallets: getSupportedWallets(),
21714
21954
  step,
21715
21955
  merchantWalletAddresses: actualMerchantWallets,
21716
- debug: effectiveDebug
21956
+ debug: effectiveDebug,
21957
+ processingStartTime,
21958
+ transactionDetected,
21959
+ paymentNetwork: selectedPaymentMethod == null ? void 0 : selectedPaymentMethod.network,
21960
+ onEarlySuccess: handleEarlySuccess
21717
21961
  }
21718
21962
  ) });
21719
21963
  });