Properly clip taxIncluded and invoice's amount (#2724)

This commit is contained in:
Nicolas Dorier 2021-07-30 18:46:49 +09:00 committed by GitHub
parent ad8f347989
commit 4c57405945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 12 deletions

View File

@ -2803,6 +2803,22 @@ namespace BTCPayServer.Tests
var invoice = user.BitPay.CreateInvoice(
new Invoice() { Price = -0.1m, Currency = "BTC", FullNotifications = true }, Facade.Merchant);
Assert.Equal(0.0m, invoice.Price);
// Should round down to 50.51, taxIncluded should be also clipped to this value because taxIncluded can't be higher than the price.
var invoice5 = user.BitPay.CreateInvoice(
new Invoice() { Price = 50.513m, Currency = "USD", FullNotifications = true, TaxIncluded = 50.516m }, Facade.Merchant);
Assert.Equal(50.51m, invoice5.Price);
Assert.Equal(50.51m, invoice5.TaxIncluded);
var greenfield = await user.CreateClient();
var invoice5g = await greenfield.CreateInvoice(user.StoreId, new CreateInvoiceRequest()
{
Amount = 50.513m,
Currency = "USD",
Metadata = new JObject() { new JProperty("taxIncluded", 50.516m) }
});
Assert.Equal(50.51m, invoice5g.Amount);
Assert.Equal(50.51m, (decimal)invoice5g.Metadata["taxIncluded"]);
}
}

View File

@ -112,24 +112,14 @@ namespace BTCPayServer.Controllers
FillBuyerInfo(invoice, entity);
var taxIncluded = invoice.TaxIncluded.HasValue ? invoice.TaxIncluded.Value : 0m;
var price = invoice.Price;
var currencyInfo = _CurrencyNameTable.GetNumberFormatInfo(invoice.Currency, false);
if (currencyInfo != null)
{
int divisibility = currencyInfo.CurrencyDecimalDigits;
invoice.Price = invoice.Price.RoundToSignificant(ref divisibility);
divisibility = currencyInfo.CurrencyDecimalDigits;
invoice.TaxIncluded = taxIncluded.RoundToSignificant(ref divisibility);
}
invoice.Price = Math.Max(0.0m, invoice.Price);
invoice.TaxIncluded = Math.Max(0.0m, taxIncluded);
invoice.TaxIncluded = Math.Min(taxIncluded, invoice.Price);
entity.Metadata.ItemCode = invoice.ItemCode;
entity.Metadata.ItemDesc = invoice.ItemDesc;
entity.Metadata.Physical = invoice.Physical;
entity.Metadata.TaxIncluded = invoice.TaxIncluded;
entity.Currency = invoice.Currency;
entity.Price = invoice.Price;
entity.Price = price;
entity.RedirectURLTemplate = invoice.RedirectURL ?? store.StoreWebsite;
entity.RedirectAutomatically =
@ -195,6 +185,23 @@ namespace BTCPayServer.Controllers
InvoiceLogs logs = new InvoiceLogs();
logs.Write("Creation of invoice starting", InvoiceEventData.EventSeverity.Info);
entity.Price = Math.Max(0.0m, entity.Price);
var currencyInfo = _CurrencyNameTable.GetNumberFormatInfo(entity.Currency, false);
if (currencyInfo != null)
{
entity.Price = entity.Price.RoundToSignificant(currencyInfo.CurrencyDecimalDigits);
}
if (entity.Metadata.TaxIncluded is decimal taxIncluded)
{
if (currencyInfo != null)
{
taxIncluded = taxIncluded.RoundToSignificant(currencyInfo.CurrencyDecimalDigits);
}
taxIncluded = Math.Max(0.0m, taxIncluded);
taxIncluded = Math.Min(taxIncluded, entity.Price);
entity.Metadata.TaxIncluded = taxIncluded;
}
var getAppsTaggingStore = _InvoiceRepository.GetAppsTaggingStore(store.Id);
var storeBlob = store.GetStoreBlob();