Move payment related properties

This commit is contained in:
Dennis Reimann 2021-09-29 17:23:01 +02:00 committed by Andrew Camilleri
parent 67aee9bdc6
commit 802fec6bf3
7 changed files with 66 additions and 70 deletions

View file

@ -137,15 +137,14 @@ namespace BTCPayServer.Tests
s.RegisterNewUser(true);
var store = s.CreateNewStore();
s.AddLightningNode();
s.GoToStore(store.storeId, StoreNavPages.Checkout);
s.GoToStore(store.storeId);
s.Driver.SetCheckbox(By.Id("LightningAmountInSatoshi"), true);
var command = s.Driver.FindElement(By.Name("command"));
command.Click();
s.Driver.FindElement(By.Id("Save")).Click();
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
var invoiceId = s.CreateInvoice(store.storeName, 10, "USD", "a@g.com");
s.GoToInvoiceCheckout(invoiceId);
Assert.Contains("Sats", s.Driver.FindElement(By.ClassName("payment__currencies_noborder")).Text);
}
}

View file

@ -2365,12 +2365,12 @@ namespace BTCPayServer.Tests
Assert.DoesNotContain("&lightning=", paymentMethodFirst.InvoiceBitcoinUrlQR);
// enable unified QR code in settings
var vm = Assert.IsType<CheckoutExperienceViewModel>(Assert
.IsType<ViewResult>(user.GetController<StoresController>().CheckoutExperience()).Model
var vm = Assert.IsType<StoreViewModel>(Assert
.IsType<ViewResult>(await user.GetController<StoresController>().UpdateStore()).Model
);
vm.OnChainWithLnInvoiceFallback = true;
Assert.IsType<RedirectToActionResult>(
user.GetController<StoresController>().CheckoutExperience(vm).Result
user.GetController<StoresController>().UpdateStore(vm).Result
);
// validate that QR code now has both onchain and offchain payment urls

View file

@ -366,8 +366,7 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(Rates), new { storeId = CurrentStore.Id });
}
[HttpGet]
[Route("{storeId}/checkout")]
[HttpGet("{storeId}/checkout")]
public IActionResult CheckoutExperience()
{
var storeBlob = CurrentStore.GetStoreBlob();
@ -398,20 +397,16 @@ namespace BTCPayServer.Controllers
};
}
}).ToList();
vm.RequiresRefundEmail = storeBlob.RequiresRefundEmail;
vm.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi;
vm.LightningPrivateRouteHints = storeBlob.LightningPrivateRouteHints;
vm.OnChainWithLnInvoiceFallback = storeBlob.OnChainWithLnInvoiceFallback;
vm.LazyPaymentMethods = storeBlob.LazyPaymentMethods;
vm.RedirectAutomatically = storeBlob.RedirectAutomatically;
vm.ShowRecommendedFee = storeBlob.ShowRecommendedFee;
vm.RecommendedFeeBlockTarget = storeBlob.RecommendedFeeBlockTarget;
vm.CustomCSS = storeBlob.CustomCSS;
vm.CustomLogo = storeBlob.CustomLogo;
vm.HtmlTitle = storeBlob.HtmlTitle;
vm.AutoDetectLanguage = storeBlob.AutoDetectLanguage;
vm.SetLanguages(_LangService, storeBlob.DefaultLang);
return View(vm);
}
@ -431,8 +426,7 @@ namespace BTCPayServer.Controllers
vm.PaymentMethods = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen?.Value);
vm.DefaultPaymentMethod = chosen?.Value;
}
[HttpPost]
[Route("{storeId}/checkout")]
public async Task<IActionResult> CheckoutExperience(CheckoutExperienceViewModel model)
@ -475,13 +469,7 @@ namespace BTCPayServer.Controllers
blob.RequiresRefundEmail = model.RequiresRefundEmail;
blob.LazyPaymentMethods = model.LazyPaymentMethods;
blob.LightningAmountInSatoshi = model.LightningAmountInSatoshi;
blob.LightningPrivateRouteHints = model.LightningPrivateRouteHints;
blob.OnChainWithLnInvoiceFallback = model.OnChainWithLnInvoiceFallback;
blob.RedirectAutomatically = model.RedirectAutomatically;
blob.ShowRecommendedFee = model.ShowRecommendedFee;
blob.RecommendedFeeBlockTarget = model.RecommendedFeeBlockTarget;
blob.CustomLogo = model.CustomLogo;
blob.CustomCSS = model.CustomCSS;
blob.HtmlTitle = string.IsNullOrWhiteSpace(model.HtmlTitle) ? null : model.HtmlTitle;
@ -578,9 +566,14 @@ namespace BTCPayServer.Controllers
vm.PayJoinEnabled = storeBlob.PayJoinEnabled;
vm.HintWallet = storeBlob.Hints.Wallet;
vm.HintLightning = storeBlob.Hints.Lightning;
vm.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi;
vm.LightningPrivateRouteHints = storeBlob.LightningPrivateRouteHints;
vm.OnChainWithLnInvoiceFallback = storeBlob.OnChainWithLnInvoiceFallback;
vm.ShowRecommendedFee = storeBlob.ShowRecommendedFee;
vm.RecommendedFeeBlockTarget = storeBlob.RecommendedFeeBlockTarget;
vm.IsOnchainSetup = vm.DerivationSchemes.Any(scheme => !string.IsNullOrWhiteSpace(scheme.Value));
vm.IsLightningSetup = vm.LightningNodes.Any(scheme => !string.IsNullOrWhiteSpace(scheme.Address));
(bool canUseHotWallet, _) = await CanUseHotWallet();
vm.CanUsePayJoin = canUseHotWallet && store
.GetSupportedPaymentMethods(_NetworkProvider)
@ -617,6 +610,12 @@ namespace BTCPayServer.Controllers
blob.InvoiceExpiration = TimeSpan.FromMinutes(model.InvoiceExpiration);
blob.LightningDescriptionTemplate = model.LightningDescriptionTemplate ?? string.Empty;
blob.PaymentTolerance = model.PaymentTolerance;
blob.LightningAmountInSatoshi = model.LightningAmountInSatoshi;
blob.LightningPrivateRouteHints = model.LightningPrivateRouteHints;
blob.OnChainWithLnInvoiceFallback = model.OnChainWithLnInvoiceFallback;
blob.ShowRecommendedFee = model.ShowRecommendedFee;
blob.RecommendedFeeBlockTarget = model.RecommendedFeeBlockTarget;
var payjoinChanged = blob.PayJoinEnabled != model.PayJoinEnabled;
blob.PayJoinEnabled = model.PayJoinEnabled;
if (CurrentStore.SetStoreBlob(blob))

View file

@ -34,27 +34,11 @@ namespace BTCPayServer.Models.StoreViewModels
[Display(Name = "Requires a refund email")]
public bool RequiresRefundEmail { get; set; }
[Display(Name = "Display Lightning payment amounts in Satoshis")]
public bool LightningAmountInSatoshi { get; set; }
[Display(Name = "Add hop hints for private channels to the Lightning invoice")]
public bool LightningPrivateRouteHints { get; set; }
[Display(Name = "Include Lightning invoice fallback to on-chain BIP21 payment URL")]
public bool OnChainWithLnInvoiceFallback { get; set; }
[Display(Name = "Only enable the payment method after user explicitly chooses it")]
public bool LazyPaymentMethods { get; set; }
[Display(Name = "Redirect invoice to redirect url automatically after paid")]
public bool RedirectAutomatically { get; set; }
[Display(Name = "Show recommended fee")]
public bool ShowRecommendedFee { get; set; }
[Display(Name = "Recommended fee confirmation target blocks")]
[Range(1, double.PositiveInfinity)]
public int RecommendedFeeBlockTarget { get; set; }
[Display(Name = "Auto-detect language on checkout")]
public bool AutoDetectLanguage { get; set; }

View file

@ -95,6 +95,22 @@ namespace BTCPayServer.Models.StoreViewModels
public bool HintWallet { get; set; }
public bool HintLightning { get; set; }
[Display(Name = "Show recommended fee")]
public bool ShowRecommendedFee { get; set; }
[Display(Name = "Recommended fee confirmation target blocks")]
[Range(1, double.PositiveInfinity)]
public int RecommendedFeeBlockTarget { get; set; }
[Display(Name = "Display Lightning payment amounts in Satoshis")]
public bool LightningAmountInSatoshi { get; set; }
[Display(Name = "Add hop hints for private channels to the Lightning invoice")]
public bool LightningPrivateRouteHints { get; set; }
[Display(Name = "Include Lightning invoice fallback to on-chain BIP21 payment URL")]
public bool OnChainWithLnInvoiceFallback { get; set; }
public class LightningNode
{
public string CryptoCode { get; set; }

View file

@ -21,7 +21,7 @@
</div>
<div class="form-group mb-4">
<div class="form-label mb-1">Enable payment methods only when amount is …</div>
<table class="table">
<table class="table table-sm mt-0 mx-0">
@for (var index = 0; index < Model.PaymentMethodCriteria.Count; index++)
{
var criteria = Model.PaymentMethodCriteria[index];
@ -43,7 +43,6 @@
</table>
</div>
}
<h5 class="mb-3">General</h5>
<div class="form-check my-1">
<input asp-for="RequiresRefundEmail" type="checkbox" class="form-check-input"/>
<label asp-for="RequiresRefundEmail" class="form-check-label"></label>
@ -56,30 +55,6 @@
<input asp-for="RedirectAutomatically" type="checkbox" class="form-check-input" />
<label asp-for="RedirectAutomatically" class="form-check-label"></label>
</div>
<div class="form-check my-1">
<input asp-for="ShowRecommendedFee" type="checkbox" class="form-check-input"/>
<label asp-for="ShowRecommendedFee" class="form-check-label"></label>
<p class="form-text text-muted mb-0">Fee will be shown for BTC and LTC onchain payments only.</p>
</div>
<div class="form-group mt-2 mb-4">
<label asp-for="RecommendedFeeBlockTarget" class="form-label"></label>
<input asp-for="RecommendedFeeBlockTarget" class="form-control" style="width:8ch" min="1" />
<span asp-validation-for="RecommendedFeeBlockTarget" class="text-danger"></span>
</div>
<h5 class="mt-4 mb-3">Lightning</h5>
<div class="form-check my-1">
<input asp-for="LightningAmountInSatoshi" type="checkbox" class="form-check-input"/>
<label asp-for="LightningAmountInSatoshi" class="form-check-label"></label>
</div>
<div class="form-check my-1">
<input asp-for="LightningPrivateRouteHints" type="checkbox" class="form-check-input"/>
<label asp-for="LightningPrivateRouteHints" class="form-check-label"></label>
</div>
<div class="form-check my-1">
<input asp-for="OnChainWithLnInvoiceFallback" type="checkbox" class="form-check-input"/>
<label asp-for="OnChainWithLnInvoiceFallback" class="form-check-label"></label>
</div>
<h4 class="mt-5 mb-3">Appearance</h4>
<div class="form-group">

View file

@ -228,7 +228,7 @@
</div>
@if (Model.IsOnchainSetup)
{
<h5 class="mt-4 mb-3">Onchain</h5>
<h5 class="mt-5 mb-3">On-Chain</h5>
@if (Model.CanUsePayJoin)
{
<div class="form-group">
@ -269,11 +269,34 @@
</div>
<span asp-validation-for="SpeedPolicy" class="text-danger"></span>
</div>
<div class="form-check my-1">
<input asp-for="ShowRecommendedFee" type="checkbox" class="form-check-input"/>
<label asp-for="ShowRecommendedFee" class="form-check-label"></label>
<p class="form-text text-muted mb-0">Fee will be shown for BTC and LTC onchain payments only.</p>
</div>
<div class="form-group mt-2 mb-4">
<label asp-for="RecommendedFeeBlockTarget" class="form-label"></label>
<input asp-for="RecommendedFeeBlockTarget" class="form-control" style="width:8ch" min="1" />
<span asp-validation-for="RecommendedFeeBlockTarget" class="text-danger"></span>
</div>
}
@if (Model.IsLightningSetup)
{
<h5 class="mt-4 mb-3">Lightning</h5>
<div class="form-group">
<h5 class="mt-5 mb-3">Lightning</h5>
<div class="form-check my-1">
<input asp-for="LightningAmountInSatoshi" type="checkbox" class="form-check-input"/>
<label asp-for="LightningAmountInSatoshi" class="form-check-label"></label>
</div>
<div class="form-check my-1">
<input asp-for="LightningPrivateRouteHints" type="checkbox" class="form-check-input"/>
<label asp-for="LightningPrivateRouteHints" class="form-check-label"></label>
</div>
<div class="form-check my-1">
<input asp-for="OnChainWithLnInvoiceFallback" type="checkbox" class="form-check-input"/>
<label asp-for="OnChainWithLnInvoiceFallback" class="form-check-label"></label>
</div>
<div class="form-group mt-3">
<label asp-for="LightningDescriptionTemplate" class="form-label"></label>
<input asp-for="LightningDescriptionTemplate" class="form-control"/>
<span asp-validation-for="LightningDescriptionTemplate" class="text-danger"></span>