Fix final bugs

This commit is contained in:
Kukks 2019-02-22 11:37:45 +01:00 committed by nicolas.dorier
parent ad25a2ed08
commit f5d366cf7f
8 changed files with 59 additions and 38 deletions

View file

@ -34,8 +34,6 @@ namespace BTCPayServer.Controllers
private readonly InvoiceController _InvoiceController; private readonly InvoiceController _InvoiceController;
private readonly UserManager<ApplicationUser> _UserManager; private readonly UserManager<ApplicationUser> _UserManager;
private readonly StoreRepository _StoreRepository; private readonly StoreRepository _StoreRepository;
private readonly RateFetcher _RateFetcher;
private readonly BTCPayNetworkProvider _BtcPayNetworkProvider;
private readonly PaymentRequestRepository _PaymentRequestRepository; private readonly PaymentRequestRepository _PaymentRequestRepository;
private readonly PaymentRequestService _PaymentRequestService; private readonly PaymentRequestService _PaymentRequestService;
private readonly EventAggregator _EventAggregator; private readonly EventAggregator _EventAggregator;
@ -46,8 +44,6 @@ namespace BTCPayServer.Controllers
InvoiceController invoiceController, InvoiceController invoiceController,
UserManager<ApplicationUser> userManager, UserManager<ApplicationUser> userManager,
StoreRepository storeRepository, StoreRepository storeRepository,
RateFetcher rateFetcher,
BTCPayNetworkProvider btcPayNetworkProvider,
PaymentRequestRepository paymentRequestRepository, PaymentRequestRepository paymentRequestRepository,
PaymentRequestService paymentRequestService, PaymentRequestService paymentRequestService,
EventAggregator eventAggregator, EventAggregator eventAggregator,
@ -57,8 +53,6 @@ namespace BTCPayServer.Controllers
_InvoiceController = invoiceController; _InvoiceController = invoiceController;
_UserManager = userManager; _UserManager = userManager;
_StoreRepository = storeRepository; _StoreRepository = storeRepository;
_RateFetcher = rateFetcher;
_BtcPayNetworkProvider = btcPayNetworkProvider;
_PaymentRequestRepository = paymentRequestRepository; _PaymentRequestRepository = paymentRequestRepository;
_PaymentRequestService = paymentRequestService; _PaymentRequestService = paymentRequestService;
_EventAggregator = eventAggregator; _EventAggregator = eventAggregator;
@ -135,6 +129,8 @@ namespace BTCPayServer.Controllers
return NotFound(); return NotFound();
} }
var oldStatus = data?.Status ?? PaymentRequestData.PaymentRequestStatus.Creating;
if (data != null && data.Status != PaymentRequestData.PaymentRequestStatus.Creating) if (data != null && data.Status != PaymentRequestData.PaymentRequestStatus.Creating)
{ {
return RedirectToAction("ViewPaymentRequest", new return RedirectToAction("ViewPaymentRequest", new
@ -176,8 +172,11 @@ namespace BTCPayServer.Controllers
_EventAggregator.Publish(new PaymentRequestUpdated() _EventAggregator.Publish(new PaymentRequestUpdated()
{ {
Data = data, Data = data,
PaymentRequestId = data.Id PaymentRequestId = data.Id,
Published = oldStatus == PaymentRequestData.PaymentRequestStatus.Creating &&
data.Status != PaymentRequestData.PaymentRequestStatus.Creating
}); });
return RedirectToAction("EditPaymentRequest", new {id = data.Id, StatusMessage = "Saved"}); return RedirectToAction("EditPaymentRequest", new {id = data.Id, StatusMessage = "Saved"});
} }
@ -307,7 +306,7 @@ namespace BTCPayServer.Controllers
store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id)); store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
try try
{ {
var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new Invoice() var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
{ {
OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}", OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}",
Currency = blob.Currency, Currency = blob.Currency,

View file

@ -34,6 +34,7 @@ using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc.Cors.Internal; using Microsoft.AspNetCore.Mvc.Cors.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Net; using System.Net;
using BTCPayServer.PaymentRequest;
using Meziantou.AspNetCore.BundleTagHelpers; using Meziantou.AspNetCore.BundleTagHelpers;
using BTCPayServer.Security; using BTCPayServer.Security;
using BTCPayServer.Services.Apps; using BTCPayServer.Services.Apps;
@ -165,6 +166,7 @@ namespace BTCPayServer.Hosting
app.UseSignalR(route => app.UseSignalR(route =>
{ {
route.MapHub<AppHub>("/apps/hub"); route.MapHub<AppHub>("/apps/hub");
route.MapHub<PaymentRequestHub>("/payment-requests/hub");
}); });
app.UseWebSockets(); app.UseWebSockets();
app.UseStatusCodePages(); app.UseStatusCodePages();

View file

@ -44,7 +44,8 @@ namespace BTCPayServer.PaymentRequest
public async Task Pay(decimal? amount = null) public async Task Pay(decimal? amount = null)
{ {
_PaymentRequestController.ControllerContext.HttpContext = Context.GetHttpContext(); _PaymentRequestController.ControllerContext.HttpContext = Context.GetHttpContext();
var result = await _PaymentRequestController.PayPaymentRequest(Context.Items["pr-id"].ToString(), false, amount); var result =
await _PaymentRequestController.PayPaymentRequest(Context.Items["pr-id"].ToString(), false, amount);
switch (result) switch (result)
{ {
case OkObjectResult okObjectResult: case OkObjectResult okObjectResult:
@ -60,31 +61,28 @@ namespace BTCPayServer.PaymentRequest
} }
} }
public class PaymentRequestStreamer : EventHostedServiceBase public class PaymentRequestStreamer : EventHostedServiceBase
{ {
private readonly IHubContext<PaymentRequestHub> _HubContext; private readonly IHubContext<PaymentRequestHub> _HubContext;
private readonly PaymentRequestRepository _PaymentRequestRepository; private readonly PaymentRequestRepository _PaymentRequestRepository;
private readonly AppService _AppService;
private readonly PaymentRequestService _PaymentRequestService; private readonly PaymentRequestService _PaymentRequestService;
public PaymentRequestStreamer(EventAggregator eventAggregator, public PaymentRequestStreamer(EventAggregator eventAggregator,
IHubContext<PaymentRequestHub> hubContext, IHubContext<PaymentRequestHub> hubContext,
PaymentRequestRepository paymentRequestRepository, PaymentRequestRepository paymentRequestRepository,
AppService appService,
PaymentRequestService paymentRequestService) : base(eventAggregator) PaymentRequestService paymentRequestService) : base(eventAggregator)
{ {
_HubContext = hubContext; _HubContext = hubContext;
_PaymentRequestRepository = paymentRequestRepository; _PaymentRequestRepository = paymentRequestRepository;
_AppService = appService;
_PaymentRequestService = paymentRequestService; _PaymentRequestService = paymentRequestService;
} }
public override async Task StartAsync(CancellationToken cancellationToken) public override async Task StartAsync(CancellationToken cancellationToken)
{ {
await base.StartAsync(cancellationToken); await base.StartAsync(cancellationToken);
_CheckingPendingPayments = CheckingPendingPayments(cancellationToken).ContinueWith(_ => _CheckingPendingPayments = null, TaskScheduler.Default); _CheckingPendingPayments = CheckingPendingPayments(cancellationToken)
.ContinueWith(_ => _CheckingPendingPayments = null, TaskScheduler.Default);
} }
private async Task CheckingPendingPayments(CancellationToken cancellationToken) private async Task CheckingPendingPayments(CancellationToken cancellationToken)
@ -92,19 +90,22 @@ namespace BTCPayServer.PaymentRequest
Logs.PayServer.LogInformation("Starting payment request expiration watcher"); Logs.PayServer.LogInformation("Starting payment request expiration watcher");
var (total, items) = await _PaymentRequestRepository.FindPaymentRequests(new PaymentRequestQuery() var (total, items) = await _PaymentRequestRepository.FindPaymentRequests(new PaymentRequestQuery()
{ {
Status = new[] { PaymentRequestData.PaymentRequestStatus.Pending } Status = new[] {PaymentRequestData.PaymentRequestStatus.Pending}
}, cancellationToken); }, cancellationToken);
Logs.PayServer.LogInformation($"{total} pending payment requests being checked since last run"); Logs.PayServer.LogInformation($"{total} pending payment requests being checked since last run");
await Task.WhenAll(items.Select(i => _PaymentRequestService.UpdatePaymentRequestStateIfNeeded(i)).ToArray()); await Task.WhenAll(items.Select(i => _PaymentRequestService.UpdatePaymentRequestStateIfNeeded(i))
.ToArray());
} }
Task _CheckingPendingPayments; Task _CheckingPendingPayments;
public override async Task StopAsync(CancellationToken cancellationToken) public override async Task StopAsync(CancellationToken cancellationToken)
{ {
await base.StopAsync(cancellationToken); await base.StopAsync(cancellationToken);
await (_CheckingPendingPayments ?? Task.CompletedTask); await (_CheckingPendingPayments ?? Task.CompletedTask);
} }
protected override void SubscibeToEvents() protected override void SubscibeToEvents()
{ {
Subscribe<InvoiceEvent>(); Subscribe<InvoiceEvent>();
@ -116,7 +117,7 @@ namespace BTCPayServer.PaymentRequest
if (evt is InvoiceEvent invoiceEvent) if (evt is InvoiceEvent invoiceEvent)
{ {
var paymentRequestId = var paymentRequestId =
PaymentRequestRepository.GetPaymentRequestIdFromOrderId(invoiceEvent.Invoice.OrderId); PaymentRequestRepository.GetPaymentRequestIdFromOrderId(invoiceEvent.Invoice.OrderId);
if (invoiceEvent.Name == InvoiceEvent.ReceivedPayment) if (invoiceEvent.Name == InvoiceEvent.ReceivedPayment)
{ {
@ -131,14 +132,18 @@ namespace BTCPayServer.PaymentRequest
invoiceEvent.Payment.GetPaymentMethodId().PaymentType) invoiceEvent.Payment.GetPaymentMethodId().PaymentType)
}); });
} }
await InfoUpdated(paymentRequestId); await InfoUpdated(paymentRequestId);
} }
else if (evt is PaymentRequestUpdated updated) else if (evt is PaymentRequestUpdated updated)
{ {
if (updated.Data.Status != PaymentRequestData.PaymentRequestStatus.Creating) if (updated.Published)
{ {
await InfoUpdated(updated.PaymentRequestId); await _PaymentRequestService.UpdatePaymentRequestStateIfNeeded(updated.Data);
} }
await InfoUpdated(updated.PaymentRequestId);
var expiry = updated.Data.GetBlob().ExpiryDate; var expiry = updated.Data.GetBlob().ExpiryDate;
if (updated.Data.Status == PaymentRequestData.PaymentRequestStatus.Pending && if (updated.Data.Status == PaymentRequestData.PaymentRequestStatus.Pending &&
expiry.HasValue) expiry.HasValue)
@ -165,10 +170,10 @@ namespace BTCPayServer.PaymentRequest
private async Task InfoUpdated(string paymentRequestId) private async Task InfoUpdated(string paymentRequestId)
{ {
var req = await _PaymentRequestService.GetPaymentRequest(paymentRequestId); var req = await _PaymentRequestService.GetPaymentRequest(paymentRequestId);
if(req != null) if (req != null)
{ {
await _HubContext.Clients.Group(paymentRequestId) await _HubContext.Clients.Group(paymentRequestId)
.SendCoreAsync(PaymentRequestHub.InfoUpdated, new object[] { req }); .SendCoreAsync(PaymentRequestHub.InfoUpdated, new object[] {req});
} }
} }
} }

View file

@ -15,21 +15,18 @@ namespace BTCPayServer.PaymentRequest
{ {
public class PaymentRequestService public class PaymentRequestService
{ {
private readonly IHubContext<PaymentRequestHub> _HubContext;
private readonly PaymentRequestRepository _PaymentRequestRepository; private readonly PaymentRequestRepository _PaymentRequestRepository;
private readonly BTCPayNetworkProvider _BtcPayNetworkProvider; private readonly BTCPayNetworkProvider _BtcPayNetworkProvider;
private readonly AppService _AppService; private readonly AppService _AppService;
private readonly CurrencyNameTable _currencies; private readonly CurrencyNameTable _currencies;
public PaymentRequestService(EventAggregator eventAggregator, public PaymentRequestService(
IHubContext<PaymentRequestHub> hubContext, IHubContext<PaymentRequestHub> hubContext,
PaymentRequestRepository paymentRequestRepository, PaymentRequestRepository paymentRequestRepository,
BTCPayNetworkProvider btcPayNetworkProvider, BTCPayNetworkProvider btcPayNetworkProvider,
AppService appService, AppService appService,
CurrencyNameTable currencies) CurrencyNameTable currencies)
{ {
_HubContext = hubContext;
_PaymentRequestRepository = paymentRequestRepository; _PaymentRequestRepository = paymentRequestRepository;
_BtcPayNetworkProvider = btcPayNetworkProvider; _BtcPayNetworkProvider = btcPayNetworkProvider;
_AppService = appService; _AppService = appService;
@ -43,6 +40,7 @@ namespace BTCPayServer.PaymentRequest
{ {
return; return;
} }
await UpdatePaymentRequestStateIfNeeded(pr); await UpdatePaymentRequestStateIfNeeded(pr);
} }
@ -55,7 +53,7 @@ namespace BTCPayServer.PaymentRequest
if (blob.ExpiryDate.Value <= DateTimeOffset.UtcNow) if (blob.ExpiryDate.Value <= DateTimeOffset.UtcNow)
currentStatus = PaymentRequestData.PaymentRequestStatus.Expired; currentStatus = PaymentRequestData.PaymentRequestStatus.Expired;
} }
else if(pr.Status == PaymentRequestData.PaymentRequestStatus.Pending) else if (pr.Status == PaymentRequestData.PaymentRequestStatus.Pending)
{ {
var rateRules = pr.StoreData.GetStoreBlob().GetRateRules(_BtcPayNetworkProvider); var rateRules = pr.StoreData.GetStoreBlob().GetRateRules(_BtcPayNetworkProvider);
var invoices = await _PaymentRequestRepository.GetInvoicesForPaymentRequest(pr.Id); var invoices = await _PaymentRequestRepository.GetInvoicesForPaymentRequest(pr.Id);
@ -67,6 +65,7 @@ namespace BTCPayServer.PaymentRequest
currentStatus = PaymentRequestData.PaymentRequestStatus.Completed; currentStatus = PaymentRequestData.PaymentRequestStatus.Completed;
} }
} }
if (pr.Status != PaymentRequestData.PaymentRequestStatus.Creating && currentStatus != pr.Status) if (pr.Status != PaymentRequestData.PaymentRequestStatus.Creating && currentStatus != pr.Status)
{ {
pr.Status = currentStatus; pr.Status = currentStatus;

View file

@ -179,6 +179,7 @@ namespace BTCPayServer.Services.PaymentRequests
{ {
public string PaymentRequestId { get; set; } public string PaymentRequestId { get; set; }
public PaymentRequestData Data { get; set; } public PaymentRequestData Data { get; set; }
public bool Published { get; set; }
} }
public class PaymentRequestQuery public class PaymentRequestQuery

View file

@ -40,7 +40,7 @@
<label asp-for="AllowCustomPaymentAmounts"></label> <label asp-for="AllowCustomPaymentAmounts"></label>
<input asp-for="AllowCustomPaymentAmounts" type="checkbox" class="form-check"/> <input asp-for="AllowCustomPaymentAmounts" type="checkbox" class="form-check"/>
<span asp-validation-for="AllowCustomPaymentAmounts" class="text-danger"></span> <span asp-validation-for="AllowCustomPaymentAmounts" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="StoreId" class="control-label"></label> <label asp-for="StoreId" class="control-label"></label>
@ -82,20 +82,25 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="CustomCSSLink" class="control-label"></label> <label asp-for="CustomCSSLink" class="control-label"></label>
<a href="https://docs.btcpayserver.org/development/theme#bootstrap-themes" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a> <a href="https://docs.btcpayserver.org/development/theme#bootstrap-themes" target="_blank">
<input asp-for="CustomCSSLink" class="form-control" /> <span class="fa fa-question-circle-o" title="More information..."></span>
</a>
<input asp-for="CustomCSSLink" class="form-control"/>
<span asp-validation-for="CustomCSSLink" class="text-danger"></span> <span asp-validation-for="CustomCSSLink" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="EmbeddedCSS" class="control-label"></label> <label asp-for="EmbeddedCSS" class="control-label"></label>
<textarea asp-for="EmbeddedCSS" rows="10" cols="40" class="form-control"></textarea> <textarea asp-for="EmbeddedCSS" rows="10" cols="40" class="form-control"></textarea>
<span asp-validation-for="EmbeddedCSS" class="text-danger"></span> <span asp-validation-for="EmbeddedCSS" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-primary" name="action" value="draft">Save for later</button> <button type="submit" class="btn btn-primary" name="action" value="draft">Save for later</button>
<button type="submit" class="btn btn-primary" name="action" value="publish">Save & Publish</button> <button type="submit" class="btn btn-primary" name="action" value="publish">Save & Publish</button>
@if (!string.IsNullOrEmpty(Model.Id))
{
<a class="btn btn-secondary" target="_blank" asp-action="ViewPaymentRequest" id="@Model.Id">View</a>
}
<a class="btn btn-secondary" target="_blank" asp-action="GetPaymentRequests">Back to list</a> <a class="btn btn-secondary" target="_blank" asp-action="GetPaymentRequests">Back to list</a>
</div> </div>
</form> </form>

View file

@ -3,6 +3,13 @@
<div class="container"> <div class="container">
<div class="row w-100 p-0 m-0" style="height: 100vh"> <div class="row w-100 p-0 m-0" style="height: 100vh">
<div class="mx-auto my-auto w-100"> <div class="mx-auto my-auto w-100">
@if (Model.Status == "Creating")
{
<div class="w-100 alert alert-danger text-center font-weight-bold d-print-none">
This payment request is still in creation mode and can only be viewed by you. Please publish from the settings in order to be able to share it.
</div>
}
<div class="card"> <div class="card">
<h1 class="card-header"> <h1 class="card-header">
@Model.Title @Model.Title
@ -117,7 +124,7 @@
class="form-control" class="form-control"
type="number" type="number"
name="amount" name="amount"
value="@Model.AmountDue" value="@Model.AmountDue"
max="@Model.AmountDue" max="@Model.AmountDue"
step="any" step="any"
@ -127,7 +134,7 @@
<span class='input-group-text'>@Model.Currency.ToUpper()</span> <span class='input-group-text'>@Model.Currency.ToUpper()</span>
<button <button
class="btn btn-primary" class="btn btn-primary"
type="submit"> type="submit">
Pay now Pay now
</button> </button>
</div> </div>

View file

@ -51,6 +51,9 @@ else
<div class="container" id="app" v-cloak> <div class="container" id="app" v-cloak>
<div class="row w-100 p-0 m-0" style="height: 100vh"> <div class="row w-100 p-0 m-0" style="height: 100vh">
<div class="mx-auto my-auto w-100"> <div class="mx-auto my-auto w-100">
<div v-if="srvModel.status === 'Creating'" class="w-100 alert alert-danger text-center font-weight-bold d-print-none">
This payment request is still in creation mode and can only be viewed by you. Please publish from the settings in order to be able to share it.
</div>
<div class="card"> <div class="card">
<h1 class="card-header"> <h1 class="card-header">
{{srvModel.title}} {{srvModel.title}}
@ -117,7 +120,7 @@ else
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered"> <table class="table table-bordered">
<tr> <tr>
<th class="p-1" style="max-width: 300px">Tx Id</th> <th class="p-1" style="max-width: 300px">Tx Id</th>
<th class="p-1">Payment Method</th> <th class="p-1">Payment Method</th>
<th class="p-1">Amount</th> <th class="p-1">Amount</th>
<th class="p-1">Link</th> <th class="p-1">Link</th>
@ -149,7 +152,7 @@ else
<template v-if="srvModel.allowCustomPaymentAmounts && !srvModel.anyPendingInvoice"> <template v-if="srvModel.allowCustomPaymentAmounts && !srvModel.anyPendingInvoice">
<form v-on:submit="submitCustomAmountForm"> <form v-on:submit="submitCustomAmountForm">
<div class="input-group m-auto" style="max-width:250px "> <div class="input-group m-auto" style="max-width: 250px">
<input <input
:readonly="!srvModel.allowCustomPaymentAmounts" :readonly="!srvModel.allowCustomPaymentAmounts"
class="form-control" class="form-control"