From cf6b17250a4d125d65eaa2682bea6d821f22a591 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Thu, 31 Jan 2019 19:07:38 +0900 Subject: [PATCH] Can set lightning network as default payment method (close #290) --- .../Controllers/InvoiceController.UI.cs | 21 +++++++-------- BTCPayServer/Controllers/RateController.cs | 4 +-- BTCPayServer/Controllers/StoresController.cs | 9 ++++--- BTCPayServer/Data/StoreData.cs | 11 ++++---- .../CheckoutExperienceViewModel.cs | 26 ++++++++++++++----- .../Views/Stores/CheckoutExperience.cshtml | 4 +-- 6 files changed, 44 insertions(+), 31 deletions(-) diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 6a79b1511..37f5494ac 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -190,7 +190,7 @@ namespace BTCPayServer.Controllers id = invoiceId; //// - var model = await GetInvoiceModel(invoiceId, paymentMethodId); + var model = await GetInvoiceModel(invoiceId, paymentMethodId == null ? null : PaymentMethodId.Parse(paymentMethodId)); if (model == null) return NotFound(); @@ -213,31 +213,29 @@ namespace BTCPayServer.Controllers return View(nameof(Checkout), model); } - private async Task GetInvoiceModel(string invoiceId, string paymentMethodIdStr) + private async Task GetInvoiceModel(string invoiceId, PaymentMethodId paymentMethodId) { var invoice = await _InvoiceRepository.GetInvoice(invoiceId); if (invoice == null) return null; var store = await _StoreRepository.FindStore(invoice.StoreId); - bool isDefaultCrypto = false; - if (paymentMethodIdStr == null) + bool isDefaultPaymentId = false; + if (paymentMethodId == null) { - paymentMethodIdStr = store.GetDefaultCrypto(_NetworkProvider); - isDefaultCrypto = true; + paymentMethodId = store.GetDefaultPaymentId(_NetworkProvider); + isDefaultPaymentId = true; } - var paymentMethodId = PaymentMethodId.Parse(paymentMethodIdStr); var network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); - if (network == null && isDefaultCrypto) + if (network == null && isDefaultPaymentId) { network = _NetworkProvider.GetAll().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); - paymentMethodIdStr = paymentMethodId.ToString(); } if (invoice == null || network == null) return null; if (!invoice.Support(paymentMethodId)) { - if (!isDefaultCrypto) + if (!isDefaultPaymentId) return null; var paymentMethodTemp = invoice.GetPaymentMethods(_NetworkProvider) .Where(c => paymentMethodId.CryptoCode == c.GetId().CryptoCode) @@ -246,7 +244,6 @@ namespace BTCPayServer.Controllers paymentMethodTemp = invoice.GetPaymentMethods(_NetworkProvider).First(); network = paymentMethodTemp.Network; paymentMethodId = paymentMethodTemp.GetId(); - paymentMethodIdStr = paymentMethodId.ToString(); } var paymentMethod = invoice.GetPaymentMethod(paymentMethodId, _NetworkProvider); @@ -375,7 +372,7 @@ namespace BTCPayServer.Controllers [Route("invoice/status")] public async Task GetStatus(string invoiceId, string paymentMethodId = null) { - var model = await GetInvoiceModel(invoiceId, paymentMethodId); + var model = await GetInvoiceModel(invoiceId, paymentMethodId == null ? null : PaymentMethodId.Parse(paymentMethodId)); if (model == null) return NotFound(); return Json(model); diff --git a/BTCPayServer/Controllers/RateController.cs b/BTCPayServer/Controllers/RateController.cs index 21869a7bb..54daf85fe 100644 --- a/BTCPayServer/Controllers/RateController.cs +++ b/BTCPayServer/Controllers/RateController.cs @@ -141,9 +141,9 @@ namespace BTCPayServer.Controllers { var supportedMethods = store.GetSupportedPaymentMethods(_NetworkProvider); var currencyCodes = supportedMethods.Select(method => method.PaymentId.CryptoCode).Distinct(); - var defaultCrypto = store.GetDefaultCrypto(_NetworkProvider); + var defaultPaymentId = store.GetDefaultPaymentId(_NetworkProvider); - currencyPairs = BuildCurrencyPairs(currencyCodes, defaultCrypto); + currencyPairs = BuildCurrencyPairs(currencyCodes, defaultPaymentId.CryptoCode); if (string.IsNullOrEmpty(currencyPairs)) { diff --git a/BTCPayServer/Controllers/StoresController.cs b/BTCPayServer/Controllers/StoresController.cs index 9604d439f..0dee1e638 100644 --- a/BTCPayServer/Controllers/StoresController.cs +++ b/BTCPayServer/Controllers/StoresController.cs @@ -331,7 +331,7 @@ namespace BTCPayServer.Controllers { var storeBlob = StoreData.GetStoreBlob(); var vm = new CheckoutExperienceViewModel(); - vm.SetCryptoCurrencies(_ExplorerProvider, StoreData.GetDefaultCrypto(_NetworkProvider)); + vm.SetCryptoCurrencies(_NetworkProvider, StoreData, StoreData.GetDefaultPaymentId(_NetworkProvider)); vm.SetLanguages(_LangService, storeBlob.DefaultLang); vm.LightningMaxValue = storeBlob.LightningMaxValue?.ToString() ?? ""; vm.OnChainMinValue = storeBlob.OnChainMinValue?.ToString() ?? ""; @@ -365,12 +365,13 @@ namespace BTCPayServer.Controllers } bool needUpdate = false; var blob = StoreData.GetStoreBlob(); - if (StoreData.GetDefaultCrypto(_NetworkProvider) != model.DefaultCryptoCurrency) + var defaultPaymentMethodId = model.DefaultPaymentMethod == null ? null : PaymentMethodId.Parse(model.DefaultPaymentMethod); + if (StoreData.GetDefaultPaymentId(_NetworkProvider) != defaultPaymentMethodId) { needUpdate = true; - StoreData.SetDefaultCrypto(model.DefaultCryptoCurrency); + StoreData.SetDefaultPaymentId(defaultPaymentMethodId); } - model.SetCryptoCurrencies(_ExplorerProvider, model.DefaultCryptoCurrency); + model.SetCryptoCurrencies(_NetworkProvider, StoreData, defaultPaymentMethodId); model.SetLanguages(_LangService, model.DefaultLang); if (!ModelState.IsValid) diff --git a/BTCPayServer/Data/StoreData.cs b/BTCPayServer/Data/StoreData.cs index 18f8c2fd2..76160f58c 100644 --- a/BTCPayServer/Data/StoreData.cs +++ b/BTCPayServer/Data/StoreData.cs @@ -195,7 +195,7 @@ namespace BTCPayServer.Data get; set; } - [Obsolete("Use GetDefaultCrypto instead")] + [Obsolete("Use GetDefaultPaymentId instead")] public string DefaultCrypto { get; set; } public List PairedSINs { get; set; } public IEnumerable APIKeys { get; set; } @@ -204,13 +204,14 @@ namespace BTCPayServer.Data public List AdditionalClaims { get; set; } = new List(); #pragma warning disable CS0618 - public string GetDefaultCrypto(BTCPayNetworkProvider networkProvider = null) + public PaymentMethodId GetDefaultPaymentId(BTCPayNetworkProvider networkProvider = null) { - return DefaultCrypto ?? (networkProvider == null ? "BTC" : GetSupportedPaymentMethods(networkProvider).Select(p => p.PaymentId.CryptoCode).FirstOrDefault() ?? "BTC"); + var str = DefaultCrypto ?? (networkProvider == null ? "BTC" : GetSupportedPaymentMethods(networkProvider).Select(p => p.PaymentId.ToString()).FirstOrDefault() ?? "BTC"); + return PaymentMethodId.Parse(str); } - public void SetDefaultCrypto(string defaultCryptoCurrency) + public void SetDefaultPaymentId(PaymentMethodId defaultPaymentId) { - DefaultCrypto = defaultCryptoCurrency; + DefaultCrypto = defaultPaymentId.ToString(); } #pragma warning restore CS0618 diff --git a/BTCPayServer/Models/StoreViewModels/CheckoutExperienceViewModel.cs b/BTCPayServer/Models/StoreViewModels/CheckoutExperienceViewModel.cs index f2d4007d1..91052a983 100644 --- a/BTCPayServer/Models/StoreViewModels/CheckoutExperienceViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/CheckoutExperienceViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; +using BTCPayServer.Payments; using BTCPayServer.Services; using BTCPayServer.Validation; using Microsoft.AspNetCore.Mvc.Rendering; @@ -19,8 +20,8 @@ namespace BTCPayServer.Models.StoreViewModels public SelectList CryptoCurrencies { get; set; } public SelectList Languages { get; set; } - [Display(Name = "Default crypto currency on checkout")] - public string DefaultCryptoCurrency { get; set; } + [Display(Name = "Default the default payment method on checkout")] + public string DefaultPaymentMethod { get; set; } [Display(Name = "Default language on checkout")] public string DefaultLang { get; set; } [Display(Name = "Do not propose lightning payment if value of the invoice is above...")] @@ -48,12 +49,25 @@ namespace BTCPayServer.Models.StoreViewModels public string HtmlTitle { get; set; } - public void SetCryptoCurrencies(ExplorerClientProvider explorerProvider, string defaultCrypto) + public void SetCryptoCurrencies(BTCPayNetworkProvider networks, Data.StoreData storeData, PaymentMethodId paymentMethodId) { - var choices = explorerProvider.GetAll().Select(o => new Format() { Name = o.Item1.CryptoCode, Value = o.Item1.CryptoCode }).ToArray(); - var chosen = choices.FirstOrDefault(f => f.Value == defaultCrypto) ?? choices.FirstOrDefault(); + var paymentIds = storeData.GetSupportedPaymentMethods(networks).Select(o => o.PaymentId) + .OrderByDescending(a => a.CryptoCode == "BTC") + .ThenBy(a => a.CryptoCode) + .ThenBy(a => a.PaymentType == PaymentTypes.LightningLike ? 1 : 0); + + + var choices = paymentIds.Select(o => new Format() { Name = GetDisplayName(networks, o), Value = o.ToString() }).ToArray(); + var chosen = choices.FirstOrDefault(f => f.Value == paymentMethodId?.ToString()) ?? choices.FirstOrDefault(); CryptoCurrencies = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen); - DefaultCryptoCurrency = chosen.Name; + DefaultPaymentMethod = chosen.Value; + } + + private string GetDisplayName(BTCPayNetworkProvider networks, PaymentMethodId paymentMethodId) + { + var display = networks.GetNetwork(paymentMethodId.CryptoCode)?.DisplayName ?? paymentMethodId.CryptoCode; + return paymentMethodId.PaymentType == PaymentTypes.BTCLike ? + display : $"{display} (Lightning)"; } public void SetLanguages(LanguageService langService, string defaultLang) diff --git a/BTCPayServer/Views/Stores/CheckoutExperience.cshtml b/BTCPayServer/Views/Stores/CheckoutExperience.cshtml index 68e87ecdf..f22386c12 100644 --- a/BTCPayServer/Views/Stores/CheckoutExperience.cshtml +++ b/BTCPayServer/Views/Stores/CheckoutExperience.cshtml @@ -31,8 +31,8 @@
- - + +