Refactor and decouple Payout logic (#2046)

* Refactor and decouple Payout logic

So that we can support lightning and more complex flows like allowing external payments to payouts.

* fix dropdown align

* switch to simpler buttons

* rebase fixes

add some comments

* rebase fixes

add some comments

* simplify enum caveman logic

* reduce code duplication and db round trips

* Fix pull payment date format

* fix issue with payouts to send page not working correctly

* try fix some style issue

* fix bip21parse
This commit is contained in:
Andrew Camilleri
2021-04-13 10:36:49 +02:00
committed by GitHub
parent 98eee27b93
commit 2e12befb8b
26 changed files with 936 additions and 645 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -31,13 +32,15 @@ namespace BTCPayServer.Controllers.GreenField
private readonly CurrencyNameTable _currencyNameTable;
private readonly BTCPayNetworkJsonSerializerSettings _serializerSettings;
private readonly BTCPayNetworkProvider _networkProvider;
private readonly IEnumerable<IPayoutHandler> _payoutHandlers;
public GreenfieldPullPaymentController(PullPaymentHostedService pullPaymentService,
LinkGenerator linkGenerator,
ApplicationDbContextFactory dbContextFactory,
CurrencyNameTable currencyNameTable,
Services.BTCPayNetworkJsonSerializerSettings serializerSettings,
BTCPayNetworkProvider networkProvider)
BTCPayNetworkProvider networkProvider,
IEnumerable<IPayoutHandler> payoutHandlers)
{
_pullPaymentService = pullPaymentService;
_linkGenerator = linkGenerator;
@@ -45,6 +48,7 @@ namespace BTCPayServer.Controllers.GreenField
_currencyNameTable = currencyNameTable;
_serializerSettings = serializerSettings;
_networkProvider = networkProvider;
_payoutHandlers = payoutHandlers;
}
[HttpGet("~/api/v1/stores/{storeId}/pull-payments")]
@@ -178,7 +182,7 @@ namespace BTCPayServer.Controllers.GreenField
return NotFound();
using var ctx = _dbContextFactory.CreateContext();
var payouts = await ctx.Payouts.Where(p => p.PullPaymentDataId == pullPaymentId)
.Where(p => p.State != Data.PayoutState.Cancelled || includeCancelled)
.Where(p => p.State != PayoutState.Cancelled || includeCancelled)
.ToListAsync();
var cd = _currencyNameTable.GetCurrencyData(pp.GetBlob().Currency, false);
return base.Ok(payouts
@@ -196,14 +200,9 @@ namespace BTCPayServer.Controllers.GreenField
Amount = blob.Amount,
PaymentMethodAmount = blob.CryptoAmount,
Revision = blob.Revision,
State = p.State == Data.PayoutState.AwaitingPayment ? Client.Models.PayoutState.AwaitingPayment :
p.State == Data.PayoutState.AwaitingApproval ? Client.Models.PayoutState.AwaitingApproval :
p.State == Data.PayoutState.Cancelled ? Client.Models.PayoutState.Cancelled :
p.State == Data.PayoutState.Completed ? Client.Models.PayoutState.Completed :
p.State == Data.PayoutState.InProgress ? Client.Models.PayoutState.InProgress :
throw new NotSupportedException(),
State = p.State
};
model.Destination = blob.Destination.ToString();
model.Destination = blob.Destination;
model.PaymentMethod = p.PaymentMethodId;
return model;
}
@@ -214,10 +213,14 @@ namespace BTCPayServer.Controllers.GreenField
{
if (request is null)
return NotFound();
var network = request?.PaymentMethod is string paymentMethod ?
this._networkProvider.GetNetwork<BTCPayNetwork>(paymentMethod) : null;
if (network is null)
if (!PaymentMethodId.TryParse(request?.PaymentMethod, out var paymentMethodId))
{
ModelState.AddModelError(nameof(request.PaymentMethod), "Invalid payment method");
return this.CreateValidationError(ModelState);
}
var payoutHandler = _payoutHandlers.FirstOrDefault(handler => handler.CanHandle(paymentMethodId));
if (payoutHandler is null)
{
ModelState.AddModelError(nameof(request.PaymentMethod), "Invalid payment method");
return this.CreateValidationError(ModelState);
@@ -228,7 +231,8 @@ namespace BTCPayServer.Controllers.GreenField
if (pp is null)
return NotFound();
var ppBlob = pp.GetBlob();
if (request.Destination is null || !ClaimDestination.TryParse(request.Destination, network, out var destination))
IClaimDestination destination = await payoutHandler.ParseClaimDestination(paymentMethodId,request.Destination);
if (destination is null)
{
ModelState.AddModelError(nameof(request.Destination), "The destination must be an address or a BIP21 URI");
return this.CreateValidationError(ModelState);
@@ -245,7 +249,7 @@ namespace BTCPayServer.Controllers.GreenField
Destination = destination,
PullPaymentId = pullPaymentId,
Value = request.Amount,
PaymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike)
PaymentMethodId = paymentMethodId
});
switch (result.Result)
{