private async Task <PaymentModel> GetInvoiceModel(string invoiceId, PaymentMethodId paymentMethodId) { var invoice = await _InvoiceRepository.GetInvoice(invoiceId); if (invoice == null) { return(null); } var store = await _StoreRepository.FindStore(invoice.StoreId); bool isDefaultPaymentId = false; if (paymentMethodId == null) { paymentMethodId = store.GetDefaultPaymentId(_NetworkProvider); isDefaultPaymentId = true; } BTCPayNetworkBase network = _NetworkProvider.GetNetwork <BTCPayNetworkBase>(paymentMethodId.bitcoinCode); if (network == null && isDefaultPaymentId) { //TODO: need to look into a better way for this as it does not scale network = _NetworkProvider.GetAll().OfType <BTCPayNetwork>().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.bitcoinCode, PaymentTypes.BTCLike); } if (invoice == null || network == null) { return(null); } if (!invoice.Support(paymentMethodId)) { if (!isDefaultPaymentId) { return(null); } var paymentMethodTemp = invoice.GetPaymentMethods() .Where(c => paymentMethodId.bitcoinCode == c.GetId().bitcoinCode) .FirstOrDefault(); if (paymentMethodTemp == null) { paymentMethodTemp = invoice.GetPaymentMethods().First(); } network = paymentMethodTemp.Network; paymentMethodId = paymentMethodTemp.GetId(); } var paymentMethod = invoice.GetPaymentMethod(paymentMethodId); var paymentMethodDetails = paymentMethod.GetPaymentMethodDetails(); var dto = invoice.EntityToDTO(); var bitcoinInfo = dto.bitcoinInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var storeBlob = store.GetStoreBlob(); var currency = invoice.ProductInformation.Currency; var accounting = paymentMethod.Calculate(); ChangellySettings changelly = (storeBlob.ChangellySettings != null && storeBlob.ChangellySettings.Enabled && storeBlob.ChangellySettings.IsConfigured()) ? storeBlob.ChangellySettings : null; CoinSwitchSettings coinswitch = (storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled && storeBlob.CoinSwitchSettings.IsConfigured()) ? storeBlob.CoinSwitchSettings : null; var changellyAmountDue = changelly != null ? (accounting.Due.ToDecimal(MoneyUnit.BTC) * (1m + (changelly.AmountMarkupPercentage / 100m))) : (decimal?)null; var paymentMethodHandler = _paymentMethodHandlerDictionary[paymentMethodId]; var divisibility = _CurrencyNameTable.GetNumberFormatInfo(paymentMethod.GetId().bitcoinCode, false)?.CurrencyDecimalDigits; var model = new PaymentModel() { bitcoinCode = network.bitcoinCode, RootPath = this.Request.PathBase.Value.WithTrailingSlash(), OrderId = invoice.OrderId, InvoiceId = invoice.Id, DefaultLang = storeBlob.DefaultLang ?? "en", CustomCSSLink = storeBlob.CustomCSS, CustomLogoLink = storeBlob.CustomLogo, HtmlTitle = storeBlob.HtmlTitle ?? "BTCPay Invoice", bitcoinImage = Request.GetRelativePathOrAbsolute(paymentMethodHandler.GetbitcoinImage(paymentMethodId)), BtcAddress = paymentMethodDetails.GetPaymentDestination(), BtcDue = accounting.Due.ShowMoney(divisibility), OrderAmount = (accounting.TotalDue - accounting.NetworkFee).ShowMoney(divisibility), OrderAmountFiat = OrderAmountFromInvoice(network.bitcoinCode, invoice.ProductInformation), CustomerEmail = invoice.RefundMail, RequiresRefundEmail = storeBlob.RequiresRefundEmail, ShowRecommendedFee = storeBlob.ShowRecommendedFee, FeeRate = paymentMethodDetails.GetFeeRate(), ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds), MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds, MaxTimeMinutes = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalMinutes, ItemDesc = invoice.ProductInformation.ItemDesc, Rate = ExchangeRate(paymentMethod), MerchantRefLink = invoice.RedirectURL?.AbsoluteUri ?? "/", RedirectAutomatically = invoice.RedirectAutomatically, StoreName = store.StoreName, PeerInfo = (paymentMethodDetails as LightningLikePaymentMethodDetails)?.NodeInfo, TxCount = accounting.TxRequired, BtcPaid = accounting.Paid.ShowMoney(divisibility), #pragma warning disable CS0618 // Type or member is obsolete Status = invoice.StatusString, #pragma warning restore CS0618 // Type or member is obsolete NetworkFee = paymentMethodDetails.GetNextNetworkFee(), IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1, ChangellyEnabled = changelly != null, ChangellyMerchantId = changelly?.ChangellyMerchantId, ChangellyAmountDue = changellyAmountDue, CoinSwitchEnabled = coinswitch != null, CoinSwitchAmountMarkupPercentage = coinswitch?.AmountMarkupPercentage ?? 0, CoinSwitchMerchantId = coinswitch?.MerchantId, CoinSwitchMode = coinswitch?.Mode, StoreId = store.Id, Availablebitcoins = invoice.GetPaymentMethods() .Where(i => i.Network != null) .Select(kv => { var availablebitcoinPaymentMethodId = kv.GetId(); var availablebitcoinHandler = _paymentMethodHandlerDictionary[availablebitcoinPaymentMethodId]; return(new PaymentModel.Availablebitcoin() { PaymentMethodId = kv.GetId().ToString(), bitcoinCode = kv.Network?.bitcoinCode ?? kv.GetId().bitcoinCode, PaymentMethodName = availablebitcoinHandler.GetPaymentMethodName(availablebitcoinPaymentMethodId), IsLightning = kv.GetId().PaymentType == PaymentTypes.LightningLike, bitcoinImage = Request.GetRelativePathOrAbsolute(availablebitcoinHandler.GetbitcoinImage(availablebitcoinPaymentMethodId)), Link = Url.Action(nameof(Checkout), new { invoiceId = invoiceId, paymentMethodId = kv.GetId().ToString() }) }); }).Where(c => c.bitcoinImage != "/") .OrderByDescending(a => a.bitcoinCode == "BTC").ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0) .ToList() }; paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob); if (model.IsLightning && storeBlob.LightningAmountInSatoshi && model.bitcoinCode == "Sats") { model.Rate = _CurrencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, paymentMethod.ParentEntity.ProductInformation.Currency); } model.UISettings = paymentMethodHandler.GetCheckoutUISettings(); model.PaymentMethodId = paymentMethodId.ToString(); var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); model.TimeLeft = expiration.PrettyPrint(); return(model); }
private async Task <PaymentModel> GetInvoiceModel(string invoiceId, PaymentMethodId paymentMethodId) { var invoice = await _InvoiceRepository.GetInvoice(invoiceId); if (invoice == null) { return(null); } var store = await _StoreRepository.FindStore(invoice.StoreId); bool isDefaultPaymentId = false; if (paymentMethodId == null) { paymentMethodId = store.GetDefaultPaymentId(_NetworkProvider); isDefaultPaymentId = true; } var network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); if (network == null && isDefaultPaymentId) { network = _NetworkProvider.GetAll().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); } if (invoice == null || network == null) { return(null); } if (!invoice.Support(paymentMethodId)) { if (!isDefaultPaymentId) { return(null); } var paymentMethodTemp = invoice.GetPaymentMethods(_NetworkProvider) .Where(c => paymentMethodId.CryptoCode == c.GetId().CryptoCode) .FirstOrDefault(); if (paymentMethodTemp == null) { paymentMethodTemp = invoice.GetPaymentMethods(_NetworkProvider).First(); } network = paymentMethodTemp.Network; paymentMethodId = paymentMethodTemp.GetId(); } var paymentMethod = invoice.GetPaymentMethod(paymentMethodId, _NetworkProvider); var paymentMethodDetails = paymentMethod.GetPaymentMethodDetails(); var dto = invoice.EntityToDTO(_NetworkProvider); var cryptoInfo = dto.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var storeBlob = store.GetStoreBlob(); var currency = invoice.ProductInformation.Currency; var accounting = paymentMethod.Calculate(); ChangellySettings changelly = (storeBlob.ChangellySettings != null && storeBlob.ChangellySettings.Enabled && storeBlob.ChangellySettings.IsConfigured()) ? storeBlob.ChangellySettings : null; CoinSwitchSettings coinswitch = (storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled && storeBlob.CoinSwitchSettings.IsConfigured()) ? storeBlob.CoinSwitchSettings : null; var changellyAmountDue = changelly != null ? (accounting.Due.ToDecimal(MoneyUnit.BTC) * (1m + (changelly.AmountMarkupPercentage / 100m))) : (decimal?)null; var model = new PaymentModel() { CryptoCode = network.CryptoCode, RootPath = this.Request.PathBase.Value.WithTrailingSlash(), PaymentMethodId = paymentMethodId.ToString(), PaymentMethodName = GetDisplayName(paymentMethodId, network), CryptoImage = GetImage(paymentMethodId, network), IsLightning = paymentMethodId.PaymentType == PaymentTypes.LightningLike, OrderId = invoice.OrderId, InvoiceId = invoice.Id, DefaultLang = storeBlob.DefaultLang ?? "en", HtmlTitle = storeBlob.HtmlTitle ?? "BTCPay Invoice", CustomCSSLink = storeBlob.CustomCSS?.AbsoluteUri, CustomLogoLink = storeBlob.CustomLogo?.AbsoluteUri, LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi, BtcAddress = paymentMethodDetails.GetPaymentDestination(), BtcDue = accounting.Due.ToString(), OrderAmount = (accounting.TotalDue - accounting.NetworkFee).ToString(), OrderAmountFiat = OrderAmountFromInvoice(network.CryptoCode, invoice.ProductInformation), CustomerEmail = invoice.RefundMail, RequiresRefundEmail = storeBlob.RequiresRefundEmail, ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds), MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds, MaxTimeMinutes = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalMinutes, ItemDesc = invoice.ProductInformation.ItemDesc, Rate = ExchangeRate(paymentMethod), MerchantRefLink = invoice.RedirectURL ?? "/", RedirectAutomatically = invoice.RedirectAutomatically, StoreName = store.StoreName, InvoiceBitcoinUrl = paymentMethodId.PaymentType == PaymentTypes.BTCLike ? cryptoInfo.PaymentUrls.BIP21 : paymentMethodId.PaymentType == PaymentTypes.LightningLike ? cryptoInfo.PaymentUrls.BOLT11 : throw new NotSupportedException(), PeerInfo = (paymentMethodDetails as LightningLikePaymentMethodDetails)?.NodeInfo, InvoiceBitcoinUrlQR = paymentMethodId.PaymentType == PaymentTypes.BTCLike ? cryptoInfo.PaymentUrls.BIP21 : paymentMethodId.PaymentType == PaymentTypes.LightningLike ? cryptoInfo.PaymentUrls.BOLT11.ToUpperInvariant() : throw new NotSupportedException(), TxCount = accounting.TxRequired, BtcPaid = accounting.Paid.ToString(), #pragma warning disable CS0618 // Type or member is obsolete Status = invoice.StatusString, #pragma warning restore CS0618 // Type or member is obsolete NetworkFee = paymentMethodDetails.GetNextNetworkFee(), IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1, ChangellyEnabled = changelly != null, ChangellyMerchantId = changelly?.ChangellyMerchantId, ChangellyAmountDue = changellyAmountDue, CoinSwitchEnabled = coinswitch != null, CoinSwitchAmountMarkupPercentage = coinswitch?.AmountMarkupPercentage ?? 0, CoinSwitchMerchantId = coinswitch?.MerchantId, CoinSwitchMode = coinswitch?.Mode, StoreId = store.Id, AvailableCryptos = invoice.GetPaymentMethods(_NetworkProvider) .Where(i => i.Network != null) .Select(kv => new PaymentModel.AvailableCrypto() { PaymentMethodId = kv.GetId().ToString(), CryptoCode = kv.GetId().CryptoCode, PaymentMethodName = GetDisplayName(kv.GetId(), kv.Network), IsLightning = kv.GetId().PaymentType == PaymentTypes.LightningLike, CryptoImage = GetImage(kv.GetId(), kv.Network), Link = Url.Action(nameof(Checkout), new { invoiceId = invoiceId, paymentMethodId = kv.GetId().ToString() }) }).Where(c => c.CryptoImage != "/") .OrderByDescending(a => a.CryptoCode == "BTC").ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0) .ToList() }; var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); model.TimeLeft = expiration.PrettyPrint(); return(model); }
public async Task <IActionResult> UpdateChangellySettings(string storeId, UpdateChangellySettingsViewModel vm, string command) { var store = HttpContext.GetStoreData(); if (store == null) { return(NotFound()); } if (vm.Enabled) { if (!ModelState.IsValid) { return(View(vm)); } } var changellySettings = new ChangellySettings() { ApiKey = vm.ApiKey, ApiSecret = vm.ApiSecret, ApiUrl = vm.ApiUrl, ChangellyMerchantId = vm.ChangellyMerchantId, Enabled = vm.Enabled, AmountMarkupPercentage = vm.AmountMarkupPercentage }; switch (command) { case "save": var storeBlob = store.GetStoreBlob(); storeBlob.ChangellySettings = changellySettings; store.SetStoreBlob(storeBlob); await _Repo.UpdateStore(store); TempData[WellKnownTempData.SuccessMessage] = "Changelly settings modified"; _changellyClientProvider.InvalidateClient(storeId); return(RedirectToAction(nameof(UpdateStore), new { storeId })); case "test": try { var client = new Changelly(_httpClientFactory.CreateClient(), changellySettings.ApiKey, changellySettings.ApiSecret, changellySettings.ApiUrl); var result = await client.GetCurrenciesFull(); TempData[WellKnownTempData.SuccessMessage] = "Test Successful"; return(View(vm)); } catch (Exception ex) { TempData[WellKnownTempData.ErrorMessage] = ex.Message; return(View(vm)); } default: return(View(vm)); } }