Merge pull request #756 from Kukks/invoice-auto-redirect

Allow POS to redirect invoices automatically after paid
This commit is contained in:
Nicolas Dorier
2019-04-11 19:10:21 +09:00
committed by GitHub
14 changed files with 75 additions and 4 deletions

View File

@@ -79,6 +79,7 @@ namespace BTCPayServer.Controllers
public string CustomCSSLink { get; set; }
public string NotificationEmail { get; set; }
public string NotificationUrl { get; set; }
public bool? RedirectAutomatically { get; set; }
}
[HttpGet]
@@ -105,7 +106,8 @@ namespace BTCPayServer.Controllers
CustomTipPercentages = settings.CustomTipPercentages != null ? string.Join(",", settings.CustomTipPercentages) : string.Join(",", PointOfSaleSettings.CUSTOM_TIP_PERCENTAGES_DEF),
CustomCSSLink = settings.CustomCSSLink,
NotificationEmail = settings.NotificationEmail,
NotificationUrl = settings.NotificationUrl
NotificationUrl = settings.NotificationUrl,
RedirectAutomatically = settings.RedirectAutomatically.HasValue? settings.RedirectAutomatically.Value? "true": "false" : ""
};
if (HttpContext?.Request != null)
{
@@ -180,7 +182,8 @@ namespace BTCPayServer.Controllers
CustomTipPercentages = ListSplit(vm.CustomTipPercentages),
CustomCSSLink = vm.CustomCSSLink,
NotificationUrl = vm.NotificationUrl,
NotificationEmail = vm.NotificationEmail
NotificationEmail = vm.NotificationEmail,
RedirectAutomatically = string.IsNullOrEmpty(vm.RedirectAutomatically)? (bool?) null: bool.Parse(vm.RedirectAutomatically)
});
await UpdateAppSettings(app);

View File

@@ -270,7 +270,8 @@ namespace BTCPayServer.Controllers
RedirectURL = redirectUrl ?? Request.GetDisplayUrl(),
FullNotifications = true,
ExtendedNotifications = true,
PosData = string.IsNullOrEmpty(posData) ? null : posData
PosData = string.IsNullOrEmpty(posData) ? null : posData,
RedirectAutomatically = settings.RedirectAutomatically,
}, store, HttpContext.Request.GetAbsoluteRoot(),
new List<string>() {AppService.GetAppInternalTag(appId)},
cancellationToken);

View File

@@ -314,6 +314,7 @@ namespace BTCPayServer.Controllers
ItemDesc = invoice.ProductInformation.ItemDesc,
Rate = ExchangeRate(paymentMethod),
MerchantRefLink = invoice.RedirectURL ?? "/",
RedirectAutomatically = invoice.RedirectAutomatically,
StoreName = store.StoreName,
InvoiceBitcoinUrl = paymentMethodId.PaymentType == PaymentTypes.BTCLike ? cryptoInfo.PaymentUrls.BIP21 :
paymentMethodId.PaymentType == PaymentTypes.LightningLike ? cryptoInfo.PaymentUrls.BOLT11 :

View File

@@ -84,6 +84,7 @@ namespace BTCPayServer.Controllers
entity.ServerUrl = serverUrl;
entity.FullNotifications = invoice.FullNotifications || invoice.ExtendedNotifications;
entity.ExtendedNotifications = invoice.ExtendedNotifications;
if (invoice.NotificationURL != null &&
Uri.TryCreate(invoice.NotificationURL, UriKind.Absolute, out var notificationUri) &&
(notificationUri.Scheme == "http" || notificationUri.Scheme == "https"))
@@ -125,6 +126,9 @@ namespace BTCPayServer.Controllers
if (!Uri.IsWellFormedUriString(entity.RedirectURL, UriKind.Absolute))
entity.RedirectURL = null;
entity.RedirectAutomatically =
invoice.RedirectAutomatically.GetValueOrDefault(storeBlob.RedirectAutomatically);
entity.Status = InvoiceStatus.New;
entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy);

View File

@@ -356,6 +356,7 @@ namespace BTCPayServer.Controllers
vm.OnChainMinValue = storeBlob.OnChainMinValue?.ToString() ?? "";
vm.LightningMaxValue = storeBlob.LightningMaxValue?.ToString() ?? "";
vm.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi;
vm.RedirectAutomatically = storeBlob.RedirectAutomatically;
return View(vm);
}
void SetCryptoCurrencies(CheckoutExperienceViewModel vm, Data.StoreData storeData)
@@ -420,6 +421,7 @@ namespace BTCPayServer.Controllers
blob.OnChainMinValue = onchainMinValue;
blob.LightningMaxValue = lightningMaxValue;
blob.LightningAmountInSatoshi = model.LightningAmountInSatoshi;
blob.RedirectAutomatically = model.RedirectAutomatically;
if (StoreData.SetStoreBlob(blob))
{
needUpdate = true;

View File

@@ -449,6 +449,7 @@ namespace BTCPayServer.Data
public Dictionary<string, string> WalletKeyPathRoots { get; set; } = new Dictionary<string, string>();
public EmailSettings EmailSettings { get; set; }
public bool RedirectAutomatically { get; set; }
public IPaymentFilter GetExcludedPaymentMethods()
{

View File

@@ -1,5 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using BTCPayServer.Validation;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BTCPayServer.Models.AppViewModels
{
@@ -54,5 +56,28 @@ namespace BTCPayServer.Models.AppViewModels
public string CustomCSSLink { get; set; }
public string Id { get; set; }
[Display(Name = "Redirect invoice to redirect url automatically after paid")]
public string RedirectAutomatically { get; set; } = string.Empty;
public SelectList RedirectAutomaticallySelectList =>
new SelectList(new List< SelectListItem>()
{
new SelectListItem()
{
Text = "Yes",
Value = "true"
},
new SelectListItem()
{
Text = "No",
Value = "false"
},
new SelectListItem()
{
Text = "Use Store Settings",
Value = ""
}
}, nameof(SelectListItem.Value), nameof(SelectListItem.Text), RedirectAutomatically);
}
}

View File

@@ -79,5 +79,8 @@ namespace BTCPayServer.Models
public string Guid { get; set; }
[JsonProperty(PropertyName = "token", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Token { get; set; }
[JsonProperty(PropertyName = "redirectAutomatically", DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool? RedirectAutomatically { get; set; }
}
}

View File

@@ -67,5 +67,6 @@ namespace BTCPayServer.Models.InvoicingModels
public string CoinSwitchMerchantId { get; set; }
public string RootPath { get; set; }
public decimal CoinSwitchAmountMarkupPercentage { get; set; }
public bool RedirectAutomatically { get; set; }
}
}

View File

@@ -49,6 +49,9 @@ namespace BTCPayServer.Models.StoreViewModels
[Display(Name = "Display lightning payment amounts in Satoshis")]
public bool LightningAmountInSatoshi { get; set; }
[Display(Name = "Redirect invoice to redirect url automatically after paid")]
public bool RedirectAutomatically { get; set; }
public void SetLanguages(LanguageService langService, string defaultLang)
{

View File

@@ -298,6 +298,12 @@ namespace BTCPayServer.Services.Invoices
get;
set;
}
public bool RedirectAutomatically
{
get;
set;
}
[Obsolete("Use GetPaymentMethod(network).GetTxFee() instead")]
public Money TxFee

View File

@@ -52,18 +52,22 @@
<div class="form-group">
<label asp-for="EnableShoppingCart"></label>
<input asp-for="EnableShoppingCart" type="checkbox" class="form-check" />
<span asp-validation-for="EnableShoppingCart" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ShowCustomAmount"></label>
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check" />
<span asp-validation-for="ShowCustomAmount" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ShowDiscount"></label>
<input asp-for="ShowDiscount" type="checkbox" class="form-check" />
<span asp-validation-for="ShowDiscount" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EnableTips"></label>
<input asp-for="EnableTips" type="checkbox" class="form-check" />
<span asp-validation-for="EnableTips" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ButtonText" class="control-label"></label>*
@@ -114,6 +118,11 @@
<input type="email" asp-for="NotificationEmail" class="form-control" />
<span asp-validation-for="NotificationEmail" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="RedirectAutomatically" class="control-label"></label>*
<select asp-for="RedirectAutomatically" asp-items="Model.RedirectAutomaticallySelectList" class="form-control"></select>
<span asp-validation-for="RedirectAutomatically" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save Settings" />
</div>

View File

@@ -57,6 +57,12 @@
<div class="form-group">
<label asp-for="LightningAmountInSatoshi"></label>
<input asp-for="LightningAmountInSatoshi" type="checkbox" class="form-check" />
<span asp-validation-for="LightningAmountInSatoshi" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="RedirectAutomatically"></label>
<input asp-for="RedirectAutomatically" type="checkbox" class="form-check" />
<span asp-validation-for="RedirectAutomatically" class="text-danger"></span>
</div>
<br />
<button name="command" type="submit" class="btn btn-primary" value="Save">Save</button>

View File

@@ -46,6 +46,12 @@ function onDataCallback(jsonData) {
resetTabsSlider();
$("#paid").addClass("active");
if (!jsonData.isModal && jsonData.redirectAutomatically && jsonData.merchantRefLink) {
$(".payment__spinner").show();
setTimeout(function () {
window.location = jsonData.merchantRefLink;
}, 2000);
}
}
if (newStatus === "expired" || newStatus === "invalid") { //TODO: different state if the invoice is invalid (failed to confirm after timeout)