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);
|
||||
vmpos.Title = "hello";
|
||||
vmpos.Currency = "CAD";
|
||||
vmpos.Template =
|
||||
"apple:\n" +
|
||||
" price: 5.0\n" +
|
||||
" title: good apple\n" +
|
||||
"orange:\n" +
|
||||
" price: 10.0\n";
|
||||
vmpos.ButtonText = "{0} Purchase";
|
||||
vmpos.CustomButtonText = "Nicolas Sexy Hair";
|
||||
vmpos.Template = @"
|
||||
apple:
|
||||
price: 5.0
|
||||
title: good apple
|
||||
orange:
|
||||
price: 10.0
|
||||
donation:
|
||||
price: 1.02
|
||||
custom: true
|
||||
";
|
||||
Assert.IsType<RedirectToActionResult>(apps.UpdatePointOfSale(appId, vmpos).Result);
|
||||
vmpos = Assert.IsType<UpdatePointOfSaleViewModel>(Assert.IsType<ViewResult>(apps.UpdatePointOfSale(appId).Result).Model);
|
||||
Assert.Equal("hello", vmpos.Title);
|
||||
@@ -1473,16 +1479,29 @@ namespace BTCPayServer.Tests
|
||||
var publicApps = user.GetController<AppsPublicController>();
|
||||
var vmview = Assert.IsType<ViewPointOfSaleViewModel>(Assert.IsType<ViewResult>(publicApps.ViewPointOfSale(appId).Result).Model);
|
||||
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("orange", vmview.Items[1].Title);
|
||||
Assert.Equal(10.0m, vmview.Items[1].Price.Value);
|
||||
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);
|
||||
var invoice = user.BitPay.GetInvoices().First();
|
||||
Assert.Equal(10.00m, invoice.Price);
|
||||
Assert.Equal("CAD", invoice.Currency);
|
||||
Assert.Equal("orange", invoice.ItemDesc);
|
||||
|
||||
//
|
||||
var invoices = user.BitPay.GetInvoices();
|
||||
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 Template { 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]
|
||||
@@ -71,7 +78,10 @@ namespace BTCPayServer.Controllers
|
||||
Title = settings.Title,
|
||||
ShowCustomAmount = settings.ShowCustomAmount,
|
||||
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)
|
||||
{
|
||||
@@ -136,7 +146,10 @@ namespace BTCPayServer.Controllers
|
||||
Title = vm.Title,
|
||||
ShowCustomAmount = vm.ShowCustomAmount,
|
||||
Currency = vm.Currency.ToUpperInvariant(),
|
||||
Template = vm.Template
|
||||
Template = vm.Template,
|
||||
ButtonText = vm.ButtonText,
|
||||
CustomButtonText = vm.CustomButtonText,
|
||||
CustomCSSLink = vm.CustomCSSLink
|
||||
});
|
||||
await UpdateAppSettings(app);
|
||||
StatusMessage = "App updated";
|
||||
|
||||
@@ -47,7 +47,10 @@ namespace BTCPayServer.Controllers
|
||||
Step = step.ToString(CultureInfo.InvariantCulture),
|
||||
ShowCustomAmount = settings.ShowCustomAmount,
|
||||
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();
|
||||
title = choice.Title;
|
||||
price = choice.Price.Value;
|
||||
if (amount > price)
|
||||
price = amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -23,5 +23,15 @@ namespace BTCPayServer.Models.AppViewModels
|
||||
public string Example2 { get; internal set; }
|
||||
public string ExampleCallback { 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 Item[] Items { get; set; }
|
||||
public string CurrencySymbol { get; set; }
|
||||
|
||||
public string ButtonText { get; set; }
|
||||
public string CustomButtonText { get; set; }
|
||||
|
||||
public string CustomCSSLink { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,26 @@
|
||||
<label asp-for="ShowCustomAmount"></label>
|
||||
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check" />
|
||||
</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">
|
||||
<label asp-for="Template" class="control-label"></label>*
|
||||
<textarea asp-for="Template" rows="20" cols="40" class="form-control"></textarea>
|
||||
<span asp-validation-for="Template" class="text-danger"></span>
|
||||
</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">
|
||||
<h5>Host button externally</h5>
|
||||
<p>You can host point of sale buttons in an external website with the following code.</p>
|
||||
@@ -63,7 +78,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" class="btn btn-primary" />
|
||||
<input type="submit" class="btn btn-primary" value="Save Settings" />
|
||||
</div>
|
||||
</form>
|
||||
<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="apple-mobile-web-app-capable" content="yes">
|
||||
<link href="@this.Context.Request.GetAbsoluteUri(themeManager.BootstrapUri)" rel="stylesheet" />
|
||||
@if (Model.CustomCSSLink != null)
|
||||
{
|
||||
<link href="@Model.CustomCSSLink" rel="stylesheet" />
|
||||
}
|
||||
</head>
|
||||
<body class="h-100">
|
||||
<div class="container d-flex h-100">
|
||||
@@ -41,6 +45,7 @@
|
||||
@if (item.Custom)
|
||||
{
|
||||
<form method="post" asp-antiforgery="false" data-buy>
|
||||
<input type="hidden" name="choicekey" value="@item.Id" />
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<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"
|
||||
value="@item.Price.Value" placeholder="Amount">
|
||||
<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>
|
||||
</form>
|
||||
@@ -56,7 +61,8 @@
|
||||
else
|
||||
{
|
||||
<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>
|
||||
}
|
||||
</div>
|
||||
@@ -78,7 +84,7 @@
|
||||
<span class="input-group-text">@Model.CurrencySymbol</span>
|
||||
</div>
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user