From 718dda403e6467fffe9c14c4f58ef9598a2da173 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 26 Nov 2025 15:03:34 +1100 Subject: [PATCH] Revert "Add back blockonomics routes" --- .../Gateways/BlockonomicsController.php | 30 ++++- resources/js/clients/payments/blockonomics.js | 110 +++++++++--------- routes/api.php | 6 +- tests/cypress/support/routes.json | 11 +- 4 files changed, 87 insertions(+), 70 deletions(-) diff --git a/app/Http/Controllers/Gateways/BlockonomicsController.php b/app/Http/Controllers/Gateways/BlockonomicsController.php index d89fff82fc..b7d1cbb80f 100644 --- a/app/Http/Controllers/Gateways/BlockonomicsController.php +++ b/app/Http/Controllers/Gateways/BlockonomicsController.php @@ -13,8 +13,12 @@ namespace App\Http\Controllers\Gateways; use App\Http\Controllers\Controller; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Http; +use Illuminate\Http\Request; // Import the Request class +use Illuminate\Support\Facades\Http; // Import the Http facade +use BaconQrCode\Renderer\Image\SvgImageBackEnd; +use BaconQrCode\Renderer\ImageRenderer; +use BaconQrCode\Renderer\RendererStyle\RendererStyle; +use BaconQrCode\Writer; class BlockonomicsController extends Controller { @@ -29,4 +33,26 @@ class BlockonomicsController extends Controller return response()->json(['error' => 'Unable to fetch BTC price'], 500); } + + public function getQRCode(Request $request) + { + $qr_string = $request->query('qr_string'); + $svg = $this->getPaymentQrCodeRaw($qr_string); + return response($svg)->header('Content-Type', 'image/svg+xml'); + } + + private function getPaymentQrCodeRaw($qr_string) + { + + $renderer = new ImageRenderer( + new RendererStyle(150, margin: 0), + new SvgImageBackEnd() + ); + $writer = new Writer($renderer); + + $qr = $writer->writeString($qr_string, 'utf-8'); + + return $qr; + + } } diff --git a/resources/js/clients/payments/blockonomics.js b/resources/js/clients/payments/blockonomics.js index 6dab79f5d4..038b746b1e 100644 --- a/resources/js/clients/payments/blockonomics.js +++ b/resources/js/clients/payments/blockonomics.js @@ -13,15 +13,17 @@ import { wait, instant } from '../wait'; class Blockonomics { constructor() { + // Bind the method to the instance this.copyToClipboard = this.copyToClipboard.bind(this); this.refreshBTCPrice = this.refreshBTCPrice.bind(this); this.fetchAndDisplayQRCode = this.fetchAndDisplayQRCode.bind(this); this.startTimer = this.startTimer.bind(this); } - copyToClipboard(elementId, passedElement, shouldGrabNextElementSibling) { + copyToClipboard(elementId, passedElement, shouldGrabNextElementSibling) { + const element = shouldGrabNextElementSibling ? passedElement.nextElementSibling : passedElement; - const originalIcon = element.src; + const originalIcon = element.src; // Store the original icon const tempInput = document.createElement("input"); const elementWithId = document.getElementById(elementId); @@ -35,64 +37,51 @@ class Blockonomics { document.body.removeChild(tempInput); element.src = 'data:image/svg+xml;base64,' + btoa(` - - - - - `); + + + + + `); + // Change the icon back to the original after 5 seconds setTimeout(() => { element.src = originalIcon; }, 5000); } - async loadQRCodeScript() { - if (window.QRCode) return; // already loaded - return new Promise((resolve, reject) => { - const script = document.createElement('script'); - script.src = "https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"; - script.onload = resolve; - script.onerror = reject; - document.head.appendChild(script); - }); - } - - async fetchAndDisplayQRCode(newBtcAmount = null) { + async fetchAndDisplayQRCode (newBtcAmount = null) { try { - await this.loadQRCodeScript(); - const btcAddress = document.querySelector('meta[name="btc_address"]').content; - const btcAmount = newBtcAmount || document.querySelector('meta[name="btc_amount"]').content; - const qrString = `bitcoin:${btcAddress}?amount=${btcAmount}`; - - document.getElementById('qrcode-container').innerHTML = ""; - - new QRCode(document.getElementById("qrcode-container"), { - text: qrString, - width: 150, - height: 150, - correctLevel: QRCode.CorrectLevel.H - }); + const btcAmount = newBtcAmount || '{{$btc_amount}}'; + const qrString = encodeURIComponent(`bitcoin:${btcAddress}?amount=${btcAmount}`); + const response = await fetch(`/api/v1/get-blockonomics-qr-code?qr_string=${qrString}`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const svgText = await response.text(); + document.getElementById('qrcode-container').innerHTML = svgText; } catch (error) { - console.error('Error generating QR code:', error); + console.error('Error fetching QR code:', error); document.getElementById('qrcode-container').textContent = 'Error loading QR code'; } - } + }; startTimer = (seconds) => { const countDownDate = new Date().getTime() + seconds * 1000; - document.getElementById("countdown").innerHTML = "10:00 min"; + document.getElementById("countdown").innerHTML = "10" + ":" + "00" + " min"; const updateCountdown = () => { const now = new Date().getTime(); const distance = countDownDate - now; const isRefreshing = document.getElementsByClassName("btc-value")[0].innerHTML.includes("Refreshing"); - if (isRefreshing) return; + if (isRefreshing) { + return; + } if (distance < 0) { - this.refreshBTCPrice(); + refreshBTCPrice(); return; } @@ -100,13 +89,14 @@ class Blockonomics { const seconds = Math.floor((distance % (1000 * 60)) / 1000); const formattedMinutes = String(minutes).padStart(2, '0'); const formattedSeconds = String(seconds).padStart(2, '0'); - document.getElementById("countdown").innerHTML = `${formattedMinutes}:${formattedSeconds} min`; - }; + document.getElementById("countdown").innerHTML = formattedMinutes + ":" + formattedSeconds + " min"; + } clearInterval(window.countdownInterval); window.countdownInterval = setInterval(updateCountdown, 1000); } + async refreshBTCPrice() { const refreshIcon = document.querySelector('.icon-refresh'); refreshIcon.classList.add('rotating'); @@ -116,41 +106,48 @@ class Blockonomics { try { const currency = document.querySelector('meta[name="currency"]').content; const response = await fetch(`/api/v1/get-btc-price?currency=${currency}`); // New endpoint to call server-side function - - if (!response.ok) throw new Error('Network response was not ok'); + if (!response.ok) { + throw new Error('Network response was not ok'); + } const data = await response.json(); - console.log("BTC price data:", data); return data.price; } catch (error) { console.error('There was a problem with the BTC price fetch operation:', error); - return null; + // Handle error appropriately } - }; + } try { const newPrice = await getBTCPrice(); if (newPrice) { + // Update the text content of the countdown span to the new bitcoin price const currency = document.querySelector('meta[name="currency"]').content; - document.getElementsByClassName("btc-value")[0].innerHTML = - `1 BTC = ${newPrice || "N/A"} ${currency}, updates in `; + document.getElementsByClassName("btc-value")[0].innerHTML = "1 BTC = " + (newPrice || "N/A") + " " + currency + ", updates in "; const newBtcAmount = (document.querySelector('meta[name="amount"]').content / newPrice).toFixed(10); + // set the value of the input field and the text content of the span to the new bitcoin amount document.querySelector('input[name="btc_price"]').value = newPrice; document.querySelector('input[name="btc_amount"]').value = newBtcAmount; document.getElementById('btc-amount').textContent = newBtcAmount; const btcAddress = document.querySelector('meta[name="btc_address"]').content; - document.getElementById('qr-code-link').href = `bitcoin:${btcAddress}?amount=${newBtcAmount}`; - document.getElementById('open-in-wallet-link').href = `bitcoin:${btcAddress}?amount=${newBtcAmount}`; + // set the href attribute of the link to the new bitcoin amount + const qrCodeLink = document.getElementById('qr-code-link'); + const openInWalletLink = document.getElementById('open-in-wallet-link'); + qrCodeLink.href = `bitcoin:${btcAddress}?amount=${newBtcAmount}`; + openInWalletLink.href = `bitcoin:${btcAddress}?amount=${newBtcAmount}`; + + // fetch and display the new QR code await this.fetchAndDisplayQRCode(newBtcAmount); - this.startTimer(600); + this.startTimer(600); // Restart timer for 10 minutes (600 seconds) } } finally { refreshIcon.classList.remove('rotating'); } } + handle() { window.copyToClipboard = this.copyToClipboard; window.refreshBTCPrice = this.refreshBTCPrice; @@ -166,20 +163,25 @@ class Blockonomics { const data = JSON.parse(event.data); const { status, txid, value } = data || {}; console.log('Payment status:', status); - if ([0, 1, 2].includes(status)) { + const isPaymentUnconfirmed = status === 0; + const isPaymentPartiallyConfirmed = status === 1; + const isPaymentConfirmed = status === 2; + // Confirmation status: 0 = unconfirmed, 1 = partially confirmed, 2 = confirmed + // If any of the statuses are true, submit the form and redirect + if (isPaymentUnconfirmed || isPaymentPartiallyConfirmed || isPaymentConfirmed) { document.querySelector('input[name="txid"]').value = txid || ''; document.querySelector('input[name="status"]').value = status || ''; document.querySelector('input[name="btc_amount"]').value = value || ''; document.querySelector('input[name="btc_address"]').value = btcAddress || ''; document.getElementById('server-response').submit(); } - }; + } }; - - this.startTimer(600); + startTimer(600); // Start timer for 10 minutes (600 seconds) connectToWebsocket(); - this.fetchAndDisplayQRCode(); + fetchAndDisplayQRCode(); } + } function boot() { diff --git a/routes/api.php b/routes/api.php index 5dac37302e..a2204d6375 100644 --- a/routes/api.php +++ b/routes/api.php @@ -76,7 +76,7 @@ use App\Http\Controllers\CompanyLedgerController; use App\Http\Controllers\EInvoiceTokenController; use App\Http\Controllers\PurchaseOrderController; use App\Http\Controllers\TaskSchedulerController; -use App\Http\Controllers\Gateways\BlockonomicsController; +use App\PaymentDrivers\BlockonomicsPaymentDriver; use App\Http\Controllers\CompanyGatewayController; use App\Http\Controllers\EInvoicePeppolController; use App\Http\Controllers\PaymentWebhookController; @@ -502,8 +502,6 @@ Route::post('api/v1/yodlee/balance', [YodleeController::class, 'balanceWebhook'] Route::get('api/v1/protected_download/{hash}', [ProtectedDownloadController::class, 'index'])->name('protected_download')->middleware('throttle:300,1'); Route::post('api/v1/ppcp/webhook', [PayPalPPCPPaymentDriver::class, 'processWebhookRequest'])->middleware('throttle:1000,1'); -Route::get('api/v1/get-btc-price', [BlockonomicsController::class, 'getBTCPrice'])->middleware('throttle:100,1'); - Route::get('quickbooks/authorize/{token}', [ImportQuickbooksController::class, 'authorizeQuickbooks'])->name('quickbooks.authorize'); Route::get('quickbooks/authorized', [ImportQuickbooksController::class, 'onAuthorized'])->name('quickbooks.authorized'); @@ -514,4 +512,4 @@ Route::get('/health', function () { 'status' => 'ok', 'message' => 'API is healthy', ]); -})->middleware('throttle:20,1'); +})->middleware('throttle:20,1'); \ No newline at end of file diff --git a/tests/cypress/support/routes.json b/tests/cypress/support/routes.json index 41fce16ce0..b8b5c8b622 100644 --- a/tests/cypress/support/routes.json +++ b/tests/cypress/support/routes.json @@ -5622,14 +5622,5 @@ "GET", "HEAD" ] - }, - "generated::Xy7ZkLm8NpQ4Rt5V": { - "name": "generated::Xy7ZkLm8NpQ4Rt5V", - "domain": null, - "action": "App\\Http\\Controllers\\BlockonomicsController@getBTCPrice", - "uri": "api/v1/get-btc-price", - "method": [ - "GET" - ] } -} +} \ No newline at end of file