diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj
index 95181a9e3..32df3a015 100644
--- a/BTCPayServer/BTCPayServer.csproj
+++ b/BTCPayServer/BTCPayServer.csproj
@@ -2,7 +2,7 @@
Exe
netcoreapp2.0
- 1.0.1.49
+ 1.0.1.50
NU1701,CA1816,CA1308,CA1810,CA2208
diff --git a/BTCPayServer/Extensions.cs b/BTCPayServer/Extensions.cs
index 5f24c943d..a93393c42 100644
--- a/BTCPayServer/Extensions.cs
+++ b/BTCPayServer/Extensions.cs
@@ -30,6 +30,19 @@ namespace BTCPayServer
{
public static class Extensions
{
+ public static decimal RoundUp(decimal value, int precision)
+ {
+ for (int i = 0; i < precision; i++)
+ {
+ value = value * 10m;
+ }
+ value = Math.Ceiling(value);
+ for (int i = 0; i < precision; i++)
+ {
+ value = value / 10m;
+ }
+ return value;
+ }
public static PaymentMethodId GetpaymentMethodId(this InvoiceCryptoInfo info)
{
return new PaymentMethodId(info.CryptoCode, Enum.Parse(info.PaymentType));
diff --git a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs
index e33b9a9e7..d3f2856d5 100644
--- a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs
+++ b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs
@@ -160,7 +160,8 @@ namespace BTCPayServer.Payments.Bitcoin
if (!alreadyExist)
{
var payment = await _InvoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, paymentData, network.CryptoCode);
- await ReceivedPayment(wallet, invoice.Id, payment, evt.DerivationStrategy);
+ if(payment != null)
+ await ReceivedPayment(wallet, invoice.Id, payment, evt.DerivationStrategy);
}
else
{
@@ -330,7 +331,8 @@ namespace BTCPayServer.Payments.Bitcoin
var paymentData = new BitcoinLikePaymentData(coin.Coin, transaction.Transaction.RBF);
var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin.Timestamp, paymentData, network.CryptoCode).ConfigureAwait(false);
alreadyAccounted.Add(coin.Coin.Outpoint);
- invoice = await ReceivedPayment(wallet, invoice.Id, payment, strategy);
+ if (payment != null)
+ invoice = await ReceivedPayment(wallet, invoice.Id, payment, strategy);
totalPayment++;
}
}
diff --git a/BTCPayServer/Payments/Lightning/ChargeListener.cs b/BTCPayServer/Payments/Lightning/ChargeListener.cs
index 4f031409b..e418a4633 100644
--- a/BTCPayServer/Payments/Lightning/ChargeListener.cs
+++ b/BTCPayServer/Payments/Lightning/ChargeListener.cs
@@ -163,12 +163,13 @@ namespace BTCPayServer.Payments.Lightning
private async Task AddPayment(BTCPayNetwork network, ChargeInvoice notification, ListenedInvoice listenedInvoice)
{
- await _InvoiceRepository.AddPayment(listenedInvoice.InvoiceId, notification.PaidAt.Value, new LightningLikePaymentData()
+ var payment = await _InvoiceRepository.AddPayment(listenedInvoice.InvoiceId, notification.PaidAt.Value, new LightningLikePaymentData()
{
BOLT11 = notification.PaymentRequest,
Amount = notification.MilliSatoshi
}, network.CryptoCode, accounted: true);
- _Aggregator.Publish(new InvoiceEvent(listenedInvoice.InvoiceId, 1002, "invoice_receivedPayment"));
+ if(payment != null)
+ _Aggregator.Publish(new InvoiceEvent(listenedInvoice.InvoiceId, 1002, "invoice_receivedPayment"));
}
private static ChargeClient GetChargeClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
index 61bc332a4..e8b852670 100644
--- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
+++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
@@ -21,7 +21,7 @@ namespace BTCPayServer.Payments.Lightning
public override async Task CreatePaymentMethodDetails(LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network)
{
var invoice = paymentMethod.ParentEntity;
- var due = invoice.ProductInformation.Price / paymentMethod.Rate;
+ var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8);
var client = GetClient(supportedPaymentMethod, network);
var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow;
var lightningInvoice = await client.CreateInvoiceAsync(new CreateInvoiceRequest()
diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs
index d1eedaf5a..0730c6c18 100644
--- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs
+++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs
@@ -646,8 +646,9 @@ namespace BTCPayServer.Services.Invoices
var paid = 0m;
var cryptoPaid = 0.0m;
+ int precision = 8;
var paidTxFee = 0m;
- bool paidEnough = paid >= RoundUp(totalDue, 8);
+ bool paidEnough = paid >= Extensions.RoundUp(totalDue, precision);
int txRequired = 0;
var payments =
ParentEntity.GetPayments()
@@ -662,7 +663,7 @@ namespace BTCPayServer.Services.Invoices
totalDue += txFee;
paidTxFee += txFee;
}
- paidEnough |= paid >= RoundUp(totalDue, 8);
+ paidEnough |= paid >= Extensions.RoundUp(totalDue, precision);
if (GetId() == _.GetPaymentMethodId())
{
cryptoPaid += _.GetCryptoPaymentData().GetValue();
@@ -681,7 +682,7 @@ namespace BTCPayServer.Services.Invoices
paidTxFee += GetTxFee();
}
- accounting.TotalDue = Money.Coins(RoundUp(totalDue, 8));
+ accounting.TotalDue = Money.Coins(Extensions.RoundUp(totalDue, precision));
accounting.Paid = Money.Coins(paid);
accounting.TxRequired = txRequired;
accounting.CryptoPaid = Money.Coins(cryptoPaid);
@@ -691,20 +692,6 @@ namespace BTCPayServer.Services.Invoices
return accounting;
}
- private static decimal RoundUp(decimal value, int precision)
- {
- for (int i = 0; i < precision; i++)
- {
- value = value * 10m;
- }
- value = Math.Ceiling(value);
- for (int i = 0; i < precision; i++)
- {
- value = value / 10m;
- }
- return value;
- }
-
private decimal GetTxFee()
{
var method = GetPaymentMethodDetails();
diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs
index fafec2908..4dc28f7c6 100644
--- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs
+++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs
@@ -461,6 +461,15 @@ namespace BTCPayServer.Services.Invoices
AddToTextSearch(invoiceId, addresses.Select(a => a.ToString()).ToArray());
}
+ ///
+ /// Add a payment to an invoice
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The PaymentEntity or null if already added
public async Task AddPayment(string invoiceId, DateTimeOffset date, CryptoPaymentData paymentData, string cryptoCode, bool accounted = false)
{
using (var context = _ContextFactory.CreateContext())
@@ -486,7 +495,11 @@ namespace BTCPayServer.Services.Invoices
context.Payments.Add(data);
- await context.SaveChangesAsync().ConfigureAwait(false);
+ try
+ {
+ await context.SaveChangesAsync().ConfigureAwait(false);
+ }
+ catch(DbUpdateException) { return null; } // Already exists
AddToTextSearch(invoiceId, paymentData.GetSearchTerms());
return entity;
}