mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-13 11:35:51 +01:00
Enhance Invoice Events
This commit is contained in:
parent
88150b6535
commit
5076d73695
9 changed files with 50 additions and 28 deletions
|
@ -51,6 +51,7 @@ using RatesViewModel = BTCPayServer.Models.StoreViewModels.RatesViewModel;
|
|||
using NBitpayClient.Extensions;
|
||||
using BTCPayServer.Services;
|
||||
using System.Text.RegularExpressions;
|
||||
using BTCPayServer.Events;
|
||||
|
||||
namespace BTCPayServer.Tests
|
||||
{
|
||||
|
@ -521,22 +522,22 @@ namespace BTCPayServer.Tests
|
|||
var evtName = request["event"]["name"].Value<string>();
|
||||
switch (evtName)
|
||||
{
|
||||
case "invoice_created":
|
||||
case InvoiceEvent.Created:
|
||||
tester.ExplorerNode.SendToAddress(url.Address, url.Amount);
|
||||
break;
|
||||
case "invoice_receivedPayment":
|
||||
case InvoiceEvent.ReceivedPayment:
|
||||
receivedPayment = true;
|
||||
break;
|
||||
case "invoice_paidInFull":
|
||||
case InvoiceEvent.PaidInFull:
|
||||
Assert.True(receivedPayment);
|
||||
tester.ExplorerNode.Generate(6);
|
||||
paid = true;
|
||||
break;
|
||||
case "invoice_confirmed":
|
||||
case InvoiceEvent.Confirmed:
|
||||
Assert.True(paid);
|
||||
confirmed = true;
|
||||
break;
|
||||
case "invoice_completed":
|
||||
case InvoiceEvent.Completed:
|
||||
Assert.True(paid); //TODO: Fix, out of order event mean we can receive invoice_confirmed after invoice_complete
|
||||
completed = true;
|
||||
break;
|
||||
|
|
|
@ -638,13 +638,13 @@ namespace BTCPayServer.Controllers
|
|||
if (newState == "invalid")
|
||||
{
|
||||
await _InvoiceRepository.UpdatePaidInvoiceToInvalid(invoiceId);
|
||||
_EventAggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1008, "invoice_markedInvalid"));
|
||||
_EventAggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1008, InvoiceEvent.MarkedInvalid));
|
||||
StatusMessage = "Invoice marked invalid";
|
||||
}
|
||||
else if(newState == "complete")
|
||||
{
|
||||
await _InvoiceRepository.UpdatePaidInvoiceToComplete(invoiceId);
|
||||
_EventAggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 2008, "invoice_markedComplete"));
|
||||
_EventAggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 2008, InvoiceEvent.MarkedCompleted));
|
||||
StatusMessage = "Invoice marked complete";
|
||||
}
|
||||
return RedirectToAction(nameof(ListInvoices));
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Logging;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Payments;
|
||||
|
@ -159,7 +160,7 @@ namespace BTCPayServer.Controllers
|
|||
entity.PosData = invoice.PosData;
|
||||
entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity, logs, _NetworkProvider);
|
||||
await fetchingAll;
|
||||
_EventAggregator.Publish(new Events.InvoiceEvent(entity.EntityToDTO(_NetworkProvider), 1001, "invoice_created"));
|
||||
_EventAggregator.Publish(new Events.InvoiceEvent(entity.EntityToDTO(_NetworkProvider), 1001, InvoiceEvent.Created));
|
||||
var resp = entity.EntityToDTO(_NetworkProvider);
|
||||
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
||||
}
|
||||
|
|
|
@ -8,6 +8,18 @@ namespace BTCPayServer.Events
|
|||
{
|
||||
public class InvoiceEvent
|
||||
{
|
||||
public const string Created = "invoice_created";
|
||||
public const string ReceivedPayment = "invoice_receivedPayment";
|
||||
public const string MarkedCompleted = "invoice_markedComplete";
|
||||
public const string MarkedInvalid= "invoice_markedInvalid";
|
||||
public const string Expired= "invoice_expired";
|
||||
public const string ExpiredPaidPartial= "invoice_expiredPaidPartial";
|
||||
public const string PaidInFull= "invoice_paidInFull";
|
||||
public const string PaidAfterExpiration= "invoice_paidAfterExpiration";
|
||||
public const string FailedToConfirm= "invoice_failedToConfirm";
|
||||
public const string Confirmed= "invoice_confirmed";
|
||||
public const string Completed= "invoice_completed";
|
||||
|
||||
public InvoiceEvent(Models.InvoiceResponse invoice, int code, string name)
|
||||
{
|
||||
Invoice = invoice;
|
||||
|
@ -19,6 +31,8 @@ namespace BTCPayServer.Events
|
|||
public int EventCode { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public PaymentEntity Payment { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Invoice {Invoice.Id} new event: {Name} ({EventCode})";
|
||||
|
|
|
@ -341,14 +341,14 @@ namespace BTCPayServer.HostedServices
|
|||
// we need to use the status in the event and not in the invoice. The invoice might now be in another status.
|
||||
if (invoice.FullNotifications)
|
||||
{
|
||||
if (e.Name == "invoice_expired" ||
|
||||
e.Name == "invoice_paidInFull" ||
|
||||
e.Name == "invoice_failedToConfirm" ||
|
||||
e.Name == "invoice_markedInvalid" ||
|
||||
e.Name == "invoice_markedComplete" ||
|
||||
e.Name == "invoice_failedToConfirm" ||
|
||||
e.Name == "invoice_completed" ||
|
||||
e.Name == "invoice_expiredPaidPartial"
|
||||
if (e.Name == InvoiceEvent.Expired ||
|
||||
e.Name == InvoiceEvent.PaidInFull ||
|
||||
e.Name == InvoiceEvent.FailedToConfirm ||
|
||||
e.Name == InvoiceEvent.MarkedInvalid ||
|
||||
e.Name == InvoiceEvent.MarkedCompleted ||
|
||||
e.Name == InvoiceEvent.FailedToConfirm ||
|
||||
e.Name == InvoiceEvent.Completed ||
|
||||
e.Name == InvoiceEvent.ExpiredPaidPartial
|
||||
)
|
||||
tasks.Add(Notify(invoice));
|
||||
}
|
||||
|
|
|
@ -66,10 +66,10 @@ namespace BTCPayServer.HostedServices
|
|||
context.MarkDirty();
|
||||
await _InvoiceRepository.UnaffectAddress(invoice.Id);
|
||||
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1004, "invoice_expired"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1004, InvoiceEvent.Expired));
|
||||
invoice.Status = InvoiceStatus.Expired;
|
||||
if(invoice.ExceptionStatus == InvoiceExceptionStatus.PaidPartial)
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 2000, "invoice_expiredPaidPartial"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 2000, InvoiceEvent.ExpiredPaidPartial));
|
||||
}
|
||||
|
||||
var payments = invoice.GetPayments().Where(p => p.Accounted).ToArray();
|
||||
|
@ -84,7 +84,7 @@ namespace BTCPayServer.HostedServices
|
|||
{
|
||||
if (invoice.Status == InvoiceStatus.New)
|
||||
{
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1003, "invoice_paidInFull"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1003, InvoiceEvent.PaidInFull));
|
||||
invoice.Status = InvoiceStatus.Paid;
|
||||
invoice.ExceptionStatus = accounting.Paid > accounting.TotalDue ? InvoiceExceptionStatus.PaidOver : InvoiceExceptionStatus.None;
|
||||
await _InvoiceRepository.UnaffectAddress(invoice.Id);
|
||||
|
@ -93,7 +93,7 @@ namespace BTCPayServer.HostedServices
|
|||
else if (invoice.Status == InvoiceStatus.Expired && invoice.ExceptionStatus != InvoiceExceptionStatus.PaidLate)
|
||||
{
|
||||
invoice.ExceptionStatus = InvoiceExceptionStatus.PaidLate;
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1009, "invoice_paidAfterExpiration"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1009, InvoiceEvent.PaidAfterExpiration));
|
||||
context.MarkDirty();
|
||||
}
|
||||
}
|
||||
|
@ -139,14 +139,14 @@ namespace BTCPayServer.HostedServices
|
|||
(confirmedAccounting.Paid < accounting.MinimumTotalDue))
|
||||
{
|
||||
await _InvoiceRepository.UnaffectAddress(invoice.Id);
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1013, "invoice_failedToConfirm"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1013, InvoiceEvent.FailedToConfirm));
|
||||
invoice.Status = InvoiceStatus.Invalid;
|
||||
context.MarkDirty();
|
||||
}
|
||||
else if (confirmedAccounting.Paid >= accounting.MinimumTotalDue)
|
||||
{
|
||||
await _InvoiceRepository.UnaffectAddress(invoice.Id);
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1005, "invoice_confirmed"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1005, InvoiceEvent.Confirmed));
|
||||
invoice.Status = InvoiceStatus.Confirmed;
|
||||
context.MarkDirty();
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ namespace BTCPayServer.HostedServices
|
|||
var completedAccounting = paymentMethod.Calculate(p => p.GetCryptoPaymentData().PaymentCompleted(p, network));
|
||||
if (completedAccounting.Paid >= accounting.MinimumTotalDue)
|
||||
{
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1006, "invoice_completed"));
|
||||
context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1006, InvoiceEvent.Completed));
|
||||
invoice.Status = InvoiceStatus.Complete;
|
||||
context.MarkDirty();
|
||||
}
|
||||
|
@ -247,13 +247,13 @@ namespace BTCPayServer.HostedServices
|
|||
}));
|
||||
leases.Add(_EventAggregator.Subscribe<Events.InvoiceEvent>(async b =>
|
||||
{
|
||||
if (b.Name == "invoice_created")
|
||||
if (b.Name == InvoiceEvent.Created)
|
||||
{
|
||||
Watch(b.Invoice.Id);
|
||||
await Wait(b.Invoice.Id);
|
||||
}
|
||||
|
||||
if (b.Name == "invoice_receivedPayment")
|
||||
if (b.Name == InvoiceEvent.ReceivedPayment)
|
||||
{
|
||||
Watch(b.Invoice.Id);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,12 @@ namespace BTCPayServer.Models
|
|||
//{"facade":"pos/invoice","data":{,}}
|
||||
public class InvoiceResponse
|
||||
{
|
||||
[JsonIgnore]
|
||||
public string StoreId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
//"url":"https://test.bitpay.com/invoice?id=9saCHtp1zyPcNoi3rDdBu8"
|
||||
[JsonProperty("url")]
|
||||
public string Url
|
||||
|
|
|
@ -373,7 +373,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||
invoice.SetPaymentMethod(paymentMethod);
|
||||
}
|
||||
wallet.InvalidateCache(strategy);
|
||||
_Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, "invoice_receivedPayment"));
|
||||
_Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, InvoiceEvent.ReceivedPayment){Payment = payment});
|
||||
return invoice;
|
||||
}
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
{
|
||||
leases.Add(_Aggregator.Subscribe<Events.InvoiceEvent>(async inv =>
|
||||
{
|
||||
if (inv.Name == "invoice_created")
|
||||
if (inv.Name == InvoiceEvent.Created)
|
||||
{
|
||||
await EnsureListening(inv.Invoice.Id, false);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
{
|
||||
var invoice = await _InvoiceRepository.GetInvoice(listenedInvoice.InvoiceId);
|
||||
if (invoice != null)
|
||||
_Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, "invoice_receivedPayment"));
|
||||
_Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, InvoiceEvent.ReceivedPayment){Payment = payment});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue