From 428c7c5444bf6171d8ba45d1f12f023875296ce8 Mon Sep 17 00:00:00 2001 From: HugoDoyon Date: Wed, 31 Jul 2019 17:29:55 -0400 Subject: [PATCH] Fix "Do not propose on chain payment if the value of the invoice is below..." and take care of the GAP edge case --- .../Bitcoin/BitcoinLikePaymentHandler.cs | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index d553c0ba0..e2c1ad50f 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -73,37 +73,62 @@ namespace BTCPayServer.Payments.Bitcoin public override async Task IsPaymentMethodAllowedBasedOnInvoiceAmount(StoreBlob storeBlob, Dictionary> rate, Money amount, PaymentMethodId paymentMethodId) { + Func compare = null; CurrencyValue limitValue = null; string errorMessage = null; - if (paymentMethodId.PaymentType == PaymentTypes.LightningLike && - storeBlob.LightningMaxValue != null) + + if (paymentMethodId.PaymentType == PaymentTypes.BTCLike) { - compare = (a, b) => a > b; - limitValue = storeBlob.LightningMaxValue; - errorMessage = "The amount of the invoice is too high to be paid with lightning"; - } - else if (paymentMethodId.PaymentType == PaymentTypes.BTCLike && - storeBlob.OnChainMinValue != null) - { - compare = (a, b) => a < b; - limitValue = storeBlob.OnChainMinValue; - errorMessage = "The amount of the invoice is too low to be paid on chain"; + if (storeBlob.LightningMaxValue == null && + storeBlob.OnChainMinValue != null) + { + compare = (value, limit) => value < limit; + limitValue = storeBlob.OnChainMinValue; + errorMessage = "The amount of the invoice is too low to be paid on chain"; + } + else if (storeBlob.LightningMaxValue != null && + storeBlob.OnChainMinValue != null) + { + if (storeBlob.LightningMaxValue.Currency == storeBlob.OnChainMinValue.Currency && + storeBlob.LightningMaxValue.Value <= storeBlob.OnChainMinValue.Value) + { + //Case where both fields are set but OnChainMinValue is greater + // --> then use LightningMaxValue as limit + compare = (value, limit) => value < limit; + limitValue = storeBlob.LightningMaxValue; + errorMessage = "The amount of the invoice is too low to be paid on chain"; + } + else if (storeBlob.LightningMaxValue.Currency == storeBlob.OnChainMinValue.Currency && + storeBlob.LightningMaxValue.Value > storeBlob.OnChainMinValue.Value) + { + //Case where both fields are set but LightningMaxValue is greater + // --> then use OnChainMinValue as limit + // (Otherwise a gap of price value with no payment method is possible) + compare = (value, limit) => value < limit; + limitValue = storeBlob.OnChainMinValue; + errorMessage = "The amount of the invoice is too low to be paid on chain"; + } + } } + if (compare != null) { - var limitValueRate = await rate[new CurrencyPair(paymentMethodId.CryptoCode, storeBlob.OnChainMinValue.Currency)]; - if (limitValueRate.BidAsk != null) + var currentRateToCrypto = await rate[new CurrencyPair(paymentMethodId.CryptoCode, limitValue.Currency)]; + + if (currentRateToCrypto.BidAsk != null) { - var limitValueCrypto = Money.Coins(limitValue.Value / limitValueRate.BidAsk.Bid); + var limitValueCrypto = Money.Coins(limitValue.Value / currentRateToCrypto.BidAsk.Bid); if (compare(amount, limitValueCrypto)) { return errorMessage; } } } + return string.Empty; + } public override IEnumerable GetSupportedPaymentMethods()