#pragma warning disable CS0618 // Type or member is obsolete public void SetWalletKeyPathRoot(PaymentMethodId paymentMethodId, KeyPath keyPath) { if (keyPath == null) { WalletKeyPathRoots.Remove(paymentMethodId.ToString()); } else { WalletKeyPathRoots.AddOrReplace(paymentMethodId.ToString().ToLowerInvariant(), keyPath.ToString()); } }
public void SetExcluded(PaymentMethodId paymentMethodId, bool value) { #pragma warning disable CS0618 // Type or member is obsolete var methods = new HashSet <string>(ExcludedPaymentMethods ?? Array.Empty <string>()); if (value) { methods.Add(paymentMethodId.ToString()); } else { methods.Remove(paymentMethodId.ToString()); } ExcludedPaymentMethods = methods.ToArray(); #pragma warning restore CS0618 // Type or member is obsolete }
private async Task <List <PayoutData> > GetPayouts(ApplicationDbContext dbContext, PaymentMethodId pmi, string[] payoutIds) { var userId = _userManager.GetUserId(User); if (string.IsNullOrEmpty(userId)) { return(new List <PayoutData>()); } var pmiStr = pmi.ToString(); var approvedStores = new Dictionary <string, bool>(); return((await dbContext.Payouts .Include(data => data.PullPaymentData) .ThenInclude(data => data.StoreData) .ThenInclude(data => data.UserStores) .Where(data => payoutIds.Contains(data.Id) && data.State == PayoutState.AwaitingPayment && data.PaymentMethodId == pmiStr) .ToListAsync()) .Where(payout => { if (approvedStores.TryGetValue(payout.PullPaymentData.StoreId, out var value)) { return value; } value = payout.PullPaymentData.StoreData.UserStores .Any(store => store.Role == StoreRoles.Owner && store.ApplicationUserId == userId); approvedStores.Add(payout.PullPaymentData.StoreId, value); return value; }).ToList()); }
public override System.Collections.Specialized.NameValueCollection GetParameters() { NameValueCollection nvc = base.GetParameters(); if (RequiresApiToken) { if (!String.IsNullOrEmpty(GetApiToken())) { nvc.Add("apiToken", GetApiToken()); } } if (RequiresServiceId) { if (!String.IsNullOrEmpty(GetServiceId())) { nvc.Add("serviceID", GetServiceId()); } } ParameterValidator.IsNotNull(PaymentMethodId, "PaymentMethodId"); nvc.Add("paymentMethodId", PaymentMethodId.ToString()); return(nvc); }
public KeyPath GetWalletKeyPathRoot(PaymentMethodId paymentMethodId) { if (WalletKeyPathRoots.TryGetValue(paymentMethodId.ToString().ToLowerInvariant(), out var k)) { return(KeyPath.Parse(k)); } return(null); }
public override NameValueCollection GetParameters(string serviceId) { var parameters = base.GetParameters(serviceId); ParameterValidator.IsNotNull(PaymentMethodId, "PaymentMethodId"); parameters.Add("paymentMethodId", PaymentMethodId.ToString()); return(parameters); }
public override System.Collections.Specialized.NameValueCollection GetParameters() { NameValueCollection nvc = base.GetParameters(); ParameterValidator.IsNotNull(PaymentMethodId, "PaymentMethodId"); nvc.Add("paymentMethodId", PaymentMethodId.ToString()); return(nvc); }
public async Task <IActionResult> InitiatePayment(PaymentMethodId paymentMethodId, string[] payoutIds) { await using var ctx = this._dbContextFactory.CreateContext(); ctx.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; var pmi = paymentMethodId.ToString(); var payouts = await ctx.Payouts.Include(data => data.PullPaymentData) .Where(data => payoutIds.Contains(data.Id) && pmi == data.PaymentMethodId && data.State == PayoutState.AwaitingPayment) .ToListAsync(); var pullPaymentIds = payouts.Select(data => data.PullPaymentDataId).Distinct().Where(s => s != null).ToArray(); var storeId = payouts.First().StoreDataId; var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(paymentMethodId.CryptoCode); List <string> bip21 = new List <string>(); foreach (var payout in payouts) { if (payout.Proof != null) { continue; } var blob = payout.GetBlob(_jsonSerializerSettings); if (payout.GetPaymentMethodId() != paymentMethodId) { continue; } var claim = await ParseClaimDestination(paymentMethodId, blob.Destination); switch (claim.destination) { case UriClaimDestination uriClaimDestination: uriClaimDestination.BitcoinUrl.Amount = new Money(blob.CryptoAmount.Value, MoneyUnit.BTC); var newUri = new UriBuilder(uriClaimDestination.BitcoinUrl.Uri); BTCPayServerClient.AppendPayloadToQuery(newUri, new KeyValuePair <string, object>("payout", payout.Id)); bip21.Add(newUri.Uri.ToString()); break; case AddressClaimDestination addressClaimDestination: var bip21New = network.GenerateBIP21(addressClaimDestination.Address.ToString(), new Money(blob.CryptoAmount.Value, MoneyUnit.BTC)); bip21New.QueryParams.Add("payout", payout.Id); bip21.Add(bip21New.ToString()); break; } } if (bip21.Any()) { return(new RedirectToActionResult("WalletSend", "UIWallets", new { walletId = new WalletId(storeId, paymentMethodId.CryptoCode).ToString(), bip21 })); } return(new RedirectToActionResult("Payouts", "UIWallets", new { walletId = new WalletId(storeId, paymentMethodId.CryptoCode).ToString(), pullPaymentId = pullPaymentIds.Length == 1 ? pullPaymentIds.First() : null })); }
private static void MarkUnassigned(string invoiceId, ApplicationDbContext context, PaymentMethodId paymentMethodId) { var paymentMethodIdStr = paymentMethodId?.ToString(); var addresses = context.HistoricalAddressInvoices.Where(data => (data.InvoiceDataId == invoiceId && paymentMethodIdStr == null || data.CryptoCode == paymentMethodIdStr) && data.UnAssigned == null); foreach (var historicalAddressInvoiceData in addresses) { historicalAddressInvoiceData.UnAssigned = DateTimeOffset.UtcNow; } }
public override NameValueCollection GetParameters() { NameValueCollection nvc = base.GetParameters(); if (RequiresApiToken) { if (!String.IsNullOrEmpty(GetApiToken())) { nvc.Add("token", GetApiToken()); } } if (RequiresServiceId) { if (!String.IsNullOrEmpty(GetServiceId())) { nvc.Add("serviceId", GetServiceId()); } } ParameterValidator.IsNotNull(CategoryId, "CategoryId"); nvc.Add("categoryId", CategoryId.ToString()); if (!ParameterValidator.IsNonEmptyInt(ProgramId)) { nvc.Add("programId", ProgramId.ToString()); } if (!ParameterValidator.IsNonEmptyInt(PaymentMethodId)) { nvc.Add("paymentMethodId", PaymentMethodId.ToString()); } if (!ParameterValidator.IsNull(ShowNotAllowedOnRegistration)) { nvc.Add("ShowNotAllowedOnRegistration", ((bool)ShowNotAllowedOnRegistration) ? "1" : "0"); } return(nvc); }
public async Task <IActionResult> InitiatePayment(PaymentMethodId paymentMethodId, string[] payoutIds) { await using var ctx = this._dbContextFactory.CreateContext(); ctx.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; var pmi = paymentMethodId.ToString(); var payouts = await ctx.Payouts.Include(data => data.PullPaymentData) .Where(data => payoutIds.Contains(data.Id) && pmi == data.PaymentMethodId && data.State == PayoutState.AwaitingPayment) .ToListAsync(); var pullPaymentIds = payouts.Select(data => data.PullPaymentDataId).Distinct().ToArray(); var storeId = payouts.First().PullPaymentData.StoreId; var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(paymentMethodId.CryptoCode); List <string> bip21 = new List <string>(); foreach (var payout in payouts) { if (payout.Proof != null) { continue; } var blob = payout.GetBlob(_jsonSerializerSettings); if (payout.GetPaymentMethodId() != paymentMethodId) { continue; } bip21.Add(network.GenerateBIP21(payout.Destination, new Money(blob.CryptoAmount.Value, MoneyUnit.BTC)).ToString()); } if (bip21.Any()) { return(new RedirectToActionResult("WalletSend", "Wallets", new { walletId = new WalletId(storeId, paymentMethodId.CryptoCode).ToString(), bip21 })); } return(new RedirectToActionResult("Payouts", "Wallets", new { walletId = new WalletId(storeId, paymentMethodId.CryptoCode).ToString(), pullPaymentId = pullPaymentIds.Length == 1? pullPaymentIds.First(): null })); }
public override NameValueCollection GetParameters() { var nvc = base.GetParameters(); ParameterValidator.IsNotNull(CategoryId, "CategoryId"); nvc.Add("categoryId", CategoryId.ToString()); if (!ParameterValidator.IsNonEmptyInt(ProgramId)) { nvc.Add("programId", ProgramId.ToString()); } if (!ParameterValidator.IsNonEmptyInt(PaymentMethodId)) { nvc.Add("paymentMethodId", PaymentMethodId.ToString()); } if (!ParameterValidator.IsNull(ShowNotAllowedOnRegistration)) { nvc.Add("ShowNotAllowedOnRegistration", ((bool)ShowNotAllowedOnRegistration) ? "1" : "0"); } return(nvc); }
private async Task <PaymentModel> GetInvoiceModel(string invoiceId, string paymentMethodIdStr) { var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); if (invoice == null) { return(null); } var store = await _StoreRepository.FindStore(invoice.StoreId); bool isDefaultCrypto = false; if (paymentMethodIdStr == null) { paymentMethodIdStr = store.GetDefaultCrypto(); isDefaultCrypto = true; } var paymentMethodId = PaymentMethodId.Parse(paymentMethodIdStr); var network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); if (network == null && isDefaultCrypto) { network = _NetworkProvider.GetAll().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); paymentMethodIdStr = paymentMethodId.ToString(); } if (invoice == null || network == null) { return(null); } if (!invoice.Support(paymentMethodId)) { if (!isDefaultCrypto) { return(null); } var paymentMethodTemp = invoice.GetPaymentMethods(_NetworkProvider).First(); network = paymentMethodTemp.Network; paymentMethodId = paymentMethodTemp.GetId(); paymentMethodIdStr = paymentMethodId.ToString(); } 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(); var model = new PaymentModel() { CryptoCode = network.CryptoCode, PaymentMethodId = paymentMethodId.ToString(), IsLightning = paymentMethodId.PaymentType == PaymentTypes.LightningLike, ServerUrl = HttpContext.Request.GetAbsoluteRoot(), OrderId = invoice.OrderId, InvoiceId = invoice.Id, DefaultLang = storeBlob.DefaultLang ?? "en-US", HtmlTitle = storeBlob.HtmlTitle ?? "BTCPay Invoice", CustomCSSLink = storeBlob.CustomCSS?.AbsoluteUri, CustomLogoLink = storeBlob.CustomLogo?.AbsoluteUri, BtcAddress = paymentMethodDetails.GetPaymentDestination(), OrderAmount = (accounting.TotalDue - accounting.NetworkFee).ToString(), BtcDue = accounting.Due.ToString(), 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 = FormatCurrency(paymentMethod), MerchantRefLink = invoice.RedirectURL ?? "/", 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(), Status = invoice.Status, CryptoImage = "/" + GetImage(paymentMethodId, network), NetworkFee = paymentMethodDetails.GetTxFee(), IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1, AllowCoinConversion = storeBlob.AllowCoinConversion, AvailableCryptos = invoice.GetPaymentMethods(_NetworkProvider) .Where(i => i.Network != null) .Select(kv => new PaymentModel.AvailableCrypto() { PaymentMethodId = kv.GetId().ToString(), CryptoImage = "/" + GetImage(kv.GetId(), kv.Network), Link = Url.Action(nameof(Checkout), new { invoiceId = invoiceId, paymentMethodId = kv.GetId().ToString() }) }).Where(c => c.CryptoImage != "/") .ToList() }; var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); model.TimeLeft = expiration.PrettyPrint(); return(model); }
public static AddressInvoiceData Set(this AddressInvoiceData addressInvoiceData, string address, PaymentMethodId paymentMethodId) { addressInvoiceData.Address = address + "#" + paymentMethodId.ToString(); return(addressInvoiceData); }
private async Task UpdatePayoutsAwaitingForPayment(NewOnChainTransactionEvent newTransaction, AddressTrackedSource addressTrackedSource) { try { var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(newTransaction.CryptoCode); var destinationSum = newTransaction.NewTransactionEvent.Outputs.Sum(output => output.Value.GetValue(network)); var destination = addressTrackedSource.Address.ToString(); var paymentMethodId = new PaymentMethodId(newTransaction.CryptoCode, BitcoinPaymentType.Instance); await using var ctx = _dbContextFactory.CreateContext(); var payouts = await ctx.Payouts .Include(o => o.StoreData) .Include(o => o.PullPaymentData) .Where(p => p.State == PayoutState.AwaitingPayment) .Where(p => p.PaymentMethodId == paymentMethodId.ToString()) #pragma warning disable CA1307 // Specify StringComparison .Where(p => destination.Equals(p.Destination)) #pragma warning restore CA1307 // Specify StringComparison .ToListAsync(); var payoutByDestination = payouts.ToDictionary(p => p.Destination); if (!payoutByDestination.TryGetValue(destination, out var payout)) { return; } var payoutBlob = payout.GetBlob(_jsonSerializerSettings); if (payoutBlob.CryptoAmount is null || // The round up here is not strictly necessary, this is temporary to fix existing payout before we // were properly roundup the crypto amount destinationSum != BTCPayServer.Extensions.RoundUp(payoutBlob.CryptoAmount.Value, network.Divisibility)) { return; } var derivationSchemeSettings = payout.StoreData .GetDerivationSchemeSettings(_btcPayNetworkProvider, newTransaction.CryptoCode).AccountDerivation; var storeWalletMatched = (await _explorerClientProvider.GetExplorerClient(newTransaction.CryptoCode) .GetTransactionAsync(derivationSchemeSettings, newTransaction.NewTransactionEvent.TransactionData.TransactionHash)); //if the wallet related to the store related to the payout does not have the tx: it is external var isInternal = storeWalletMatched is { }; var proof = ParseProof(payout) as PayoutTransactionOnChainBlob ?? new PayoutTransactionOnChainBlob() { Accounted = isInternal }; var txId = newTransaction.NewTransactionEvent.TransactionData.TransactionHash; if (!proof.Candidates.Add(txId)) { return; } if (isInternal) { payout.State = PayoutState.InProgress; var walletId = new WalletId(payout.StoreDataId, newTransaction.CryptoCode); _eventAggregator.Publish(new UpdateTransactionLabel(walletId, newTransaction.NewTransactionEvent.TransactionData.TransactionHash, UpdateTransactionLabel.PayoutTemplate(new () { { payout.PullPaymentDataId ?? "", new List <string> { payout.Id } } }, walletId.ToString()))); } else { await _notificationSender.SendNotification(new StoreScope(payout.StoreDataId), new ExternalPayoutTransactionNotification() { PaymentMethod = payout.PaymentMethodId, PayoutId = payout.Id, StoreId = payout.StoreDataId }); } proof.TransactionId ??= txId; SetProofBlob(payout, proof); await ctx.SaveChangesAsync(); } catch (Exception ex) { Logs.PayServer.LogWarning(ex, "Error while processing a transaction in the pull payment hosted service"); } }
public AddressInvoiceData Set(string address, PaymentMethodId paymentMethodId) { Address = address + "#" + paymentMethodId.ToString(); return(this); }
private async Task <PaymentModel> GetInvoiceModel(string invoiceId, string paymentMethodIdStr) { var invoice = await _InvoiceRepository.GetInvoice(invoiceId); if (invoice == null) { return(null); } var store = await _StoreRepository.FindStore(invoice.StoreId); bool isDefaultCrypto = false; if (paymentMethodIdStr == null) { paymentMethodIdStr = store.GetDefaultCrypto(_NetworkProvider); isDefaultCrypto = true; } var paymentMethodId = PaymentMethodId.Parse(paymentMethodIdStr); var network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); if (network == null && isDefaultCrypto) { network = _NetworkProvider.GetAll().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); paymentMethodIdStr = paymentMethodId.ToString(); } if (invoice == null || network == null) { return(null); } if (!invoice.Support(paymentMethodId)) { if (!isDefaultCrypto) { 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(); paymentMethodIdStr = paymentMethodId.ToString(); } 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, PaymentMethodId = paymentMethodId.ToString(), PaymentMethodName = GetDisplayName(paymentMethodId, network), CryptoImage = GetImage(paymentMethodId, network), IsLightning = paymentMethodId.PaymentType == PaymentTypes.LightningLike, ServerUrl = HttpContext.Request.GetAbsoluteRoot(), OrderId = invoice.OrderId, InvoiceId = invoice.Id, DefaultLang = storeBlob.DefaultLang ?? "en", HtmlTitle = storeBlob.HtmlTitle ?? "BTCPay Invoice", CustomCSSLink = storeBlob.CustomCSS?.AbsoluteUri, CustomLogoLink = storeBlob.CustomLogo?.AbsoluteUri, 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 ?? "/", 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, 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); }
private async Task UpdatePayoutsAwaitingForPayment(NewOnChainTransactionEvent newTransaction) { try { var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(newTransaction.CryptoCode); Dictionary <string, decimal> destinations; if (newTransaction.NewTransactionEvent.TrackedSource is AddressTrackedSource addressTrackedSource) { destinations = new Dictionary <string, decimal>() { { addressTrackedSource.Address.ToString(), newTransaction.NewTransactionEvent.Outputs.Sum(output => output.Value.GetValue(network)) } }; } else { destinations = newTransaction.NewTransactionEvent.TransactionData.Transaction.Outputs .GroupBy(txout => txout.ScriptPubKey) .ToDictionary( txoutSet => txoutSet.Key.GetDestinationAddress(network.NBitcoinNetwork).ToString(), txoutSet => txoutSet.Sum(txout => txout.Value.ToDecimal(MoneyUnit.BTC))); } var paymentMethodId = new PaymentMethodId(newTransaction.CryptoCode, BitcoinPaymentType.Instance); using var ctx = _dbContextFactory.CreateContext(); var payouts = await ctx.Payouts .Include(o => o.PullPaymentData) .Where(p => p.State == PayoutState.AwaitingPayment) .Where(p => p.PaymentMethodId == paymentMethodId.ToString()) .Where(p => destinations.Keys.Contains(p.Destination)) .ToListAsync(); var payoutByDestination = payouts.ToDictionary(p => p.Destination); foreach (var destination in destinations) { if (!payoutByDestination.TryGetValue(destination.Key, out var payout)) { continue; } var payoutBlob = payout.GetBlob(_jsonSerializerSettings); if (payoutBlob.CryptoAmount is null || // The round up here is not strictly necessary, this is temporary to fix existing payout before we // were properly roundup the crypto amount destination.Value != BTCPayServer.Extensions.RoundUp(payoutBlob.CryptoAmount.Value, network.Divisibility)) { continue; } var proof = ParseProof(payout) as PayoutTransactionOnChainBlob; if (proof is null) { proof = new PayoutTransactionOnChainBlob() { Accounted = !(newTransaction.NewTransactionEvent.TrackedSource is AddressTrackedSource), }; } var txId = newTransaction.NewTransactionEvent.TransactionData.TransactionHash; if (proof.Candidates.Add(txId)) { if (proof.Accounted is true) { payout.State = PayoutState.InProgress; var walletId = new WalletId(payout.PullPaymentData.StoreId, newTransaction.CryptoCode); _eventAggregator.Publish(new UpdateTransactionLabel(walletId, newTransaction.NewTransactionEvent.TransactionData.TransactionHash, UpdateTransactionLabel.PayoutTemplate(payout.Id, payout.PullPaymentDataId, walletId.ToString()))); } if (proof.TransactionId is null) { proof.TransactionId = txId; } SetProofBlob(payout, proof); } } await ctx.SaveChangesAsync(); } catch (Exception ex) { Logs.PayServer.LogWarning(ex, "Error while processing a transaction in the pull payment hosted service"); } }
public static void SetDefaultPaymentId(this StoreData storeData, PaymentMethodId defaultPaymentId) { storeData.DefaultCrypto = defaultPaymentId.ToString(); }
public void SetDefaultPaymentId(PaymentMethodId defaultPaymentId) { DefaultCrypto = defaultPaymentId.ToString(); }