mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-21 22:11:48 +01:00
Decouple the CreateInvoiceCore from BitpayCreateInvoice, remove some features from greenfield invoice for now
This commit is contained in:
parent
b2ff041ec0
commit
67b04473b5
13 changed files with 135 additions and 126 deletions
|
@ -4,13 +4,38 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace BTCPayServer.Client.JsonConverters
|
||||
{
|
||||
public class TimeSpanJsonConverter : JsonConverter
|
||||
public abstract class TimeSpanJsonConverter : JsonConverter
|
||||
{
|
||||
public class Seconds : TimeSpanJsonConverter
|
||||
{
|
||||
protected override long ToLong(TimeSpan value)
|
||||
{
|
||||
return (long)value.TotalSeconds;
|
||||
}
|
||||
|
||||
protected override TimeSpan ToTimespan(long value)
|
||||
{
|
||||
return TimeSpan.FromSeconds(value);
|
||||
}
|
||||
}
|
||||
public class Minutes : TimeSpanJsonConverter
|
||||
{
|
||||
protected override long ToLong(TimeSpan value)
|
||||
{
|
||||
return (long)value.TotalMinutes;
|
||||
}
|
||||
protected override TimeSpan ToTimespan(long value)
|
||||
{
|
||||
return TimeSpan.FromMinutes(value);
|
||||
}
|
||||
}
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(TimeSpan) || objectType == typeof(TimeSpan?);
|
||||
}
|
||||
|
||||
protected abstract TimeSpan ToTimespan(long value);
|
||||
protected abstract long ToLong(TimeSpan value);
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
try
|
||||
|
@ -24,11 +49,11 @@ namespace BTCPayServer.Client.JsonConverters
|
|||
}
|
||||
if (reader.TokenType != JsonToken.Integer)
|
||||
throw new JsonObjectException("Invalid timespan, expected integer", reader);
|
||||
return TimeSpan.FromSeconds((long)reader.Value);
|
||||
return ToTimespan((long)reader.Value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new JsonObjectException("Invalid locktime", reader);
|
||||
throw new JsonObjectException("Invalid timespan", reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +61,7 @@ namespace BTCPayServer.Client.JsonConverters
|
|||
{
|
||||
if (value is TimeSpan s)
|
||||
{
|
||||
writer.WriteValue((long)s.TotalSeconds);
|
||||
writer.WriteValue(ToLong(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
@ -20,12 +21,13 @@ namespace BTCPayServer.Client.Models
|
|||
public SpeedPolicy? SpeedPolicy { get; set; }
|
||||
|
||||
public string[] PaymentMethods { get; set; }
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public string RedirectUri { get; set; }
|
||||
public Uri WebHook { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? ExpirationTime { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Minutes))]
|
||||
[JsonProperty("expirationMinutes")]
|
||||
public TimeSpan? Expiration { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Minutes))]
|
||||
[JsonProperty("monitoringMinutes")]
|
||||
public TimeSpan? Monitoring { get; set; }
|
||||
|
||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||
public double? PaymentTolerance { get; set; }
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace BTCPayServer.Client.Models
|
|||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Amount { get; set; }
|
||||
public string Description { get; set; }
|
||||
[JsonConverter(typeof(JsonConverters.TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(JsonConverters.TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan Expiry { get; set; }
|
||||
public bool PrivateRouteHints { get; set; }
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace BTCPayServer.Client.Models
|
|||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||
public decimal Amount { get; set; }
|
||||
public string Currency { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan? Period { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace BTCPayServer.Client.Models
|
|||
public string Currency { get; set; }
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal Amount { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan? Period { get; set; }
|
||||
public bool Archived { get; set; }
|
||||
public string ViewLink { get; set; }
|
||||
|
|
|
@ -16,11 +16,11 @@ namespace BTCPayServer.Client.Models
|
|||
|
||||
public string Website { get; set; }
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan InvoiceExpiration { get; set; } = TimeSpan.FromMinutes(15);
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan MonitoringExpiration { get; set; } = TimeSpan.FromMinutes(60);
|
||||
|
||||
|
|
|
@ -125,10 +125,10 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
}
|
||||
}
|
||||
|
||||
if (request.Checkout.ExpirationTime != null && request.Checkout.ExpirationTime < DateTime.Now)
|
||||
if (request.Checkout.Expiration != null && request.Checkout.Expiration < TimeSpan.FromSeconds(30.0))
|
||||
{
|
||||
request.AddModelError(invoiceRequest => invoiceRequest.Checkout.ExpirationTime,
|
||||
"Expiration time must be in the future", this);
|
||||
request.AddModelError(invoiceRequest => invoiceRequest.Checkout.Expiration,
|
||||
"Expiration time must be at least 30 seconds", this);
|
||||
}
|
||||
|
||||
if (request.Checkout.PaymentTolerance != null &&
|
||||
|
@ -143,7 +143,7 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
|
||||
try
|
||||
{
|
||||
var invoice = await _invoiceController.CreateInvoiceCoreRaw(FromModel(request), store,
|
||||
var invoice = await _invoiceController.CreateInvoiceCoreRaw(request, store,
|
||||
Request.GetAbsoluteUri(""));
|
||||
return Ok(ToModel(invoice));
|
||||
}
|
||||
|
@ -263,14 +263,12 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
Metadata = entity.Metadata.ToJObject(),
|
||||
Checkout = new CreateInvoiceRequest.CheckoutOptions()
|
||||
{
|
||||
ExpirationTime = entity.ExpirationTime,
|
||||
Expiration = entity.ExpirationTime - entity.InvoiceTime,
|
||||
Monitoring = entity.MonitoringExpiration - entity.ExpirationTime,
|
||||
PaymentTolerance = entity.PaymentTolerance,
|
||||
PaymentMethods =
|
||||
entity.GetPaymentMethods().Select(method => method.GetId().ToString()).ToArray(),
|
||||
RedirectAutomatically = entity.RedirectAutomatically,
|
||||
RedirectUri = entity.RedirectURL?.ToString(),
|
||||
SpeedPolicy = entity.SpeedPolicy,
|
||||
WebHook = entity.NotificationURL
|
||||
SpeedPolicy = entity.SpeedPolicy
|
||||
},
|
||||
PaymentMethodData = entity.GetPaymentMethods().ToDictionary(method => method.GetId().ToString(),
|
||||
method =>
|
||||
|
@ -317,47 +315,5 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
})
|
||||
};
|
||||
}
|
||||
|
||||
private Models.BitpayCreateInvoiceRequest FromModel(CreateInvoiceRequest entity)
|
||||
{
|
||||
InvoiceMetadata invoiceMetadata = null;
|
||||
if (entity.Metadata != null)
|
||||
{
|
||||
invoiceMetadata = entity.Metadata.ToObject<InvoiceMetadata>();
|
||||
}
|
||||
return new Models.BitpayCreateInvoiceRequest()
|
||||
{
|
||||
Buyer = invoiceMetadata == null ? null : new Buyer()
|
||||
{
|
||||
Address1 = invoiceMetadata.BuyerAddress1,
|
||||
Address2 = invoiceMetadata.BuyerAddress2,
|
||||
City = invoiceMetadata.BuyerCity,
|
||||
country = invoiceMetadata.BuyerCountry,
|
||||
email = invoiceMetadata.BuyerEmail,
|
||||
Name = invoiceMetadata.BuyerName,
|
||||
phone = invoiceMetadata.BuyerPhone,
|
||||
State = invoiceMetadata.BuyerState,
|
||||
zip = invoiceMetadata.BuyerZip,
|
||||
},
|
||||
Currency = entity.Currency,
|
||||
Price = entity.Amount,
|
||||
Refundable = true,
|
||||
ExtendedNotifications = true,
|
||||
FullNotifications = true,
|
||||
RedirectURL = entity.Checkout.RedirectUri,
|
||||
RedirectAutomatically = entity.Checkout.RedirectAutomatically,
|
||||
ExpirationTime = entity.Checkout.ExpirationTime,
|
||||
TransactionSpeed = entity.Checkout.SpeedPolicy?.ToString(),
|
||||
PaymentCurrencies = entity.Checkout.PaymentMethods,
|
||||
NotificationURL = entity.Checkout.RedirectUri,
|
||||
PosData = invoiceMetadata?.PosData,
|
||||
Physical = invoiceMetadata?.Physical ?? false,
|
||||
ItemCode = invoiceMetadata?.ItemCode,
|
||||
ItemDesc = invoiceMetadata?.ItemDesc,
|
||||
TaxIncluded = invoiceMetadata?.TaxIncluded,
|
||||
OrderId = invoiceMetadata?.OrderId,
|
||||
Metadata = entity.Metadata
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,8 +124,8 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
ShowRecommendedFee = storeBlob.ShowRecommendedFee,
|
||||
RecommendedFeeBlockTarget = storeBlob.RecommendedFeeBlockTarget,
|
||||
DefaultLang = storeBlob.DefaultLang,
|
||||
MonitoringExpiration = TimeSpan.FromMinutes(storeBlob.MonitoringExpiration),
|
||||
InvoiceExpiration = TimeSpan.FromMinutes(storeBlob.InvoiceExpiration),
|
||||
MonitoringExpiration = storeBlob.MonitoringExpiration,
|
||||
InvoiceExpiration = storeBlob.InvoiceExpiration,
|
||||
LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi,
|
||||
CustomLogo = storeBlob.CustomLogo,
|
||||
CustomCSS = storeBlob.CustomCSS,
|
||||
|
@ -160,8 +160,8 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
blob.ShowRecommendedFee = restModel.ShowRecommendedFee;
|
||||
blob.RecommendedFeeBlockTarget = restModel.RecommendedFeeBlockTarget;
|
||||
blob.DefaultLang = restModel.DefaultLang;
|
||||
blob.MonitoringExpiration = (int)restModel.MonitoringExpiration.TotalMinutes;
|
||||
blob.InvoiceExpiration = (int)restModel.InvoiceExpiration.TotalMinutes;
|
||||
blob.MonitoringExpiration = restModel.MonitoringExpiration;
|
||||
blob.InvoiceExpiration = restModel.InvoiceExpiration;
|
||||
blob.LightningAmountInSatoshi = restModel.LightningAmountInSatoshi;
|
||||
blob.CustomLogo = restModel.CustomLogo;
|
||||
blob.CustomCSS = restModel.CustomCSS;
|
||||
|
|
|
@ -21,6 +21,7 @@ using BTCPayServer.Services.Stores;
|
|||
using BTCPayServer.Validation;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using NBitpayClient;
|
||||
using Newtonsoft.Json;
|
||||
using BitpayCreateInvoiceRequest = BTCPayServer.Models.BitpayCreateInvoiceRequest;
|
||||
|
@ -78,41 +79,31 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
var entity = await CreateInvoiceCoreRaw(invoice, store, serverUrl, additionalTags, cancellationToken);
|
||||
var resp = entity.EntityToDTO();
|
||||
return new DataWrapper<InvoiceResponse>(resp) {Facade = "pos/invoice"};
|
||||
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
||||
}
|
||||
|
||||
internal async Task<InvoiceEntity> CreateInvoiceCoreRaw(BitpayCreateInvoiceRequest invoice, StoreData store, string serverUrl, List<string> additionalTags = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
invoice.Currency = invoice.Currency?.ToUpperInvariant() ?? "USD";
|
||||
InvoiceLogs logs = new InvoiceLogs();
|
||||
logs.Write("Creation of invoice starting");
|
||||
var entity = _InvoiceRepository.CreateNewInvoice();
|
||||
|
||||
var getAppsTaggingStore = _InvoiceRepository.GetAppsTaggingStore(store.Id);
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
EmailAddressAttribute emailValidator = new EmailAddressAttribute();
|
||||
entity.ExpirationTime = invoice.ExpirationTime is DateTimeOffset v ? v : entity.InvoiceTime.AddMinutes(storeBlob.InvoiceExpiration);
|
||||
var entity = _InvoiceRepository.CreateNewInvoice();
|
||||
entity.ExpirationTime = invoice.ExpirationTime is DateTimeOffset v ? v : entity.InvoiceTime + storeBlob.InvoiceExpiration;
|
||||
entity.MonitoringExpiration = entity.ExpirationTime + storeBlob.MonitoringExpiration;
|
||||
if (entity.ExpirationTime - TimeSpan.FromSeconds(30.0) < entity.InvoiceTime)
|
||||
{
|
||||
throw new BitpayHttpException(400, "The expirationTime is set too soon");
|
||||
}
|
||||
entity.MonitoringExpiration = entity.ExpirationTime + TimeSpan.FromMinutes(storeBlob.MonitoringExpiration);
|
||||
invoice.Currency = invoice.Currency?.ToUpperInvariant() ?? "USD";
|
||||
entity.Currency = invoice.Currency;
|
||||
entity.Metadata.OrderId = invoice.OrderId;
|
||||
entity.Metadata.PosData = invoice.PosData;
|
||||
entity.ServerUrl = serverUrl;
|
||||
entity.FullNotifications = invoice.FullNotifications || invoice.ExtendedNotifications;
|
||||
entity.ExtendedNotifications = invoice.ExtendedNotifications;
|
||||
entity.NotificationURLTemplate = invoice.NotificationURL;
|
||||
entity.NotificationEmail = invoice.NotificationEmail;
|
||||
entity.PaymentTolerance = storeBlob.PaymentTolerance;
|
||||
if (additionalTags != null)
|
||||
entity.InternalTags.AddRange(additionalTags);
|
||||
FillBuyerInfo(invoice, entity);
|
||||
if (entity.Metadata.BuyerEmail != null)
|
||||
{
|
||||
if (!EmailValidator.IsEmail(entity.Metadata.BuyerEmail))
|
||||
throw new BitpayHttpException(400, "Invalid email");
|
||||
entity.RefundMail = entity.Metadata.BuyerEmail;
|
||||
}
|
||||
|
||||
var taxIncluded = invoice.TaxIncluded.HasValue ? invoice.TaxIncluded.Value : 0m;
|
||||
|
||||
|
@ -127,7 +118,6 @@ namespace BTCPayServer.Controllers
|
|||
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;
|
||||
|
@ -135,29 +125,12 @@ namespace BTCPayServer.Controllers
|
|||
entity.Currency = invoice.Currency;
|
||||
entity.Price = invoice.Price;
|
||||
|
||||
if (invoice.Metadata != null)
|
||||
{
|
||||
var currentMetadata = entity.Metadata.ToJObject();
|
||||
foreach (var prop in invoice.Metadata.Properties())
|
||||
{
|
||||
if (!currentMetadata.ContainsKey(prop.Name))
|
||||
currentMetadata.Add(prop.Name, prop.Value);
|
||||
}
|
||||
entity.Metadata = InvoiceMetadata.FromJObject(currentMetadata);
|
||||
}
|
||||
|
||||
entity.RedirectURLTemplate = invoice.RedirectURL ?? store.StoreWebsite;
|
||||
|
||||
entity.RedirectAutomatically =
|
||||
invoice.RedirectAutomatically.GetValueOrDefault(storeBlob.RedirectAutomatically);
|
||||
|
||||
entity.Status = InvoiceStatus.New;
|
||||
entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy);
|
||||
|
||||
HashSet<CurrencyPair> currencyPairsToFetch = new HashSet<CurrencyPair>();
|
||||
var rules = storeBlob.GetRateRules(_NetworkProvider);
|
||||
var excludeFilter = storeBlob.GetExcludedPaymentMethods(); // Here we can compose filters from other origin with PaymentFilter.Any()
|
||||
|
||||
IPaymentFilter excludeFilter = null;
|
||||
if (invoice.PaymentCurrencies?.Any() is true)
|
||||
{
|
||||
invoice.SupportedTransactionCurrencies ??=
|
||||
|
@ -173,17 +146,67 @@ namespace BTCPayServer.Controllers
|
|||
var supportedTransactionCurrencies = invoice.SupportedTransactionCurrencies
|
||||
.Where(c => c.Value.Enabled)
|
||||
.Select(c => PaymentMethodId.TryParse(c.Key, out var p) ? p : null)
|
||||
.Where(c => c != null)
|
||||
.ToHashSet();
|
||||
excludeFilter = PaymentFilter.Or(excludeFilter,
|
||||
PaymentFilter.Where(p => !supportedTransactionCurrencies.Contains(p)));
|
||||
excludeFilter = PaymentFilter.Where(p => !supportedTransactionCurrencies.Contains(p));
|
||||
}
|
||||
entity.PaymentTolerance = storeBlob.PaymentTolerance;
|
||||
return await CreateInvoiceCoreRaw(entity, store, excludeFilter, cancellationToken);
|
||||
}
|
||||
|
||||
internal async Task<InvoiceEntity> CreateInvoiceCoreRaw(CreateInvoiceRequest invoice, StoreData store, string serverUrl, List<string> additionalTags = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var entity = _InvoiceRepository.CreateNewInvoice();
|
||||
entity.ExpirationTime = entity.InvoiceTime + (invoice.Checkout.Expiration ?? storeBlob.InvoiceExpiration);
|
||||
entity.MonitoringExpiration = entity.ExpirationTime + (invoice.Checkout.Monitoring ?? storeBlob.MonitoringExpiration);
|
||||
if (invoice.Metadata != null)
|
||||
entity.Metadata = InvoiceMetadata.FromJObject(invoice.Metadata);
|
||||
invoice.Checkout ??= new CreateInvoiceRequest.CheckoutOptions();
|
||||
entity.Currency = invoice.Currency;
|
||||
entity.Price = invoice.Amount;
|
||||
entity.SpeedPolicy = invoice.Checkout.SpeedPolicy ?? store.SpeedPolicy;
|
||||
IPaymentFilter excludeFilter = null;
|
||||
if (invoice.Checkout.PaymentMethods != null)
|
||||
{
|
||||
var supportedTransactionCurrencies = invoice.Checkout.PaymentMethods
|
||||
.Select(c => PaymentMethodId.TryParse(c, out var p) ? p : null)
|
||||
.ToHashSet();
|
||||
excludeFilter = PaymentFilter.Where(p => !supportedTransactionCurrencies.Contains(p));
|
||||
}
|
||||
entity.PaymentTolerance = invoice.Checkout.PaymentTolerance ?? storeBlob.PaymentTolerance;
|
||||
return await CreateInvoiceCoreRaw(entity, store, excludeFilter, cancellationToken);
|
||||
}
|
||||
|
||||
internal async Task<InvoiceEntity> CreateInvoiceCoreRaw(InvoiceEntity entity, StoreData store, IPaymentFilter invoicePaymentMethodFilter, CancellationToken cancellationToken = default)
|
||||
{
|
||||
InvoiceLogs logs = new InvoiceLogs();
|
||||
logs.Write("Creation of invoice starting");
|
||||
|
||||
var getAppsTaggingStore = _InvoiceRepository.GetAppsTaggingStore(store.Id);
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
|
||||
if (entity.Metadata.BuyerEmail != null)
|
||||
{
|
||||
if (!EmailValidator.IsEmail(entity.Metadata.BuyerEmail))
|
||||
throw new BitpayHttpException(400, "Invalid email");
|
||||
entity.RefundMail = entity.Metadata.BuyerEmail;
|
||||
}
|
||||
entity.Status = InvoiceStatus.New;
|
||||
HashSet<CurrencyPair> currencyPairsToFetch = new HashSet<CurrencyPair>();
|
||||
var rules = storeBlob.GetRateRules(_NetworkProvider);
|
||||
var excludeFilter = storeBlob.GetExcludedPaymentMethods(); // Here we can compose filters from other origin with PaymentFilter.Any()
|
||||
if (invoicePaymentMethodFilter != null)
|
||||
{
|
||||
excludeFilter = PaymentFilter.Or(excludeFilter,
|
||||
invoicePaymentMethodFilter);
|
||||
}
|
||||
foreach (var network in store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Where(s => !excludeFilter.Match(s.PaymentId))
|
||||
.Select(c => _NetworkProvider.GetNetwork<BTCPayNetworkBase>(c.PaymentId.CryptoCode))
|
||||
.Where(c => c != null))
|
||||
{
|
||||
currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, invoice.Currency));
|
||||
currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, entity.Currency));
|
||||
//TODO: abstract
|
||||
if (storeBlob.LightningMaxValue != null)
|
||||
currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, storeBlob.LightningMaxValue.Currency));
|
||||
|
@ -195,7 +218,12 @@ namespace BTCPayServer.Controllers
|
|||
var fetchingByCurrencyPair = _RateProvider.FetchRates(currencyPairsToFetch, rateRules, cancellationToken);
|
||||
var fetchingAll = WhenAllFetched(logs, fetchingByCurrencyPair);
|
||||
|
||||
var supportedPaymentMethods = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
List<ISupportedPaymentMethod> supported = new List<ISupportedPaymentMethod>();
|
||||
var paymentMethods = new PaymentMethodDictionary();
|
||||
|
||||
// This loop ends with .ToList so we are querying all payment methods at once
|
||||
// instead of sequentially to improve response time
|
||||
foreach (var o in store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Where(s => !excludeFilter.Match(s.PaymentId) && _paymentMethodHandlerDictionary.Support(s.PaymentId))
|
||||
.Select(c =>
|
||||
(Handler: _paymentMethodHandlerDictionary[c.PaymentId],
|
||||
|
@ -205,10 +233,7 @@ namespace BTCPayServer.Controllers
|
|||
.Select(o =>
|
||||
(SupportedPaymentMethod: o.SupportedPaymentMethod,
|
||||
PaymentMethod: CreatePaymentMethodAsync(fetchingByCurrencyPair, o.Handler, o.SupportedPaymentMethod, o.Network, entity, store, logs)))
|
||||
.ToList();
|
||||
List<ISupportedPaymentMethod> supported = new List<ISupportedPaymentMethod>();
|
||||
var paymentMethods = new PaymentMethodDictionary();
|
||||
foreach (var o in supportedPaymentMethods)
|
||||
.ToList())
|
||||
{
|
||||
var paymentMethod = await o.PaymentMethod;
|
||||
if (paymentMethod == null)
|
||||
|
@ -231,7 +256,6 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
entity.SetSupportedPaymentMethods(supported);
|
||||
entity.SetPaymentMethods(paymentMethods);
|
||||
entity.Metadata.PosData = invoice.PosData;
|
||||
foreach (var app in await getAppsTaggingStore)
|
||||
{
|
||||
entity.InternalTags.Add(AppService.GetAppInternalTag(app.Id));
|
||||
|
|
|
@ -481,8 +481,8 @@ namespace BTCPayServer.Controllers
|
|||
vm.SpeedPolicy = store.SpeedPolicy;
|
||||
vm.CanDelete = _Repo.CanDeleteStores();
|
||||
AddPaymentMethods(store, storeBlob, vm);
|
||||
vm.MonitoringExpiration = storeBlob.MonitoringExpiration;
|
||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||
vm.MonitoringExpiration = (int)storeBlob.MonitoringExpiration.TotalMinutes;
|
||||
vm.InvoiceExpiration = (int)storeBlob.InvoiceExpiration.TotalMinutes;
|
||||
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
|
||||
vm.PaymentTolerance = storeBlob.PaymentTolerance;
|
||||
vm.PayJoinEnabled = storeBlob.PayJoinEnabled;
|
||||
|
@ -579,8 +579,8 @@ namespace BTCPayServer.Controllers
|
|||
var blob = CurrentStore.GetStoreBlob();
|
||||
blob.AnyoneCanInvoice = model.AnyoneCanCreateInvoice;
|
||||
blob.NetworkFeeMode = model.NetworkFeeMode;
|
||||
blob.MonitoringExpiration = model.MonitoringExpiration;
|
||||
blob.InvoiceExpiration = model.InvoiceExpiration;
|
||||
blob.MonitoringExpiration = TimeSpan.FromMinutes(model.MonitoringExpiration);
|
||||
blob.InvoiceExpiration = TimeSpan.FromMinutes(model.InvoiceExpiration);
|
||||
blob.LightningDescriptionTemplate = model.LightningDescriptionTemplate ?? string.Empty;
|
||||
blob.PaymentTolerance = model.PaymentTolerance;
|
||||
var payjoinChanged = blob.PayJoinEnabled != model.PayJoinEnabled;
|
||||
|
|
|
@ -195,7 +195,7 @@ namespace BTCPayServer.Data
|
|||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal MinimumClaim { get; set; }
|
||||
public PullPaymentView View { get; set; } = new PullPaymentView();
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter))]
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan? Period { get; set; }
|
||||
|
||||
[JsonProperty(ItemConverterType = typeof(PaymentMethodIdJsonConverter))]
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using BTCPayServer.Payments;
|
||||
|
@ -19,8 +20,8 @@ namespace BTCPayServer.Data
|
|||
{
|
||||
public StoreBlob()
|
||||
{
|
||||
InvoiceExpiration = 15;
|
||||
MonitoringExpiration = 1440;
|
||||
InvoiceExpiration = TimeSpan.FromMinutes(15);
|
||||
MonitoringExpiration = TimeSpan.FromDays(1);
|
||||
PaymentTolerance = 0;
|
||||
ShowRecommendedFee = true;
|
||||
RecommendedFeeBlockTarget = 1;
|
||||
|
@ -66,17 +67,19 @@ namespace BTCPayServer.Data
|
|||
}
|
||||
|
||||
public string DefaultLang { get; set; }
|
||||
[DefaultValue(60)]
|
||||
[DefaultValue(typeof(TimeSpan), "1.00:00:00")]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public int MonitoringExpiration
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Minutes))]
|
||||
public TimeSpan MonitoringExpiration
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[DefaultValue(15)]
|
||||
[DefaultValue(typeof(TimeSpan), "00:15:00")]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public int InvoiceExpiration
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Minutes))]
|
||||
public TimeSpan InvoiceExpiration
|
||||
{
|
||||
get;
|
||||
set;
|
||||
|
|
|
@ -82,6 +82,5 @@ namespace BTCPayServer.Models
|
|||
//Bitpay compatibility: create invoice in btcpay uses this instead of supportedTransactionCurrencies
|
||||
[JsonProperty(PropertyName = "paymentCurrencies", DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public IEnumerable<string> PaymentCurrencies { get; set; }
|
||||
public JObject Metadata { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue