mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-29 03:44:27 +01:00
Fix: Payout Transaction not matching when rate provided longer decima… (#2518)
* Fix: Payout Transaction not matching when rate provided longer decimal precision fixes #2513 most likely * Do not sue rounding and ensure crypto amount is saved with correct decimal places * Round pull payment payout to the nearest digit supported by network Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
This commit is contained in:
@@ -471,6 +471,25 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
Revision = payout.Revision
|
||||
}));
|
||||
|
||||
// Create one pull payment with an amount of 9 decimals
|
||||
var test3 = await client.CreatePullPayment(storeId, new Client.Models.CreatePullPaymentRequest()
|
||||
{
|
||||
Name = "Test 2",
|
||||
Amount = 12.303228134m,
|
||||
Currency = "BTC",
|
||||
PaymentMethods = new[] { "BTC" }
|
||||
});
|
||||
destination = (await tester.ExplorerNode.GetNewAddressAsync()).ToString();
|
||||
payout = await unauthenticated.CreatePayout(test3.Id, new CreatePayoutRequest()
|
||||
{
|
||||
Destination = destination,
|
||||
PaymentMethod = "BTC"
|
||||
});
|
||||
payout = await client.ApprovePayout(storeId, payout.Id, new ApprovePayoutRequest());
|
||||
// The payout should round the value of the payment down to the network of the payment method
|
||||
Assert.Equal(12.30322814m, payout.PaymentMethodAmount);
|
||||
Assert.Equal(12.303228134m, payout.Amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,10 @@ public class BitcoinLikePayoutHandler : IPayoutHandler
|
||||
if (!payoutByDestination.TryGetValue(destination.Key, out var payout))
|
||||
continue;
|
||||
var payoutBlob = payout.GetBlob(_jsonSerializerSettings);
|
||||
if (destination.Value != payoutBlob.CryptoAmount)
|
||||
if (payoutBlob.CryptoAmount is null ||
|
||||
// The round up here is not strictly necessary, this is temporary to fix existing payout before we
|
||||
// were properly roundup the crypto amount
|
||||
destination.Value != BTCPayServer.Extensions.RoundUp(payoutBlob.CryptoAmount.Value, network.Divisibility))
|
||||
continue;
|
||||
var proof = ParseProof(payout) as PayoutTransactionOnChainBlob;
|
||||
if (proof is null)
|
||||
|
||||
@@ -274,13 +274,14 @@ namespace BTCPayServer.HostedServices
|
||||
var cryptoAmount = payoutBlob.Amount / req.Rate;
|
||||
var payoutHandler = _payoutHandlers.First(handler => handler.CanHandle(paymentMethod));
|
||||
var dest = await payoutHandler.ParseClaimDestination(paymentMethod, payoutBlob.Destination);
|
||||
|
||||
decimal minimumCryptoAmount = await payoutHandler.GetMinimumPayoutAmount(paymentMethod, dest);
|
||||
if (cryptoAmount < minimumCryptoAmount)
|
||||
{
|
||||
req.Completion.TrySetResult(PayoutApproval.Result.TooLowAmount);
|
||||
return;
|
||||
}
|
||||
payoutBlob.CryptoAmount = cryptoAmount;
|
||||
payoutBlob.CryptoAmount = BTCPayServer.Extensions.RoundUp(cryptoAmount, _networkProvider.GetNetwork(paymentMethod.CryptoCode).Divisibility);
|
||||
payout.SetBlob(payoutBlob, _jsonSerializerSettings);
|
||||
await ctx.SaveChangesAsync();
|
||||
req.Completion.SetResult(PayoutApproval.Result.Ok);
|
||||
@@ -298,6 +299,7 @@ namespace BTCPayServer.HostedServices
|
||||
DateTimeOffset now = DateTimeOffset.UtcNow;
|
||||
await using var ctx = _dbContextFactory.CreateContext();
|
||||
var pp = await ctx.PullPayments.FindAsync(req.ClaimRequest.PullPaymentId);
|
||||
|
||||
if (pp is null || pp.Archived)
|
||||
{
|
||||
req.Completion.TrySetResult(new ClaimRequest.ClaimResponse(ClaimRequest.ClaimResult.Archived));
|
||||
@@ -316,7 +318,7 @@ namespace BTCPayServer.HostedServices
|
||||
var ppBlob = pp.GetBlob();
|
||||
var payoutHandler =
|
||||
_payoutHandlers.FirstOrDefault(handler => handler.CanHandle(req.ClaimRequest.PaymentMethodId));
|
||||
if (!ppBlob.SupportedPaymentMethods.Contains(req.ClaimRequest.PaymentMethodId) || payoutHandler is null )
|
||||
if (!ppBlob.SupportedPaymentMethods.Contains(req.ClaimRequest.PaymentMethodId) || payoutHandler is null)
|
||||
{
|
||||
req.Completion.TrySetResult(new ClaimRequest.ClaimResponse(ClaimRequest.ClaimResult.PaymentMethodNotSupported));
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user