diff --git a/BTCPayServer/Controllers/UIInvoiceController.UI.cs b/BTCPayServer/Controllers/UIInvoiceController.UI.cs
index 0f51a1118..ae594d3cf 100644
--- a/BTCPayServer/Controllers/UIInvoiceController.UI.cs
+++ b/BTCPayServer/Controllers/UIInvoiceController.UI.cs
@@ -875,13 +875,7 @@ namespace BTCPayServer.Controllers
return extension?.Image ?? "";
}
- var cd = this._CurrencyNameTable.GetCurrencyData(prompt.Currency, false);
- // Show the "Common divisibility" rather than the payment method disibility.
- // For example, BTC has commonly 8 digits, but on lightning it has 11. In this case, pick 8.
- if (cd?.Divisibility is not int divisibility)
- divisibility = prompt.Divisibility;
-
- string ShowMoney(decimal value) => MoneyExtensions.ShowMoney(value, divisibility);
+ string ShowMoney(decimal value) => MoneyExtensions.ShowMoney(value, prompt.RateDivisibility ?? prompt.Divisibility);
var model = new PaymentModel
{
Activated = prompt.Activated,
diff --git a/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs b/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs
index aa42fc565..9ddc05108 100644
--- a/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs
+++ b/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs
@@ -53,6 +53,7 @@ namespace BTCPayServer.Payments.Lightning
context.Prompt.Inactive = false;
context.Prompt.Currency = _network.CryptoCode;
context.Prompt.Divisibility = 11;
+ context.Prompt.RateDivisibility = 8;
context.Prompt.PaymentMethodFee = 0.0m;
return Task.CompletedTask;
}
diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
index ccf9f8361..3bca13009 100644
--- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
+++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs
@@ -62,6 +62,7 @@ namespace BTCPayServer.Payments.Lightning
context.Prompt.Currency = _Network.CryptoCode;
context.Prompt.PaymentMethodFee = 0m;
context.Prompt.Divisibility = 11;
+ context.Prompt.RateDivisibility = 8;
return Task.CompletedTask;
}
diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs
index 842025ec7..b8ec55855 100644
--- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs
+++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs
@@ -870,8 +870,16 @@ namespace BTCPayServer.Services.Invoices
public string Currency { get; set; }
[JsonIgnore]
public decimal Rate => Currency is null ? throw new InvalidOperationException("Currency of the payment prompt isn't set") : ParentEntity.GetInvoiceRate(Currency);
+ ///
+ /// The maximum divisibility supported by the underlying payment method
+ ///
public int Divisibility { get; set; }
///
+ /// The divisibility to use when calculating the amount to pay.
+ /// If null, it will use the .
+ ///
+ public int? RateDivisibility { get; set; }
+ ///
/// Total additional fee imposed by this specific payment method.
/// It includes the .
///
@@ -909,24 +917,25 @@ namespace BTCPayServer.Services.Invoices
accounting.TxRequired = accounting.TxCount;
var grossDue = i.Price + i.PaidFee;
var rate = Rate;
+ var divisibility = RateDivisibility ?? Divisibility;
if (i.MinimumNetDue > 0.0m)
{
accounting.TxRequired++;
grossDue += rate * PaymentMethodFee;
}
- accounting.TotalDue = Coins(grossDue / rate, Divisibility);
- accounting.Paid = Coins(i.PaidAmount.Gross / rate, Divisibility);
- accounting.PaymentMethodPaid = Coins(thisPaymentMethodPayments.Sum(p => p.PaidAmount.Gross), Divisibility);
+ accounting.TotalDue = Coins(grossDue / rate, divisibility);
+ accounting.Paid = Coins(i.PaidAmount.Gross / rate, divisibility);
+ accounting.PaymentMethodPaid = Coins(thisPaymentMethodPayments.Sum(p => p.PaidAmount.Gross), divisibility);
// This one deal with the fact where it might looks like a slight over payment due to the dust of another payment method.
// So if we detect the NetDue is zero, just cap dueUncapped to 0
var dueUncapped = i.NetDue == 0.0m ? 0.0m : grossDue - i.PaidAmount.Gross;
- accounting.DueUncapped = Coins(dueUncapped / rate, Divisibility);
+ accounting.DueUncapped = Coins(dueUncapped / rate, divisibility);
accounting.Due = Max(accounting.DueUncapped, 0.0m);
- accounting.PaymentMethodFee = Coins((grossDue - i.Price) / rate, Divisibility);
+ accounting.PaymentMethodFee = Coins((grossDue - i.Price) / rate, divisibility);
- accounting.MinimumTotalDue = Max(Smallest(Divisibility), Coins((grossDue * (1.0m - ((decimal)i.PaymentTolerance / 100.0m))) / rate, Divisibility));
+ accounting.MinimumTotalDue = Max(Smallest(divisibility), Coins((grossDue * (1.0m - ((decimal)i.PaymentTolerance / 100.0m))) / rate, divisibility));
return accounting;
}