start work on payment tolerance feature

This commit is contained in:
Andrew Camilleri
2018-05-04 16:15:34 +02:00
parent 8a4da361fd
commit c3d73236e0
9 changed files with 44 additions and 4 deletions

View File

@@ -98,6 +98,7 @@ namespace BTCPayServer.Controllers
entity.ExtendedNotifications = invoice.ExtendedNotifications;
entity.NotificationURL = notificationUri?.AbsoluteUri;
entity.BuyerInformation = Map<Invoice, BuyerInformation>(invoice);
entity.PaymentTolerance = storeBlob.PaymentTolerance;
//Another way of passing buyer info to support
FillBuyerInfo(invoice.Buyer, entity.BuyerInformation);
if (entity?.BuyerInformation?.BuyerEmail != null)

View File

@@ -431,6 +431,7 @@ namespace BTCPayServer.Controllers
vm.MonitoringExpiration = storeBlob.MonitoringExpiration;
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
vm.PaymentTolerance = storeBlob.PaymentTolerance;
return View(vm);
}
@@ -496,6 +497,7 @@ namespace BTCPayServer.Controllers
blob.MonitoringExpiration = model.MonitoringExpiration;
blob.InvoiceExpiration = model.InvoiceExpiration;
blob.LightningDescriptionTemplate = model.LightningDescriptionTemplate ?? string.Empty;
blob.PaymentTolerance = model.PaymentTolerance;
if (StoreData.SetStoreBlob(blob))
{

View File

@@ -247,6 +247,7 @@ namespace BTCPayServer.Data
{
InvoiceExpiration = 15;
MonitoringExpiration = 60;
PaymentTolerance = 0;
RequiresRefundEmail = true;
}
public bool NetworkFeeDisabled
@@ -326,6 +327,10 @@ namespace BTCPayServer.Data
}
}
[DefaultValue(0)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public double PaymentTolerance { get; set; }
public BTCPayServer.Rating.RateRules GetRateRules(BTCPayNetworkProvider networkProvider)
{
if (!RateScripting ||

View File

@@ -312,6 +312,7 @@ namespace BTCPayServer.HostedServices
{
if (e.Name == "invoice_expired" ||
e.Name == "invoice_paidInFull" ||
e.Name == "invoice_paidWithinTolerance" ||
e.Name == "invoice_failedToConfirm" ||
e.Name == "invoice_markedInvalid" ||
e.Name == "invoice_failedToConfirm" ||

View File

@@ -96,13 +96,30 @@ namespace BTCPayServer.HostedServices
}
}
if (accounting.Paid < accounting.TotalDue && invoice.GetPayments().Count != 0 && invoice.ExceptionStatus != "paidPartial")
if (accounting.Paid < accounting.TotalDue && invoice.GetPayments().Count != 0)
{
if (invoice.PaymentTolerance > 0)
{
var tolerantAmount = (accounting.TotalDue.Satoshi * (invoice.PaymentTolerance / 100));
var minimumTotalDue = accounting.TotalDue.Satoshi - tolerantAmount;
if (accounting.Paid.Satoshi >= minimumTotalDue)
{
context.Events.Add(new InvoiceEvent(invoice, 1003, "invoide_paidWithinTolerance"));
invoice.ExceptionStatus = "paidWithinTolerance";
invoice.Status = "paid";
}
}
if (invoice.ExceptionStatus != "paidPartial")
{
invoice.ExceptionStatus = "paidPartial";
context.MarkDirty();
}
}
}
// Just make sure RBF did not cancelled a payment
if (invoice.Status == "paid")
{

View File

@@ -178,7 +178,7 @@ namespace BTCPayServer.Models
}
//"exceptionStatus":false
//Can be `paidPartial`, `paidOver`, or false
//Can be `paidPartial`, `paidOver`, `paidWithinTolerance` or false
[JsonProperty("exceptionStatus")]
public JToken ExceptionStatus
{

View File

@@ -85,5 +85,13 @@ namespace BTCPayServer.Models.StoreViewModels
{
get; set;
} = new List<LightningNode>();
[Display(Name = "Consider the invoice paid even if the paid amount is ... % less than expected")]
[Range(0, 100)]
public double PaymentTolerance
{
get;
set;
}
}
}

View File

@@ -314,6 +314,7 @@ namespace BTCPayServer.Services.Invoices
}
public bool ExtendedNotifications { get; set; }
public List<InvoiceEventData> Events { get; internal set; }
public double PaymentTolerance { get; set; }
public bool IsExpired()
{

View File

@@ -44,6 +44,11 @@
<input asp-for="MonitoringExpiration" class="form-control" />
<span asp-validation-for="MonitoringExpiration" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PaymentTolerance"></label>
<input asp-for="PaymentTolerance" class="form-control" />
<span asp-validation-for="PaymentTolerance" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SpeedPolicy"></label>
<select asp-for="SpeedPolicy" class="form-control">