예제 #1
0
        private async Task ProcessDeposits()
        {
            Log.Message(LogLevel.Info, "Processing Deposits..");
            using (var context = DataContextFactory.CreateContext())
            {
                var paymentMethods = await context.PaymentMethod
                                     .Where(x => x.Status == PaymentMethodStatus.Ok && x.Type == PaymentMethodType.Crypto)
                                     .ToListAsync();

                foreach (var paymentMethod in paymentMethods)
                {
                    Log.Message(LogLevel.Info, $"Processing {paymentMethod.Name}");
                    var walletDeposits = await GetWalletDeposits(paymentMethod);

                    if (!walletDeposits.Any())
                    {
                        Log.Message(LogLevel.Info, "No new deposits found.");
                        Log.Message(LogLevel.Info, $"Processing {paymentMethod.Name} complete.");
                        continue;
                    }

                    var minConfirmations = int.Parse(paymentMethod.Data4);
                    Log.Message(LogLevel.Info, $"{walletDeposits.Count()} new deposits found.");
                    var unconfirmedDeposits = await context.PaymentReceipt
                                              .Include(x => x.User)
                                              .Where(x => x.PaymentMethodId == paymentMethod.Id && x.Status == PaymentReceiptStatus.Pending)
                                              .ToListAsync();

                    foreach (var walletDeposit in walletDeposits.OrderBy(x => x.Time))
                    {
                        var exists = unconfirmedDeposits.FirstOrDefault(x => x.Data == walletDeposit.Address && x.Data2 == walletDeposit.Txid);
                        if (exists != null)
                        {
                            int confirmations = int.Parse(exists.Data3);
                            if (confirmations == walletDeposit.Confirmations)
                            {
                                continue;
                            }

                            Log.Message(LogLevel.Info, $"Updating deposit #{exists.Id} confirmations.");
                            exists.Data3  = Math.Min(walletDeposit.Confirmations, minConfirmations).ToString();
                            exists.Status = confirmations >= minConfirmations
                                                                ? PaymentReceiptStatus.Complete
                                                                : PaymentReceiptStatus.Pending;
                            await context.SaveChangesAsync();

                            if (exists.Status == PaymentReceiptStatus.Complete)
                            {
                                Log.Message(LogLevel.Info, $"Deposit #{exists.Id} confirmed, auditing user points...");
                                await context.Database.Connection.ExecuteAsync(StoredProcedure.User_AuditPoints, new { UserId = exists.UserId }, commandType : System.Data.CommandType.StoredProcedure);

                                Log.Message(LogLevel.Info, $"Deposit #{exists.Id} audit complete.");
                                paymentMethod.Data5 = walletDeposit.Blockhash;
                            }
                        }
                        else
                        {
                            var paymentUserMethod = await context.PaymentUserMethod.FirstOrDefaultAsync(x => x.PaymentMethodId == paymentMethod.Id && x.Data == walletDeposit.Address);

                            if (paymentUserMethod == null)
                            {
                                continue;
                            }

                            if (await context.PaymentReceipt.AnyAsync(x => x.PaymentUserMethodId == paymentUserMethod.Id && x.Data == walletDeposit.Address && x.Data2 == walletDeposit.Txid))
                            {
                                continue;
                            }

                            var points     = (int)(walletDeposit.Amount / paymentMethod.Rate);
                            var newDeposit = new Entity.PaymentReceipt
                            {
                                UserId              = paymentUserMethod.UserId,
                                Data                = paymentUserMethod.Data,
                                Data2               = walletDeposit.Txid,
                                Data3               = Math.Min(walletDeposit.Confirmations, minConfirmations).ToString(),
                                Data4               = walletDeposit.Blockhash,
                                Amount              = walletDeposit.Amount,
                                PaymentMethodId     = paymentMethod.Id,
                                PaymentUserMethodId = paymentUserMethod.Id,
                                Rate                = paymentMethod.Rate,
                                Status              = PaymentReceiptStatus.Pending,
                                Updated             = DateTime.UtcNow,
                                Timestamp           = DateTime.UtcNow,
                                Points              = points
                            };
                            context.PaymentReceipt.Add(newDeposit);
                            await context.SaveChangesAsync();

                            Log.Message(LogLevel.Info, $"Added new deposit, TxId: {walletDeposit.Txid}.");
                        }
                    }

                    Log.Message(LogLevel.Info, $"Processing {paymentMethod.Name} complete");
                }
            }
            Log.Message(LogLevel.Info, "Processing Deposits complete.");
        }
예제 #2
0
        private async Task ProcessWithdrawals()
        {
            Log.Message(LogLevel.Info, "Processing Withdrawals..");
            using (var context = DataContextFactory.CreateContext())
            {
                var internalAddresses = await context.PaymentUserMethod
                                        .Include(x => x.PaymentMethod)
                                        .ToListAsync();

                var pendingPrizes = await context.Database.Connection.QueryAsync <PrizePayment>(StoredProcedure.WalletService_GetWithdrawals, commandType : System.Data.CommandType.StoredProcedure);

                Log.Message(LogLevel.Info, $"{pendingPrizes.Count()} withdrawals found to process.");
                foreach (var prize in pendingPrizes)
                {
                    Log.Message(LogLevel.Info, $"Processing prize Id: {prize.PrizeId}, Symbol: {prize.Symbol}, Amount: {prize.Amount}, Destination: {prize.Destination}");

                    var userPaymentMethod = internalAddresses.FirstOrDefault(x => x.Data.Equals(prize.Destination, StringComparison.OrdinalIgnoreCase));
                    if (userPaymentMethod != null)
                    {
                        Log.Message(LogLevel.Debug, "INTERNAL CLAIM");
                        var transactionId    = $"Internal_Prize_Claim: #{prize.PrizeId}";
                        var cryptoAmount     = decimal.Parse(prize.Amount);
                        var minConfirmations = int.Parse(userPaymentMethod.PaymentMethod.Data4);
                        var points           = (int)(cryptoAmount / userPaymentMethod.PaymentMethod.Rate);
                        var newDeposit       = new Entity.PaymentReceipt
                        {
                            UserId              = userPaymentMethod.UserId,
                            Data                = userPaymentMethod.Data,
                            Data2               = transactionId,
                            Data3               = userPaymentMethod.PaymentMethod.Data4,               // minconfirms
                            Data4               = default(string),
                            Amount              = cryptoAmount,
                            PaymentMethodId     = userPaymentMethod.PaymentMethodId,
                            PaymentUserMethodId = userPaymentMethod.Id,
                            Rate                = userPaymentMethod.PaymentMethod.Rate,
                            Status              = PaymentReceiptStatus.Complete,
                            Updated             = DateTime.UtcNow,
                            Timestamp           = DateTime.UtcNow,
                            Points              = points
                        };
                        context.PaymentReceipt.Add(newDeposit);
                        await context.SaveChangesAsync();

                        await context.Database.Connection.QueryAsync(StoredProcedure.WalletService_UpdateWithdraw, new
                        {
                            PrizeId       = prize.PrizeId,
                            TransactionId = transactionId
                        }, commandType : System.Data.CommandType.StoredProcedure);

                        await context.Database.Connection.ExecuteAsync(StoredProcedure.User_AuditPoints, new { UserId = userPaymentMethod.UserId }, commandType : System.Data.CommandType.StoredProcedure);
                    }
                    else
                    {
                        Log.Message(LogLevel.Debug, "EXTERNAL CLAIM");
                        var transactionId = await SendTransaction(prize);

                        if (string.IsNullOrEmpty(transactionId))
                        {
                            continue;
                        }

                        Log.Message(LogLevel.Info, $"Transaction sent, TrasnactionId: {transactionId}");
                        await context.Database.Connection.QueryAsync(StoredProcedure.WalletService_UpdateWithdraw, new
                        {
                            PrizeId       = prize.PrizeId,
                            TransactionId = transactionId
                        }, commandType : System.Data.CommandType.StoredProcedure);
                    }

                    Log.Message(LogLevel.Info, $"Processing prize complete.");
                }
            }
            Log.Message(LogLevel.Info, "Processing Withdrawals complete.");
        }