mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Preserving title with custom amount (#403)
* Preserving title with custom amount * Custom button texts for complete localization * Update tests, now checking custom amount description and button text * Support for Custom CSS in POS
This commit is contained in:
committed by
Nicolas Dorier
parent
24a8c4015c
commit
9d21c89151
@@ -1460,12 +1460,18 @@ namespace BTCPayServer.Tests
|
|||||||
var vmpos = Assert.IsType<UpdatePointOfSaleViewModel>(Assert.IsType<ViewResult>(apps.UpdatePointOfSale(appId).Result).Model);
|
var vmpos = Assert.IsType<UpdatePointOfSaleViewModel>(Assert.IsType<ViewResult>(apps.UpdatePointOfSale(appId).Result).Model);
|
||||||
vmpos.Title = "hello";
|
vmpos.Title = "hello";
|
||||||
vmpos.Currency = "CAD";
|
vmpos.Currency = "CAD";
|
||||||
vmpos.Template =
|
vmpos.ButtonText = "{0} Purchase";
|
||||||
"apple:\n" +
|
vmpos.CustomButtonText = "Nicolas Sexy Hair";
|
||||||
" price: 5.0\n" +
|
vmpos.Template = @"
|
||||||
" title: good apple\n" +
|
apple:
|
||||||
"orange:\n" +
|
price: 5.0
|
||||||
" price: 10.0\n";
|
title: good apple
|
||||||
|
orange:
|
||||||
|
price: 10.0
|
||||||
|
donation:
|
||||||
|
price: 1.02
|
||||||
|
custom: true
|
||||||
|
";
|
||||||
Assert.IsType<RedirectToActionResult>(apps.UpdatePointOfSale(appId, vmpos).Result);
|
Assert.IsType<RedirectToActionResult>(apps.UpdatePointOfSale(appId, vmpos).Result);
|
||||||
vmpos = Assert.IsType<UpdatePointOfSaleViewModel>(Assert.IsType<ViewResult>(apps.UpdatePointOfSale(appId).Result).Model);
|
vmpos = Assert.IsType<UpdatePointOfSaleViewModel>(Assert.IsType<ViewResult>(apps.UpdatePointOfSale(appId).Result).Model);
|
||||||
Assert.Equal("hello", vmpos.Title);
|
Assert.Equal("hello", vmpos.Title);
|
||||||
@@ -1473,16 +1479,29 @@ namespace BTCPayServer.Tests
|
|||||||
var publicApps = user.GetController<AppsPublicController>();
|
var publicApps = user.GetController<AppsPublicController>();
|
||||||
var vmview = Assert.IsType<ViewPointOfSaleViewModel>(Assert.IsType<ViewResult>(publicApps.ViewPointOfSale(appId).Result).Model);
|
var vmview = Assert.IsType<ViewPointOfSaleViewModel>(Assert.IsType<ViewResult>(publicApps.ViewPointOfSale(appId).Result).Model);
|
||||||
Assert.Equal("hello", vmview.Title);
|
Assert.Equal("hello", vmview.Title);
|
||||||
Assert.Equal(2, vmview.Items.Length);
|
Assert.Equal(3, vmview.Items.Length);
|
||||||
Assert.Equal("good apple", vmview.Items[0].Title);
|
Assert.Equal("good apple", vmview.Items[0].Title);
|
||||||
Assert.Equal("orange", vmview.Items[1].Title);
|
Assert.Equal("orange", vmview.Items[1].Title);
|
||||||
Assert.Equal(10.0m, vmview.Items[1].Price.Value);
|
Assert.Equal(10.0m, vmview.Items[1].Price.Value);
|
||||||
Assert.Equal("$5.00", vmview.Items[0].Price.Formatted);
|
Assert.Equal("$5.00", vmview.Items[0].Price.Formatted);
|
||||||
|
Assert.Equal("{0} Purchase", vmview.ButtonText);
|
||||||
|
Assert.Equal("Nicolas Sexy Hair", vmview.CustomButtonText);
|
||||||
Assert.IsType<RedirectResult>(publicApps.ViewPointOfSale(appId, 0, null, null, null, null, "orange").Result);
|
Assert.IsType<RedirectResult>(publicApps.ViewPointOfSale(appId, 0, null, null, null, null, "orange").Result);
|
||||||
var invoice = user.BitPay.GetInvoices().First();
|
|
||||||
Assert.Equal(10.00m, invoice.Price);
|
//
|
||||||
Assert.Equal("CAD", invoice.Currency);
|
var invoices = user.BitPay.GetInvoices();
|
||||||
Assert.Equal("orange", invoice.ItemDesc);
|
var orangeInvoice = invoices.First();
|
||||||
|
Assert.Equal(10.00m, orangeInvoice.Price);
|
||||||
|
Assert.Equal("CAD", orangeInvoice.Currency);
|
||||||
|
Assert.Equal("orange", orangeInvoice.ItemDesc);
|
||||||
|
|
||||||
|
// testing custom amount
|
||||||
|
Assert.IsType<RedirectResult>(publicApps.ViewPointOfSale(appId, 5, null, null, null, null, "donation").Result);
|
||||||
|
invoices = user.BitPay.GetInvoices();
|
||||||
|
var donationInvoice = invoices.First(); // expected behavior is that new invoice should now be first
|
||||||
|
Assert.Equal(5m, donationInvoice.Price);
|
||||||
|
Assert.Equal("CAD", donationInvoice.Currency);
|
||||||
|
Assert.Equal("donation", donationInvoice.ItemDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ namespace BTCPayServer.Controllers
|
|||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
public string Template { get; set; }
|
public string Template { get; set; }
|
||||||
public bool ShowCustomAmount { get; set; }
|
public bool ShowCustomAmount { get; set; }
|
||||||
|
|
||||||
|
public const string BUTTON_TEXT_DEF = "Buy for {0}";
|
||||||
|
public string ButtonText { get; set; } = BUTTON_TEXT_DEF;
|
||||||
|
public const string CUSTOM_BUTTON_TEXT_DEF = "Pay";
|
||||||
|
public string CustomButtonText { get; set; } = CUSTOM_BUTTON_TEXT_DEF;
|
||||||
|
|
||||||
|
public string CustomCSSLink { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -71,7 +78,10 @@ namespace BTCPayServer.Controllers
|
|||||||
Title = settings.Title,
|
Title = settings.Title,
|
||||||
ShowCustomAmount = settings.ShowCustomAmount,
|
ShowCustomAmount = settings.ShowCustomAmount,
|
||||||
Currency = settings.Currency,
|
Currency = settings.Currency,
|
||||||
Template = settings.Template
|
Template = settings.Template,
|
||||||
|
ButtonText = settings.ButtonText ?? PointOfSaleSettings.BUTTON_TEXT_DEF,
|
||||||
|
CustomButtonText = settings.CustomButtonText ?? PointOfSaleSettings.CUSTOM_BUTTON_TEXT_DEF,
|
||||||
|
CustomCSSLink = settings.CustomCSSLink
|
||||||
};
|
};
|
||||||
if (HttpContext?.Request != null)
|
if (HttpContext?.Request != null)
|
||||||
{
|
{
|
||||||
@@ -136,7 +146,10 @@ namespace BTCPayServer.Controllers
|
|||||||
Title = vm.Title,
|
Title = vm.Title,
|
||||||
ShowCustomAmount = vm.ShowCustomAmount,
|
ShowCustomAmount = vm.ShowCustomAmount,
|
||||||
Currency = vm.Currency.ToUpperInvariant(),
|
Currency = vm.Currency.ToUpperInvariant(),
|
||||||
Template = vm.Template
|
Template = vm.Template,
|
||||||
|
ButtonText = vm.ButtonText,
|
||||||
|
CustomButtonText = vm.CustomButtonText,
|
||||||
|
CustomCSSLink = vm.CustomCSSLink
|
||||||
});
|
});
|
||||||
await UpdateAppSettings(app);
|
await UpdateAppSettings(app);
|
||||||
StatusMessage = "App updated";
|
StatusMessage = "App updated";
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ namespace BTCPayServer.Controllers
|
|||||||
Step = step.ToString(CultureInfo.InvariantCulture),
|
Step = step.ToString(CultureInfo.InvariantCulture),
|
||||||
ShowCustomAmount = settings.ShowCustomAmount,
|
ShowCustomAmount = settings.ShowCustomAmount,
|
||||||
CurrencySymbol = currency.Symbol,
|
CurrencySymbol = currency.Symbol,
|
||||||
Items = _AppsHelper.Parse(settings.Template, settings.Currency)
|
Items = _AppsHelper.Parse(settings.Template, settings.Currency),
|
||||||
|
ButtonText = settings.ButtonText,
|
||||||
|
CustomButtonText = settings.CustomButtonText,
|
||||||
|
CustomCSSLink = settings.CustomCSSLink
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +88,8 @@ namespace BTCPayServer.Controllers
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
title = choice.Title;
|
title = choice.Title;
|
||||||
price = choice.Price.Value;
|
price = choice.Price.Value;
|
||||||
|
if (amount > price)
|
||||||
|
price = amount;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,5 +23,15 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string Example2 { get; internal set; }
|
public string Example2 { get; internal set; }
|
||||||
public string ExampleCallback { get; internal set; }
|
public string ExampleCallback { get; internal set; }
|
||||||
public string InvoiceUrl { get; internal set; }
|
public string InvoiceUrl { get; internal set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(30)]
|
||||||
|
public string ButtonText { get; set; }
|
||||||
|
[Required]
|
||||||
|
[MaxLength(30)]
|
||||||
|
public string CustomButtonText { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string CustomCSSLink { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,10 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public Item[] Items { get; set; }
|
public Item[] Items { get; set; }
|
||||||
public string CurrencySymbol { get; set; }
|
public string CurrencySymbol { get; set; }
|
||||||
|
|
||||||
|
public string ButtonText { get; set; }
|
||||||
|
public string CustomButtonText { get; set; }
|
||||||
|
|
||||||
|
public string CustomCSSLink { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,35 @@
|
|||||||
<label asp-for="ShowCustomAmount"></label>
|
<label asp-for="ShowCustomAmount"></label>
|
||||||
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check" />
|
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="ButtonText" class="control-label"></label>*
|
||||||
|
<input asp-for="ButtonText" class="form-control" />
|
||||||
|
<span asp-validation-for="ButtonText" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="CustomButtonText" class="control-label"></label>*
|
||||||
|
<input asp-for="CustomButtonText" class="form-control" />
|
||||||
|
<span asp-validation-for="CustomButtonText" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="Template" class="control-label"></label>*
|
<label asp-for="Template" class="control-label"></label>*
|
||||||
<textarea asp-for="Template" rows="20" cols="40" class="form-control"></textarea>
|
<textarea asp-for="Template" rows="20" cols="40" class="form-control"></textarea>
|
||||||
<span asp-validation-for="Template" class="text-danger"></span>
|
<span asp-validation-for="Template" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="CustomCSSLink" class="control-label"></label>
|
||||||
|
<input asp-for="CustomCSSLink" class="form-control" />
|
||||||
|
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<h5>Host button externally</h5>
|
<h5>Host button externally</h5>
|
||||||
<p>You can host point of sale buttons in an external website with the following code.</p>
|
<p>You can host point of sale buttons in an external website with the following code.</p>
|
||||||
@if(Model.Example1 != null)
|
@if (Model.Example1 != null)
|
||||||
{
|
{
|
||||||
<span>For anything with a custom amount</span>
|
<span>For anything with a custom amount</span>
|
||||||
<pre><code class="html">@Model.Example1</code></pre>
|
<pre><code class="html">@Model.Example1</code></pre>
|
||||||
}
|
}
|
||||||
@if(Model.Example2 != null)
|
@if (Model.Example2 != null)
|
||||||
{
|
{
|
||||||
<span>For a specific item of your template</span>
|
<span>For a specific item of your template</span>
|
||||||
<pre><code class="html">@Model.Example2</code></pre>
|
<pre><code class="html">@Model.Example2</code></pre>
|
||||||
@@ -63,7 +78,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="submit" class="btn btn-primary" />
|
<input type="submit" class="btn btn-primary" value="Save Settings" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<a asp-action="ListApps">Back to the app list</a>
|
<a asp-action="ListApps">Back to the app list</a>
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<link href="@this.Context.Request.GetAbsoluteUri(themeManager.BootstrapUri)" rel="stylesheet" />
|
<link href="@this.Context.Request.GetAbsoluteUri(themeManager.BootstrapUri)" rel="stylesheet" />
|
||||||
|
@if (Model.CustomCSSLink != null)
|
||||||
|
{
|
||||||
|
<link href="@Model.CustomCSSLink" rel="stylesheet" />
|
||||||
|
}
|
||||||
</head>
|
</head>
|
||||||
<body class="h-100">
|
<body class="h-100">
|
||||||
<div class="container d-flex h-100">
|
<div class="container d-flex h-100">
|
||||||
@@ -41,6 +45,7 @@
|
|||||||
@if (item.Custom)
|
@if (item.Custom)
|
||||||
{
|
{
|
||||||
<form method="post" asp-antiforgery="false" data-buy>
|
<form method="post" asp-antiforgery="false" data-buy>
|
||||||
|
<input type="hidden" name="choicekey" value="@item.Id" />
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">@Model.CurrencySymbol</span>
|
<span class="input-group-text">@Model.CurrencySymbol</span>
|
||||||
@@ -48,7 +53,7 @@
|
|||||||
<input class="form-control" type="number" min="@item.Price.Value" step="@Model.Step" name="amount"
|
<input class="form-control" type="number" min="@item.Price.Value" step="@Model.Step" name="amount"
|
||||||
value="@item.Price.Value" placeholder="Amount">
|
value="@item.Price.Value" placeholder="Amount">
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button class="btn btn-primary" type="submit">Pay</button>
|
<button class="btn btn-primary" type="submit">@Model.CustomButtonText</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -56,7 +61,8 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<form method="post" asp-antiforgery="false">
|
<form method="post" asp-antiforgery="false">
|
||||||
<button type="submit" name="choiceKey" class="btn btn-primary" value="@item.Id">Buy for @item.Price.Formatted</button>
|
<button type="submit" name="choiceKey" class="btn btn-primary" value="@item.Id">
|
||||||
|
@String.Format(Model.ButtonText, @item.Price.Formatted)</button>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -78,7 +84,7 @@
|
|||||||
<span class="input-group-text">@Model.CurrencySymbol</span>
|
<span class="input-group-text">@Model.CurrencySymbol</span>
|
||||||
</div>
|
</div>
|
||||||
<input class="form-control" type="number" min="0" step="@Model.Step" name="amount" placeholder="Amount">
|
<input class="form-control" type="number" min="0" step="@Model.Step" name="amount" placeholder="Amount">
|
||||||
<div class="input-group-append"><button class="btn btn-primary" type="submit">Pay</button></div>
|
<div class="input-group-append"><button class="btn btn-primary" type="submit">@Model.CustomButtonText</button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user