mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 14:34:23 +01:00
Fake payment fixes (#3058)
Fixes and various minor improvements for the fake payment form.
This commit is contained in:
@@ -1,42 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Mime;
|
|
||||||
using System.Net.WebSockets;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Abstractions.Constants;
|
|
||||||
using BTCPayServer.Abstractions.Extensions;
|
|
||||||
using BTCPayServer.Abstractions.Models;
|
|
||||||
using BTCPayServer.Client;
|
|
||||||
using BTCPayServer.Client.Models;
|
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Events;
|
|
||||||
using BTCPayServer.Filters;
|
using BTCPayServer.Filters;
|
||||||
using BTCPayServer.Logging;
|
|
||||||
using BTCPayServer.HostedServices;
|
|
||||||
using BTCPayServer.Models;
|
|
||||||
using BTCPayServer.Models.InvoicingModels;
|
|
||||||
using BTCPayServer.Payments;
|
using BTCPayServer.Payments;
|
||||||
using BTCPayServer.Payments.Lightning;
|
|
||||||
using BTCPayServer.Rating;
|
|
||||||
using BTCPayServer.Security;
|
|
||||||
using BTCPayServer.Services.Invoices;
|
|
||||||
using BTCPayServer.Services.Invoices.Export;
|
|
||||||
using BTCPayServer.Services.Rates;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.RPC;
|
|
||||||
using NBitpayClient;
|
|
||||||
using NBXplorer;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using BitpayCreateInvoiceRequest = BTCPayServer.Models.BitpayCreateInvoiceRequest;
|
|
||||||
using StoreData = BTCPayServer.Data.StoreData;
|
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers
|
namespace BTCPayServer.Controllers
|
||||||
@@ -46,7 +15,9 @@ namespace BTCPayServer.Controllers
|
|||||||
public class FakePaymentRequest
|
public class FakePaymentRequest
|
||||||
{
|
{
|
||||||
public Decimal Amount { get; set; }
|
public Decimal Amount { get; set; }
|
||||||
|
public string CryptoCode { get; set; } = "BTC";
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("i/{invoiceId}/test-payment")]
|
[Route("i/{invoiceId}/test-payment")]
|
||||||
[CheatModeRoute]
|
[CheatModeRoute]
|
||||||
@@ -56,21 +27,16 @@ namespace BTCPayServer.Controllers
|
|||||||
var store = await _StoreRepository.FindStore(invoice.StoreId);
|
var store = await _StoreRepository.FindStore(invoice.StoreId);
|
||||||
|
|
||||||
// TODO support altcoins, not just bitcoin
|
// TODO support altcoins, not just bitcoin
|
||||||
//var network = invoice.Networks.GetNetwork(invoice.Currency);
|
var network = _NetworkProvider.GetNetwork<BTCPayNetwork>(request.CryptoCode);
|
||||||
var cryptoCode = "BTC";
|
var paymentMethodId = store.GetDefaultPaymentId() ?? store.GetEnabledPaymentIds(_NetworkProvider).FirstOrDefault(p => p.CryptoCode == request.CryptoCode && p.PaymentType == PaymentTypes.BTCLike);
|
||||||
var network = _NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
|
||||||
var paymentMethodId = store.GetDefaultPaymentId();
|
|
||||||
|
|
||||||
//var network = NetworkProvider.GetNetwork<BTCPayNetwork>("BTC");
|
|
||||||
var bitcoinAddressString = invoice.GetPaymentMethod(paymentMethodId).GetPaymentMethodDetails().GetPaymentDestination();
|
var bitcoinAddressString = invoice.GetPaymentMethod(paymentMethodId).GetPaymentMethodDetails().GetPaymentDestination();
|
||||||
|
|
||||||
var bitcoinAddressObj = BitcoinAddress.Create(bitcoinAddressString, network.NBitcoinNetwork);
|
var bitcoinAddressObj = BitcoinAddress.Create(bitcoinAddressString, network.NBitcoinNetwork);
|
||||||
var BtcAmount = request.Amount;
|
var BtcAmount = request.Amount;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
|
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
|
||||||
var rate = paymentMethod.Rate;
|
var rate = paymentMethod.Rate;
|
||||||
|
|
||||||
var txid = cheater.CashCow.SendToAddress(bitcoinAddressObj, new Money(BtcAmount, MoneyUnit.BTC)).ToString();
|
var txid = cheater.CashCow.SendToAddress(bitcoinAddressObj, new Money(BtcAmount, MoneyUnit.BTC)).ToString();
|
||||||
|
|
||||||
// TODO The value of totalDue is wrong. How can we get the real total due? invoice.Price is only correct if this is the 2nd payment, not for a 3rd or 4th payment.
|
// TODO The value of totalDue is wrong. How can we get the real total due? invoice.Price is only correct if this is the 2nd payment, not for a 3rd or 4th payment.
|
||||||
|
|||||||
@@ -2,22 +2,24 @@
|
|||||||
|
|
||||||
<div id="testing">
|
<div id="testing">
|
||||||
<hr class="my-3" />
|
<hr class="my-3" />
|
||||||
|
<p class="alert alert-danger" style="display: none; word-break: break-all;"></p>
|
||||||
|
<p class="alert alert-success" style="display: none; word-break: break-all;"></p>
|
||||||
<form id="test-payment" action="/i/@Model.InvoiceId/test-payment" method="post" class="form-inline my-2">
|
<form id="test-payment" action="/i/@Model.InvoiceId/test-payment" method="post" class="form-inline my-2">
|
||||||
|
<input name="CryptoCode" type="hidden" value="@Model.CryptoCode">
|
||||||
<div class="form-group mb-1">
|
<div class="form-group mb-1">
|
||||||
<label for="test-payment-crypto-code" class="control-label">{{$t("Fake a @Model.CryptoCode payment for testing")}}</label>
|
<label for="test-payment-amount" class="control-label">{{$t("Fake a @Model.CryptoCode payment for testing")}}</label>
|
||||||
<p class="alert alert-danger" style="display: none; word-break: break-all;"></p>
|
|
||||||
<p class="alert alert-success" style="display: none; word-break: break-all;"></p>
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="test-payment-amount" name="amount" type="number" step="any" min="0" class="form-control" placeholder="Amount" value="@Model.BtcDue" aria-label="Amount" aria-describedby="test-payment-crypto-code">
|
<input id="test-payment-amount" name="Amount" type="number" step="0.00000001" min="0" class="form-control" placeholder="Amount" value="@Model.BtcDue" />
|
||||||
<div class="input-group-addon" id="test-payment-crypto-code">@Model.CryptoCode</div>
|
<div id="test-payment-crypto-code" class="input-group-addon">@Model.CryptoCode</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" type="submit">{{$t("Fake Payment")}}</button>
|
<button class="btn btn-primary" type="submit">{{$t("Fake Payment")}}</button>
|
||||||
<p class="text-muted mt-1">{{$t("This is the same as running bitcoin-cli.sh sendtoaddress xxx")}}</p>
|
<p class="text-muted mt-1">{{$t("This is the same as running bitcoin-cli.sh sendtoaddress xxx")}}</p>
|
||||||
</form>
|
</form>
|
||||||
<form id="expire-invoice" action="/i/@Model.InvoiceId/expire" method="post" class="mb-1">
|
<form id="expire-invoice" action="/i/@Model.InvoiceId/expire" method="post" class="mb-1">
|
||||||
<button class="btn btn-secondary" type="submit">{{$t("Expire Invoice Now")}} (TODO)</button>
|
<button class="btn btn-secondary" type="submit">{{$t("Expire Invoice Now")}}</button>
|
||||||
</form>
|
</form>
|
||||||
|
@* TODO
|
||||||
<form id="expire-monitoring" action="/i/@Model.InvoiceId/expire-monitoring" method="post" class="mb-1">
|
<form id="expire-monitoring" action="/i/@Model.InvoiceId/expire-monitoring" method="post" class="mb-1">
|
||||||
<!-- TODO only show when expired -->
|
<!-- TODO only show when expired -->
|
||||||
<button class="btn btn-secondary" type="submit">{{$t("Expire Monitoring Now")}} (TODO)</button>
|
<button class="btn btn-secondary" type="submit">{{$t("Expire Monitoring Now")}} (TODO)</button>
|
||||||
@@ -27,82 +29,80 @@
|
|||||||
<!-- TODO to make it work use Bitcoin RPC calls getnewaddress + generatetoaddress -->
|
<!-- TODO to make it work use Bitcoin RPC calls getnewaddress + generatetoaddress -->
|
||||||
<button class="btn btn-secondary" type="submit">{{$t("Mine a block now")}} (TODO)</button>
|
<button class="btn btn-secondary" type="submit">{{$t("Mine a block now")}} (TODO)</button>
|
||||||
</form>
|
</form>
|
||||||
|
*@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
let payForm = $('form#test-payment');
|
const payForm = $('form#test-payment');
|
||||||
let loader = $('form#test-payment-loading');
|
const loader = $('form#test-payment-loading');
|
||||||
let inputField = $('#test-payment-amount');
|
const inputField = $('#test-payment-amount');
|
||||||
let submitButton = payForm.find('button[type=submit]');
|
const successAlert = $('#testing p.alert-success');
|
||||||
let paySuccess = payForm.find('p.alert-success');
|
const errorAlert = $('#testing p.alert-danger');
|
||||||
let payAlert = payForm.find('p.alert-danger');
|
const submitButton = payForm.find('button[type=submit]');
|
||||||
|
const expireForm = $('form#expire-invoice');
|
||||||
|
const expireButton = expireForm.find('[type=submit]');
|
||||||
|
|
||||||
payForm.submit(function (e){
|
payForm.submit(e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
let form = $(this);
|
const form = $(e.target);
|
||||||
let data = form.serialize();
|
const url = form.attr('action');
|
||||||
|
const data = form.serialize();
|
||||||
paySuccess.hide();
|
|
||||||
payAlert.hide();
|
successAlert.hide();
|
||||||
|
errorAlert.hide();
|
||||||
loader.show();
|
loader.show();
|
||||||
inputField.prop('disabled', true);
|
inputField.prop('disabled', true);
|
||||||
submitButton.prop('disabled', true);
|
submitButton.prop('disabled', true);
|
||||||
|
|
||||||
$.post({
|
$.post({
|
||||||
url: form.attr('action'),
|
url,
|
||||||
data: data,
|
data,
|
||||||
success: function (data,status,xhr){
|
success(data) {
|
||||||
paySuccess.html(data.successMessage);
|
const { successMessage, amountRemaining } = data;
|
||||||
paySuccess.show();
|
successAlert.html(successMessage);
|
||||||
inputField.val(data.amountRemaining);
|
successAlert.show();
|
||||||
if (data.amountRemaining <= 0){
|
if (amountRemaining > 0) {
|
||||||
// No need to fake any more payments.
|
inputField.val(amountRemaining);
|
||||||
form.hide();
|
} else {
|
||||||
|
form.hide();
|
||||||
|
expireForm.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
complete: function (xhr,status){
|
error(xhr) {
|
||||||
|
const { errorMessage } = JSON.parse(xhr.responseText);
|
||||||
|
errorAlert.html(errorMessage).show();
|
||||||
|
},
|
||||||
|
complete() {
|
||||||
loader.hide();
|
loader.hide();
|
||||||
inputField.prop('disabled', false);
|
inputField.prop('disabled', false);
|
||||||
submitButton.prop('disabled', false);
|
submitButton.prop('disabled', false);
|
||||||
},
|
|
||||||
error: function (xhr,status,error){
|
|
||||||
var data = JSON.parse(xhr.responseText);
|
|
||||||
payAlert.html(data.errorMessage);
|
|
||||||
payAlert.show();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expire invoice form
|
// Expire invoice form
|
||||||
let expireForm = $('form#expire-invoice');
|
expireForm.submit(e => {
|
||||||
let expireButton = expireForm.find('[type=submit]');
|
|
||||||
let expireSuccess = expireForm.find('p.alert-success');
|
|
||||||
let expireAlert = expireForm.find('p.alert-danger');
|
|
||||||
|
|
||||||
expireForm.submit(function (e){
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
expireSuccess.hide();
|
successAlert.hide();
|
||||||
expireAlert.hide();
|
errorAlert.hide();
|
||||||
|
|
||||||
$.post({
|
$.post({
|
||||||
url: form.attr('action'),
|
url: expireForm.attr('action'),
|
||||||
data: data,
|
success(data) {
|
||||||
success: function (data,status,xhr){
|
const { successMessage } = data;
|
||||||
expireSuccess.html(data.successMessage);
|
successAlert.html(successMessage).show();
|
||||||
expireSuccess.show();
|
|
||||||
expireButton.hide();
|
expireButton.hide();
|
||||||
},
|
},
|
||||||
complete: function (xhr,status){
|
complete() {
|
||||||
loader.hide();
|
loader.hide();
|
||||||
submitButton.prop('disabled', false);
|
submitButton.prop('disabled', false);
|
||||||
},
|
},
|
||||||
error: function (xhr,status,error){
|
error(xhr) {
|
||||||
var data = JSON.parse(xhr.responseText);
|
const { errorMessage } = JSON.parse(xhr.responseText);
|
||||||
expireAlert.html(data.errorMessage);
|
errorAlert.html(errorMessage).show();
|
||||||
expireAlert.show();
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user