diff --git a/BTCPayServer.Data/Data/PaymentRequestData.cs b/BTCPayServer.Data/Data/PaymentRequestData.cs index bbe194905..da4c3df27 100644 --- a/BTCPayServer.Data/Data/PaymentRequestData.cs +++ b/BTCPayServer.Data/Data/PaymentRequestData.cs @@ -1,4 +1,6 @@ using System; +using System.ComponentModel.DataAnnotations.Schema; +using BTCPayServer.Client.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -18,6 +20,9 @@ namespace BTCPayServer.Data public Client.Models.PaymentRequestStatus Status { get; set; } + [NotMapped] + public bool Expirable => Status is PaymentRequestStatus.Pending or PaymentRequestStatus.Processing && Expiry is not null; + [Obsolete("Use Blob2 instead")] public byte[] Blob { get; set; } public string Blob2 { get; set; } diff --git a/BTCPayServer/PaymentRequest/PaymentRequestHub.cs b/BTCPayServer/PaymentRequest/PaymentRequestHub.cs index 70d6eef79..269d803fb 100644 --- a/BTCPayServer/PaymentRequest/PaymentRequestHub.cs +++ b/BTCPayServer/PaymentRequest/PaymentRequestHub.cs @@ -199,7 +199,7 @@ namespace BTCPayServer.PaymentRequest { if (data is { - Status: PaymentRequestStatus.Pending or PaymentRequestStatus.Processing, + Expirable: true, Expiry: { } e }) { diff --git a/BTCPayServer/PaymentRequest/PaymentRequestService.cs b/BTCPayServer/PaymentRequest/PaymentRequestService.cs index 008dd4737..af75fcb7b 100644 --- a/BTCPayServer/PaymentRequest/PaymentRequestService.cs +++ b/BTCPayServer/PaymentRequest/PaymentRequestService.cs @@ -10,6 +10,7 @@ using BTCPayServer.Services.Apps; using BTCPayServer.Services.Invoices; using BTCPayServer.Services.PaymentRequests; using BTCPayServer.Services.Rates; +using static System.Runtime.InteropServices.JavaScript.JSType; using PaymentRequestData = BTCPayServer.Data.PaymentRequestData; namespace BTCPayServer.PaymentRequest @@ -50,24 +51,21 @@ namespace BTCPayServer.PaymentRequest public async Task UpdatePaymentRequestStateIfNeeded(PaymentRequestData pr) { - var blob = pr.GetBlob(); - var currentStatus = pr.Status; - if (pr.Expiry.HasValue) + var newStatus = pr.Status; + newStatus = pr switch { - if (pr.Expiry.Value <= DateTimeOffset.UtcNow) - currentStatus = Client.Models.PaymentRequestStatus.Expired; - } - else if (currentStatus != Client.Models.PaymentRequestStatus.Completed) - { - currentStatus = Client.Models.PaymentRequestStatus.Pending; - } + { Expirable: true, Expiry: { } e } + when e <= DateTimeOffset.UtcNow => PaymentRequestStatus.Expired, + { Status: PaymentRequestStatus.Expired, Expiry: null } => PaymentRequestStatus.Pending, + _ => pr.Status + }; - if (currentStatus != Client.Models.PaymentRequestStatus.Expired) + if (newStatus is not (PaymentRequestStatus.Expired or PaymentRequestStatus.Completed)) { var invoices = await _paymentRequestRepository.GetInvoicesForPaymentRequest(pr.Id); var contributions = _invoiceRepository.GetContributionsByPaymentMethodId(pr.Currency, invoices, true); - currentStatus = + newStatus = (PaidEnough: contributions.Total >= pr.Amount, SettledEnough: contributions.TotalSettled >= pr.Amount) switch { @@ -77,10 +75,10 @@ namespace BTCPayServer.PaymentRequest }; } - if (currentStatus != pr.Status) + if (newStatus != pr.Status) { - pr.Status = currentStatus; - await _paymentRequestRepository.UpdatePaymentRequestStatus(pr.Id, currentStatus); + pr.Status = newStatus; + await _paymentRequestRepository.UpdatePaymentRequestStatus(pr.Id, newStatus); } } diff --git a/BTCPayServer/Services/DelayedTaskScheduler.cs b/BTCPayServer/Services/DelayedTaskScheduler.cs index d6cac8e85..84e619df4 100644 --- a/BTCPayServer/Services/DelayedTaskScheduler.cs +++ b/BTCPayServer/Services/DelayedTaskScheduler.cs @@ -22,6 +22,8 @@ namespace BTCPayServer.Services var due = ExecuteAt - DateTimeOffset.UtcNow; if (due < TimeSpan.Zero) due = TimeSpan.Zero; + else + due += TimeSpan.FromSeconds(1.0); // Better to be a bit late than too early // Max timer needed, else dotnet crash if (due > MaxTimer) due = MaxTimer; @@ -61,7 +63,7 @@ namespace BTCPayServer.Services var s = (TimerState)state!; Task.Run(async () => { - bool run = s.NextWait() == TimeSpan.Zero; + bool run = s.NextWait() < TimeSpan.FromSeconds(5.0); try { if (run)