2019-01-14 22:43:29 +01:00
using System ;
using System.Linq ;
2019-03-05 17:09:17 +09:00
using System.Threading ;
2019-01-14 22:43:29 +01:00
using System.Threading.Tasks ;
2020-11-17 13:46:23 +01:00
using BTCPayServer.Abstractions.Constants ;
2024-01-11 16:25:56 +01:00
using BTCPayServer.Abstractions.Extensions ;
2022-11-25 16:11:13 +09:00
using BTCPayServer.Abstractions.Form ;
2024-01-11 16:25:56 +01:00
using BTCPayServer.Abstractions.Models ;
2021-12-11 04:32:23 +01:00
using BTCPayServer.Client ;
2020-07-24 09:40:37 +02:00
using BTCPayServer.Client.Models ;
2019-01-14 22:43:29 +01:00
using BTCPayServer.Data ;
using BTCPayServer.Filters ;
2022-11-25 18:14:33 +09:00
using BTCPayServer.Forms ;
2023-02-20 11:35:54 +01:00
using BTCPayServer.Forms.Models ;
2023-12-01 16:13:44 +01:00
using BTCPayServer.Models ;
2019-01-14 22:43:29 +01:00
using BTCPayServer.Models.PaymentRequestViewModels ;
using BTCPayServer.PaymentRequest ;
2023-03-13 02:12:58 +01:00
using BTCPayServer.Services ;
2019-01-14 22:43:29 +01:00
using BTCPayServer.Services.Invoices ;
using BTCPayServer.Services.PaymentRequests ;
using BTCPayServer.Services.Rates ;
using BTCPayServer.Services.Stores ;
using Microsoft.AspNetCore.Authorization ;
using Microsoft.AspNetCore.Identity ;
using Microsoft.AspNetCore.Mvc ;
2020-07-24 09:40:37 +02:00
using PaymentRequestData = BTCPayServer . Data . PaymentRequestData ;
using StoreData = BTCPayServer . Data . StoreData ;
2019-01-14 22:43:29 +01:00
namespace BTCPayServer.Controllers
{
[Route("payment-requests")]
2023-12-14 12:42:07 +01:00
[Authorize(Policy = Policies.CanViewPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2022-01-07 12:32:00 +09:00
public class UIPaymentRequestController : Controller
2019-01-14 22:43:29 +01:00
{
2022-01-07 12:32:00 +09:00
private readonly UIInvoiceController _InvoiceController ;
2019-01-14 22:43:29 +01:00
private readonly UserManager < ApplicationUser > _UserManager ;
private readonly PaymentRequestRepository _PaymentRequestRepository ;
private readonly PaymentRequestService _PaymentRequestService ;
private readonly EventAggregator _EventAggregator ;
private readonly CurrencyNameTable _Currencies ;
2023-03-13 02:12:58 +01:00
private readonly DisplayFormatter _displayFormatter ;
2019-05-07 08:26:40 +00:00
private readonly InvoiceRepository _InvoiceRepository ;
2022-11-10 15:12:15 +01:00
private readonly StoreRepository _storeRepository ;
2024-05-09 02:18:02 +02:00
private readonly UriResolver _uriResolver ;
2024-01-11 16:25:56 +01:00
private readonly BTCPayNetworkProvider _networkProvider ;
2019-01-14 22:43:29 +01:00
2022-11-26 05:01:00 +01:00
private FormComponentProviders FormProviders { get ; }
2023-02-20 11:35:54 +01:00
public FormDataService FormDataService { get ; }
2022-11-25 18:14:33 +09:00
2022-01-07 12:32:00 +09:00
public UIPaymentRequestController (
UIInvoiceController invoiceController ,
2019-01-14 22:43:29 +01:00
UserManager < ApplicationUser > userManager ,
PaymentRequestRepository paymentRequestRepository ,
PaymentRequestService paymentRequestService ,
EventAggregator eventAggregator ,
CurrencyNameTable currencies ,
2023-03-13 02:12:58 +01:00
DisplayFormatter displayFormatter ,
2022-11-10 15:12:15 +01:00
StoreRepository storeRepository ,
2024-05-09 02:18:02 +02:00
UriResolver uriResolver ,
2022-11-25 18:14:33 +09:00
InvoiceRepository invoiceRepository ,
2023-02-20 11:35:54 +01:00
FormComponentProviders formProviders ,
2024-01-11 16:25:56 +01:00
FormDataService formDataService ,
BTCPayNetworkProvider networkProvider )
2019-01-14 22:43:29 +01:00
{
_InvoiceController = invoiceController ;
_UserManager = userManager ;
_PaymentRequestRepository = paymentRequestRepository ;
_PaymentRequestService = paymentRequestService ;
_EventAggregator = eventAggregator ;
_Currencies = currencies ;
2023-03-13 02:12:58 +01:00
_displayFormatter = displayFormatter ;
2022-11-10 15:12:15 +01:00
_storeRepository = storeRepository ;
2024-05-09 02:18:02 +02:00
_uriResolver = uriResolver ;
2019-05-07 08:26:40 +00:00
_InvoiceRepository = invoiceRepository ;
2022-11-25 18:14:33 +09:00
FormProviders = formProviders ;
2023-02-20 11:35:54 +01:00
FormDataService = formDataService ;
2024-01-11 16:25:56 +01:00
_networkProvider = networkProvider ;
2019-01-14 22:43:29 +01:00
}
2021-12-11 04:32:23 +01:00
[HttpGet("/stores/{storeId}/payment-requests")]
2023-12-01 09:12:02 +01:00
[Authorize(Policy = Policies.CanViewPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > GetPaymentRequests ( string storeId , ListPaymentRequestsViewModel model = null )
2019-01-14 22:43:29 +01:00
{
2020-07-30 09:10:10 -05:00
model = this . ParseListQuery ( model ? ? new ListPaymentRequestsViewModel ( ) ) ;
2020-07-19 16:40:57 -05:00
2021-12-20 15:15:32 +01:00
var store = GetCurrentStore ( ) ;
2023-07-06 09:02:23 +01:00
var fs = new SearchString ( model . SearchTerm , model . TimezoneOffset ? ? 0 ) ;
2021-12-11 04:32:23 +01:00
var result = await _PaymentRequestRepository . FindPaymentRequests ( new PaymentRequestQuery
2019-01-14 22:43:29 +01:00
{
2020-06-28 17:55:27 +09:00
UserId = GetUserId ( ) ,
2021-12-20 15:15:32 +01:00
StoreId = store . Id ,
2020-07-30 09:10:10 -05:00
Skip = model . Skip ,
Count = model . Count ,
2023-07-06 09:02:23 +01:00
Status = fs . GetFilterArray ( "status" ) ? . Select ( s = > Enum . Parse < Client . Models . PaymentRequestData . PaymentRequestStatus > ( s , true ) ) . ToArray ( ) ,
IncludeArchived = fs . GetFilterBool ( "includearchived" ) ? ? false
2019-01-14 22:43:29 +01:00
} ) ;
2023-07-06 09:02:23 +01:00
model . Search = fs ;
model . SearchText = fs . TextSearch ;
2022-11-18 05:24:57 +01:00
model . Items = result . Select ( data = >
{
var blob = data . GetBlob ( ) ;
return new ViewPaymentRequestViewModel ( data )
{
2023-03-13 02:12:58 +01:00
AmountFormatted = _displayFormatter . Currency ( blob . Amount , blob . Currency )
2022-11-18 05:24:57 +01:00
} ;
} ) . ToList ( ) ;
2023-01-06 14:18:07 +01:00
2020-07-30 09:10:10 -05:00
return View ( model ) ;
2019-01-14 22:43:29 +01:00
}
2021-12-11 04:32:23 +01:00
[HttpGet("/stores/{storeId}/payment-requests/edit/{payReqId?}")]
2024-03-14 10:25:40 +01:00
[Authorize(Policy = Policies.CanModifyPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2022-12-13 21:01:48 -08:00
public async Task < IActionResult > EditPaymentRequest ( string storeId , string payReqId )
2019-01-14 22:43:29 +01:00
{
2021-12-20 15:15:32 +01:00
var store = GetCurrentStore ( ) ;
2024-01-11 16:25:56 +01:00
if ( store = = null )
{
return NotFound ( ) ;
}
2021-12-20 15:15:32 +01:00
var paymentRequest = GetCurrentPaymentRequest ( ) ;
if ( paymentRequest = = null & & ! string . IsNullOrEmpty ( payReqId ) )
2019-01-14 22:43:29 +01:00
{
return NotFound ( ) ;
}
2024-04-04 16:31:04 +09:00
if ( ! store . AnyPaymentMethodAvailable ( ) )
2024-01-11 16:25:56 +01:00
{
return NoPaymentMethodResult ( storeId ) ;
}
2023-12-01 10:50:05 +01:00
var storeBlob = store . GetStoreBlob ( ) ;
2022-12-13 21:01:48 -08:00
var prInvoices = payReqId is null ? null : ( await _PaymentRequestService . GetPaymentRequest ( payReqId , GetUserId ( ) ) ) . Invoices ;
2022-04-11 10:50:30 +02:00
var vm = new UpdatePaymentRequestViewModel ( paymentRequest )
2019-01-14 22:43:29 +01:00
{
2022-12-13 21:01:48 -08:00
StoreId = store . Id ,
AmountAndCurrencyEditable = payReqId is null | | ! prInvoices . Any ( )
2022-04-11 10:50:30 +02:00
} ;
2023-12-01 10:50:05 +01:00
vm . Currency ? ? = storeBlob . DefaultCurrency ;
vm . HasEmailRules = storeBlob . EmailRules ? . Any ( rule = >
rule . Trigger . Contains ( "PaymentRequest" , StringComparison . InvariantCultureIgnoreCase ) ) ;
2022-04-11 10:50:30 +02:00
return View ( nameof ( EditPaymentRequest ) , vm ) ;
2019-01-14 22:43:29 +01:00
}
2021-12-11 04:32:23 +01:00
[HttpPost("/stores/{storeId}/payment-requests/edit/{payReqId?}")]
2023-12-01 09:12:02 +01:00
[Authorize(Policy = Policies.CanModifyPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > EditPaymentRequest ( string payReqId , UpdatePaymentRequestViewModel viewModel )
2019-01-14 22:43:29 +01:00
{
2022-01-11 18:42:44 +09:00
if ( ! string . IsNullOrEmpty ( viewModel . Currency ) & &
2019-01-14 22:43:29 +01:00
_Currencies . GetCurrencyData ( viewModel . Currency , false ) = = null )
ModelState . AddModelError ( nameof ( viewModel . Currency ) , "Invalid currency" ) ;
2022-01-11 18:42:44 +09:00
if ( string . IsNullOrEmpty ( viewModel . Currency ) )
viewModel . Currency = null ;
2021-12-20 15:15:32 +01:00
var store = GetCurrentStore ( ) ;
var paymentRequest = GetCurrentPaymentRequest ( ) ;
if ( paymentRequest = = null & & ! string . IsNullOrEmpty ( payReqId ) )
2019-01-14 22:43:29 +01:00
{
return NotFound ( ) ;
}
2024-04-04 16:31:04 +09:00
if ( ! store . AnyPaymentMethodAvailable ( ) )
2024-01-11 16:25:56 +01:00
{
return NoPaymentMethodResult ( store . Id ) ;
}
2021-12-20 15:15:32 +01:00
if ( paymentRequest ? . Archived is true & & viewModel . Archived )
2020-05-08 12:33:47 +02:00
{
ModelState . AddModelError ( string . Empty , "You cannot edit an archived payment request." ) ;
}
2022-12-13 21:01:48 -08:00
var data = paymentRequest ? ? new PaymentRequestData ( ) ;
data . StoreDataId = viewModel . StoreId ;
data . Archived = viewModel . Archived ;
var blob = data . GetBlob ( ) ;
if ( blob . Amount ! = viewModel . Amount & & payReqId ! = null )
{
var prInvoices = ( await _PaymentRequestService . GetPaymentRequest ( payReqId , GetUserId ( ) ) ) . Invoices ;
if ( prInvoices . Any ( ) )
ModelState . AddModelError ( nameof ( viewModel . Amount ) , "Amount and currency are not editable once payment request has invoices" ) ;
}
2020-05-08 12:33:47 +02:00
2019-01-14 22:43:29 +01:00
if ( ! ModelState . IsValid )
{
2023-12-01 10:50:05 +01:00
var storeBlob = store . GetStoreBlob ( ) ;
viewModel . HasEmailRules = storeBlob . EmailRules ? . Any ( rule = >
rule . Trigger . Contains ( "PaymentRequest" , StringComparison . InvariantCultureIgnoreCase ) ) ;
2020-06-28 17:55:27 +09:00
return View ( nameof ( EditPaymentRequest ) , viewModel ) ;
2019-01-14 22:43:29 +01:00
}
blob . Title = viewModel . Title ;
blob . Email = viewModel . Email ;
2019-08-10 14:05:11 +09:00
blob . Description = viewModel . Description ;
2019-01-14 22:43:29 +01:00
blob . Amount = viewModel . Amount ;
2019-05-15 08:02:39 -05:00
blob . ExpiryDate = viewModel . ExpiryDate ? . ToUniversalTime ( ) ;
2022-01-11 18:42:44 +09:00
blob . Currency = viewModel . Currency ? ? store . GetStoreBlob ( ) . DefaultCurrency ;
2019-01-14 22:43:29 +01:00
blob . AllowCustomPaymentAmounts = viewModel . AllowCustomPaymentAmounts ;
2022-11-25 02:42:55 +01:00
blob . FormId = viewModel . FormId ;
2019-01-14 22:43:29 +01:00
data . SetBlob ( blob ) ;
2022-06-04 14:33:26 -07:00
var isNewPaymentRequest = string . IsNullOrEmpty ( payReqId ) ;
if ( isNewPaymentRequest )
2019-07-01 17:22:54 +09:00
{
data . Created = DateTimeOffset . UtcNow ;
}
2020-05-08 12:33:47 +02:00
2019-01-14 22:43:29 +01:00
data = await _PaymentRequestRepository . CreateOrUpdatePaymentRequest ( data ) ;
2021-08-31 08:07:54 +02:00
_EventAggregator . Publish ( new PaymentRequestUpdated { Data = data , PaymentRequestId = data . Id , } ) ;
2019-02-22 11:37:45 +01:00
2022-06-19 19:52:12 -07:00
TempData [ WellKnownTempData . SuccessMessage ] = $"Payment request \" { viewModel . Title } \ " {(isNewPaymentRequest ? " created " : " updated ")} successfully" ;
2022-06-04 14:33:26 -07:00
return RedirectToAction ( nameof ( GetPaymentRequests ) , new { storeId = store . Id , payReqId = data . Id } ) ;
2019-01-14 22:43:29 +01:00
}
2021-12-11 04:32:23 +01:00
[HttpGet("{payReqId}")]
2019-01-14 22:43:29 +01:00
[AllowAnonymous]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > ViewPaymentRequest ( string payReqId )
2019-01-14 22:43:29 +01:00
{
2023-01-30 09:23:49 +01:00
var vm = await _PaymentRequestService . GetPaymentRequest ( payReqId , GetUserId ( ) ) ;
if ( vm = = null )
2019-01-14 22:43:29 +01:00
{
return NotFound ( ) ;
}
2023-01-30 09:23:49 +01:00
var store = await _storeRepository . FindStore ( vm . StoreId ) ;
if ( store = = null )
{
return NotFound ( ) ;
}
2023-04-10 11:07:03 +09:00
2023-01-30 09:23:49 +01:00
var storeBlob = store . GetStoreBlob ( ) ;
2023-12-01 16:13:44 +01:00
vm . HubPath = PaymentRequestHub . GetHubPath ( Request ) ;
2023-01-30 09:23:49 +01:00
vm . StoreName = store . StoreName ;
2023-11-20 02:45:43 +01:00
vm . StoreWebsite = store . StoreWebsite ;
2024-05-09 02:18:02 +02:00
vm . StoreBranding = await StoreBrandingViewModel . CreateAsync ( Request , _uriResolver , storeBlob ) ;
2023-04-10 11:07:03 +09:00
2023-01-30 09:23:49 +01:00
return View ( vm ) ;
2019-01-14 22:43:29 +01:00
}
2022-11-25 02:42:55 +01:00
[HttpGet("{payReqId}/form")]
[HttpPost("{payReqId}/form")]
[AllowAnonymous]
2023-03-01 07:27:18 +01:00
[XFrameOptions(XFrameOptionsAttribute.XFrameOptions.Unset)]
2023-02-20 11:35:54 +01:00
public async Task < IActionResult > ViewPaymentRequestForm ( string payReqId , FormViewModel viewModel )
2022-11-25 02:42:55 +01:00
{
var result = await _PaymentRequestRepository . FindPaymentRequest ( payReqId , GetUserId ( ) ) ;
if ( result = = null )
{
return NotFound ( ) ;
}
var prBlob = result . GetBlob ( ) ;
2023-02-20 11:35:54 +01:00
if ( prBlob . FormResponse is not null )
{
2023-04-10 11:07:03 +09:00
return RedirectToAction ( "PayPaymentRequest" , new { payReqId } ) ;
2023-02-20 11:35:54 +01:00
}
2022-11-25 02:42:55 +01:00
var prFormId = prBlob . FormId ;
2023-02-20 11:35:54 +01:00
var formData = await FormDataService . GetForm ( prFormId ) ;
if ( formData is null )
2022-11-25 02:42:55 +01:00
{
2023-04-10 11:07:03 +09:00
return RedirectToAction ( "PayPaymentRequest" , new { payReqId } ) ;
2022-11-25 16:11:13 +09:00
}
2023-02-20 11:35:54 +01:00
var form = Form . Parse ( formData . Config ) ;
2023-04-26 09:45:35 +02:00
if ( ! string . IsNullOrEmpty ( prBlob . Email ) )
{
var emailField = form . GetFieldByFullName ( "buyerEmail" ) ;
if ( emailField is not null )
{
emailField . Value = prBlob . Email ;
}
}
2023-02-20 11:35:54 +01:00
if ( Request . Method = = "POST" & & Request . HasFormContentType )
2022-11-25 16:11:13 +09:00
{
2023-02-20 11:35:54 +01:00
form . ApplyValuesFromForm ( Request . Form ) ;
if ( FormDataService . Validate ( form , ModelState ) )
2023-04-10 11:07:03 +09:00
{
2023-04-04 04:01:34 +02:00
prBlob . FormResponse = FormDataService . GetValues ( form ) ;
2024-04-12 12:56:11 +02:00
if ( string . IsNullOrEmpty ( prBlob . Email ) & & form . GetFieldByFullName ( "buyerEmail" ) is { } emailField )
{
prBlob . Email = emailField . Value ;
}
2023-02-20 11:35:54 +01:00
result . SetBlob ( prBlob ) ;
await _PaymentRequestRepository . CreateOrUpdatePaymentRequest ( result ) ;
2023-04-10 11:07:03 +09:00
return RedirectToAction ( "PayPaymentRequest" , new { payReqId } ) ;
2022-11-26 05:01:00 +01:00
}
2023-02-20 11:35:54 +01:00
}
viewModel . FormName = formData . Name ;
viewModel . Form = form ;
2023-12-01 16:13:44 +01:00
var storeBlob = result . StoreData . GetStoreBlob ( ) ;
2024-05-09 02:18:02 +02:00
viewModel . StoreBranding = await StoreBrandingViewModel . CreateAsync ( Request , _uriResolver , storeBlob ) ;
2023-02-20 11:35:54 +01:00
return View ( "Views/UIForms/View" , viewModel ) ;
2022-11-25 02:42:55 +01:00
}
2023-01-06 14:18:07 +01:00
2021-12-11 04:32:23 +01:00
[HttpGet("{payReqId}/pay")]
2019-01-14 22:43:29 +01:00
[AllowAnonymous]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > PayPaymentRequest ( string payReqId , bool redirectToInvoice = true ,
2019-03-05 17:09:17 +09:00
decimal? amount = null , CancellationToken cancellationToken = default )
2019-01-14 22:43:29 +01:00
{
2020-03-16 09:06:40 +01:00
if ( amount . HasValue & & amount . Value < = 0 )
{
return BadRequest ( "Please provide an amount greater than 0" ) ;
}
2020-05-08 12:33:47 +02:00
2021-12-11 04:32:23 +01:00
var result = await _PaymentRequestService . GetPaymentRequest ( payReqId , GetUserId ( ) ) ;
2019-01-14 22:43:29 +01:00
if ( result = = null )
{
return NotFound ( ) ;
}
2020-05-08 12:33:47 +02:00
if ( result . Archived )
{
if ( redirectToInvoice )
{
2022-04-22 15:52:57 +02:00
return RedirectToAction ( "ViewPaymentRequest" , new { payReqId } ) ;
2020-05-08 12:33:47 +02:00
}
return BadRequest ( "Payment Request cannot be paid as it has been archived" ) ;
}
2023-02-20 11:35:54 +01:00
if ( ! result . FormSubmitted & & ! string . IsNullOrEmpty ( result . FormId ) )
{
var formData = await FormDataService . GetForm ( result . FormId ) ;
if ( formData is not null )
{
2023-04-10 11:07:03 +09:00
return RedirectToAction ( "ViewPaymentRequestForm" , new { payReqId } ) ;
2023-02-20 11:35:54 +01:00
}
}
2021-08-31 08:07:54 +02:00
result . HubPath = PaymentRequestHub . GetHubPath ( Request ) ;
2019-01-14 22:43:29 +01:00
if ( result . AmountDue < = 0 )
{
if ( redirectToInvoice )
{
2022-04-22 15:52:57 +02:00
return RedirectToAction ( "ViewPaymentRequest" , new { payReqId } ) ;
2019-01-14 22:43:29 +01:00
}
return BadRequest ( "Payment Request has already been settled." ) ;
}
2019-02-24 09:26:37 +01:00
2021-12-17 15:31:06 +09:00
if ( result . ExpiryDate . HasValue & & DateTime . UtcNow > = result . ExpiryDate )
2019-01-14 22:43:29 +01:00
{
if ( redirectToInvoice )
{
2022-04-22 15:52:57 +02:00
return RedirectToAction ( "ViewPaymentRequest" , new { payReqId } ) ;
2019-01-14 22:43:29 +01:00
}
return BadRequest ( "Payment Request has expired" ) ;
}
2022-11-02 18:41:19 +09:00
var currentInvoice = result . Invoices . GetReusableInvoice ( amount ) ;
2020-10-23 21:00:23 +09:00
if ( currentInvoice ! = null )
2019-01-14 22:43:29 +01:00
{
if ( redirectToInvoice )
{
2022-01-07 12:32:00 +09:00
return RedirectToAction ( "Checkout" , "UIInvoice" , new { currentInvoice . Id } ) ;
2019-01-14 22:43:29 +01:00
}
2020-10-23 21:00:23 +09:00
return Ok ( currentInvoice . Id ) ;
2019-01-14 22:43:29 +01:00
}
2019-02-24 09:26:37 +01:00
2019-01-14 22:43:29 +01:00
try
{
2022-11-10 15:12:15 +01:00
var store = await _storeRepository . FindStore ( result . StoreId ) ;
2023-09-19 03:10:13 +02:00
var prData = await _PaymentRequestRepository . FindPaymentRequest ( result . Id , null , cancellationToken ) ;
2023-04-24 18:04:46 +09:00
var newInvoice = await _InvoiceController . CreatePaymentRequestInvoice ( prData , amount , result . AmountDue , store , Request , cancellationToken ) ;
2019-01-14 22:43:29 +01:00
if ( redirectToInvoice )
{
2022-04-22 15:52:57 +02:00
return RedirectToAction ( "Checkout" , "UIInvoice" , new { invoiceId = newInvoice . Id } ) ;
2019-01-14 22:43:29 +01:00
}
2021-07-14 13:43:13 +02:00
return Ok ( newInvoice . Id ) ;
2019-01-14 22:43:29 +01:00
}
catch ( BitpayHttpException e )
{
return BadRequest ( e . Message ) ;
}
}
2021-12-11 04:32:23 +01:00
[HttpGet("{payReqId}/cancel")]
2023-12-14 12:42:07 +01:00
[AllowAnonymous]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > CancelUnpaidPendingInvoice ( string payReqId , bool redirect = true )
2019-05-07 08:26:40 +00:00
{
2021-12-11 04:32:23 +01:00
var result = await _PaymentRequestService . GetPaymentRequest ( payReqId , GetUserId ( ) ) ;
2020-05-08 12:33:47 +02:00
if ( result = = null )
2019-05-07 08:26:40 +00:00
{
return NotFound ( ) ;
}
2019-03-05 17:13:34 +09:00
2021-12-31 16:59:02 +09:00
if ( ! result . AllowCustomPaymentAmounts )
{
2021-09-16 18:24:48 -07:00
return BadRequest ( "Not allowed to cancel this invoice" ) ;
}
2020-08-04 07:55:13 +02:00
var invoices = result . Invoices . Where ( requestInvoice = >
2024-05-15 07:49:53 +09:00
requestInvoice . State . Status = = InvoiceStatus . New & & ! requestInvoice . Payments . Any ( ) ) ;
2019-05-07 08:26:40 +00:00
2020-08-04 07:55:13 +02:00
if ( ! invoices . Any ( ) )
2019-05-07 08:26:40 +00:00
{
return BadRequest ( "No unpaid pending invoice to cancel" ) ;
}
2020-05-08 12:33:47 +02:00
2020-08-04 07:55:13 +02:00
foreach ( var invoice in invoices )
{
2020-07-24 09:40:37 +02:00
await _InvoiceRepository . MarkInvoiceStatus ( invoice . Id , InvoiceStatus . Invalid ) ;
2020-08-04 07:55:13 +02:00
}
2019-05-07 08:26:40 +00:00
if ( redirect )
{
2019-11-07 17:59:35 +09:00
TempData [ WellKnownTempData . SuccessMessage ] = "Payment cancelled" ;
2022-04-22 15:52:57 +02:00
return RedirectToAction ( nameof ( ViewPaymentRequest ) , new { payReqId } ) ;
2019-05-07 08:26:40 +00:00
}
return Ok ( "Payment cancelled" ) ;
}
2020-05-08 12:33:47 +02:00
2021-12-11 04:32:23 +01:00
[HttpGet("{payReqId}/clone")]
2023-12-01 09:12:02 +01:00
[Authorize(Policy = Policies.CanModifyPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2022-12-13 21:01:48 -08:00
public async Task < IActionResult > ClonePaymentRequest ( string payReqId )
2019-03-07 06:27:16 +01:00
{
2021-12-20 15:15:32 +01:00
var store = GetCurrentStore ( ) ;
2022-12-13 21:01:48 -08:00
var result = await EditPaymentRequest ( store . Id , payReqId ) ;
2019-03-07 06:27:16 +01:00
if ( result is ViewResult viewResult )
{
var model = ( UpdatePaymentRequestViewModel ) viewResult . Model ;
model . Id = null ;
2020-05-08 12:33:47 +02:00
model . Archived = false ;
2021-08-31 08:07:54 +02:00
model . ExpiryDate = null ;
2019-03-07 06:27:16 +01:00
model . Title = $"Clone of {model.Title}" ;
2023-02-15 15:33:26 +09:00
model . AmountAndCurrencyEditable = true ;
2019-03-07 06:27:16 +01:00
return View ( "EditPaymentRequest" , model ) ;
2020-05-08 12:33:47 +02:00
}
return NotFound ( ) ;
}
2021-12-11 04:32:23 +01:00
[HttpGet("{payReqId}/archive")]
2023-12-01 09:12:02 +01:00
[Authorize(Policy = Policies.CanModifyPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
2021-12-11 04:32:23 +01:00
public async Task < IActionResult > TogglePaymentRequestArchival ( string payReqId )
2020-05-08 12:33:47 +02:00
{
2021-12-20 15:15:32 +01:00
var store = GetCurrentStore ( ) ;
2023-12-01 10:50:05 +01:00
var result = await _PaymentRequestRepository . ArchivePaymentRequest ( payReqId , true ) ;
if ( result is not null )
2020-05-08 12:33:47 +02:00
{
2023-12-01 10:50:05 +01:00
TempData [ WellKnownTempData . SuccessMessage ] = result . Value
2022-02-09 15:37:15 +01:00
? "The payment request has been archived and will no longer appear in the payment request list by default again."
: "The payment request has been unarchived and will appear in the payment request list by default." ;
return RedirectToAction ( "GetPaymentRequests" , new { storeId = store . Id } ) ;
2019-03-07 06:27:16 +01:00
}
return NotFound ( ) ;
}
2021-12-11 04:32:23 +01:00
2021-12-20 15:15:32 +01:00
private string GetUserId ( ) = > _UserManager . GetUserId ( User ) ;
2021-12-31 16:59:02 +09:00
2021-12-20 15:15:32 +01:00
private StoreData GetCurrentStore ( ) = > HttpContext . GetStoreData ( ) ;
2021-12-31 16:59:02 +09:00
2021-12-20 15:15:32 +01:00
private PaymentRequestData GetCurrentPaymentRequest ( ) = > HttpContext . GetPaymentRequestData ( ) ;
2024-01-11 16:25:56 +01:00
private IActionResult NoPaymentMethodResult ( string storeId )
{
TempData . SetStatusMessageModel ( new StatusMessageModel
{
Severity = StatusMessageModel . StatusSeverity . Error ,
Html = $"To create a payment request, you need to <a href='{Url.Action(nameof(UIStoresController.SetupWallet), " UIStores ", new { cryptoCode = _networkProvider.DefaultNetwork.CryptoCode, storeId })}' class='alert-link'>set up a wallet</a> first" ,
AllowDismiss = false
} ) ;
return RedirectToAction ( nameof ( GetPaymentRequests ) , new { storeId } ) ;
}
2019-01-14 22:43:29 +01:00
}
}