mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Add a way to customize lightning invoice description
This commit is contained in:
parent
21215dc537
commit
d7cb6f1cca
11 changed files with 53 additions and 16 deletions
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Version>1.0.1.76</Version>
|
||||
<Version>1.0.1.77</Version>
|
||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace BTCPayServer.Controllers
|
|||
.Where(c => c.Network != null)
|
||||
.Select(o =>
|
||||
(SupportedPaymentMethod: o.SupportedPaymentMethod,
|
||||
PaymentMethod: CreatePaymentMethodAsync(o.Handler, o.SupportedPaymentMethod, o.Network, entity, storeBlob)))
|
||||
PaymentMethod: CreatePaymentMethodAsync(o.Handler, o.SupportedPaymentMethod, o.Network, entity, store)))
|
||||
.ToList();
|
||||
|
||||
List<string> paymentMethodErrors = new List<string>();
|
||||
|
@ -183,15 +183,16 @@ namespace BTCPayServer.Controllers
|
|||
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
||||
}
|
||||
|
||||
private async Task<PaymentMethod> CreatePaymentMethodAsync(IPaymentMethodHandler handler, ISupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network, InvoiceEntity entity, StoreBlob storeBlob)
|
||||
private async Task<PaymentMethod> CreatePaymentMethodAsync(IPaymentMethodHandler handler, ISupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network, InvoiceEntity entity, StoreData store)
|
||||
{
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var rate = await storeBlob.ApplyRateRules(network, _RateProviders.GetRateProvider(network, false)).GetRateAsync(entity.ProductInformation.Currency);
|
||||
PaymentMethod paymentMethod = new PaymentMethod();
|
||||
paymentMethod.ParentEntity = entity;
|
||||
paymentMethod.Network = network;
|
||||
paymentMethod.SetId(supportedPaymentMethod.PaymentId);
|
||||
paymentMethod.Rate = rate;
|
||||
var paymentDetails = await handler.CreatePaymentMethodDetails(supportedPaymentMethod, paymentMethod, network);
|
||||
var paymentDetails = await handler.CreatePaymentMethodDetails(supportedPaymentMethod, paymentMethod, store, network);
|
||||
if (storeBlob.NetworkFeeDisabled)
|
||||
paymentDetails.SetNoTxFee();
|
||||
paymentMethod.SetPaymentMethodDetails(paymentDetails);
|
||||
|
|
|
@ -282,6 +282,7 @@ namespace BTCPayServer.Controllers
|
|||
vm.MonitoringExpiration = storeBlob.MonitoringExpiration;
|
||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||
vm.RateMultiplier = (double)storeBlob.GetRateMultiplier();
|
||||
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
|
||||
vm.PreferredExchange = storeBlob.PreferredExchange.IsCoinAverage() ? "coinaverage" : storeBlob.PreferredExchange;
|
||||
return View(vm);
|
||||
}
|
||||
|
@ -356,6 +357,7 @@ namespace BTCPayServer.Controllers
|
|||
blob.NetworkFeeDisabled = !model.NetworkFee;
|
||||
blob.MonitoringExpiration = model.MonitoringExpiration;
|
||||
blob.InvoiceExpiration = model.InvoiceExpiration;
|
||||
blob.LightningDescriptionTemplate = model.LightningDescriptionTemplate ?? string.Empty;
|
||||
|
||||
bool newExchange = blob.PreferredExchange != model.PreferredExchange;
|
||||
blob.PreferredExchange = model.PreferredExchange;
|
||||
|
|
|
@ -270,6 +270,20 @@ namespace BTCPayServer.Data
|
|||
[JsonConverter(typeof(UriJsonConverter))]
|
||||
public Uri CustomCSS { get; set; }
|
||||
|
||||
|
||||
string _LightningDescriptionTemplate;
|
||||
public string LightningDescriptionTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
return _LightningDescriptionTemplate ?? "Paid to {StoreName} (Order ID: {OrderId})";
|
||||
}
|
||||
set
|
||||
{
|
||||
_LightningDescriptionTemplate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IRateProvider ApplyRateRules(BTCPayNetwork network, IRateProvider rateProvider)
|
||||
{
|
||||
if (!PreferredExchange.IsCoinAverage())
|
||||
|
|
|
@ -91,6 +91,9 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name = "Description template of the lightning invoice")]
|
||||
public string LightningDescriptionTemplate { get; set; }
|
||||
|
||||
public class LightningNode
|
||||
{
|
||||
public string CryptoCode { get; set; }
|
||||
|
@ -100,6 +103,5 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||
{
|
||||
get; set;
|
||||
} = new List<LightningNode>();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||
_WalletProvider = walletProvider;
|
||||
}
|
||||
|
||||
public override async Task<IPaymentMethodDetails> CreatePaymentMethodDetails(DerivationStrategy supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network)
|
||||
public override async Task<IPaymentMethodDetails> CreatePaymentMethodDetails(DerivationStrategy supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network)
|
||||
{
|
||||
if (!_ExplorerProvider.IsAvailable(network))
|
||||
throw new PaymentMethodUnavailableException($"Full node not available");
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
|
||||
namespace BTCPayServer.Payments
|
||||
|
@ -16,25 +17,26 @@ namespace BTCPayServer.Payments
|
|||
/// </summary>
|
||||
/// <param name="supportedPaymentMethod"></param>
|
||||
/// <param name="paymentMethod"></param>
|
||||
/// <param name="store"></param>
|
||||
/// <param name="network"></param>
|
||||
/// <returns></returns>
|
||||
Task<IPaymentMethodDetails> CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network);
|
||||
Task<IPaymentMethodDetails> CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network);
|
||||
}
|
||||
|
||||
public interface IPaymentMethodHandler<T> : IPaymentMethodHandler where T : ISupportedPaymentMethod
|
||||
{
|
||||
Task<IPaymentMethodDetails> CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network);
|
||||
Task<IPaymentMethodDetails> CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network);
|
||||
}
|
||||
|
||||
public abstract class PaymentMethodHandlerBase<T> : IPaymentMethodHandler<T> where T : ISupportedPaymentMethod
|
||||
{
|
||||
public abstract Task<IPaymentMethodDetails> CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network);
|
||||
public abstract Task<IPaymentMethodDetails> CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network);
|
||||
|
||||
Task<IPaymentMethodDetails> IPaymentMethodHandler.CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network)
|
||||
Task<IPaymentMethodDetails> IPaymentMethodHandler.CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network)
|
||||
{
|
||||
if (supportedPaymentMethod is T method)
|
||||
{
|
||||
return CreatePaymentMethodDetails(method, paymentMethod, network);
|
||||
return CreatePaymentMethodDetails(method, paymentMethod, store, network);
|
||||
}
|
||||
throw new NotSupportedException("Invalid supportedPaymentMethod");
|
||||
}
|
||||
|
|
|
@ -48,8 +48,10 @@ namespace BTCPayServer.Payments.Lightning.Charge
|
|||
{
|
||||
var message = CreateMessage(HttpMethod.Post, "invoice");
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>();
|
||||
parameters.Add("msatoshi", request.Amont.MilliSatoshi.ToString(CultureInfo.InvariantCulture));
|
||||
parameters.Add("msatoshi", request.Amount.MilliSatoshi.ToString(CultureInfo.InvariantCulture));
|
||||
parameters.Add("expiry", ((int)request.Expiry.TotalSeconds).ToString(CultureInfo.InvariantCulture));
|
||||
if(request.Description != null)
|
||||
parameters.Add("description", request.Description);
|
||||
message.Content = new FormUrlEncodedContent(parameters);
|
||||
var result = await _Client.SendAsync(message, cancellation);
|
||||
result.EnsureSuccessStatusCode();
|
||||
|
@ -154,7 +156,7 @@ namespace BTCPayServer.Payments.Lightning.Charge
|
|||
|
||||
async Task<LightningInvoice> ILightningInvoiceClient.CreateInvoice(LightMoney amount, string description, TimeSpan expiry, CancellationToken cancellation)
|
||||
{
|
||||
var invoice = await CreateInvoiceAsync(new CreateInvoiceRequest() { Amont = amount, Expiry = expiry, Description = description ?? "" });
|
||||
var invoice = await CreateInvoiceAsync(new CreateInvoiceRequest() { Amount = amount, Expiry = expiry, Description = description ?? "" });
|
||||
return new LightningInvoice() { Id = invoice.Id, Amount = amount, BOLT11 = invoice.PayReq, Status = "unpaid" };
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace BTCPayServer.Payments.Lightning.Charge
|
|||
{
|
||||
public class CreateInvoiceRequest
|
||||
{
|
||||
public LightMoney Amont { get; set; }
|
||||
public LightMoney Amount { get; set; }
|
||||
public TimeSpan Expiry { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Net;
|
|||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Payments.Lightning.Charge;
|
||||
using BTCPayServer.Payments.Lightning.CLightning;
|
||||
|
@ -23,8 +24,9 @@ namespace BTCPayServer.Payments.Lightning
|
|||
_LightningClientFactory = lightningClientFactory;
|
||||
_Dashboard = dashboard;
|
||||
}
|
||||
public override async Task<IPaymentMethodDetails> CreatePaymentMethodDetails(LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, BTCPayNetwork network)
|
||||
public override async Task<IPaymentMethodDetails> CreatePaymentMethodDetails(LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network)
|
||||
{
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var test = Test(supportedPaymentMethod, network);
|
||||
var invoice = paymentMethod.ParentEntity;
|
||||
var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8);
|
||||
|
@ -36,7 +38,11 @@ namespace BTCPayServer.Payments.Lightning
|
|||
LightningInvoice lightningInvoice = null;
|
||||
try
|
||||
{
|
||||
lightningInvoice = await client.CreateInvoice(new LightMoney(due, LightMoneyUnit.BTC), invoice.ProductInformation.ItemDesc, expiry);
|
||||
string description = storeBlob.LightningDescriptionTemplate;
|
||||
description = description.Replace("{StoreName}", store.StoreName ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{ItemDescription}", invoice.ProductInformation.ItemDesc ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{OrderId}", invoice.OrderId ?? "", StringComparison.OrdinalIgnoreCase);
|
||||
lightningInvoice = await client.CreateInvoice(new LightMoney(due, LightMoneyUnit.BTC), description, expiry);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
|
|
|
@ -129,6 +129,14 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="LightningDescriptionTemplate"></label>
|
||||
<input asp-for="LightningDescriptionTemplate" class="form-control" />
|
||||
<span asp-validation-for="LightningDescriptionTemplate" class="text-danger"></span>
|
||||
<p class="form-text text-muted">
|
||||
Placeholder available are: {StoreName}, {ItemDescription} and {OrderId}
|
||||
</p>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-success" value="Save">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue