diff --git a/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php b/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php index 548ced05e1..5642a0e861 100644 --- a/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php +++ b/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php @@ -138,7 +138,7 @@ class AuthorizeCreditCard implements LivewireMethodInterface { $client_gateway_token = ClientGatewayToken::query() ->where('id', $this->decodePrimaryKey($request->token)) - ->where('company_id', auth()->guard('contact')->user()->client->company->id) + ->where('company_id', auth()->guard('contact')->user()->client->company_id) ->first(); if (! $client_gateway_token) { diff --git a/app/PaymentDrivers/PayFast/CreditCard.php b/app/PaymentDrivers/PayFast/CreditCard.php index 468f7d8352..adaa2e4e72 100644 --- a/app/PaymentDrivers/PayFast/CreditCard.php +++ b/app/PaymentDrivers/PayFast/CreditCard.php @@ -195,6 +195,11 @@ class CreditCard implements LivewireMethodInterface */ public function paymentResponse(Request $request) { + + if($request->token){ + return $this->processTokenPayment($request->token, $request->payment_hash); + } + $response_array = $request->all(); nlog($request->all()); @@ -216,6 +221,27 @@ class CreditCard implements LivewireMethodInterface } } + + private function processTokenPayment(string $token, string $payment_hash) + { + + $client_gateway_token = \App\Models\ClientGatewayToken::query() + ->where('token', $token) + ->where('company_id', auth()->guard('contact')->user()->client->company_id) + ->first(); + + if (! $client_gateway_token) { + throw new \App\Exceptions\PaymentFailed(ctrans('texts.payment_token_not_found'), 401); + } + + $payment_hash = \App\Models\PaymentHash::with('fee_invoice')->where('hash', $payment_hash)->firstOrFail(); + + $payment = $this->payfast->tokenBilling($client_gateway_token, $payment_hash); + + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + + } + private function processSuccessfulPayment($response_array) { $payment_record = []; diff --git a/app/PaymentDrivers/PayFast/PaymentCompletedWebhook.php b/app/PaymentDrivers/PayFast/PaymentCompletedWebhook.php new file mode 100644 index 0000000000..b9da5f752f --- /dev/null +++ b/app/PaymentDrivers/PayFast/PaymentCompletedWebhook.php @@ -0,0 +1,95 @@ + 'aobgUGfYHQXCdFdXYyfXiEolPOOYIdbb', +// 'pf_payment_id' => '2579', +// 'payment_status' => 'COMPLETE', +// 'item_name' => 'Invoices: ["0081"]', +// 'item_description' => 'Credit Card Pre Authorization', +// 'amount_gross' => '1481.55', +// 'amount_fee' => '-68.75', +// 'amount_net' => '1412.80', +// 'custom_str1' => NULL, +// 'custom_str2' => NULL, +// 'custom_str3' => NULL, +// 'custom_str4' => NULL, +// 'custom_str5' => NULL, +// 'custom_int1' => NULL, +// 'custom_int2' => NULL, +// 'custom_int3' => NULL, +// 'custom_int4' => NULL, +// 'custom_int5' => NULL, +// 'name_first' => NULL, +// 'name_last' => NULL, +// 'email_address' => NULL, +// 'merchant_id' => '10023100', +// 'token' => '8e1bf463-0c75-4f9c-836b-9bd02de14fc4', +// 'billing_date' => '2025-06-16', +// 'signature' => 'acfddcf33967679bcc743532dfef9a89', +// 'q' => '/payment_notification_webhook/M2zB4QN6EabKLGV319vzqXFy0J2Xvxer/4w9aAOdvMR/7LDdwRb1YK', + + public function handle() + { + nlog("PaymentCompletedWebhook"); + nlog(now()->format('Y-m-d H:i:s')); + MultiDB::findAndSetDbByCompanyKey($this->company_key); + + $company = Company::query()->where('company_key', $this->company_key)->first(); + + $p = Payment::query() + ->where('company_id', $company->id) + ->where('transaction_reference', $this->data['pf_payment_id']) + ->first(); + + if($p){ + nlog("payment found returning"); + return; + } + + nlog("yolo"); + $payment_hash = PaymentHash::where('hash', $this->data['m_payment_id'])->first(); + + $company_gateway = CompanyGateway::query()->where('company_id', $company->id)->where('id', $this->company_gateway_id)->first(); + $driver = $company_gateway->driver($payment_hash->fee_invoice->client)->init(); + $driver->setPaymentHash($payment_hash); + + $payment_record = []; + $payment_record['amount'] = $this->data['amount_gross']; + $payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER; + $payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD; + $payment_record['transaction_reference'] = $this->data['pf_payment_id']; + $payment_record['idempotency_key'] = $this->data['pf_payment_id'].$payment_hash->hash; + + $payment = $driver->createPayment($payment_record, Payment::STATUS_COMPLETED); + + } +} \ No newline at end of file diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index e90df744fc..830fa9d90b 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -12,10 +12,15 @@ namespace App\PaymentDrivers\PayFast; -use App\Models\ClientGatewayToken; +use App\Models\Payment; +use App\Models\SystemLog; +use App\Models\GatewayType; use App\Models\PaymentHash; +use App\Models\PaymentType; +use App\Jobs\Util\SystemLogger; +use App\Exceptions\PaymentFailed; +use App\Models\ClientGatewayToken; use App\PaymentDrivers\PayFastPaymentDriver; -use GuzzleHttp\RequestOptions; class Token { @@ -29,98 +34,93 @@ class Token public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) { $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total; - $amount = round(($amount * pow(10, $this->payfast->client->currency()->precision)), 0); - - $header = [ - 'merchant-id' => $this->payfast->company_gateway->getConfigField('merchantId'), - 'version' => 'v1', - 'timestamp' => now()->format('c'), - ]; - - $body = [ - 'amount' => $amount, - 'item_name' => 'purchase', - 'item_description' => ctrans('texts.invoices').': '.collect($payment_hash->invoices())->pluck('invoice_number'), - 'm_payment_id' => $payment_hash->hash, - ]; - - $header['signature'] = $this->payfast->generateTokenSignature(array_merge($body, $header)); - - // nlog($header['signature']); - - $result = $this->send($header, $body, $cgt->token); - } - - protected function generate_parameter_string($api_data, $sort_data_before_merge = true, $skip_empty_values = true) - { - // if sorting is required the passphrase should be added in before sort. - if (! empty($this->payfast->company_gateway->getConfigField('passphrase')) && $sort_data_before_merge) { - $api_data['passphrase'] = $this->payfast->company_gateway->getConfigField('passphrase'); - } - - if ($sort_data_before_merge) { - ksort($api_data); - } - - // concatenate the array key value pairs. - $parameter_string = ''; - foreach ($api_data as $key => $val) { - if ($skip_empty_values && empty($val)) { - continue; - } - - if ('signature' !== $key) { - $val = urlencode($val); - $parameter_string .= "$key=$val&"; - } - } - // when not sorting passphrase should be added to the end before md5 - if ($sort_data_before_merge) { - $parameter_string = rtrim($parameter_string, '&'); - } elseif (! empty($this->pass_phrase)) { - $parameter_string .= 'passphrase='.urlencode($this->payfast->company_gateway->getConfigField('passphrase')); - } else { - $parameter_string = rtrim($parameter_string, '&'); - } - - // nlog($parameter_string); - - return $parameter_string; - } - - private function genSig($data) - { - $fields = []; - - ksort($data); - - foreach ($data as $key => $value) { - if (! empty($data[$key])) { - $fields[$key] = $data[$key]; - } - } - - nlog(http_build_query($fields)); - - return md5(http_build_query($fields)); - } - - private function send($headers, $body, $token) - { - $client = new \GuzzleHttp\Client( - [ - 'headers' => $headers, - ] - ); + $amount = (int)round(($amount * pow(10, $this->payfast->client->currency()->precision)), 0); try { - $response = $client->post("https://api.payfast.co.za/subscriptions/{$token}/adhoc?testing=true", [ - RequestOptions::JSON => ['body' => $body], RequestOptions::ALLOW_REDIRECTS => false, - ]); + $payfast = new \PayFast\PayFastApi( + [ + 'merchantId' => (string)$this->payfast->company_gateway->getConfigField('merchantId'), + 'merchantKey' => $this->payfast->company_gateway->getConfigField('merchantKey'), + 'passPhrase' => $this->payfast->company_gateway->getConfigField('passphrase'), + 'testMode' => $this->payfast->company_gateway->getConfigField('testMode') + ] + ); - return json_decode($response->getBody(), true); - } catch (\Exception $e) { - nlog($e->getMessage()); + $data = [ + 'amount' => $amount, + 'item_name' => ctrans('texts.invoices').': '.collect($payment_hash->invoices())->pluck('invoice_number'), + 'm_payment_id' => $payment_hash->hash, + ]; + + $response = $payfast->subscriptions->adhoc($cgt->token, $data); + + nlog("TokenBilling"); + nlog($response); + nlog(now()->format('Y-m-d H:i:s')); + + if($response['code'] == 200 && $response['status'] == 'success') { + return $this->processSuccessfulPayment($response); + } + + return $this->processUnsuccessfulPayment($response, $payment_hash); + + } catch (Exception $e) { + echo 'There was an exception: '.$e->getMessage(); + return $this->processUnsuccessfulPayment($e->getMessage()); } + } + +// Array +// ( +// [code] => 200 +// [status] => success +// [data] => Array +// ( +// [response] => true +// [message] => Transaction was successful (00) +// [pf_payment_id] => 2577761 +// ) + +// ) + + private function processSuccessfulPayment(array $response) + { + + $payment_record = []; + $payment_record['amount'] = array_sum(array_column($this->payfast->payment_hash->invoices(), 'amount')) + $this->payfast->payment_hash->fee_total; + $payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER; + $payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD; + $payment_record['transaction_reference'] = $response['data']['pf_payment_id']; + $payment_record['idempotency_key'] = $response['data']['pf_payment_id'].$this->payfast->payment_hash->hash; + $payment = $this->payfast->createPayment($payment_record, Payment::STATUS_COMPLETED); + + return $payment; + } + + private function processUnsuccessfulPayment($response) + { + $error_message = $response['data']['message']; + $error_code = $response['code']; + + $this->payfast->sendFailureMail($error_message); + + $message = [ + 'server_response' => $response, + 'data' => $this->payfast->payment_hash->data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_PAYFAST, + $this->payfast->client, + $this->payfast->client->company, + ); + + throw new PaymentFailed('Failed to process the payment.', 500); + + } + } diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index 67c804afd9..d6c1f57738 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -12,16 +12,18 @@ namespace App\PaymentDrivers; -use App\Models\ClientGatewayToken; -use App\Models\GatewayType; use App\Models\Payment; -use App\Models\PaymentHash; use App\Models\SystemLog; -use App\PaymentDrivers\PayFast\CreditCard; -use App\PaymentDrivers\PayFast\Token; -use App\Utils\Traits\MakesHash; +use App\Models\GatewayType; +use App\Models\PaymentHash; use Illuminate\Http\Request; +use App\Utils\Traits\MakesHash; +use App\Models\ClientGatewayToken; +use App\PaymentDrivers\PayFast\Token; use Illuminate\Support\Facades\Cache; +use App\PaymentDrivers\PayFast\CreditCard; +use App\PaymentDrivers\PayFast\PaymentCompletedWebhook; +use App\Http\Requests\Payments\PaymentNotificationWebhookRequest; class PayFastPaymentDriver extends BaseDriver { @@ -69,19 +71,6 @@ class PayFastPaymentDriver extends BaseDriver public function init() { - // try { - // $this->payfast = new \Payfast\PayFastPayment( - // [ - // 'merchantId' => $this->company_gateway->getConfigField('merchantId'), - // 'merchantKey' => $this->company_gateway->getConfigField('merchantKey'), - // 'passPhrase' => $this->company_gateway->getConfigField('passphrase'), - // 'testMode' => $this->company_gateway->getConfigField('testMode'), - // ] - // ); - // } catch (\Exception $e) { - // nlog('##PAYFAST## There was an exception: '.$e->getMessage()); - // } - return $this; } @@ -196,12 +185,17 @@ class PayFastPaymentDriver extends BaseDriver return md5(http_build_query($fields)); } - public function processWebhookRequest(Request $request, Payment $payment = null) + public function processWebhookRequest(PaymentNotificationWebhookRequest $request, Payment $payment = null) { $data = $request->all(); // nlog("payfast"); // nlog($data); + if(array_key_exists('pf_payment_id', $data) && strlen($data['pf_payment_id']) > 1) { + PaymentCompletedWebhook::dispatch($data, $request->company_key, $this->company_gateway->id)->delay(10); + return; + } + if (array_key_exists('m_payment_id', $data)) { $hash = Cache::get($data['m_payment_id']); @@ -215,13 +209,13 @@ class PayFastPaymentDriver extends BaseDriver default: - $payment_hash = PaymentHash::where('hash', $data['m_payment_id'])->first(); + $payment_hash = PaymentHash::where('hash', $data['m_payment_id'])->first(); - $this->setPaymentMethod(GatewayType::CREDIT_CARD) - ->setPaymentHash($payment_hash) - ->processPaymentResponse($request); + $this->setPaymentMethod(GatewayType::CREDIT_CARD) + ->setPaymentHash($payment_hash) + ->processPaymentResponse($request); - return response()->json([], 200); + return response()->json([], 200); } } diff --git a/composer.json b/composer.json index 17a06e6b32..78f19d4db9 100644 --- a/composer.json +++ b/composer.json @@ -66,6 +66,7 @@ "hyvor/php-json-exporter": "^0.0.3", "imdhemy/laravel-purchases": "^1.7", "intervention/image": "^2.5", + "invoiceninja/admin-api": "dev-main", "invoiceninja/einvoice": "dev-main", "invoiceninja/inspector": "^3.0", "invoiceninja/ubl_invoice": "^2", @@ -89,6 +90,7 @@ "nelexa/zip": "^4.0", "nordigen/nordigen-php": "^1.1", "nwidart/laravel-modules": "^11.0", + "payfast/payfast-php-sdk": "^1.1", "phpoffice/phpspreadsheet": "^2.2", "pragmarx/google2fa": "^8.0", "predis/predis": "^2", diff --git a/composer.lock b/composer.lock index 0ea65d20c5..7416685575 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4361272676d998d08fb1926198065b39", + "content-hash": "afc109ee881bc826259c15922048972d", "packages": [ { "name": "adrienrn/php-mimetyper", @@ -4667,6 +4667,65 @@ ], "time": "2022-05-21T17:30:32+00:00" }, + { + "name": "invoiceninja/admin-api", + "version": "dev-main", + "dist": { + "type": "path", + "url": "../admin-api", + "reference": "4d95a2318a4dc41cdea95793d85ffe5589ed9117" + }, + "require": { + "afosto/yaac": "^1.5", + "asm/php-ansible": "dev-main", + "ext-curl": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*", + "illuminate/database": "^11", + "illuminate/support": "^11", + "imdhemy/laravel-purchases": "^1.7", + "php": "^8.2|^8.3|^8.4" + }, + "require-dev": { + "larastan/larastan": "^3.0", + "orchestra/testbench": "^9.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "InvoiceNinja\\AdminApi\\Providers\\AdminApiServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "InvoiceNinja\\AdminApi\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "InvoiceNinja\\AdminApi\\Tests\\": "tests/" + } + }, + "license": [ + "Elastic" + ], + "authors": [ + { + "name": "David Bomba", + "email": "turbo124@gmail.com" + } + ], + "description": "API endpoints for the admin interface", + "transport-options": { + "relative": true + } + }, { "name": "invoiceninja/einvoice", "version": "dev-main", @@ -9088,6 +9147,59 @@ }, "time": "2024-09-04T12:51:01+00:00" }, + { + "name": "payfast/payfast-php-sdk", + "version": "v1.1.6", + "source": { + "type": "git", + "url": "https://github.com/Payfast/payfast-php-sdk.git", + "reference": "015efcd2df3e580e023dae6e16c943328d38bb78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Payfast/payfast-php-sdk/zipball/015efcd2df3e580e023dae6e16c943328d38bb78", + "reference": "015efcd2df3e580e023dae6e16c943328d38bb78", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": ">=6.0.0", + "php": ">=8.1" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "PayFast\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Payfast", + "email": "support@payfast.help" + } + ], + "description": "Payfast PHP Library", + "keywords": [ + "api", + "onsite", + "payfast", + "php" + ], + "support": { + "issues": "https://github.com/Payfast/payfast-php-sdk/issues", + "source": "https://github.com/Payfast/payfast-php-sdk/tree/v1.1.6" + }, + "time": "2024-02-28T09:54:10+00:00" + }, { "name": "php-http/client-common", "version": "2.7.2", @@ -9883,16 +9995,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.43", + "version": "3.0.44", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "709ec107af3cb2f385b9617be72af8cf62441d02" + "reference": "1d0b5e7e1434678411787c5a0535e68907cf82d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/709ec107af3cb2f385b9617be72af8cf62441d02", - "reference": "709ec107af3cb2f385b9617be72af8cf62441d02", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/1d0b5e7e1434678411787c5a0535e68907cf82d9", + "reference": "1d0b5e7e1434678411787c5a0535e68907cf82d9", "shasum": "" }, "require": { @@ -9973,7 +10085,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.43" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.44" }, "funding": [ { @@ -9989,7 +10101,7 @@ "type": "tidelift" } ], - "time": "2024-12-14T21:12:59+00:00" + "time": "2025-06-15T09:59:26+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -21396,6 +21508,7 @@ "asm/php-ansible": 20, "beganovich/snappdf": 20, "horstoeko/orderx": 20, + "invoiceninja/admin-api": 20, "invoiceninja/einvoice": 20, "socialiteproviders/apple": 20 }, diff --git a/public/build/assets/blockonomics-56ba6746.js b/public/build/assets/blockonomics-56ba6746.js deleted file mode 100644 index c7b6db67fe..0000000000 --- a/public/build/assets/blockonomics-56ba6746.js +++ /dev/null @@ -1,14 +0,0 @@ -var h=Object.defineProperty;var w=(a,e,n)=>e in a?h(a,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[e]=n;var u=(a,e,n)=>(w(a,typeof e!="symbol"?e+"":e,n),n);import{i as y,w as p}from"./wait-8f4ae121.js";/** - * Invoice Ninja (https://invoiceninja.com). - * - * @link https://github.com/invoiceninja/invoiceninja source repository - * - * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) - * - * @license https://www.elastic.co/licensing/elastic-license - */class b{constructor(){u(this,"startTimer",e=>{const n=new Date().getTime()+e*1e3;document.getElementById("countdown").innerHTML="10:00 min";const c=()=>{const r=new Date().getTime(),t=n-r;if(document.getElementsByClassName("btc-value")[0].innerHTML.includes("Refreshing"))return;if(t<0){refreshBTCPrice();return}const s=Math.floor(t%(1e3*60*60)/(1e3*60)),i=Math.floor(t%(1e3*60)/1e3),d=String(s).padStart(2,"0"),m=String(i).padStart(2,"0");document.getElementById("countdown").innerHTML=d+":"+m+" min"};clearInterval(window.countdownInterval),window.countdownInterval=setInterval(c,1e3)});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(e,n,c){const r=c?n.nextElementSibling:n,t=r.src,o=document.createElement("input"),s=document.getElementById(e),{value:i,innerText:d}=s||{},m=i||d;o.value=m,document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o),r.src="data:image/svg+xml;base64,"+btoa(` - - `),setTimeout(()=>{r.src=t},5e3)}async fetchAndDisplayQRCode(e=null){try{const n=document.querySelector('meta[name="btc_address"]').content,r=encodeURIComponent(`bitcoin:${n}?amount=${e||"{{$btc_amount}}"}`),t=await fetch(`/api/v1/get-blockonomics-qr-code?qr_string=${r}`);if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const o=await t.text();document.getElementById("qrcode-container").innerHTML=o}catch(n){console.error("Error fetching QR code:",n),document.getElementById("qrcode-container").textContent="Error loading QR code"}}async refreshBTCPrice(){const e=document.querySelector(".icon-refresh");e.classList.add("rotating"),document.getElementsByClassName("btc-value")[0].innerHTML="Refreshing...";const n=async()=>{try{const c=document.querySelector('meta[name="currency"]').content,r=await fetch(`/api/v1/get-btc-price?currency=${c}`);if(!r.ok)throw new Error("Network response was not ok");return(await r.json()).price}catch(c){console.error("There was a problem with the BTC price fetch operation:",c)}};try{const c=await n();if(c){const r=document.querySelector('meta[name="currency"]').content;document.getElementsByClassName("btc-value")[0].innerHTML="1 BTC = "+(c||"N/A")+" "+r+", updates in ";const t=(document.querySelector('meta[name="amount"]').content/c).toFixed(10);document.querySelector('input[name="btc_price"]').value=c,document.querySelector('input[name="btc_amount"]').value=t,document.getElementById("btc-amount").textContent=t;const o=document.querySelector('meta[name="btc_address"]').content,s=document.getElementById("qr-code-link"),i=document.getElementById("open-in-wallet-link");s.href=`bitcoin:${o}?amount=${t}`,i.href=`bitcoin:${o}?amount=${t}`,await this.fetchAndDisplayQRCode(t),this.startTimer(600)}}finally{e.classList.remove("rotating")}}handle(){window.copyToClipboard=this.copyToClipboard,window.refreshBTCPrice=this.refreshBTCPrice,window.fetchAndDisplayQRCode=this.fetchAndDisplayQRCode,window.startTimer=this.startTimer;const e=()=>{const c=`wss://www.blockonomics.co/payment/${document.querySelector('meta[name="btc_address"]').content}`,r=new WebSocket(c);r.onmessage=function(t){const o=JSON.parse(t.data);console.log("Payment status:",o.status);const s=o.status===0,i=o.status===1,d=o.status===2;(s||i||d)&&(document.querySelector('input[name="txid"]').value=o.txid||"",document.getElementById("server-response").submit())}};startTimer(600),e(),fetchAndDisplayQRCode()}}function l(){new b().handle(),window.bootBlockonomics=l}y()?l():p("#blockonomics-payment").then(()=>l()); diff --git a/public/build/assets/blockonomics-c3966bec.js b/public/build/assets/blockonomics-c3966bec.js new file mode 100644 index 0000000000..96863b34cf --- /dev/null +++ b/public/build/assets/blockonomics-c3966bec.js @@ -0,0 +1,14 @@ +var h=Object.defineProperty;var y=(a,t,e)=>t in a?h(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var l=(a,t,e)=>(y(a,typeof t!="symbol"?t+"":t,e),e);import{i as w,w as p}from"./wait-8f4ae121.js";/** + * Invoice Ninja (https://invoiceninja.com). + * + * @link https://github.com/invoiceninja/invoiceninja source repository + * + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) + * + * @license https://www.elastic.co/licensing/elastic-license + */class f{constructor(){l(this,"startTimer",t=>{const e=new Date().getTime()+t*1e3;document.getElementById("countdown").innerHTML="10:00 min";const o=()=>{const c=new Date().getTime(),n=e-c;if(document.getElementsByClassName("btc-value")[0].innerHTML.includes("Refreshing"))return;if(n<0){refreshBTCPrice();return}const s=Math.floor(n%(1e3*60*60)/(1e3*60)),i=Math.floor(n%(1e3*60)/1e3),d=String(s).padStart(2,"0"),m=String(i).padStart(2,"0");document.getElementById("countdown").innerHTML=d+":"+m+" min"};clearInterval(window.countdownInterval),window.countdownInterval=setInterval(o,1e3)});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(t,e,o){const c=o?e.nextElementSibling:e,n=c.src,r=document.createElement("input"),s=document.getElementById(t),{value:i,innerText:d}=s||{},m=i||d;r.value=m,document.body.appendChild(r),r.select(),document.execCommand("copy"),document.body.removeChild(r),c.src="data:image/svg+xml;base64,"+btoa(` + + `),setTimeout(()=>{c.src=n},5e3)}async fetchAndDisplayQRCode(t=null){try{const e=document.querySelector('meta[name="btc_address"]').content,c=encodeURIComponent(`bitcoin:${e}?amount=${t||"{{$btc_amount}}"}`),n=await fetch(`/api/v1/get-blockonomics-qr-code?qr_string=${c}`);if(!n.ok)throw new Error(`HTTP error! status: ${n.status}`);const r=await n.text();document.getElementById("qrcode-container").innerHTML=r}catch(e){console.error("Error fetching QR code:",e),document.getElementById("qrcode-container").textContent="Error loading QR code"}}async refreshBTCPrice(){const t=document.querySelector(".icon-refresh");t.classList.add("rotating"),document.getElementsByClassName("btc-value")[0].innerHTML="Refreshing...";const e=async()=>{try{const o=document.querySelector('meta[name="currency"]').content,c=await fetch(`/api/v1/get-btc-price?currency=${o}`);if(!c.ok)throw new Error("Network response was not ok");return(await c.json()).price}catch(o){console.error("There was a problem with the BTC price fetch operation:",o)}};try{const o=await e();if(o){const c=document.querySelector('meta[name="currency"]').content;document.getElementsByClassName("btc-value")[0].innerHTML="1 BTC = "+(o||"N/A")+" "+c+", updates in ";const n=(document.querySelector('meta[name="amount"]').content/o).toFixed(10);document.querySelector('input[name="btc_price"]').value=o,document.querySelector('input[name="btc_amount"]').value=n,document.getElementById("btc-amount").textContent=n;const r=document.querySelector('meta[name="btc_address"]').content,s=document.getElementById("qr-code-link"),i=document.getElementById("open-in-wallet-link");s.href=`bitcoin:${r}?amount=${n}`,i.href=`bitcoin:${r}?amount=${n}`,await this.fetchAndDisplayQRCode(n),this.startTimer(600)}}finally{t.classList.remove("rotating")}}handle(){window.copyToClipboard=this.copyToClipboard,window.refreshBTCPrice=this.refreshBTCPrice,window.fetchAndDisplayQRCode=this.fetchAndDisplayQRCode,window.startTimer=this.startTimer;const t=()=>{const e=document.querySelector('meta[name="btc_address"]').content,o=`wss://www.blockonomics.co/payment/${e}`,c=new WebSocket(o);c.onmessage=function(n){const r=JSON.parse(n.data),{status:s,txid:i,value:d}=r||{};console.log("Payment status:",s),(s===0||s===1||s===2)&&(document.querySelector('input[name="txid"]').value=i||"",document.querySelector('input[name="status"]').value=s||"",document.querySelector('input[name="btc_amount"]').value=d||"",document.querySelector('input[name="btc_address"]').value=e||"",document.getElementById("server-response").submit())}};startTimer(600),t(),fetchAndDisplayQRCode()}}function u(){new f().handle(),window.bootBlockonomics=u}w()?u():p("#blockonomics-payment").then(()=>u()); diff --git a/public/build/manifest.json b/public/build/manifest.json index 252fc547dc..1e9f0be7d0 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -99,7 +99,7 @@ "src": "resources/js/clients/payments/authorize-credit-card-payment.js" }, "resources/js/clients/payments/blockonomics.js": { - "file": "assets/blockonomics-56ba6746.js", + "file": "assets/blockonomics-c3966bec.js", "imports": [ "_wait-8f4ae121.js" ], diff --git a/resources/views/portal/ninja2020/gateways/payfast/pay.blade.php b/resources/views/portal/ninja2020/gateways/payfast/pay.blade.php index 73c4089327..3015b37cbc 100644 --- a/resources/views/portal/ninja2020/gateways/payfast/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/payfast/pay.blade.php @@ -8,6 +8,7 @@ @section('gateway_content')