Enhance Invoice Events

This commit is contained in:
Kukks 2019-01-06 10:12:45 +01:00
parent 88150b6535
commit 5076d73695
9 changed files with 50 additions and 28 deletions

View file

@ -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;

View file

@ -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));

View file

@ -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" };
}

View file

@ -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})";

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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

View file

@ -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)

View file

@ -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});
}
}