mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
Can disable method of payments
This commit is contained in:
parent
3775317047
commit
d480be925b
@ -123,9 +123,10 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
HashSet<CurrencyPair> currencyPairsToFetch = new HashSet<CurrencyPair>();
|
||||
var rules = storeBlob.GetRateRules(_NetworkProvider);
|
||||
|
||||
var excludeFilter = storeBlob.GetExcludedPaymentMethods(); // Here we can compose filters from other origin with PaymentFilter.Any()
|
||||
foreach (var network in store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Select(c => _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode))
|
||||
.Where(s => !excludeFilter.Match(s.PaymentId))
|
||||
.Select(c => _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode))
|
||||
.Where(c => c != null))
|
||||
{
|
||||
currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, invoice.Currency));
|
||||
@ -140,6 +141,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
var fetchingAll = WhenAllFetched(logs, fetchingByCurrencyPair);
|
||||
var supportedPaymentMethods = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Where(s => !excludeFilter.Match(s.PaymentId))
|
||||
.Select(c =>
|
||||
(Handler: (IPaymentMethodHandler)_ServiceProvider.GetService(typeof(IPaymentMethodHandler<>).MakeGenericType(c.GetType())),
|
||||
SupportedPaymentMethod: c,
|
||||
|
@ -44,6 +44,7 @@ namespace BTCPayServer.Controllers
|
||||
private void SetExistingValues(StoreData store, DerivationSchemeViewModel vm)
|
||||
{
|
||||
vm.DerivationScheme = GetExistingDerivationStrategy(vm.CryptoCode, store)?.DerivationStrategyBase.ToString();
|
||||
vm.Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(vm.CryptoCode, PaymentTypes.BTCLike));
|
||||
}
|
||||
|
||||
private DerivationStrategy GetExistingDerivationStrategy(string cryptoCode, StoreData store)
|
||||
@ -93,10 +94,8 @@ namespace BTCPayServer.Controllers
|
||||
vm.Confirmation = false;
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
if (!vm.Confirmation && strategy != null)
|
||||
return ShowAddresses(vm, strategy);
|
||||
|
||||
if (vm.Confirmation && !string.IsNullOrWhiteSpace(vm.HintAddress))
|
||||
{
|
||||
BitcoinAddress address = null;
|
||||
@ -132,6 +131,10 @@ namespace BTCPayServer.Controllers
|
||||
if (strategy != null)
|
||||
await wallet.TrackAsync(strategy.DerivationStrategyBase);
|
||||
store.SetSupportedPaymentMethod(paymentMethodId, strategy);
|
||||
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
storeBlob.SetExcluded(paymentMethodId, !vm.Enabled);
|
||||
store.SetStoreBlob(storeBlob);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -24,9 +24,11 @@ namespace BTCPayServer.Controllers
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
LightningNodeViewModel vm = new LightningNodeViewModel();
|
||||
vm.CryptoCode = cryptoCode;
|
||||
vm.InternalLightningNode = GetInternalLighningNode(cryptoCode)?.ToString();
|
||||
LightningNodeViewModel vm = new LightningNodeViewModel
|
||||
{
|
||||
CryptoCode = cryptoCode,
|
||||
InternalLightningNode = GetInternalLighningNode(cryptoCode)?.ToString()
|
||||
};
|
||||
SetExistingValues(store, vm);
|
||||
return View(vm);
|
||||
}
|
||||
@ -34,6 +36,7 @@ namespace BTCPayServer.Controllers
|
||||
private void SetExistingValues(StoreData store, LightningNodeViewModel vm)
|
||||
{
|
||||
vm.ConnectionString = GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store)?.GetLightningUrl()?.ToString();
|
||||
vm.Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(vm.CryptoCode, PaymentTypes.LightningLike));
|
||||
}
|
||||
private LightningSupportedPaymentMethod GetExistingLightningSupportedPaymentMethod(string cryptoCode, StoreData store)
|
||||
{
|
||||
@ -132,41 +135,43 @@ namespace BTCPayServer.Controllers
|
||||
CryptoCode = paymentMethodId.CryptoCode
|
||||
};
|
||||
paymentMethod.SetLightningUrl(connectionString);
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
storeBlob.SetExcluded(paymentMethod.PaymentId , vm.Enabled);
|
||||
store.SetStoreBlob(storeBlob);
|
||||
}
|
||||
|
||||
if (command == "save")
|
||||
switch (command)
|
||||
{
|
||||
store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
|
||||
await _Repo.UpdateStore(store);
|
||||
StatusMessage = $"Lightning node modified ({network.CryptoCode})";
|
||||
return RedirectToAction(nameof(UpdateStore), new { storeId = storeId });
|
||||
}
|
||||
else // if(command == "test")
|
||||
{
|
||||
if (paymentMethod == null)
|
||||
{
|
||||
case "save":
|
||||
store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
|
||||
await _Repo.UpdateStore(store);
|
||||
StatusMessage = $"Lightning node modified ({network.CryptoCode})";
|
||||
return RedirectToAction(nameof(UpdateStore), new { storeId = storeId });
|
||||
case "test" when paymentMethod == null:
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "Missing url parameter");
|
||||
return View(vm);
|
||||
}
|
||||
var handler = (LightningLikePaymentHandler)_ServiceProvider.GetRequiredService<IPaymentMethodHandler<Payments.Lightning.LightningSupportedPaymentMethod>>();
|
||||
try
|
||||
{
|
||||
var info = await handler.Test(paymentMethod, network);
|
||||
if (!vm.SkipPortTest)
|
||||
case "test":
|
||||
var handler = (LightningLikePaymentHandler)_ServiceProvider.GetRequiredService<IPaymentMethodHandler<Payments.Lightning.LightningSupportedPaymentMethod>>();
|
||||
try
|
||||
{
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
|
||||
var info = await handler.Test(paymentMethod, network);
|
||||
if (!vm.SkipPortTest)
|
||||
{
|
||||
await handler.TestConnection(info, cts.Token);
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
|
||||
{
|
||||
await handler.TestConnection(info, cts.Token);
|
||||
}
|
||||
}
|
||||
vm.StatusMessage = $"Connection to the lightning node succeeded ({info})";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
vm.StatusMessage = $"Error: {ex.Message}";
|
||||
return View(vm);
|
||||
}
|
||||
vm.StatusMessage = $"Connection to the lightning node succeeded ({info})";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
vm.StatusMessage = $"Error: {ex.Message}";
|
||||
return View(vm);
|
||||
}
|
||||
return View(vm);
|
||||
default:
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ namespace BTCPayServer.Controllers
|
||||
vm.NetworkFee = !storeBlob.NetworkFeeDisabled;
|
||||
vm.SpeedPolicy = store.SpeedPolicy;
|
||||
vm.CanDelete = _Repo.CanDeleteStores();
|
||||
AddPaymentMethods(store, vm);
|
||||
AddPaymentMethods(store, storeBlob, vm);
|
||||
vm.MonitoringExpiration = storeBlob.MonitoringExpiration;
|
||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
|
||||
@ -413,8 +413,9 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
|
||||
|
||||
private void AddPaymentMethods(StoreData store, StoreViewModel vm)
|
||||
private void AddPaymentMethods(StoreData store, StoreBlob storeBlob, StoreViewModel vm)
|
||||
{
|
||||
var excludeFilters = storeBlob.GetExcludedPaymentMethods();
|
||||
var derivationByCryptoCode =
|
||||
store
|
||||
.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
@ -428,6 +429,7 @@ namespace BTCPayServer.Controllers
|
||||
Crypto = network.CryptoCode,
|
||||
Value = strategy?.DerivationStrategyBase?.ToString() ?? string.Empty,
|
||||
WalletId = new WalletId(store.Id, network.CryptoCode),
|
||||
Enabled = !excludeFilters.Match(new Payments.PaymentMethodId(network.CryptoCode, Payments.PaymentTypes.BTCLike))
|
||||
});
|
||||
}
|
||||
|
||||
@ -439,10 +441,12 @@ namespace BTCPayServer.Controllers
|
||||
foreach (var network in _NetworkProvider.GetAll())
|
||||
{
|
||||
var lightning = lightningByCryptoCode.TryGet(network.CryptoCode);
|
||||
var paymentId = new Payments.PaymentMethodId(network.CryptoCode, Payments.PaymentTypes.LightningLike);
|
||||
vm.LightningNodes.Add(new StoreViewModel.LightningNode()
|
||||
{
|
||||
CryptoCode = network.CryptoCode,
|
||||
Address = lightning?.GetLightningUrl()?.BaseUri.AbsoluteUri ?? string.Empty
|
||||
Address = lightning?.GetLightningUrl()?.BaseUri.AbsoluteUri ?? string.Empty,
|
||||
Enabled = !excludeFilters.Match(paymentId)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ namespace BTCPayServer.Data
|
||||
#pragma warning disable CS0618
|
||||
public string GetDefaultCrypto(BTCPayNetworkProvider networkProvider = null)
|
||||
{
|
||||
return DefaultCrypto ?? (networkProvider == null? "BTC" : GetSupportedPaymentMethods(networkProvider).First().PaymentId.CryptoCode);
|
||||
return DefaultCrypto ?? (networkProvider == null ? "BTC" : GetSupportedPaymentMethods(networkProvider).First().PaymentId.CryptoCode);
|
||||
}
|
||||
public void SetDefaultCrypto(string defaultCryptoCurrency)
|
||||
{
|
||||
@ -336,8 +336,8 @@ namespace BTCPayServer.Data
|
||||
|
||||
public BTCPayServer.Rating.RateRules GetRateRules(BTCPayNetworkProvider networkProvider)
|
||||
{
|
||||
if (!RateScripting ||
|
||||
string.IsNullOrEmpty(RateScript) ||
|
||||
if (!RateScripting ||
|
||||
string.IsNullOrEmpty(RateScript) ||
|
||||
!BTCPayServer.Rating.RateRules.TryParse(RateScript, out var rules))
|
||||
{
|
||||
return GetDefaultRateRules(networkProvider);
|
||||
@ -373,5 +373,34 @@ namespace BTCPayServer.Data
|
||||
rules.GlobalMultiplier = GetRateMultiplier();
|
||||
return rules;
|
||||
}
|
||||
|
||||
[Obsolete("Use GetExcludedPaymentMethods instead")]
|
||||
public string[] ExcludedPaymentMethods { get; set; }
|
||||
|
||||
public IPaymentFilter GetExcludedPaymentMethods()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (ExcludedPaymentMethods == null || ExcludedPaymentMethods.Length == 0)
|
||||
return PaymentFilter.Never();
|
||||
return PaymentFilter.Any(ExcludedPaymentMethods.Select(p => PaymentFilter.WhereIs(PaymentMethodId.Parse(p))).ToArray());
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
public bool IsExcluded(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
return GetExcludedPaymentMethods().Match(paymentMethodId);
|
||||
}
|
||||
|
||||
public void SetExcluded(PaymentMethodId paymentMethodId, bool value)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var methods = new HashSet<string>(ExcludedPaymentMethods ?? Array.Empty<string>());
|
||||
if (value)
|
||||
methods.Add(paymentMethodId.ToString());
|
||||
else
|
||||
methods.Remove(paymentMethodId.ToString());
|
||||
ExcludedPaymentMethods = methods.ToArray();
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
[Display(Name = "Hint address")]
|
||||
public string HintAddress { get; set; }
|
||||
public bool Confirmation { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public string ServerUrl { get; set; }
|
||||
public string StatusMessage { get; internal set; }
|
||||
|
@ -24,5 +24,6 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
public string StatusMessage { get; set; }
|
||||
public string InternalLightningNode { get; internal set; }
|
||||
public bool SkipPortTest { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
public string Crypto { get; set; }
|
||||
public string Value { get; set; }
|
||||
public WalletId WalletId { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
|
||||
public StoreViewModel()
|
||||
@ -83,6 +84,7 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
{
|
||||
public string CryptoCode { get; set; }
|
||||
public string Address { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
public List<LightningNode> LightningNodes
|
||||
{
|
||||
|
74
BTCPayServer/Payments/IPaymentFilter.cs
Normal file
74
BTCPayServer/Payments/IPaymentFilter.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Payments
|
||||
{
|
||||
public interface IPaymentFilter
|
||||
{
|
||||
bool Match(PaymentMethodId paymentMethodId);
|
||||
}
|
||||
|
||||
public class PaymentFilter
|
||||
{
|
||||
class NeverPaymentFilter : IPaymentFilter
|
||||
{
|
||||
|
||||
private static readonly NeverPaymentFilter _Instance = new NeverPaymentFilter();
|
||||
public static NeverPaymentFilter Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Instance;
|
||||
}
|
||||
}
|
||||
public bool Match(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
class CompositePaymentFilter : IPaymentFilter
|
||||
{
|
||||
private readonly IPaymentFilter[] _filters;
|
||||
|
||||
public CompositePaymentFilter(IPaymentFilter[] filters)
|
||||
{
|
||||
_filters = filters;
|
||||
}
|
||||
public bool Match(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
return _filters.Any(f => f.Match(paymentMethodId));
|
||||
}
|
||||
}
|
||||
class PaymentIdFilter : IPaymentFilter
|
||||
{
|
||||
private readonly PaymentMethodId _paymentMethodId;
|
||||
|
||||
public PaymentIdFilter(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
_paymentMethodId = paymentMethodId;
|
||||
}
|
||||
public bool Match(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
return paymentMethodId == _paymentMethodId;
|
||||
}
|
||||
}
|
||||
public static IPaymentFilter Never()
|
||||
{
|
||||
return NeverPaymentFilter.Instance;
|
||||
}
|
||||
public static IPaymentFilter Any(IPaymentFilter[] filters)
|
||||
{
|
||||
if (filters == null)
|
||||
throw new ArgumentNullException(nameof(filters));
|
||||
return new CompositePaymentFilter(filters);
|
||||
}
|
||||
public static IPaymentFilter WhereIs(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
if (paymentMethodId == null)
|
||||
throw new ArgumentNullException(nameof(paymentMethodId));
|
||||
return new PaymentIdFilter(paymentMethodId);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
@model DerivationSchemeViewModel
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewData["Title"] = "Add derivation scheme";
|
||||
ViewData["Title"] = $"{Model.CryptoCode} Derivation scheme";
|
||||
ViewData.AddActivePage(BTCPayServer.Views.Stores.StoreNavPages.Index);
|
||||
}
|
||||
|
||||
@ -77,7 +77,12 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-primary">Continue</button>
|
||||
<div class="form-check">
|
||||
<input id="enabled" asp-for="Enabled" class="form-check-input" />
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
<span asp-validation-for="Enabled" class="text-danger"></span>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-primary" value="save">Continue</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -87,6 +92,7 @@
|
||||
</div>
|
||||
<input type="hidden" asp-for="Confirmation" />
|
||||
<input type="hidden" asp-for="DerivationScheme" />
|
||||
<input type="hidden" asp-for="Enabled" />
|
||||
<div class="form-group">
|
||||
<table class="table table-sm table-responsive-md">
|
||||
<thead>
|
||||
@ -116,7 +122,7 @@
|
||||
<input asp-for="HintAddress" class="form-control" />
|
||||
<span asp-validation-for="HintAddress" class="text-danger"></span>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-primary">Confirm</button>
|
||||
<button name="command" type="submit" class="btn btn-primary" value="save">Confirm</button>
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
|
@ -55,13 +55,18 @@
|
||||
<label asp-for="ConnectionString"></label>
|
||||
<input id="lightningurl" asp-for="ConnectionString" class="form-control" />
|
||||
<span asp-validation-for="ConnectionString" class="text-danger"></span>
|
||||
@if(Model.InternalLightningNode != null)
|
||||
@if (Model.InternalLightningNode != null)
|
||||
{
|
||||
<p class="form-text text-muted">
|
||||
You can use the internal lightning node by <a href="#" onclick="$('#lightningurl').val('@Model.InternalLightningNode'); return false;">clicking here</a>
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input id="enabled" asp-for="Enabled" class="form-check-input" />
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
<span asp-validation-for="Enabled" class="text-danger"></span>
|
||||
</div>
|
||||
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
|
||||
<button name="command" type="submit" value="test" class="btn btn-secondary">Test connection</button>
|
||||
</form>
|
||||
|
@ -70,6 +70,7 @@
|
||||
<tr>
|
||||
<th>Crypto</th>
|
||||
<th>Derivation Scheme</th>
|
||||
<th>Status</th>
|
||||
<th style="text-align:right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -79,6 +80,12 @@
|
||||
<tr>
|
||||
<td>@scheme.Crypto</td>
|
||||
<td style="max-width:300px;overflow:hidden;">@scheme.Value</td>
|
||||
<td>
|
||||
@if (!string.IsNullOrWhiteSpace(scheme.Value))
|
||||
{
|
||||
@(scheme.Enabled ? "Enabled" : "Disabled")
|
||||
}
|
||||
</td>
|
||||
<td style="text-align:right">
|
||||
@if(!string.IsNullOrWhiteSpace(scheme.Value))
|
||||
{
|
||||
@ -106,6 +113,7 @@
|
||||
<tr>
|
||||
<th>Crypto</th>
|
||||
<th>Address</th>
|
||||
<th>Status</th>
|
||||
<th style="text-align:right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -115,6 +123,9 @@
|
||||
<tr>
|
||||
<td>@scheme.CryptoCode</td>
|
||||
<td>@scheme.Address</td>
|
||||
<td>
|
||||
@(scheme.Enabled ? "Enabled" : "Disabled")
|
||||
</td>
|
||||
<td style="text-align:right"><a asp-action="AddLightningNode" asp-route-cryptoCode="@scheme.CryptoCode">Modify</a></td>
|
||||
</tr>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user