2020-05-19 19:59:23 +02:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading.Tasks;
|
2020-11-17 13:46:23 +01:00
|
|
|
using BTCPayServer.Abstractions.Constants;
|
2022-02-24 09:00:44 +01:00
|
|
|
using BTCPayServer.Abstractions.Extensions;
|
2020-05-19 19:59:23 +02:00
|
|
|
using BTCPayServer.Client;
|
|
|
|
using BTCPayServer.Client.Models;
|
|
|
|
using BTCPayServer.Data;
|
|
|
|
using BTCPayServer.Security;
|
|
|
|
using BTCPayServer.Services.PaymentRequests;
|
|
|
|
using BTCPayServer.Services.Rates;
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
2020-06-30 08:26:19 +02:00
|
|
|
using Microsoft.AspNetCore.Cors;
|
2020-05-19 19:59:23 +02:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
using PaymentRequestData = BTCPayServer.Data.PaymentRequestData;
|
|
|
|
|
2022-01-14 05:05:23 +01:00
|
|
|
namespace BTCPayServer.Controllers.Greenfield
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
|
|
|
[ApiController]
|
|
|
|
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
2020-06-30 08:26:19 +02:00
|
|
|
[EnableCors(CorsPolicies.All)]
|
2022-01-07 04:17:59 +01:00
|
|
|
public class GreenfieldPaymentRequestsController : ControllerBase
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
|
|
|
private readonly PaymentRequestRepository _paymentRequestRepository;
|
|
|
|
private readonly CurrencyNameTable _currencyNameTable;
|
|
|
|
|
2022-01-07 04:17:59 +01:00
|
|
|
public GreenfieldPaymentRequestsController(PaymentRequestRepository paymentRequestRepository,
|
2020-05-19 19:59:23 +02:00
|
|
|
CurrencyNameTable currencyNameTable)
|
|
|
|
{
|
|
|
|
_paymentRequestRepository = paymentRequestRepository;
|
|
|
|
_currencyNameTable = currencyNameTable;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Authorize(Policy = Policies.CanViewPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
|
|
[HttpGet("~/api/v1/stores/{storeId}/payment-requests")]
|
2021-07-27 14:11:47 +02:00
|
|
|
public async Task<ActionResult<IEnumerable<Client.Models.PaymentRequestData>>> GetPaymentRequests(string storeId, bool includeArchived = false)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
|
|
|
var prs = await _paymentRequestRepository.FindPaymentRequests(
|
2020-07-27 10:43:35 +02:00
|
|
|
new PaymentRequestQuery() { StoreId = storeId, IncludeArchived = includeArchived });
|
2022-05-02 09:35:28 +02:00
|
|
|
return Ok(prs.Select(FromModel));
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
[Authorize(Policy = Policies.CanViewPaymentRequests, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
|
|
[HttpGet("~/api/v1/stores/{storeId}/payment-requests/{paymentRequestId}")]
|
2021-12-23 05:32:08 +01:00
|
|
|
public async Task<IActionResult> GetPaymentRequest(string storeId, string paymentRequestId)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
|
|
|
var pr = await _paymentRequestRepository.FindPaymentRequests(
|
2020-06-28 10:55:27 +02:00
|
|
|
new PaymentRequestQuery() { StoreId = storeId, Ids = new[] { paymentRequestId } });
|
2020-05-19 19:59:23 +02:00
|
|
|
|
2022-05-02 09:35:28 +02:00
|
|
|
if (pr.Length == 0)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
2021-12-23 05:32:08 +01:00
|
|
|
return PaymentRequestNotFound();
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
2022-05-02 09:35:28 +02:00
|
|
|
return Ok(FromModel(pr.First()));
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
[Authorize(Policy = Policies.CanModifyPaymentRequests,
|
|
|
|
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
|
|
[HttpDelete("~/api/v1/stores/{storeId}/payment-requests/{paymentRequestId}")]
|
2021-12-23 05:32:08 +01:00
|
|
|
public async Task<IActionResult> ArchivePaymentRequest(string storeId, string paymentRequestId)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
|
|
|
var pr = await _paymentRequestRepository.FindPaymentRequests(
|
2020-06-28 10:55:27 +02:00
|
|
|
new PaymentRequestQuery() { StoreId = storeId, Ids = new[] { paymentRequestId }, IncludeArchived = false });
|
2022-05-02 09:35:28 +02:00
|
|
|
if (pr.Length == 0)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
2021-12-23 05:32:08 +01:00
|
|
|
return PaymentRequestNotFound();
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
2022-05-02 09:35:28 +02:00
|
|
|
var updatedPr = pr.First();
|
2020-05-19 19:59:23 +02:00
|
|
|
updatedPr.Archived = true;
|
|
|
|
await _paymentRequestRepository.CreateOrUpdatePaymentRequest(updatedPr);
|
|
|
|
return Ok();
|
|
|
|
}
|
|
|
|
|
|
|
|
[HttpPost("~/api/v1/stores/{storeId}/payment-requests")]
|
|
|
|
[Authorize(Policy = Policies.CanModifyPaymentRequests,
|
|
|
|
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
|
|
public async Task<IActionResult> CreatePaymentRequest(string storeId,
|
|
|
|
CreatePaymentRequestRequest request)
|
|
|
|
{
|
|
|
|
var validationResult = Validate(request);
|
|
|
|
if (validationResult != null)
|
|
|
|
{
|
|
|
|
return validationResult;
|
|
|
|
}
|
2022-01-11 10:42:44 +01:00
|
|
|
request.Currency ??= StoreData.GetStoreBlob().DefaultCurrency;
|
2020-05-19 19:59:23 +02:00
|
|
|
var pr = new PaymentRequestData()
|
|
|
|
{
|
|
|
|
StoreDataId = storeId,
|
|
|
|
Status = Client.Models.PaymentRequestData.PaymentRequestStatus.Pending,
|
2021-12-27 05:15:43 +01:00
|
|
|
Created = DateTimeOffset.UtcNow
|
2020-05-19 19:59:23 +02:00
|
|
|
};
|
|
|
|
pr.SetBlob(request);
|
|
|
|
pr = await _paymentRequestRepository.CreateOrUpdatePaymentRequest(pr);
|
|
|
|
return Ok(FromModel(pr));
|
|
|
|
}
|
2022-01-11 10:42:44 +01:00
|
|
|
public Data.StoreData StoreData => HttpContext.GetStoreData();
|
2020-05-19 19:59:23 +02:00
|
|
|
[HttpPut("~/api/v1/stores/{storeId}/payment-requests/{paymentRequestId}")]
|
|
|
|
[Authorize(Policy = Policies.CanModifyPaymentRequests,
|
|
|
|
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
|
|
public async Task<IActionResult> UpdatePaymentRequest(string storeId,
|
|
|
|
string paymentRequestId, [FromBody] UpdatePaymentRequestRequest request)
|
|
|
|
{
|
|
|
|
var validationResult = Validate(request);
|
|
|
|
if (validationResult != null)
|
|
|
|
{
|
|
|
|
return validationResult;
|
|
|
|
}
|
2022-01-11 10:42:44 +01:00
|
|
|
request.Currency ??= StoreData.GetStoreBlob().DefaultCurrency;
|
2020-05-19 19:59:23 +02:00
|
|
|
var pr = await _paymentRequestRepository.FindPaymentRequests(
|
2020-06-28 10:55:27 +02:00
|
|
|
new PaymentRequestQuery() { StoreId = storeId, Ids = new[] { paymentRequestId } });
|
2022-05-02 09:35:28 +02:00
|
|
|
if (pr.Length == 0)
|
2020-05-19 19:59:23 +02:00
|
|
|
{
|
2021-12-23 05:32:08 +01:00
|
|
|
return PaymentRequestNotFound();
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
2022-05-02 09:35:28 +02:00
|
|
|
var updatedPr = pr.First();
|
2020-05-19 19:59:23 +02:00
|
|
|
updatedPr.SetBlob(request);
|
|
|
|
|
|
|
|
return Ok(FromModel(await _paymentRequestRepository.CreateOrUpdatePaymentRequest(updatedPr)));
|
|
|
|
}
|
|
|
|
|
|
|
|
private IActionResult Validate(PaymentRequestBaseData data)
|
|
|
|
{
|
|
|
|
if (data is null)
|
|
|
|
return BadRequest();
|
|
|
|
if (data.Amount <= 0)
|
|
|
|
{
|
|
|
|
ModelState.AddModelError(nameof(data.Amount), "Please provide an amount greater than 0");
|
|
|
|
}
|
|
|
|
|
2022-01-11 10:42:44 +01:00
|
|
|
if (!string.IsNullOrEmpty(data.Currency) &&
|
2020-05-19 19:59:23 +02:00
|
|
|
_currencyNameTable.GetCurrencyData(data.Currency, false) == null)
|
|
|
|
ModelState.AddModelError(nameof(data.Currency), "Invalid currency");
|
2022-01-11 10:42:44 +01:00
|
|
|
if (string.IsNullOrEmpty(data.Currency))
|
|
|
|
data.Currency = null;
|
2020-05-19 19:59:23 +02:00
|
|
|
if (string.IsNullOrEmpty(data.Title))
|
|
|
|
ModelState.AddModelError(nameof(data.Title), "Title is required");
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(data.CustomCSSLink) && data.CustomCSSLink.Length > 500)
|
|
|
|
ModelState.AddModelError(nameof(data.CustomCSSLink), "CustomCSSLink is 500 chars max");
|
|
|
|
|
2020-06-28 10:55:27 +02:00
|
|
|
return !ModelState.IsValid ? this.CreateValidationError(ModelState) : null;
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static Client.Models.PaymentRequestData FromModel(PaymentRequestData data)
|
|
|
|
{
|
|
|
|
var blob = data.GetBlob();
|
|
|
|
return new Client.Models.PaymentRequestData()
|
|
|
|
{
|
2021-12-23 14:48:10 +01:00
|
|
|
CreatedTime = data.Created,
|
2020-05-19 19:59:23 +02:00
|
|
|
Id = data.Id,
|
2021-12-21 10:51:15 +01:00
|
|
|
StoreId = data.StoreDataId,
|
2020-05-19 19:59:23 +02:00
|
|
|
Status = data.Status,
|
|
|
|
Archived = data.Archived,
|
|
|
|
Amount = blob.Amount,
|
|
|
|
Currency = blob.Currency,
|
|
|
|
Description = blob.Description,
|
|
|
|
Title = blob.Title,
|
|
|
|
ExpiryDate = blob.ExpiryDate,
|
|
|
|
Email = blob.Email,
|
|
|
|
AllowCustomPaymentAmounts = blob.AllowCustomPaymentAmounts,
|
|
|
|
EmbeddedCSS = blob.EmbeddedCSS,
|
|
|
|
CustomCSSLink = blob.CustomCSSLink
|
|
|
|
};
|
|
|
|
}
|
2021-12-31 08:59:02 +01:00
|
|
|
|
2021-12-23 05:32:08 +01:00
|
|
|
private IActionResult PaymentRequestNotFound()
|
|
|
|
{
|
|
|
|
return this.CreateAPIError(404, "payment-request-not-found", "The payment request was not found");
|
|
|
|
}
|
2020-05-19 19:59:23 +02:00
|
|
|
}
|
|
|
|
}
|