예제 #1
0
        private ZcashLikePaymentMethodViewModel GetZcashLikePaymentMethodViewModel(
            IEnumerable <ZcashSupportedPaymentMethod> Zcash, string cryptoCode,
            IPaymentFilter excludeFilters, GetAccountsResponse accountsResponse)
        {
            var settings = Zcash.SingleOrDefault(method => method.CryptoCode == cryptoCode);

            _ZcashRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary);
            _ZcashLikeConfiguration.ZcashLikeConfigurationItems.TryGetValue(cryptoCode,
                                                                            out var configurationItem);
            var fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet");
            var accounts    = accountsResponse?.SubaddressAccounts?.Select(account =>
                                                                           new SelectListItem(
                                                                               $"{account.AccountIndex} - {(string.IsNullOrEmpty(account.Label) ? "No label" : account.Label)}",
                                                                               account.AccountIndex.ToString(CultureInfo.InvariantCulture)));

            return(new ZcashLikePaymentMethodViewModel()
            {
                WalletFileFound = System.IO.File.Exists(fileAddress),
                Enabled =
                    settings != null &&
                    !excludeFilters.Match(new PaymentMethodId(cryptoCode, ZcashPaymentType.Instance)),
                Summary = summary,
                CryptoCode = cryptoCode,
                AccountIndex = settings?.AccountIndex ?? accountsResponse?.SubaddressAccounts?.FirstOrDefault()?.AccountIndex ?? 0,
                Accounts = accounts == null ? null : new SelectList(accounts, nameof(SelectListItem.Value),
                                                                    nameof(SelectListItem.Text))
            });
        }
예제 #2
0
        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;
            entity.DefaultLanguage = invoice.Checkout.DefaultLanguage;
            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;
            entity.RedirectURLTemplate = invoice.Checkout.RedirectURL?.Trim();
            if (additionalTags != null)
            {
                entity.InternalTags.AddRange(additionalTags);
            }
            return(await CreateInvoiceCoreRaw(entity, store, excludeFilter, cancellationToken));
        }
예제 #3
0
 public static IPaymentFilter Or(IPaymentFilter a, IPaymentFilter b)
 {
     if (a == null)
     {
         throw new ArgumentNullException(nameof(a));
     }
     if (b == null)
     {
         throw new ArgumentNullException(nameof(b));
     }
     return(new OrPaymentFilter(a, b));
 }
예제 #4
0
        internal async Task <InvoiceEntity> CreateInvoiceCoreRaw(BitpayCreateInvoiceRequest invoice, StoreData store, string serverUrl, List <string> additionalTags = null, CancellationToken cancellationToken = default)
        {
            var storeBlob = store.GetStoreBlob();
            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");
            }
            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;
            if (additionalTags != null)
            {
                entity.InternalTags.AddRange(additionalTags);
            }
            FillBuyerInfo(invoice, entity);

            var taxIncluded = invoice.TaxIncluded.HasValue ? invoice.TaxIncluded.Value : 0m;

            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.RedirectURLTemplate   = invoice.RedirectURL ?? store.StoreWebsite;
            entity.RedirectAutomatically =
                invoice.RedirectAutomatically.GetValueOrDefault(storeBlob.RedirectAutomatically);
            entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy);

            IPaymentFilter excludeFilter = null;

            if (invoice.PaymentCurrencies?.Any() is true)
            {
                invoice.SupportedTransactionCurrencies ??=
                new Dictionary <string, InvoiceSupportedTransactionCurrency>();
                foreach (string paymentCurrency in invoice.PaymentCurrencies)
                {
                    invoice.SupportedTransactionCurrencies.TryAdd(paymentCurrency,
                                                                  new InvoiceSupportedTransactionCurrency()
                    {
                        Enabled = true
                    });
                }
            }
            if (invoice.SupportedTransactionCurrencies != null && invoice.SupportedTransactionCurrencies.Count != 0)
            {
                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.Where(p => !supportedTransactionCurrencies.Contains(p));
            }
            entity.PaymentTolerance = storeBlob.PaymentTolerance;
            return(await CreateInvoiceCoreRaw(entity, store, excludeFilter, cancellationToken));
        }
예제 #5
0
        internal async Task <InvoiceEntity> CreateInvoiceCoreRaw(InvoiceEntity entity, StoreData store, IPaymentFilter invoicePaymentMethodFilter, CancellationToken cancellationToken = default)
        {
            InvoiceLogs logs = new InvoiceLogs();

            logs.Write("Creation of invoice starting", InvoiceEventData.EventSeverity.Info);

            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 = InvoiceStatusLegacy.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, entity.Currency));
                foreach (var paymentMethodCriteria in store.GetPaymentMethodCriteria(_NetworkProvider, storeBlob))
                {
                    if (paymentMethodCriteria.Value != null)
                    {
                        currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, paymentMethodCriteria.Value.Currency));
                    }
                }
            }

            var rateRules = storeBlob.GetRateRules(_NetworkProvider);
            var fetchingByCurrencyPair = _RateProvider.FetchRates(currencyPairsToFetch, rateRules, cancellationToken);
            var fetchingAll            = WhenAllFetched(logs, fetchingByCurrencyPair);

            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],
                              SupportedPaymentMethod: c,
                              Network: _NetworkProvider.GetNetwork <BTCPayNetworkBase>(c.PaymentId.CryptoCode)))
                     .Where(c => c.Network != null)
                     .Select(o =>
                             (SupportedPaymentMethod: o.SupportedPaymentMethod,
                              PaymentMethod: CreatePaymentMethodAsync(fetchingByCurrencyPair, o.Handler, o.SupportedPaymentMethod, o.Network, entity, store, logs)))
                     .ToList())
            {
                var paymentMethod = await o.PaymentMethod;
                if (paymentMethod == null)
                {
                    continue;
                }
                supported.Add(o.SupportedPaymentMethod);
                paymentMethods.Add(paymentMethod);
            }

            if (supported.Count == 0)
            {
                StringBuilder errors = new StringBuilder();
                if (!store.GetSupportedPaymentMethods(_NetworkProvider).Any())
                {
                    errors.AppendLine("Warning: No wallet has been linked to your BTCPay Store. See the following link for more information on how to connect your store and wallet. (https://docs.btcpayserver.org/WalletSetup/)");
                }
                foreach (var error in logs.ToList())
                {
                    errors.AppendLine(error.ToString());
                }
                throw new BitpayHttpException(400, errors.ToString());
            }

            entity.SetSupportedPaymentMethods(supported);
            entity.SetPaymentMethods(paymentMethods);
            foreach (var app in await getAppsTaggingStore)
            {
                entity.InternalTags.Add(AppService.GetAppInternalTag(app.Id));
            }

            using (logs.Measure("Saving invoice"))
            {
                entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity);
            }
            _ = Task.Run(async() =>
            {
                try
                {
                    await fetchingAll;
                }
                catch (AggregateException ex)
                {
                    ex.Handle(e => { logs.Write($"Error while fetching rates {ex}", InvoiceEventData.EventSeverity.Error); return(true); });
                }
                await _InvoiceRepository.AddInvoiceLogs(entity.Id, logs);
            });
            _EventAggregator.Publish(new Events.InvoiceEvent(entity, InvoiceEvent.Created));
            return(entity);
        }
예제 #6
0
 public OrPaymentFilter(IPaymentFilter a, IPaymentFilter b)
 {
     _a = a;
     _b = b;
 }
예제 #7
0
 protected bool IsAccountMatch(IPaymentFilter paymentFilter, IPayment payment)
 {
     return(paymentFilter.AccountIds.Contains(payment.AccountId));
 }
예제 #8
0
 protected bool IsToDateMatch(IPaymentFilter paymentFilter, IPayment payment)
 {
     return(paymentFilter.ToDate >= payment.Date);
 }
예제 #9
0
 protected bool IsFromDateMatch(IPaymentFilter paymentFilter, IPayment payment)
 {
     return(paymentFilter.FromDate <= payment.Date);
 }
예제 #10
0
 public static IPaymentFilter Or(IPaymentFilter a, IPaymentFilter b)
 {
     ArgumentNullException.ThrowIfNull(a);
     ArgumentNullException.ThrowIfNull(b);
     return(new OrPaymentFilter(a, b));
 }