diff --git a/BTCPayServer.Tests/PaymentRequestTests.cs b/BTCPayServer.Tests/PaymentRequestTests.cs index 5c098506e..98fa378cd 100644 --- a/BTCPayServer.Tests/PaymentRequestTests.cs +++ b/BTCPayServer.Tests/PaymentRequestTests.cs @@ -6,6 +6,7 @@ using BTCPayServer.Data; using BTCPayServer.Models.PaymentRequestViewModels; using BTCPayServer.Services.Invoices; using BTCPayServer.Services.PaymentRequests; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using NBitpayClient; using Xunit; @@ -101,7 +102,7 @@ namespace BTCPayServer.Tests user.RegisterDerivationScheme("BTC"); var paymentRequestController = user.GetController(); - + var repo = tester.PayTester.GetService(); Assert.IsType( await paymentRequestController.PayPaymentRequest(Guid.NewGuid().ToString())); @@ -112,20 +113,21 @@ namespace BTCPayServer.Tests Currency = "BTC", Amount = 1, StoreId = user.StoreId, - Description = "description" + Description = "description", + ExpiryDate = (DateTimeOffset.UtcNow + TimeSpan.FromDays(1.0)).UtcDateTime }; - var response = Assert + var prId = Assert .IsType(paymentRequestController.EditPaymentRequest(null, request).Result) - .RouteValues.Last(); + .RouteValues.Last().Value.ToString(); var invoiceId = Assert .IsType( - await paymentRequestController.PayPaymentRequest(response.Value.ToString(), false)).Value + await paymentRequestController.PayPaymentRequest(prId, false)).Value .ToString(); var actionResult = Assert .IsType( - await paymentRequestController.PayPaymentRequest(response.Value.ToString())); + await paymentRequestController.PayPaymentRequest(prId)); Assert.Equal("Checkout", actionResult.ActionName); Assert.Equal("UIInvoice", actionResult.ControllerName); @@ -135,6 +137,14 @@ namespace BTCPayServer.Tests var invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant); Assert.Equal(1, invoice.Price); + // Check if we can modify a PaymentRequest after an invoice has been made + request.ExpiryDate = null; + var paymentRequest = await repo.FindPaymentRequest(prId, null); + paymentRequestController.HttpContext.SetPaymentRequestData(paymentRequest); + Assert + .IsType(paymentRequestController.EditPaymentRequest(prId, request).Result) + .RouteValues.Last().Value.ToString(); + paymentRequestController.HttpContext.SetPaymentRequestData(null); request = new UpdatePaymentRequestViewModel() { Title = "original juice with expiry", @@ -145,13 +155,13 @@ namespace BTCPayServer.Tests Description = "description" }; - response = Assert + prId = Assert .IsType(paymentRequestController.EditPaymentRequest(null, request).Result) - .RouteValues.Last(); + .RouteValues.Last().Value.ToString(); Assert .IsType( - await paymentRequestController.PayPaymentRequest(response.Value.ToString(), false)); + await paymentRequestController.PayPaymentRequest(prId, false)); } [Fact(Timeout = 60 * 2 * 1000)] diff --git a/BTCPayServer/Controllers/UIPaymentRequestController.cs b/BTCPayServer/Controllers/UIPaymentRequestController.cs index 8071a5776..192347685 100644 --- a/BTCPayServer/Controllers/UIPaymentRequestController.cs +++ b/BTCPayServer/Controllers/UIPaymentRequestController.cs @@ -155,6 +155,7 @@ namespace BTCPayServer.Controllers [Authorize(Policy = Policies.CanModifyPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task EditPaymentRequest(string payReqId, UpdatePaymentRequestViewModel viewModel) { + viewModel.Id = payReqId; if (!string.IsNullOrEmpty(viewModel.Currency) && _Currencies.GetCurrencyData(viewModel.Currency, false) == null) ModelState.AddModelError(nameof(viewModel.Currency), "Invalid currency"); @@ -162,7 +163,8 @@ namespace BTCPayServer.Controllers viewModel.Currency = null; var store = GetCurrentStore(); var paymentRequest = GetCurrentPaymentRequest(); - if (paymentRequest == null && !string.IsNullOrEmpty(payReqId)) + if ((paymentRequest == null && !string.IsNullOrEmpty(payReqId)) || + (paymentRequest != null && paymentRequest.Id != payReqId)) { return NotFound(); } @@ -180,13 +182,16 @@ namespace BTCPayServer.Controllers data.Archived = viewModel.Archived; var blob = data.GetBlob(); - if (data.Amount != viewModel.Amount && payReqId != null) + var prInvoices = payReqId is null ? [] : (await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId())).Invoices; + viewModel.AmountAndCurrencyEditable = payReqId is null || !prInvoices.Any(); + if (!viewModel.AmountAndCurrencyEditable) { - var prInvoices = (await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId())).Invoices; - if (prInvoices.Any()) - ModelState.AddModelError(nameof(viewModel.Amount), StringLocalizer["Amount and currency are not editable once payment request has invoices"]); + ModelState.Remove(nameof(data.Amount)); + ModelState.Remove(nameof(data.Currency)); + viewModel.Amount = data.Amount; + viewModel.Currency = data.Currency; } - + if (!ModelState.IsValid) { var storeBlob = store.GetStoreBlob(); @@ -199,8 +204,8 @@ namespace BTCPayServer.Controllers blob.Email = viewModel.Email; blob.Description = viewModel.Description; data.Amount = viewModel.Amount; - data.Expiry = viewModel.ExpiryDate?.ToUniversalTime(); data.Currency = viewModel.Currency ?? store.GetStoreBlob().DefaultCurrency; + data.Expiry = viewModel.ExpiryDate?.ToUniversalTime(); blob.AllowCustomPaymentAmounts = viewModel.AllowCustomPaymentAmounts; blob.FormId = viewModel.FormId;