Пример #1
0
        public RedPocket Push(UserAccount userAccount, Guid accountId, int cryptoId, decimal amount, int count, string userPIN, string pin, string message = "")
        {
            if (userAccount.L1VerifyStatus != Entities.Enums.VerifyStatus.Certified)
            {
                throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied);
            }

            if (amount <= 0 || cryptoId <= 0)
            {
                throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat);
            }
            if (count <= 0)
            {
                throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat);
            }

            if (count > MaxCount)
            {
                throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxCount, MaxCount));
            }

            if (!string.IsNullOrWhiteSpace(message) && message.Length > 46)
            {
                throw new CommonException(Argument_Error, MessageResources.RedPocket_MaxMessage);
            }

            SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, accountId.ToString(), userPIN, pin);

            var cryptoDAC = new CryptocurrencyDAC();
            var priceDAC  = new PriceInfoDAC();

            var crypto = cryptoDAC.GetById(cryptoId);

            if (crypto == null)
            {
                throw new SystemErrorException();
            }

            if (!crypto.Status.HasFlag(Foundation.Entities.Enum.CryptoStatus.RedPocket) || crypto.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }

            var min = crypto.DecimalPlace == 8 ? 0.00000001M : crypto.DecimalPlace == 6 ? 0.000001M : 0.00000001M;

            var minAmount = count * min;

            if (amount < minAmount)
            {
                throw new CommonException(Push_MinAmount, string.Format(MessageResources.RedPocket_MinAmount, minAmount, crypto.Code));
            }

            var price = priceDAC.GetPriceByName("USD", crypto.Code);

            var max       = crypto.DecimalPlace == 8 ? 999999999.999999999M : crypto.DecimalPlace == 6 ? 999999999.999999M : 999999999.999999999M;
            var maxAmount = Math.Round(MaxAmount / price, crypto.DecimalPlace);

            if (count > 1)
            {
                maxAmount = Math.Round(MaxAmount * count / price, crypto.DecimalPlace);
            }

            if (amount >= max || Math.Round(amount, crypto.DecimalPlace) > maxAmount)
            {
                throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxAmount, maxAmount, crypto.Code));
            }

            var userWalletDAC          = new UserWalletDAC();
            var redPocketDAC           = new RedPocketDAC();
            var userWalletStatementDAC = new UserWalletStatementDAC();
            var userTransactionDAC     = new UserTransactionDAC();

            var wallet = userWalletDAC.GetByAccountId(accountId, cryptoId);

            if (wallet == null || wallet.Balance < amount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }

            var fiatAmount = price * amount;

            using (var scope = new TransactionScope())
            {
                try
                {
                    var redPocket = new RedPocket
                    {
                        AccountId      = accountId,
                        Status         = RedPocketStatus.Actived,
                        PassCode       = GeneralPassCode(),
                        CryptoCode     = crypto.Code,
                        Amount         = amount,
                        Balance        = amount,
                        Count          = count,
                        RemainCount    = count,
                        Message        = message,
                        Timestamp      = DateTime.UtcNow,
                        ExpirationDate = DateTime.UtcNow.AddMinutes(_expried),
                        CryptoId       = cryptoId,
                        OrderNo        = IdentityHelper.OrderNo(),
                        FiatAmount     = fiatAmount <= 0 ? 0M : Math.Round(fiatAmount, 8)
                    };

                    var redPocketId = redPocketDAC.Insert(redPocket);
                    userTransactionDAC.Insert(new UserTransaction
                    {
                        Id         = Guid.NewGuid(),
                        AccountId  = accountId,
                        CryptoId   = redPocket.CryptoId,
                        CryptoCode = redPocket.CryptoCode,
                        Type       = UserTransactionType.PushRedPocket,
                        DetailId   = redPocketId.ToString(),
                        Status     = (byte)redPocket.Status,
                        Timestamp  = redPocket.Timestamp,
                        Amount     = redPocket.Amount,
                        OrderNo    = redPocket.OrderNo
                    });

                    userWalletDAC.Decrease(wallet.Id, amount);
                    userWalletStatementDAC.Insert(new UserWalletStatement
                    {
                        WalletId      = wallet.Id,
                        Balance       = wallet.Balance - amount,
                        Amount        = 0 - amount,
                        FrozenAmount  = 0,
                        FrozenBalance = wallet.FrozenBalance,
                        Action        = "Push Red Pocket",
                        Timestamp     = DateTime.UtcNow
                    });

                    QueueHelper.DelaySender.Send("FiiiPay_RedPocket", redPocketId);

                    scope.Complete();

                    return(redPocket);
                }
                catch (Exception ex)
                {
                    _log.Error(ex);

                    throw new SystemErrorException();
                }
            }
        }
Пример #2
0
        private static decimal GetMarketPrice(string currency, string cryptoName)
        {
            var dac = new PriceInfoDAC();

            return(dac.GetPriceByName(currency, cryptoName));
        }
Пример #3
0
        public RedPocketDetailOM Receive(UserAccount userAccount, string passcode, bool isZH = false)
        {
            if (userAccount == null)
            {
                throw new SystemErrorException();
            }

            if (string.IsNullOrWhiteSpace(passcode))
            {
                throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat);
            }

            if (userAccount.L1VerifyStatus != Entities.Enums.VerifyStatus.Certified)
            {
                throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied);
            }

            var count = RedisHelper.StringGet(LockDbIndex, string.Format(KeyFormat, userAccount.Id));

            if (!string.IsNullOrWhiteSpace(count) && int.Parse(count) >= 10)
            {
                var ttl = RedisHelper.KeyTimeToLive(LockDbIndex, string.Format(KeyFormat, userAccount.Id));
                if (ttl != null)
                {
                    var message = "";
                    var t       = "";
                    try
                    {
                        t       = TimeConvert(ttl.Value, isZH);
                        message = string.Format(MessageResources.RedPocket_PassCodeErrorMaxCount, t);
                    }
                    catch (Exception exception)
                    {
                        _log.Error(exception.Message + "    " + MessageResources.RedPocket_PassCodeErrorMaxCount + "    " + t);
                    }

                    throw new CommonException(MaxError, message);
                }
            }

            var redPocketDAC = new RedPocketDAC();

            var redPocket = redPocketDAC.GetByPassCode(passcode);

            if (redPocket == null)
            {
                var errorCount = ErrorCount(userAccount.Id, count, isZH);
                throw new CommonException(PassCodeError, string.Format(MessageResources.RedPocket_PassCodeError, errorCount, 10 - errorCount));
            }

            if (redPocket.ExpirationDate < DateTime.UtcNow)
            {
                var errorCount = ErrorCount(userAccount.Id, count, isZH);
                throw new CommonException(PassCodeExpired, MessageResources.RedPocket_ReceiveExpired + Environment.NewLine + string.Format(MessageResources.RedPocket_PassCodeError, errorCount, 10 - errorCount));
            }

            var crypto = new CryptocurrencyDAC().GetByCode(redPocket.CryptoCode);

            if (!crypto.Status.HasFlag(Foundation.Entities.Enum.CryptoStatus.RedPocket) || crypto.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }

            var om = new RedPocketDetailOM();
            var redPocketReceiveDAC = new RedPocketReceiverDAC();

            var hasReceive = redPocketReceiveDAC.HasReceive(userAccount.Id, redPocket.Id);

            if (redPocket.Status == RedPocketStatus.Actived && hasReceive == null)
            {
                var userWalletDAC          = new UserWalletDAC();
                var userWalletStatementDAC = new UserWalletStatementDAC();
                var uwComponent            = new UserWalletComponent();
                var userTransactionDAC     = new UserTransactionDAC();

                var wallet = userWalletDAC.GetByCryptoCode(userAccount.Id, redPocket.CryptoCode);
                if (wallet == null)
                {
                    wallet = uwComponent.GenerateWallet(userAccount.Id, redPocket.CryptoCode);
                }

                var min = crypto.DecimalPlace == 8 ? 0.00000001M : crypto.DecimalPlace == 6 ? 0.000001M : 0.00000001M;
                var n   = crypto.DecimalPlace == 8 ? 100000000 : crypto.DecimalPlace == 6 ? 1000000 : 100000000;

                var amount = GetRandomMoney(redPocket, min, n);

                var priceDAC   = new PriceInfoDAC();
                var price      = priceDAC.GetPriceByName("USD", crypto.Code);
                var fiatAmount = price * amount;
                using (var scope = new TransactionScope())
                {
                    try
                    {
                        var redPocketReceiver = new RedPocketReceiver
                        {
                            PocketId      = redPocket.Id,
                            AccountId     = userAccount.Id,
                            SendAccountId = redPocket.AccountId,
                            CryptoCode    = redPocket.CryptoCode,
                            Amount        = amount,
                            Timestamp     = DateTime.UtcNow,
                            IsBestLuck    = redPocket.Count == 1,
                            OrderNo       = IdentityHelper.OrderNo(),
                            FiatAmount    = fiatAmount <= 0 ? 0M : Math.Round(fiatAmount, 8)
                        };
                        var id = redPocketReceiveDAC.Insert(redPocketReceiver);

                        userTransactionDAC.Insert(new UserTransaction
                        {
                            Id         = Guid.NewGuid(),
                            AccountId  = redPocketReceiver.AccountId,
                            CryptoId   = redPocket.CryptoId,
                            CryptoCode = redPocket.CryptoCode,
                            Type       = UserTransactionType.ReceiveRedPocket,
                            DetailId   = id.ToString(),
                            Status     = (byte)redPocket.Status,
                            Timestamp  = redPocketReceiver.Timestamp,
                            Amount     = redPocketReceiver.Amount,
                            OrderNo    = redPocketReceiver.OrderNo
                        });

                        userWalletDAC.Increase(wallet.Id, amount);
                        userWalletStatementDAC.Insert(new UserWalletStatement
                        {
                            WalletId      = wallet.Id,
                            Balance       = wallet.Balance + amount,
                            Amount        = amount,
                            FrozenAmount  = 0,
                            FrozenBalance = wallet.FrozenBalance,
                            Action        = "Receive Red Pocket",
                            Timestamp     = DateTime.UtcNow
                        });

                        redPocketDAC.UpdateRemain(redPocket.Id, amount);

                        if (redPocket.RemainCount == 0)
                        {
                            redPocketDAC.UpdateStatus(redPocket.Id, RedPocketStatus.Complate);
                            userTransactionDAC.UpdateStatus(UserTransactionType.PushRedPocket, redPocket.Id.ToString(), redPocket.AccountId, (byte)RedPocketStatus.Complate);

                            if (redPocket.Count > 1)
                            {
                                redPocketReceiveDAC.UpdateBestLuck(redPocket.Id);
                            }
                        }

                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex);
                        throw new CommonException();
                    }
                }
                om.SelfAmount      = amount.ToString();
                om.ReceiveStatus   = ReceiveStatusEnum.Receive;
                om.HasExpried      = false;
                redPocket.Balance -= amount;
            }
            else
            {
                if (hasReceive != null)
                {
                    om.ReceiveStatus = ReceiveStatusEnum.HasReceive;
                    om.SelfAmount    = hasReceive.Amount.ToString();
                }
                else
                {
                    om.ReceiveStatus = ReceiveStatusEnum.None;
                    om.SelfAmount    = string.Empty;
                }
            }

            var account = new UserAccountComponent().GetById(redPocket.AccountId);

            om.Message        = redPocket.Message;
            om.SnederNickname = account.Nickname;

            om.TotalAmount   = redPocket.Amount.ToString();
            om.TotalCount    = redPocket.Count;
            om.CryptoCode    = redPocket.CryptoCode;
            om.ReceiveAmount = (redPocket.Amount - redPocket.Balance).ToString();
            om.ReceiveCount  = redPocket.Count - redPocket.RemainCount;
            om.Id            = redPocket.Id;
            om.HasExpried    = redPocket.ExpirationDate < DateTime.UtcNow;
            om.HasSelfSned   = redPocket.AccountId == userAccount.Id;

            return(om);
        }