diff --git a/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs b/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs index c4b62e609..b892c025a 100644 --- a/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs +++ b/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs @@ -875,7 +875,7 @@ normal: var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[] { new BitcoinLikePaymentHandler(null, networkProvider, null, null, null), - new LightningLikePaymentHandler(null, null, networkProvider, null), + new LightningLikePaymentHandler(null, null, networkProvider, null, null), }); var networkBTC = networkProvider.GetNetwork("BTC"); var networkLTC = networkProvider.GetNetwork("LTC"); diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index ad2f59a1c..f380f9281 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -364,7 +364,7 @@ namespace BTCPayServer.Tests var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[] { new BitcoinLikePaymentHandler(null, networkProvider, null, null, null), - new LightningLikePaymentHandler(null, null, networkProvider, null), + new LightningLikePaymentHandler(null, null, networkProvider, null, null), }); var entity = new InvoiceEntity(); entity.Networks = networkProvider; @@ -563,7 +563,7 @@ namespace BTCPayServer.Tests var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[] { new BitcoinLikePaymentHandler(null, networkProvider, null, null, null), - new LightningLikePaymentHandler(null, null, networkProvider, null), + new LightningLikePaymentHandler(null, null, networkProvider, null, null), }); var entity = new InvoiceEntity(); entity.Networks = networkProvider; diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 6548f6cc8..b94cb949d 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -464,12 +464,9 @@ namespace BTCPayServer.Controllers var paymentMethod = invoice.GetPaymentMethod(paymentMethodId); var paymentMethodDetails = paymentMethod.GetPaymentMethodDetails(); var dto = invoice.EntityToDTO(); - var cryptoInfo = dto.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var storeBlob = store.GetStoreBlob(); - var currency = invoice.Currency; var accounting = paymentMethod.Calculate(); - CoinSwitchSettings coinswitch = (storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled && storeBlob.CoinSwitchSettings.IsConfigured()) ? storeBlob.CoinSwitchSettings @@ -492,12 +489,11 @@ namespace BTCPayServer.Controllers CryptoImage = Request.GetRelativePathOrAbsolute(paymentMethodHandler.GetCryptoImage(paymentMethodId)), BtcAddress = paymentMethodDetails.GetPaymentDestination(), BtcDue = accounting.Due.ShowMoney(divisibility), + InvoiceCurrency = invoice.Currency, OrderAmount = (accounting.TotalDue - accounting.NetworkFee).ShowMoney(divisibility), OrderAmountFiat = OrderAmountFromInvoice(network.CryptoCode, invoice), CustomerEmail = invoice.RefundMail, RequiresRefundEmail = storeBlob.RequiresRefundEmail, - ShowRecommendedFee = storeBlob.ShowRecommendedFee, - FeeRate = paymentMethodDetails.GetFeeRate(), ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds), MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds, MaxTimeMinutes = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalMinutes, @@ -506,7 +502,6 @@ namespace BTCPayServer.Controllers MerchantRefLink = invoice.RedirectURL?.AbsoluteUri ?? "/", RedirectAutomatically = invoice.RedirectAutomatically, StoreName = store.StoreName, - PeerInfo = (paymentMethodDetails as LightningLikePaymentMethodDetails)?.NodeInfo, TxCount = accounting.TxRequired, BtcPaid = accounting.Paid.ShowMoney(divisibility), #pragma warning disable CS0618 // Type or member is obsolete @@ -544,12 +539,7 @@ namespace BTCPayServer.Controllers .OrderByDescending(a => a.CryptoCode == "BTC").ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0) .ToList() }; - - paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob); - if (model.IsLightning && storeBlob.LightningAmountInSatoshi && model.CryptoCode == "Sats") - { - model.Rate = _CurrencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, paymentMethod.ParentEntity.Currency); - } + paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob, paymentMethod); model.UISettings = paymentMethodHandler.GetCheckoutUISettings(); model.PaymentMethodId = paymentMethodId.ToString(); var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); diff --git a/BTCPayServer/Models/InvoicingModels/PaymentModel.cs b/BTCPayServer/Models/InvoicingModels/PaymentModel.cs index 6b191a0ce..24cf0446d 100644 --- a/BTCPayServer/Models/InvoicingModels/PaymentModel.cs +++ b/BTCPayServer/Models/InvoicingModels/PaymentModel.cs @@ -25,10 +25,8 @@ namespace BTCPayServer.Models.InvoicingModels public string CustomLogoLink { get; set; } public string HtmlTitle { get; set; } public string DefaultLang { get; set; } - public bool LightningAmountInSatoshi { get; set; } public List AvailableCryptos { get; set; } = new List(); public bool IsModal { get; set; } - public bool IsLightning { get; set; } public string CryptoCode { get; set; } public string InvoiceId { get; set; } public string BtcAddress { get; set; } @@ -71,5 +69,6 @@ namespace BTCPayServer.Models.InvoicingModels public string RootPath { get; set; } public decimal CoinSwitchAmountMarkupPercentage { get; set; } public bool RedirectAutomatically { get; set; } + public string InvoiceCurrency { get; set; } } } diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index e1c582752..366757779 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -8,10 +7,8 @@ using BTCPayServer.HostedServices; using BTCPayServer.Logging; using BTCPayServer.Models; using BTCPayServer.Models.InvoicingModels; -using BTCPayServer.Rating; using BTCPayServer.Services; using BTCPayServer.Services.Invoices; -using BTCPayServer.Services.Rates; using NBitcoin; using NBXplorer.Models; using StoreData = BTCPayServer.Data.StoreData; @@ -47,13 +44,13 @@ namespace BTCPayServer.Payments.Bitcoin } public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, - StoreBlob storeBlob) + StoreBlob storeBlob, IPaymentMethod paymentMethod) { - var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.BTCLike); - + var paymentMethodId = paymentMethod.GetId(); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var network = _networkProvider.GetNetwork(model.CryptoCode); - model.IsLightning = false; + model.ShowRecommendedFee = storeBlob.ShowRecommendedFee; + model.FeeRate = ((BitcoinLikeOnChainPaymentMethod) paymentMethod.GetPaymentMethodDetails()).GetFeeRate(); model.PaymentMethodName = GetPaymentMethodName(network); model.InvoiceBitcoinUrl = cryptoInfo.PaymentUrls.BIP21; model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21; diff --git a/BTCPayServer/Payments/IPaymentMethodDetails.cs b/BTCPayServer/Payments/IPaymentMethodDetails.cs index 6b8d4974f..865ff7fd5 100644 --- a/BTCPayServer/Payments/IPaymentMethodDetails.cs +++ b/BTCPayServer/Payments/IPaymentMethodDetails.cs @@ -16,10 +16,5 @@ namespace BTCPayServer.Payments /// /// decimal GetNextNetworkFee(); - /// - /// Returns recommended fee rate for a transaction - /// - /// - decimal GetFeeRate(); } } diff --git a/BTCPayServer/Payments/IPaymentMethodHandler.cs b/BTCPayServer/Payments/IPaymentMethodHandler.cs index adb639591..24895f0e8 100644 --- a/BTCPayServer/Payments/IPaymentMethodHandler.cs +++ b/BTCPayServer/Payments/IPaymentMethodHandler.cs @@ -38,7 +38,8 @@ namespace BTCPayServer.Payments /// object PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network); - void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob); + void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob, + IPaymentMethod paymentMethod); string GetCryptoImage(PaymentMethodId paymentMethodId); string GetPaymentMethodName(PaymentMethodId paymentMethodId); @@ -67,7 +68,7 @@ namespace BTCPayServer.Payments PaymentMethod paymentMethod, StoreData store, TBTCPayNetwork network, object preparePaymentObject); public abstract void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, - StoreBlob storeBlob); + StoreBlob storeBlob, IPaymentMethod paymentMethod); public abstract string GetCryptoImage(PaymentMethodId paymentMethodId); public abstract string GetPaymentMethodName(PaymentMethodId paymentMethodId); diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index 5490aba5f..01f28a882 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -25,17 +25,20 @@ namespace BTCPayServer.Payments.Lightning private readonly LightningClientFactoryService _lightningClientFactory; private readonly BTCPayNetworkProvider _networkProvider; private readonly SocketFactory _socketFactory; + private readonly CurrencyNameTable _currencyNameTable; public LightningLikePaymentHandler( NBXplorerDashboard dashboard, LightningClientFactoryService lightningClientFactory, BTCPayNetworkProvider networkProvider, - SocketFactory socketFactory) + SocketFactory socketFactory, + CurrencyNameTable currencyNameTable) { _Dashboard = dashboard; _lightningClientFactory = lightningClientFactory; _networkProvider = networkProvider; _socketFactory = socketFactory; + _currencyNameTable = currencyNameTable; } public override PaymentType PaymentType => PaymentTypes.LightningLike; @@ -159,28 +162,27 @@ namespace BTCPayServer.Payments.Lightning } public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, - StoreBlob storeBlob) + StoreBlob storeBlob, IPaymentMethod paymentMethod) { - var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.LightningLike); + var paymentMethodId = paymentMethod.GetId(); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var network = _networkProvider.GetNetwork(model.CryptoCode); - model.IsLightning = true; model.PaymentMethodName = GetPaymentMethodName(network); model.InvoiceBitcoinUrl = cryptoInfo.PaymentUrls.BOLT11; model.InvoiceBitcoinUrlQR = $"lightning:{cryptoInfo.PaymentUrls.BOLT11.ToUpperInvariant().Substring("LIGHTNING:".Length)}"; - model.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi; + + model.PeerInfo = ((LightningLikePaymentMethodDetails) paymentMethod.GetPaymentMethodDetails()).NodeInfo; if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC") { var satoshiCulture = new CultureInfo(CultureInfo.InvariantCulture.Name); satoshiCulture.NumberFormat.NumberGroupSeparator = " "; - model.CryptoCode = "Sats"; model.BtcDue = Money.Parse(model.BtcDue).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture); model.BtcPaid = Money.Parse(model.BtcPaid).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture); model.OrderAmount = Money.Parse(model.OrderAmount).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture); - model.NetworkFee = new Money(model.NetworkFee, MoneyUnit.BTC).ToUnit(MoneyUnit.Satoshi); + model.Rate = _currencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, model.InvoiceCurrency); } } public override string GetCryptoImage(PaymentMethodId paymentMethodId) diff --git a/BTCPayServer/Services/Altcoins/Ethereum/Payments/EthereumLikePaymentMethodHandler.cs b/BTCPayServer/Services/Altcoins/Ethereum/Payments/EthereumLikePaymentMethodHandler.cs index 69c8d5d08..786148672 100644 --- a/BTCPayServer/Services/Altcoins/Ethereum/Payments/EthereumLikePaymentMethodHandler.cs +++ b/BTCPayServer/Services/Altcoins/Ethereum/Payments/EthereumLikePaymentMethodHandler.cs @@ -71,12 +71,11 @@ namespace BTCPayServer.Services.Altcoins.Ethereum.Payments } public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, - StoreBlob storeBlob) + StoreBlob storeBlob, IPaymentMethod paymentMethod) { - var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentType); + var paymentMethodId = paymentMethod.GetId(); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var network = _networkProvider.GetNetwork(model.CryptoCode); - model.IsLightning = false; model.PaymentMethodName = GetPaymentMethodName(network); model.CryptoImage = GetCryptoImage(network); model.InvoiceBitcoinUrl = ""; diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs index 3b2494413..8e66f646f 100644 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs +++ b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs @@ -73,12 +73,12 @@ namespace BTCPayServer.Services.Altcoins.Monero.Payments public Func> ReserveAddress; } - public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob) + public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, + StoreBlob storeBlob, IPaymentMethod paymentMethod) { - var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentType); + var paymentMethodId = paymentMethod.GetId(); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var network = _networkProvider.GetNetwork(model.CryptoCode); - model.IsLightning = false; model.PaymentMethodName = GetPaymentMethodName(network); model.CryptoImage = GetCryptoImage(network); model.InvoiceBitcoinUrl = MoneroPaymentType.Instance.GetPaymentLink(network, new MoneroLikeOnChainPaymentMethodDetails() diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index cd94407a1..4f0af911e 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -908,7 +908,14 @@ namespace BTCPayServer.Services.Invoices public Money MinimumTotalDue { get; set; } } - public class PaymentMethod + public interface IPaymentMethod + { + PaymentMethodId GetId(); + decimal Rate { get; set; } + IPaymentMethodDetails GetPaymentMethodDetails(); + } + + public class PaymentMethod : IPaymentMethod { [JsonIgnore] public InvoiceEntity ParentEntity { get; set; }