Mark Payouts as Paid (#2539)

* Mark Payouts as Paid

This PR allows users to mark payouts as paid manually through the UI  and through the API. It also sets up the payout proof system to be able store a manual proof that will in a later PR allow you to specify a proof of payment (link or text)

* add docs, test and greenfield client

* remove extra docs stuff

* Update BTCPayServer.Tests/GreenfieldAPITests.cs

Co-authored-by: britttttk <39231115+britttttk@users.noreply.github.com>

* clean up pull payment/payouts fetch code

* Ensure payoutis are retrieved with pull payment

Co-authored-by: britttttk <39231115+britttttk@users.noreply.github.com>
This commit is contained in:
Andrew Camilleri
2021-06-10 11:43:45 +02:00
committed by GitHub
parent f1f3dffc97
commit cd9feccf6e
16 changed files with 320 additions and 29 deletions

View File

@@ -18,6 +18,7 @@ using NBitcoin.Payment;
using NBitcoin.RPC;
using NBXplorer.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NewBlockEvent = BTCPayServer.Events.NewBlockEvent;
using PayoutData = BTCPayServer.Data.PayoutData;
@@ -70,8 +71,16 @@ public class BitcoinLikePayoutHandler : IPayoutHandler
if (payout?.Proof is null)
return null;
var paymentMethodId = payout.GetPaymentMethodId();
var res = JsonConvert.DeserializeObject<PayoutTransactionOnChainBlob>(Encoding.UTF8.GetString(payout.Proof), _jsonSerializerSettings.GetSerializer(paymentMethodId.CryptoCode));
var raw = JObject.Parse(Encoding.UTF8.GetString(payout.Proof));
if (raw.TryGetValue("proofType", StringComparison.InvariantCultureIgnoreCase, out var proofType) &&
proofType.Value<string>() == ManualPayoutProof.Type)
{
return raw.ToObject<ManualPayoutProof>();
}
var res = raw.ToObject<PayoutTransactionOnChainBlob>(
JsonSerializer.Create(_jsonSerializerSettings.GetSerializer(paymentMethodId.CryptoCode)));
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
if (res == null) return null;
res.LinkTemplate = network.BlockExplorerLink;
return res;
}

View File

@@ -13,6 +13,8 @@ namespace BTCPayServer.Data
public HashSet<uint256> Candidates { get; set; } = new HashSet<uint256>();
[JsonIgnore] public string LinkTemplate { get; set; }
public string ProofType { get; } = "PayoutTransactionOnChainBlob";
[JsonIgnore]
public string Link
{

View File

@@ -1,12 +1,8 @@
using System;
namespace BTCPayServer.Data
{
public interface IClaimDestination
{
}
public interface IPayoutProof
{
string Link { get; }
string Id { get; }
}
}

View File

@@ -0,0 +1,9 @@
namespace BTCPayServer.Data
{
public interface IPayoutProof
{
string ProofType { get; }
string Link { get; }
string Id { get; }
}
}

View File

@@ -0,0 +1,10 @@
namespace BTCPayServer.Data
{
public class ManualPayoutProof : IPayoutProof
{
public static string Type = "ManualPayoutProof";
public string ProofType { get; } = Type;
public string Link { get; set; }
public string Id { get; set; }
}
}

View File

@@ -38,5 +38,17 @@ namespace BTCPayServer.Data
{
data.Blob = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(blob, serializers.GetSerializer(data.GetPaymentMethodId().CryptoCode)));
}
public static void SetProofBlob(this PayoutData data, ManualPayoutProof blob)
{
if(blob is null)
return;
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(blob));
// We only update the property if the bytes actually changed, this prevent from hammering the DB too much
if (data.Proof is null || bytes.Length != data.Proof.Length || !bytes.SequenceEqual(data.Proof))
{
data.Proof = bytes;
}
}
}
}