btcpayserver/BTCPayServer/Controllers/UIPublicController.cs
Andrew Camilleri f74ea14d8b
Plugins can now build apps (#4608)
* Plugins can now build apps

* fix tests

* fixup

* pluginize existing apps

* Test fixes part 1

* Test fixes part 2

* Fix Crowdfund namespace

* Syntax

* More namespace fixes

* Markup

* Test fix

* upstream fixes

* Add plugin icon

* Fix nullable build warnings

* allow pre popualting app creation

* Fixes after merge

* Make link methods async

* Use AppData as parameter for ConfigureLink

* GetApps by AppType

* Use ConfigureLink on dashboard

* Rename method

* Add properties to indicate stats support

* Property updates

* Test fixes

* Clean up imports

* Fixes after merge

---------

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2023-03-17 11:56:32 +09:00

110 lines
3.9 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Data;
using BTCPayServer.Models;
using BTCPayServer.Plugins.PayButton.Models;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using NicolasDorier.RateLimits;
namespace BTCPayServer.Controllers
{
public class UIPublicController : Controller
{
public UIPublicController(UIInvoiceController invoiceController,
StoreRepository storeRepository)
{
_InvoiceController = invoiceController;
_StoreRepository = storeRepository;
}
private readonly UIInvoiceController _InvoiceController;
private readonly StoreRepository _StoreRepository;
[HttpGet]
[IgnoreAntiforgeryToken]
[EnableCors(CorsPolicies.All)]
[Route("api/v1/invoices")]
public async Task<IActionResult> PayButtonHandle(PayButtonViewModel model)
{
return await PayButtonHandle(model, CancellationToken.None);
}
[HttpPost]
[Route("api/v1/invoices")]
[IgnoreAntiforgeryToken]
[EnableCors(CorsPolicies.All)]
[RateLimitsFilter(ZoneLimits.PublicInvoices, Scope = RateLimitsScope.RemoteAddress)]
public async Task<IActionResult> PayButtonHandle([FromForm] PayButtonViewModel model, CancellationToken cancellationToken)
{
var store = await _StoreRepository.FindStore(model.StoreId);
if (store == null)
ModelState.AddModelError("Store", "Invalid store");
else
{
var storeBlob = store.GetStoreBlob();
if (!storeBlob.AnyoneCanInvoice)
ModelState.AddModelError("Store", "Store has not enabled Pay Button");
}
if (model == null || (model.Price is decimal v ? v <= 0 : false))
ModelState.AddModelError("Price", "Price must be greater than 0");
if (!ModelState.IsValid)
return View();
DataWrapper<InvoiceResponse> invoice = null;
try
{
invoice = await _InvoiceController.CreateInvoiceCore(new BitpayCreateInvoiceRequest()
{
Price = model.Price,
Currency = model.Currency,
ItemDesc = model.CheckoutDesc,
OrderId = model.OrderId,
NotificationEmail = model.NotifyEmail,
NotificationURL = model.ServerIpn,
RedirectURL = model.BrowserRedirect,
FullNotifications = true,
DefaultPaymentMethod = model.DefaultPaymentMethod
}, store, HttpContext.Request.GetAbsoluteRoot(), cancellationToken: cancellationToken);
}
catch (BitpayHttpException e)
{
ModelState.AddModelError("Store", e.Message);
if (model.JsonResponse)
{
return BadRequest(ModelState);
}
return View();
}
if (model.JsonResponse)
{
return Json(new
{
InvoiceId = invoice.Data.Id,
InvoiceUrl = invoice.Data.Url
});
}
if (string.IsNullOrEmpty(model.CheckoutQueryString))
{
return Redirect(invoice.Data.Url);
}
var additionalParamValues = HttpUtility.ParseQueryString(model.CheckoutQueryString);
var uriBuilder = new UriBuilder(invoice.Data.Url);
var paramValues = HttpUtility.ParseQueryString(uriBuilder.Query);
paramValues.Add(additionalParamValues);
uriBuilder.Query = paramValues.ToString();
return Redirect(uriBuilder.Uri.AbsoluteUri);
}
}
}