Merge pull request #10975 from cnohall/improve-blockonomics-callback-logic
Improve blockonomics callback logic
This commit is contained in:
commit
f5dc292ef5
|
|
@ -29,6 +29,7 @@ use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||||
class Blockonomics implements LivewireMethodInterface
|
class Blockonomics implements LivewireMethodInterface
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
private string $test_txid = 'WarningThisIsAGeneratedTestPaymentAndNotARealBitcoinTransaction';
|
||||||
|
|
||||||
public function __construct(public BlockonomicsPaymentDriver $blockonomics)
|
public function __construct(public BlockonomicsPaymentDriver $blockonomics)
|
||||||
{
|
{
|
||||||
|
|
@ -124,6 +125,7 @@ class Blockonomics implements LivewireMethodInterface
|
||||||
return render('gateways.blockonomics.pay', $data);
|
return render('gateways.blockonomics.pay', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function paymentResponse(PaymentResponseRequest $request)
|
public function paymentResponse(PaymentResponseRequest $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
|
|
@ -132,20 +134,50 @@ class Blockonomics implements LivewireMethodInterface
|
||||||
'currency' => ['required'],
|
'currency' => ['required'],
|
||||||
'txid' => ['required'],
|
'txid' => ['required'],
|
||||||
'payment_method_id' => ['required'],
|
'payment_method_id' => ['required'],
|
||||||
|
'btc_address' => ['required'],
|
||||||
|
'btc_amount' => ['required'],
|
||||||
|
'btc_price' => ['required'],
|
||||||
|
// Setting status to required will break the payment process
|
||||||
|
// because sometimes the status is returned as 0 which is falsy
|
||||||
|
// and the validation will fail.
|
||||||
|
// 'status' => ['required'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$data = [];
|
$data = [];
|
||||||
$fiat_amount = round(($request->btc_price * $request->btc_amount), 2);
|
$fiat_amount = round(($request->btc_price * $request->btc_amount / 100000000), 2);
|
||||||
$data['amount'] = $fiat_amount;
|
$data['amount'] = $fiat_amount;
|
||||||
$data['currency'] = $request->currency;
|
|
||||||
$data['payment_method_id'] = $request->payment_method_id;
|
$data['payment_method_id'] = $request->payment_method_id;
|
||||||
$data['payment_type'] = PaymentType::CRYPTO;
|
$data['payment_type'] = PaymentType::CRYPTO;
|
||||||
$data['gateway_type_id'] = GatewayType::CRYPTO;
|
$data['gateway_type_id'] = GatewayType::CRYPTO;
|
||||||
$data['transaction_reference'] = $request->txid;
|
|
||||||
|
|
||||||
$statusId = Payment::STATUS_PENDING;
|
// Append a random value to the transaction reference for test payments
|
||||||
|
// to prevent duplicate entries in the database.
|
||||||
|
// This ensures the payment hashed_id remains unique.
|
||||||
|
$testTxid = $this->test_txid;
|
||||||
|
$data['transaction_reference'] = ($request->txid === $testTxid)
|
||||||
|
? $request->txid . bin2hex(random_bytes(16))
|
||||||
|
: $request->txid;
|
||||||
|
|
||||||
|
$statusId;
|
||||||
|
|
||||||
|
switch ($request->status) {
|
||||||
|
case 0:
|
||||||
|
$statusId = Payment::STATUS_PENDING;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$statusId = Payment::STATUS_PENDING;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$statusId = Payment::STATUS_COMPLETED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$statusId = Payment::STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
$payment = $this->blockonomics->createPayment($data, $statusId);
|
$payment = $this->blockonomics->createPayment($data, $statusId);
|
||||||
|
$payment->private_notes = "{$request->btc_address} - {$request->btc_amount}";
|
||||||
|
$payment->save();
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
['response' => $payment, 'data' => $data],
|
['response' => $payment, 'data' => $data],
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class BlockonomicsPaymentDriver extends BaseDriver
|
||||||
public $NEW_ADDRESS_URL = 'https://www.blockonomics.co/api/new_address';
|
public $NEW_ADDRESS_URL = 'https://www.blockonomics.co/api/new_address';
|
||||||
public $PRICE_URL = 'https://www.blockonomics.co/api/price';
|
public $PRICE_URL = 'https://www.blockonomics.co/api/price';
|
||||||
public $STORES_URL = 'https://www.blockonomics.co/api/v2/stores';
|
public $STORES_URL = 'https://www.blockonomics.co/api/v2/stores';
|
||||||
|
private string $test_txid = 'WarningThisIsAGeneratedTestPaymentAndNotARealBitcoinTransaction';
|
||||||
|
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
|
|
@ -106,17 +107,22 @@ class BlockonomicsPaymentDriver extends BaseDriver
|
||||||
$status = $request->status;
|
$status = $request->status;
|
||||||
$addr = $request->addr;
|
$addr = $request->addr;
|
||||||
|
|
||||||
$payment = Payment::query()
|
if ($txid === $this->test_txid) {
|
||||||
->where('company_id', $company->id)
|
$payment = Payment::query()
|
||||||
->where('transaction_reference', $txid)
|
->where('company_id', $company->id)
|
||||||
->firstOrFail();
|
->where('private_notes', "$addr - $value")
|
||||||
|
->firstOrFail();
|
||||||
if (!$payment) {
|
} else {
|
||||||
return response()->json([], 200);
|
$payment = Payment::query()
|
||||||
// TODO: Implement logic to create new payment in case user sends payment to the address after closing the payment page
|
->where('company_id', $company->id)
|
||||||
|
->where('transaction_reference', $txid)
|
||||||
|
->firstOrFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
$statusId = Payment::STATUS_PENDING;
|
// Already completed payment, no need to update status
|
||||||
|
if ($payment->status_id == Payment::STATUS_COMPLETED) {
|
||||||
|
return response()->json([], 200);
|
||||||
|
}
|
||||||
|
|
||||||
switch ($status) {
|
switch ($status) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -128,16 +134,16 @@ class BlockonomicsPaymentDriver extends BaseDriver
|
||||||
case 2:
|
case 2:
|
||||||
$statusId = Payment::STATUS_COMPLETED;
|
$statusId = Payment::STATUS_COMPLETED;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
$statusId = Payment::STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($payment->status_id == $statusId) {
|
if ($payment->status_id !== $statusId) {
|
||||||
return response()->json([], 200);
|
|
||||||
} else {
|
|
||||||
$payment->status_id = $statusId;
|
$payment->status_id = $statusId;
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
|
||||||
return response()->json([], 200);
|
|
||||||
}
|
}
|
||||||
|
return response()->json([], 200);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,14 +161,18 @@ class Blockonomics {
|
||||||
|
|
||||||
ws.onmessage = function (event) {
|
ws.onmessage = function (event) {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
console.log('Payment status:', data.status);
|
const { status, txid, value } = data || {};
|
||||||
const isPaymentUnconfirmed = data.status === 0;
|
console.log('Payment status:', status);
|
||||||
const isPaymentPartiallyConfirmed = data.status === 1;
|
const isPaymentUnconfirmed = status === 0;
|
||||||
const isPaymentConfirmed = data.status === 2;
|
const isPaymentPartiallyConfirmed = status === 1;
|
||||||
|
const isPaymentConfirmed = status === 2;
|
||||||
// Confirmation status: 0 = unconfirmed, 1 = partially confirmed, 2 = confirmed
|
// Confirmation status: 0 = unconfirmed, 1 = partially confirmed, 2 = confirmed
|
||||||
// If any of the statuses are true, submit the form and redirect
|
// If any of the statuses are true, submit the form and redirect
|
||||||
if (isPaymentUnconfirmed || isPaymentPartiallyConfirmed || isPaymentConfirmed) {
|
if (isPaymentUnconfirmed || isPaymentPartiallyConfirmed || isPaymentConfirmed) {
|
||||||
document.querySelector('input[name="txid"]').value = data.txid || '';
|
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();
|
document.getElementById('server-response').submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@
|
||||||
<input type="hidden" name="currency" value="{{ $currency }}">
|
<input type="hidden" name="currency" value="{{ $currency }}">
|
||||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||||
<input type="hidden" name="txid" value="">
|
<input type="hidden" name="txid" value="">
|
||||||
|
<input type="hidden" name="btc_address" value="{{ $btc_address }}" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="rounded-lg border bg-card text-card-foreground shadow-sm overflow-hidden py-5 bg-white sm:gap-4" id="blockonomics-payment">
|
<div class="rounded-lg border bg-card text-card-foreground shadow-sm overflow-hidden py-5 bg-white sm:gap-4" id="blockonomics-payment">
|
||||||
|
|
||||||
<meta name="amount" content="{{ $amount }}" />
|
<meta name="amount" content="{{ $amount }}" />
|
||||||
<meta name="btc_amount" content="{{ $btc_amount }}" />
|
<meta name="btc_amount" content="{{ $btc_amount }}" />
|
||||||
<meta name="btc_address" content="{{ $btc_address }}" />
|
<meta name="btc_address" content="{{ $btc_address }}" />
|
||||||
|
|
@ -58,6 +57,8 @@
|
||||||
<input type="hidden" name="amount" value="{{ $amount }}">
|
<input type="hidden" name="amount" value="{{ $amount }}">
|
||||||
<input type="hidden" name="btc_price" value="{{ $btc_price }}">
|
<input type="hidden" name="btc_price" value="{{ $btc_price }}">
|
||||||
<input type="hidden" name="btc_amount" value="{{ $btc_amount }}">
|
<input type="hidden" name="btc_amount" value="{{ $btc_amount }}">
|
||||||
|
<input type="hidden" name="btc_address" value="{{ $btc_address }}">
|
||||||
|
<input type="hidden" name="status" value="">
|
||||||
<input type="hidden" name="currency" value="{{ $currency }}">
|
<input type="hidden" name="currency" value="{{ $currency }}">
|
||||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||||
<input type="hidden" name="txid" value="">
|
<input type="hidden" name="txid" value="">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue