public void Refund(long id)
        {
            var redPocket = _redPocketDac.GetById(id);

            if (redPocket == null)
            {
                _log.Error($"Red pocket is not found. {id}");
                return;
            }

            if (redPocket.RemainCount > 0)
            {
                var userWalletDAC          = new UserWalletDAC();
                var userWalletStatementDAC = new UserWalletStatementDAC();
                var userTransactionDAC     = new UserTransactionDAC();

                var wallet = userWalletDAC.GetByAccountId(redPocket.AccountId, redPocket.CryptoId);
                if (wallet == null)
                {
                    _log.Error($"Wallet exception. {redPocket.AccountId} RedPocketId={id}");
                    return;
                }

                using (var scope = new TransactionScope())
                {
                    userWalletDAC.Increase(wallet.Id, redPocket.Balance);
                    userWalletStatementDAC.Insert(new UserWalletStatement
                    {
                        WalletId      = wallet.Id,
                        Balance       = wallet.Balance + redPocket.Balance,
                        Amount        = redPocket.Balance,
                        FrozenAmount  = 0,
                        FrozenBalance = wallet.FrozenBalance,
                        Action        = "Refund Red Pocket",
                        Timestamp     = DateTime.UtcNow
                    });

                    _refundDac.Insert(new RedPocketRefund
                    {
                        Id        = redPocket.Id,
                        Amount    = redPocket.Balance,
                        OrderNo   = _identity.StringId(),
                        Timestamp = DateTime.UtcNow
                    });

                    _redPocketDac.UpdateStatus(redPocket.Id, redPocket.RemainCount == redPocket.Count ? RedPocketStatus.FullRefund : RedPocketStatus.Refund);

                    userTransactionDAC.UpdateStatus(UserTransactionType.PushRedPocket, redPocket.Id.ToString(), redPocket.AccountId, (byte)RedPocketStatus.Refund);

                    scope.Complete();
                }
            }
        }
        /// <summary>
        /// 支付网关发起退款
        /// </summary>
        /// <param name="tradeId"></param>
        public void GatewayRefund(string tradeId)
        {
            //获取订单详情
            var orderDetail = new GatewayOrderDAC().GetByTradeNo(tradeId);

            if (orderDetail == null)
            {
                throw new Exception("Have no record of this order:tradeId=" + tradeId);
            }
            if (orderDetail.Status != GatewayOrderStatus.Completed)
            {
                throw new Exception($"The status of this order {tradeId} is not completed");
            }

            var uwComponent = new UserWalletComponent();
            var userWallet  = uwComponent.GetUserWallet(orderDetail.UserAccountId.Value, orderDetail.CryptoId);
            var goDAC       = new GatewayOrderDAC();
            var rgoDAC      = new GatewayRefundOrderDAC();
            var uwDAC       = new UserWalletDAC();
            var uwsDAC      = new UserWalletStatementDAC();

            using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                orderDetail.Status = GatewayOrderStatus.Refunded;
                goDAC.Update(orderDetail);

                uwDAC.Increase(userWallet.Id, orderDetail.ActualCryptoAmount);
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = userWallet.Id,
                    Action        = UserWalletStatementAction.TansferIn,
                    Amount        = orderDetail.ActualCryptoAmount,
                    Balance       = userWallet.Balance + orderDetail.ActualCryptoAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = userWallet.FrozenBalance,
                    Timestamp     = DateTime.UtcNow
                });
                rgoDAC.Insert(new GatewayRefundOrder
                {
                    Id        = Guid.NewGuid(),
                    OrderId   = orderDetail.Id,
                    Timestamp = DateTime.UtcNow,
                    Status    = RefundStatus.Completed
                });

                scope.Complete();
            }
        }
Example #3
0
        public SaveResult Reward(Guid id, int userId, string userName)
        {
            var settingCollection = new MasterSettingDAC().SelectByGroup("InviteReward");
            var inviteMoney       = decimal.Parse(settingCollection.Where(item => item.Name == "Invite_Reward_Amount").Select(item => item.Value).FirstOrDefault());

            var uwComponent = new UserWalletBLL();
            var uwsDAC      = new UserWalletStatementDAC();
            var uwDAC       = new UserWalletDAC();

            var cryptoId     = new CryptocurrencyDAC().GetByCode("FIII").Id;
            var inviteWallet = uwComponent.GetUserWallet(id, cryptoId);

            if (inviteWallet == null)
            {
                inviteWallet = uwComponent.GenerateWallet(id, cryptoId);
            }

            var adoResult = FiiiPayDB.DB.Ado.UseTran(() =>
            {
                //解冻奖励
                uwDAC.Increase(inviteWallet.Id, inviteMoney);
                //插入奖励流水
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId  = inviteWallet.Id,
                    Action    = UserWalletStatementAction.Invite,
                    Amount    = inviteMoney,
                    Balance   = inviteWallet.Balance + inviteMoney,
                    Timestamp = DateTime.UtcNow,
                    Remark    = "BO Reward"
                });
            });
            ActionLog actionLog = new ActionLog();

            actionLog.IPAddress  = GetClientIPAddress();
            actionLog.AccountId  = userId;
            actionLog.CreateTime = DateTime.UtcNow;
            actionLog.ModuleCode = typeof(UserManageBLL).FullName + ".Reward";
            actionLog.Username   = userName;
            actionLog.LogContent = "Reward " + id + " Fiii:" + inviteMoney;
            new ActionLogBLL().Create(actionLog);


            return(new SaveResult(true, "Save Success"));
        }
Example #4
0
        public BillerPayOM Pay(UserAccount account, BillerPayIM im, ref int errorCode)
        {
            var coin = new CryptocurrencyDAC().GetById(im.CryptoId);

            if (!coin.Status.HasFlag(CryptoStatus.Biller) || coin.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }
            var result = PrePay(new BillerPrePayIM()
            {
                CountryId = im.CountryId, CryptoAmount = im.CryptoAmount, CryptoCode = im.CryptoCode,
                CryptoId  = im.CryptoId, FiatAmount = im.FiatAmount, FiatCurrency = im.FiatCurrency
            }).Status;

            if (result != 0)
            {
                errorCode = 10400 + result;
                return(null);
            }

            new SecurityComponent().VerifyPin(account, im.Pin);
            var cryptoCurrency = new CryptocurrencyDAC().GetById(im.CryptoId);

            if (cryptoCurrency?.Id == null)
            {
                throw new CommonException(ReasonCode.CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency");
            }
            var uwComponent = new UserWalletComponent();
            var userWallet  = uwComponent.GetUserWallet(account.Id, im.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            if (userWallet.Balance < im.CryptoAmount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            var uwDAC       = new UserWalletDAC();
            var uwsDAC      = new UserWalletStatementDAC();
            var boDAC       = new BillerOrderDAC();
            var billerOrder = new BillerOrder()
            {
                Id           = Guid.NewGuid(),
                BillerCode   = im.BillerCode,
                CryptoAmount = im.CryptoAmount,
                CryptoCode   = im.CryptoCode,
                CryptoId     = im.CryptoId,
                Discount     = im.CryptoCode.Equals("Fiii", StringComparison.InvariantCultureIgnoreCase)
                    ? decimal.Parse(new MasterSettingDAC().SelectByGroup("BillerMaxAmount").First(item =>
                                                                                                  item.Name.Equals("DiscountRate", StringComparison.CurrentCultureIgnoreCase)).Value)
                    : 0,
                ExchangeRate    = im.ExchangeRate,
                FiatAmount      = im.FiatAmount,
                FiatCurrency    = im.FiatCurrency,
                ReferenceNumber = im.ReferenceNumber,
                Tag             = im.Tag,
                Status          = BillerOrderStatus.Pending,
                Timestamp       = DateTime.UtcNow,
                AccountId       = account.Id,
                OrderNo         = IdentityHelper.OrderNo(),
                PayTime         = DateTime.UtcNow,
                CountryId       = im.CountryId
            };
            var address = new BillerAddressDAC().GetAllAddresses(account.Id).FirstOrDefault(item =>
                                                                                            item.BillerCode == im.BillerCode && im.ReferenceNumber == item.ReferenceNumber);

            billerOrder.Tag = address?.Tag;
            using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                uwDAC.Decrease(userWallet.Id, billerOrder.CryptoAmount);
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = userWallet.Id,
                    Action        = UserWalletStatementAction.Consume,
                    Amount        = -billerOrder.CryptoAmount,
                    Balance       = userWallet.Balance - billerOrder.CryptoAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = userWallet.FrozenBalance,
                    Timestamp     = DateTime.UtcNow
                });

                boDAC.Insert(billerOrder);
                new UserTransactionDAC().Insert(new UserTransaction
                {
                    Id         = Guid.NewGuid(),
                    AccountId  = billerOrder.AccountId,
                    CryptoId   = cryptoCurrency.Id,
                    CryptoCode = cryptoCurrency.Code,
                    Type       = UserTransactionType.BillOrder,
                    DetailId   = billerOrder.Id.ToString(),
                    Status     = (byte)billerOrder.Status,
                    Timestamp  = billerOrder.Timestamp,
                    Amount     = billerOrder.CryptoAmount,
                    OrderNo    = billerOrder.OrderNo
                });
                scope.Complete();
            }

            return(new BillerPayOM()
            {
                CryptoAmount = billerOrder.CryptoAmount.ToString(), OrderNo = billerOrder.OrderNo,
                CryptoCode = billerOrder.CryptoCode, OrderId = billerOrder.Id,
                Timestamp = billerOrder.PayTime.ToUnixTime().ToString(),
                SaveAddress = address != null
            });
        }
        private GatewayOrder ExcutePay(GatewayOrderOM orderDetail, Guid id)
        {
            var cryptoCurrency = new CryptocurrencyDAC().GetByCode(orderDetail.Crypto);

            if (cryptoCurrency == null || cryptoCurrency?.Id == null)
            {
                throw new CommonException(CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency");
            }
            //var uwComponent = new UserWalletComponent();
            var userWallet = new UserWalletDAC().GetUserWallet(orderDetail.UserAccountId.Value, cryptoCurrency.Id);

            if (userWallet.Balance < orderDetail.ActualCryptoAmount)
            {
                throw new CommonException(INSUFFICIENT_BALANCE, Resources.余额不足);
            }
            var uwDAC  = new UserWalletDAC();
            var uwsDAC = new UserWalletStatementDAC();
            var goDAC  = new GatewayOrderDAC();

            bool needAddOrder = true;
            var  gatewayOrder = goDAC.GetByTradeNo(orderDetail.Id.ToString());

            if (gatewayOrder != null)
            {
                if (gatewayOrder.Status != GatewayOrderStatus.Pending)
                {
                    throw new CommonException(ORDER_HAD_COMPLETE, Resources.订单已完成或者已退款);
                }
                needAddOrder = false;
            }
            else
            {
                gatewayOrder = new Entities.GatewayOrder()
                {
                    OrderNo            = CreateOrderno(),
                    TradeNo            = orderDetail.Id.ToString(),
                    Id                 = id,
                    CryptoId           = cryptoCurrency.Id,
                    MerchantAccountId  = orderDetail.MerchantAccountId,
                    FiatAmount         = orderDetail.FiatAmount,
                    MerchantName       = orderDetail.MerchantName,
                    UserAccountId      = orderDetail.UserAccountId,
                    CryptoAmount       = orderDetail.CryptoAmount,
                    ActualCryptoAmount = orderDetail.ActualCryptoAmount,
                    FiatCurrency       = orderDetail.FiatCurrency,
                    Markup             = orderDetail.MarkupRate,
                    ActualFiatAmount   = orderDetail.ActualFiatAmount,
                    Status             = GatewayOrderStatus.Completed,
                    ExchangeRate       = orderDetail.ExchangeRate,
                    ExpiredTime        = orderDetail.ExpiredTime,
                    TransactionFee     = orderDetail.TransactionFee,
                    Timestamp          = DateTime.UtcNow,
                    PaymentTime        = DateTime.UtcNow,
                    Remark             = orderDetail.Remark
                };
            }

            using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                if (needAddOrder)
                {
                    goDAC.Insert(gatewayOrder);
                }
                uwDAC.Decrease(userWallet.Id, orderDetail.ActualCryptoAmount);
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = userWallet.Id,
                    Action        = UserWalletStatementAction.TansferOut,
                    Amount        = -orderDetail.ActualCryptoAmount,
                    Balance       = userWallet.Balance - orderDetail.ActualCryptoAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = userWallet.FrozenBalance,
                    Timestamp     = DateTime.UtcNow
                });

                scope.Complete();
            }

            return(gatewayOrder);
        }
Example #6
0
        //private readonly Dictionary<string, int> _notificationErrorCount = new Dictionary<string, int>();

        public void Payment(string message)
        {
            var orderModel = JsonConvert.DeserializeObject <MallPaymentOrder>(message);

            var userWalletDac      = new UserWalletDAC();
            var walletStatementDac = new UserWalletStatementDAC();
            var gatewayOrderDac    = new GatewayOrderDAC();
            var mallDac            = new MallPaymentOrderDAC();
            var cryptoDac          = new CryptocurrencyDAC();

            var extsis = gatewayOrderDac.GetByOrderNo(orderModel.OrderId);

            if (extsis != null && extsis.Status == GatewayOrderStatus.Completed)
            {
                _log.Info("Order message " + message + " hased Payment.");
                return;
            }

            var cryptoFiii = cryptoDac.GetByCode("FIII");
            var fiiiWallet = userWalletDac.GetByAccountId(orderModel.UserAccountId, cryptoFiii.Id);

            if (fiiiWallet.Balance < orderModel.CryptoAmount)
            {
                _log.ErrorFormat("message {0}, Insufficient balance", message);
            }

            try
            {
                var fiiiPrice      = GetMarketPrice("USD", "FIII");
                var fiiiFiatAmount = Math.Round(orderModel.CryptoAmount * fiiiPrice, 2);

                var trdeNo = NumberGenerator.GenerateUnixOrderNo();
                var id     = Guid.NewGuid();
                using (var scope = new TransactionScope())
                {
                    userWalletDac.Decrease(fiiiWallet.Id, orderModel.CryptoAmount);
                    walletStatementDac.Insert(new UserWalletStatement
                    {
                        WalletId      = fiiiWallet.Id,
                        Action        = UserWalletStatementAction.Consume,
                        Amount        = -orderModel.CryptoAmount,
                        Balance       = fiiiWallet.Balance - orderModel.CryptoAmount,
                        FrozenAmount  = 0,
                        FrozenBalance = fiiiWallet.FrozenBalance,
                        Timestamp     = DateTime.UtcNow
                    });

                    var gatewayFiiiOrder = new GatewayOrder
                    {
                        Id                 = id,
                        OrderNo            = orderModel.OrderId,
                        MerchantAccountId  = Guid.Empty,
                        MerchantName       = "FiiiShop",
                        CryptoId           = cryptoFiii.Id,
                        CryptoCode         = "FIII",
                        FiatAmount         = fiiiFiatAmount,
                        FiatCurrency       = "USD",
                        Status             = GatewayOrderStatus.Completed,
                        ExpiredTime        = DateTime.UtcNow.AddMinutes(30),
                        Markup             = 0M,
                        ExchangeRate       = fiiiPrice,
                        PaymentTime        = DateTime.UtcNow,
                        Timestamp          = DateTime.UtcNow,
                        UserAccountId      = orderModel.UserAccountId,
                        ActualCryptoAmount = orderModel.CryptoAmount,
                        ActualFiatAmount   = fiiiFiatAmount,
                        CryptoAmount       = orderModel.CryptoAmount,
                        TransactionFee     = 0,
                        Remark             = null,
                        TradeNo            = trdeNo
                    };
                    gatewayOrderDac.Insert(gatewayFiiiOrder);

                    mallDac.UpdateStatus(orderModel.Id, (byte)OrderStatus.Completed);
                    mallDac.UpdateTradeNo(orderModel.Id, trdeNo);

                    scope.Complete();
                }

                RabbitMQSender.SendMessage("ShopPayment", id);
                SendNotificationMessage(TradeType.Payment, orderModel.Id, orderModel.OrderId, trdeNo, "success");
            }
            catch (Exception exception)
            {
                //SendNotificationMessage(TradeType.Payment, orderModel.Id, orderModel.OrderId, string.Empty, "error");
                _log.Error("Payment error, exception : " + exception.Message);
            }
        }
Example #7
0
        public void Refund(string message)
        {
            var orderModel = JsonConvert.DeserializeObject <MallPaymentOrder>(message);

            var userWalletDac      = new UserWalletDAC();
            var walletStatementDac = new UserWalletStatementDAC();
            var gatewayOrderDac    = new GatewayOrderDAC();
            var mallDac            = new MallPaymentOrderDAC();
            var refundDac          = new GatewayRefundOrderDAC();

            var gatewayOrder = gatewayOrderDac.GetByTradeNo(orderModel.TradeNo);

            if (gatewayOrder.Status == GatewayOrderStatus.Pending)
            {
                _log.Error("Order message " + message + " not payment.");
                return;
            }
            if (gatewayOrder.Status == GatewayOrderStatus.Refunded)
            {
                _log.Info("Order message " + message + " has refund.");
                return;
            }

            var fiiiWallet = userWalletDac.GetByCryptoCode(orderModel.UserAccountId, "FIII");

            try
            {
                var id            = Guid.NewGuid();
                var refundTradeNo = NumberGenerator.GenerateUnixOrderNo();
                using (var scope = new TransactionScope())
                {
                    mallDac.UpdateStatus(orderModel.Id, (byte)OrderStatus.Refunded);
                    mallDac.UpdateRefundTradeNo(orderModel.Id, refundTradeNo);

                    gatewayOrderDac.UpdateStatus(gatewayOrder.Id, (byte)OrderStatus.Refunded);

                    userWalletDac.Increase(fiiiWallet.Id, gatewayOrder.CryptoAmount);
                    walletStatementDac.Insert(new UserWalletStatement
                    {
                        WalletId      = fiiiWallet.Id,
                        Action        = UserWalletStatementAction.Refund,
                        Amount        = orderModel.CryptoAmount,
                        Balance       = fiiiWallet.Balance + gatewayOrder.CryptoAmount,
                        FrozenAmount  = 0,
                        FrozenBalance = fiiiWallet.FrozenBalance,
                        Timestamp     = DateTime.UtcNow
                    });

                    refundDac.Insert(new GatewayRefundOrder
                    {
                        Id            = id,
                        OrderId       = gatewayOrder.Id,
                        Remark        = "",
                        Status        = RefundStatus.Completed,
                        Timestamp     = DateTime.UtcNow,
                        RefundTradeNo = refundTradeNo
                    });

                    scope.Complete();
                }

                RabbitMQSender.SendMessage("ShopPaymentRefund", id);
                SendNotificationMessage(TradeType.Refund, orderModel.Id, orderModel.OrderId, refundTradeNo, "success");
            }
            catch (Exception exception)
            {
                _log.Error("Refund error, exception : " + exception.Message);

                //SendNotificationMessage(TradeType.Refund, orderModel.Id, orderModel.OrderId, string.Empty, "error");
            }
        }
Example #8
0
        /// <summary>
        /// 插入记录
        /// </summary>
        /// <param name="inviteCode">邀请码</param>
        /// <param name="accoundId">被邀请人id</param>
        /// /// <param name="type">1:fiiipay 2:fiiipos</param>
        public void InsertRecord(InviteRecordIM im)
        {
            //判断是fiiipos还是fiiipay

            //1 插入数据 invite profit两个表 邀请双方都支持插入数据 钱包 流水进行更新
            // 判断当前邀请人数到达五十 进行推送。。。。。。。。。。。。

            //2 插入数据 invite
            if (!(im.Type == (int)SystemPlatform.FiiiPay || im.Type == (int)SystemPlatform.FiiiPOS))
            {
                throw new ArgumentException("只支持fiiipay和fiiipos邀请");
            }
            var userAccountDAC    = new UserAccountDAC();
            var account           = userAccountDAC.GetByInvitationCode(im.InvitationCode);
            var settingCollection = new MasterSettingDAC().SelectByGroup("InviteReward");
            var cryptoCurrencty   = new CryptocurrencyDAC().GetByCode("FIII");
            var cryptoId          = cryptoCurrencty.Id;

            if (im.Type == (int)SystemPlatform.FiiiPay)
            {
                var iDAC        = new InviteRecordDAC();
                var pfDAC       = new ProfitDetailDAC();
                var uwComponent = new UserWalletComponent();

                var uwDAC  = new UserWalletDAC();
                var uwsDAC = new UserWalletStatementDAC();
                var utDAC  = new UserTransactionDAC();

                var inviteMoney  = decimal.Parse(settingCollection.Where(item => item.Name == "Invite_Reward_Amount").Select(item => item.Value).FirstOrDefault());
                var rewardMoney  = decimal.Parse(settingCollection.Where(item => item.Name == "Over_People_Count_Reward_Amount").Select(item => item.Value).FirstOrDefault());
                var maxCount     = decimal.Parse(settingCollection.Where(item => item.Name == "Max_Reward_Amount").Select(item => item.Value).FirstOrDefault());
                var orderNo1     = CreateOrderno();
                var orderNo2     = CreateOrderno();
                var inviteWallet = uwComponent.GetUserWallet(account.Id, cryptoId);
                if (inviteWallet == null)
                {
                    inviteWallet = uwComponent.GenerateWallet(account.Id, cryptoId);
                }

                var beInvitedWallet = uwComponent.GetUserWallet(im.BeInvitedAccountId, cryptoId);
                if (beInvitedWallet == null)
                {
                    beInvitedWallet = uwComponent.GenerateWallet(im.BeInvitedAccountId, cryptoId);
                }

                int     inviteId;
                long    profitId1    = 0; //邀请人奖励ID
                long    profitId2    = 0; //被邀请人奖励ID
                long    exProfitId1  = 0; //邀请人额外奖励ID
                decimal totalReward  = pfDAC.GetTotalReward(account);
                int     invitedCount = pfDAC.GetInvitedCount(account);

                using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
                {
                    //插入数据到inviterecord表中
                    inviteId = iDAC.Insert(new InviteRecord()
                    {
                        Type = (InviteType)im.Type, AccountId = im.BeInvitedAccountId, Timestamp = DateTime.UtcNow, InviterCode = im.InvitationCode, InviterAccountId = account.Id
                    });

                    if (totalReward < maxCount)
                    {
                        profitId1 = pfDAC.Insert(new ProfitDetail()
                        {
                            InvitationId = inviteId,
                            CryptoAmount = inviteMoney,
                            AccountId    = account.Id,
                            Status       = InviteStatusType.IssuedFrozen,
                            Type         = ProfitType.InvitePiiiPay,
                            OrderNo      = orderNo1,
                            Timestamp    = DateTime.UtcNow,
                            CryptoId     = cryptoId
                        });

                        utDAC.Insert(new UserTransaction
                        {
                            Id         = Guid.NewGuid(),
                            AccountId  = account.Id,
                            CryptoId   = cryptoCurrencty.Id,
                            CryptoCode = cryptoCurrencty.Code,
                            Type       = UserTransactionType.Profit,
                            DetailId   = profitId1.ToString(),
                            Status     = (byte)InviteStatusType.IssuedFrozen,
                            Timestamp  = DateTime.UtcNow,
                            Amount     = inviteMoney,
                            OrderNo    = orderNo1
                        });

                        uwDAC.IncreaseFrozen(inviteWallet.Id, inviteMoney);

                        uwsDAC.Insert(new UserWalletStatement
                        {
                            WalletId      = inviteWallet.Id,
                            Action        = UserWalletStatementAction.Invite,
                            Amount        = 0,
                            Balance       = inviteWallet.Balance,
                            FrozenAmount  = inviteMoney,
                            FrozenBalance = inviteWallet.FrozenBalance + inviteMoney,
                            Timestamp     = DateTime.UtcNow
                        });

                        // 每当满50人时则可以奖励 采用了插入操作 所以只要满足为49个就可以了
                        if ((invitedCount + 1) % 50 == 0)
                        {
                            var pd50 = new ProfitDetail()
                            {
                                InvitationId = inviteId,
                                CryptoAmount = rewardMoney,
                                AccountId    = account.Id,
                                Status       = InviteStatusType.IssuedFrozen,
                                Type         = ProfitType.Reward,
                                OrderNo      = CreateOrderno(),
                                Timestamp    = DateTime.UtcNow,
                                CryptoId     = cryptoId
                            };
                            exProfitId1 = pfDAC.Insert(pd50);

                            utDAC.Insert(new UserTransaction
                            {
                                Id         = Guid.NewGuid(),
                                AccountId  = account.Id,
                                CryptoId   = cryptoCurrencty.Id,
                                CryptoCode = cryptoCurrencty.Code,
                                Type       = UserTransactionType.Profit,
                                DetailId   = exProfitId1.ToString(),
                                Status     = (byte)InviteStatusType.IssuedFrozen,
                                Timestamp  = DateTime.UtcNow,
                                Amount     = rewardMoney,
                                OrderNo    = pd50.OrderNo
                            });

                            uwDAC.IncreaseFrozen(inviteWallet.Id, rewardMoney);

                            uwsDAC.Insert(new UserWalletStatement
                            {
                                WalletId      = inviteWallet.Id,
                                Action        = UserWalletStatementAction.Invite,
                                Amount        = 0,
                                Balance       = inviteWallet.Balance,
                                FrozenAmount  = rewardMoney,
                                FrozenBalance = inviteWallet.FrozenBalance + inviteMoney + rewardMoney,
                                Timestamp     = DateTime.UtcNow
                            });
                        }
                        profitId2 = pfDAC.Insert(new ProfitDetail()
                        {
                            InvitationId = inviteId,
                            CryptoAmount = inviteMoney,
                            AccountId    = im.BeInvitedAccountId,
                            Type         = ProfitType.BeInvited,
                            Status       = InviteStatusType.IssuedActive,
                            OrderNo      = orderNo2,
                            Timestamp    = DateTime.UtcNow,
                            CryptoId     = cryptoId
                        });
                        utDAC.Insert(new UserTransaction
                        {
                            Id         = Guid.NewGuid(),
                            AccountId  = im.BeInvitedAccountId,
                            CryptoId   = cryptoCurrencty.Id,
                            CryptoCode = cryptoCurrencty.Code,
                            Type       = UserTransactionType.Profit,
                            DetailId   = profitId2.ToString(),
                            Status     = (byte)InviteStatusType.IssuedActive,
                            Timestamp  = DateTime.UtcNow,
                            Amount     = inviteMoney,
                            OrderNo    = orderNo2
                        });
                        uwDAC.Increase(beInvitedWallet.Id, inviteMoney);
                        uwsDAC.Insert(new UserWalletStatement
                        {
                            WalletId      = beInvitedWallet.Id,
                            Action        = UserWalletStatementAction.BeInvite,
                            Amount        = inviteMoney,
                            Balance       = beInvitedWallet.Balance + inviteMoney,
                            FrozenAmount  = 0,
                            FrozenBalance = beInvitedWallet.FrozenBalance,
                            Timestamp     = DateTime.UtcNow
                        });
                    }
                    scope.Complete();
                }

                if (!(im.Type == (int)SystemPlatform.FiiiPay || im.Type == (int)SystemPlatform.FiiiPOS))
                {
                    throw new ArgumentException("只支持fiiipay和fiiipos邀请");
                }

                if (im.Type == (int)SystemPlatform.FiiiPay)
                {
                    UserMSMQ.PubUserInviteSuccessed(profitId2, 0);
                }
                //else if (im.Type == SystemPlatform.FiiiPOS)
                //    MerchantMSMQ.PubUserInviteSuccessed(profitId2, 0);
            }
            //else
            //{
            //    var iDAC = new InviteRecordDAC();
            //    iDAC.Insert(new InviteRecord() { Type = im.Type, AccountId = im.BeInvitedAccountId, Timestamp = DateTime.UtcNow, InviterCode = im.InvitationCode, InviterAccountId = account.Id });
            //}
        }
        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();
                }
            }
        }
Example #10
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);
        }
Example #11
0
        public TransferOM Transfer(UserAccount account, TransferIM im)
        {
            SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, account.Id.ToString(), account.Pin, im.Pin);
            if (account.L1VerifyStatus != VerifyStatus.Certified)
            {
                throw new ApplicationException();
            }
            if (account.IsAllowTransfer.HasValue && !account.IsAllowTransfer.Value)
            {
                throw new CommonException(ReasonCode.TRANSFER_FORBIDDEN, MessageResources.TransferForbidden);
            }
            var toAccount = new UserAccountDAC().GetByCountryIdAndCellphone(im.ToCountryId, im.ToCellphone);

            if (toAccount == null)
            {
                throw new CommonException(ReasonCode.ACCOUNT_NOT_EXISTS, MessageResources.AccountNotExist);
            }
            if (toAccount.IsAllowTransfer.HasValue && !toAccount.IsAllowTransfer.Value)
            {
                throw new CommonException(ReasonCode.TRANSFER_FORBIDDEN, MessageResources.ToAccountTransferForbidden);
            }
            if (im.Amount >= Convert.ToDecimal(Math.Pow(10, 11)))
            {
                throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountOverflow);
            }
            var currency = new CryptocurrencyDAC().GetById(im.CoinId);

            if (!currency.Status.HasFlag(CryptoStatus.Transfer) || currency.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }
            if (im.Amount < (decimal)Math.Pow(10, -currency.DecimalPlace))
            {
                throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountTooSmall);
            }
            var decimalDigits = im.Amount.ToString().Length - im.Amount.ToString().IndexOf('.') - 1;

            if (decimalDigits > currency.DecimalPlace)
            {
                throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountOverflow);
            }

            if (account.Id == toAccount.Id)
            {
                throw new CommonException(ReasonCode.TRANSFER_TO_SELF, MessageResources.TransferToSelf);
            }

            var uwComponent = new UserWalletComponent();

            var toWallet = uwComponent.GetUserWallet(toAccount.Id, im.CoinId);

            if (toWallet == null)
            {
                toWallet = uwComponent.GenerateWallet(toAccount.Id, currency.Id);
            }

            var      country      = new CountryComponent().GetById(im.ToCountryId);
            DateTime dtCreateTime = DateTime.UtcNow;

            var fromWallet = uwComponent.GetUserWallet(account.Id, im.CoinId);

            if (fromWallet.Balance < im.Amount)
            {
                throw new CommonException(ReasonCode.TRANSFER_BALANCE_LOW, MessageResources.TransferBalanceLow);
            }

            UserTransfer transfer = new UserTransfer
            {
                Timestamp         = dtCreateTime,
                OrderNo           = CreateOrderno(),
                FromUserAccountId = account.Id,
                FromUserWalletId  = fromWallet.Id,
                CoinId            = currency.Id,
                CoinCode          = currency.Code,
                ToUserAccountId   = toAccount.Id,
                ToUserWalletId    = toWallet.Id,
                Amount            = im.Amount,
                Status            = (byte)TransactionStatus.Confirmed
            };

            var uwDAC  = new UserWalletDAC();
            var uwsDAC = new UserWalletStatementDAC();
            var utDAC  = new UserTransactionDAC();

            //var pushComponent = new FiiiPayPushComponent();
            using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                transfer.Id = new UserTransferDAC().Insert(transfer);

                utDAC.Insert(new UserTransaction
                {
                    Id         = Guid.NewGuid(),
                    AccountId  = transfer.FromUserAccountId,
                    CryptoId   = transfer.CoinId,
                    CryptoCode = transfer.CoinCode,
                    Type       = UserTransactionType.TransferOut,
                    DetailId   = transfer.Id.ToString(),
                    Status     = transfer.Status,
                    Timestamp  = dtCreateTime,
                    Amount     = transfer.Amount,
                    OrderNo    = transfer.OrderNo
                });

                utDAC.Insert(new UserTransaction
                {
                    Id         = Guid.NewGuid(),
                    AccountId  = transfer.ToUserAccountId,
                    CryptoId   = transfer.CoinId,
                    CryptoCode = transfer.CoinCode,
                    Type       = UserTransactionType.TransferIn,
                    DetailId   = transfer.Id.ToString(),
                    Status     = transfer.Status,
                    Timestamp  = dtCreateTime,
                    Amount     = transfer.Amount,
                    OrderNo    = transfer.OrderNo
                });

                uwDAC.Decrease(fromWallet.Id, transfer.Amount);
                uwDAC.Increase(toWallet.Id, transfer.Amount);

                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = fromWallet.Id,
                    Action        = UserWalletStatementAction.TansferOut,
                    Amount        = -transfer.Amount,
                    Balance       = fromWallet.Balance - transfer.Amount,
                    FrozenAmount  = 0,
                    FrozenBalance = fromWallet.FrozenBalance,
                    Timestamp     = dtCreateTime
                });

                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = toWallet.Id,
                    Action        = UserWalletStatementAction.TansferIn,
                    Amount        = transfer.Amount,
                    Balance       = toWallet.Balance + transfer.Amount,
                    FrozenAmount  = 0,
                    FrozenBalance = toWallet.FrozenBalance,
                    Timestamp     = dtCreateTime
                });

                scope.Complete();
            }

            RabbitMQSender.SendMessage("UserTransferOutFiiiPay", transfer.Id);
            RabbitMQSender.SendMessage("UserTransferIntoFiiiPay", transfer.Id);
            //pushComponent.PushTransferOut(transfer.Id);
            //pushComponent.PushTransferInto(transfer.Id);

            return(new TransferOM
            {
                Timestamp = dtCreateTime.ToUnixTime().ToString(),
                TracingId = transfer.Id,
                TracingNo = transfer.OrderNo,
                AccountName = country.PhoneCode + " " + toAccount.Cellphone
            });
        }
        /// <summary>
        /// FiiiPay扫描第三方二维码支付
        /// </summary>
        /// <param name="code">二维码字符</param>
        /// <returns></returns>
        public GatewayOrderInfoOM Pay(GatewayPayIM im, UserAccount account)
        {
            new SecurityComponent().VerifyPin(account, im.Pin);

            var gatewayOrder = new GatewayOrderDAC().GetByOrderId(im.OrderId);

            if (gatewayOrder.Status != GatewayOrderStatus.Pending)
            {
                throw new CommonException(ReasonCode.ORDER_HAD_COMPLETE, MessageResources.OrderComplated);
            }
            var cryptoCurrency = new CryptocurrencyDAC().GetById(gatewayOrder.CryptoId);

            if (cryptoCurrency == null || cryptoCurrency?.Id == null)
            {
                throw new CommonException(ReasonCode.CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency");
            }
            var uwComponent = new UserWalletComponent();
            var userWallet  = uwComponent.GetUserWallet(gatewayOrder.UserAccountId.Value, gatewayOrder.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            if (userWallet.Balance < gatewayOrder.CryptoAmount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            var uwDAC  = new UserWalletDAC();
            var uwsDAC = new UserWalletStatementDAC();
            var goDAC  = new GatewayOrderDAC();

            using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                uwDAC.Decrease(userWallet.Id, gatewayOrder.ActualCryptoAmount);
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = userWallet.Id,
                    Action        = UserWalletStatementAction.TansferOut,
                    Amount        = -gatewayOrder.ActualCryptoAmount,
                    Balance       = userWallet.Balance - gatewayOrder.ActualCryptoAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = userWallet.FrozenBalance,
                    Timestamp     = DateTime.UtcNow
                });
                gatewayOrder.Status      = GatewayOrderStatus.Completed;
                gatewayOrder.PaymentTime = DateTime.UtcNow;
                goDAC.Update(gatewayOrder);

                new UserTransactionDAC().Insert(new UserTransaction
                {
                    Id           = Guid.NewGuid(),
                    AccountId    = userWallet.UserAccountId,
                    CryptoId     = cryptoCurrency.Id,
                    CryptoCode   = cryptoCurrency.Code,
                    Type         = UserTransactionType.Order,
                    DetailId     = gatewayOrder.Id.ToString(),
                    Status       = (byte)gatewayOrder.Status,
                    Timestamp    = DateTime.UtcNow,
                    Amount       = gatewayOrder.CryptoAmount,
                    OrderNo      = gatewayOrder.OrderNo,
                    MerchantName = gatewayOrder.MerchantName
                });
                scope.Complete();
            }
            RabbitMQSender.SendMessage("FiiiPay_Gateway_PayCompleted", gatewayOrder.TradeNo);
            return(new GatewayOrderInfoOM()
            {
                Timestamp = gatewayOrder.PaymentTime?.ToUnixTime().ToString(),
                OrderId = gatewayOrder.Id,
                MerchantName = gatewayOrder.MerchantName,
                CryptoCode = cryptoCurrency.Code,
                ActurlCryptoAmount = gatewayOrder.ActualCryptoAmount
            });
        }
Example #13
0
        public SaveResult SaveProfileVerify(int AdminId, string AdminName, UserProfile profile)
        {
            var oldProfile  = GetUserProfile(profile.UserAccountId.Value);
            var userAccount = FiiiPayDB.UserAccountDb.GetById(profile.UserAccountId);

            userAccount.L1VerifyStatus = profile.L1VerifyStatus.Value;
            if (oldProfile == null)
            {
                return(new SaveResult(false, "Data error"));
            }

            var profileSDK = new UserProfileAgent();
            int count      = profileSDK.GetCountByIdentityDocNo(profile.UserAccountId.Value, oldProfile.IdentityDocNo);

            if (profile.L1VerifyStatus == VerifyStatus.Certified && count > 6)
            {
                return(new SaveResult(false, "This identty document has been used for 7 accounts, cannot be verified "));
            }
            long profitId   = 0; //被邀请人奖励ID
            long exProfitId = 0; //邀请人额外奖励ID

            bool result = profileSDK.UpdateL1Status(profile.UserAccountId.Value, profile.L1VerifyStatus.Value, profile.L1Remark);

            if (result)
            {
                FiiiPayDB.UserAccountDb.Update(userAccount);
            }
            else
            {
                profileSDK.UpdateL1Status(profile.UserAccountId.Value, oldProfile.L1VerifyStatus.Value, oldProfile.L1Remark);
            }

            if (result && profile.L1VerifyStatus == VerifyStatus.Certified)
            {
                var invite = FiiiPayDB.DB.Queryable <InviteRecords>().Where(t => t.AccountId == profile.UserAccountId.Value).First();
                if (invite != null)
                {
                    var inviteProfit = FiiiPayDB.DB.Queryable <ProfitDetails>().Where(t => t.AccountId == invite.InviterAccountId && t.InvitationId == invite.Id && t.Type == ProfitType.InvitePiiiPay).First();
                    var rewardProfit = FiiiPayDB.DB.Queryable <ProfitDetails>().Where(t => t.AccountId == invite.InviterAccountId && t.Status == InviteStatusType.IssuedFrozen && t.Type == ProfitType.Reward).OrderBy(t => t.Timestamp).First();

                    profitId = inviteProfit.Id;
                    var uwComponent = new UserWalletBLL();
                    var uwsDAC      = new UserWalletStatementDAC();
                    var uwDAC       = new UserWalletDAC();
                    var pfDAC       = new ProfitDetailDAC();
                    var utDAC       = new UserTransactionDAC();

                    int invitedCount = pfDAC.GetInvitedAndActiveCount(invite.InviterAccountId);

                    var cryptoId     = new CryptocurrencyDAC().GetByCode("FIII").Id;
                    var inviteWallet = uwComponent.GetUserWallet(invite.InviterAccountId, cryptoId);
                    if (inviteWallet == null)
                    {
                        inviteWallet = uwComponent.GenerateWallet(invite.InviterAccountId, cryptoId);
                    }

                    var inviteMoney = inviteProfit.CryptoAmount;

                    var adoResult = FiiiPayDB.DB.Ado.UseTran(() =>
                    {
                        try
                        {
                            //解冻奖励
                            uwDAC.Unfreeze(inviteWallet.Id, inviteMoney);
                            //插入奖励流水
                            uwsDAC.Insert(new UserWalletStatement
                            {
                                WalletId  = inviteWallet.Id,
                                Action    = UserWalletStatementAction.Invite,
                                Amount    = inviteMoney,
                                Balance   = inviteWallet.Balance + inviteMoney,
                                Timestamp = DateTime.UtcNow
                            });
                            //修改奖励状态为已激活
                            pfDAC.UpdateStatus(inviteProfit.Id, InviteStatusType.IssuedActive);
                            utDAC.UpdateStatus(UserTransactionType.Profit, inviteProfit.Id.ToString(), invite.InviterAccountId, (byte)InviteStatusType.IssuedActive);

                            // 每当满50人时则可以奖励 采用了插入操作 所以只要满足为49个就可以了
                            if ((invitedCount + 1) % 50 == 0)
                            {
                                exProfitId      = rewardProfit.Id;
                                var rewardMoney = rewardProfit.CryptoAmount;
                                //解冻满50人的额外奖励
                                uwDAC.Unfreeze(inviteWallet.Id, rewardMoney);
                                //插入满50人的额外奖励流水
                                uwsDAC.Insert(new UserWalletStatement
                                {
                                    WalletId  = inviteWallet.Id,
                                    Action    = UserWalletStatementAction.Reward,
                                    Amount    = rewardMoney,
                                    Balance   = inviteWallet.Balance + rewardMoney,
                                    Timestamp = DateTime.UtcNow
                                });
                                //修改奖励状态为已激活
                                pfDAC.UpdateStatus(rewardProfit.Id, InviteStatusType.IssuedActive);
                                utDAC.UpdateStatus(UserTransactionType.Profit, rewardProfit.Id.ToString(), invite.InviterAccountId, (byte)InviteStatusType.IssuedActive);
                            }
                        }
                        catch (Exception e)
                        {
                            log.Info(profile.UserAccountId + "    --------- " + e.ToString());
                        }
                    });
                    result = adoResult.Data;
                }
            }

            if (result && (profile.L1VerifyStatus == VerifyStatus.Certified || profile.L1VerifyStatus == VerifyStatus.Disapproval))
            {
                var recordId = FiiiPayDB.VerifyRecordDb.InsertReturnIdentity(new VerifyRecords()
                {
                    AccountId  = profile.UserAccountId.Value,
                    Username   = userAccount.Cellphone,
                    Body       = profile.L1Remark,
                    Type       = profile.L1VerifyStatus == VerifyStatus.Certified ? VerifyRecordType.UserLv1Verified : VerifyRecordType.UserLv1Reject,
                    CreateTime = DateTime.UtcNow
                });
                if (profile.L1VerifyStatus == VerifyStatus.Certified)
                {
                    RabbitMQSender.SendMessage("UserKYC_LV1_VERIFIED", recordId);
                }
                else if (profile.L1VerifyStatus == VerifyStatus.Disapproval)
                {
                    RabbitMQSender.SendMessage("UserKYC_LV1_REJECT", recordId);
                }
            }

            if (result && profitId > 0)
            {
                RabbitMQSender.SendMessage("UserInviteSuccessed", profitId);
            }
            if (result && exProfitId > 0)
            {
                RabbitMQSender.SendMessage("UserInviteSuccessed", profitId);
            }
            ActionLog actionLog = new ActionLog();

            actionLog.IPAddress  = GetClientIPAddress();
            actionLog.AccountId  = AdminId;
            actionLog.CreateTime = DateTime.UtcNow;
            actionLog.ModuleCode = typeof(UserProfileBLL).FullName + ".SaveProfileVerify";
            actionLog.Username   = AdminName;
            actionLog.LogContent = string.Format("verify user profile.accountId:{0},verifystatus:{1}", profile.UserAccountId, profile.L1VerifyStatus.ToString());
            new ActionLogBLL().Create(actionLog);

            return(new SaveResult(result));
        }
Example #14
0
        public async Task <PayOrderOM> PayAsync(UserAccount user, StoreOrderPayIM im)
        {
            #region 验证
            if (im.FiatAmount <= 0)
            {
                throw new ApplicationException();
            }
            SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, user.Id.ToString(), user.Pin, im.Pin);
            if (!user.IsAllowExpense.HasValue || !user.IsAllowExpense.Value)
            {
                throw new CommonException(ReasonCode.Not_Allow_Expense, MessageResources.PaymentForbidden);
            }

            var coin = new CryptocurrencyDAC().GetById(im.CoinId);
            if (!coin.Status.HasFlag(CryptoStatus.Pay) || coin.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }

            var merchantInfo = new MerchantInformationDAC().GetById(im.MerchantInfoId);
            if (merchantInfo.Status != Status.Enabled || merchantInfo.VerifyStatus != VerifyStatus.Certified || merchantInfo.IsPublic != Status.Enabled)
            {
                throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantExceptionTransClose);
            }
            if (!merchantInfo.IsAllowExpense)
            {
                throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantReceiveNotAllowed);
            }
            if (merchantInfo.AccountType == AccountType.Merchant)
            {
                throw new ApplicationException();
            }

            var storeAccount = new UserAccountDAC().GetById(merchantInfo.MerchantAccountId);
            if (storeAccount.Id == user.Id)
            {
                throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.PaytoSelf);
            }
            if (storeAccount == null || storeAccount.Status.Value != (byte)AccountStatus.Active)
            {
                throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantFiiipayAbnormal);
            }

            var paySetting = await new StorePaySettingDAC().GetByCountryIdAsync(merchantInfo.CountryId);
            if (paySetting != null)
            {
                if (im.FiatAmount > paySetting.LimitAmount)
                {
                    throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, string.Format(MessageResources.TransferAmountOverflow, paySetting.LimitAmount, paySetting.FiatCurrency));
                }
            }
            #endregion

            var walletDAC     = new UserWalletDAC();
            var statementDAC  = new UserWalletStatementDAC();
            var storeOrderDAC = new StoreOrderDAC();
            var utDAC         = new UserTransactionDAC();

            #region 计算
            decimal markup       = merchantInfo.Markup;
            decimal feeRate      = merchantInfo.FeeRate;
            var     exchangeRate = new PriceInfoDAC().GetPriceByName(storeAccount.FiatCurrency, coin.Code);

            decimal failTotalAmount    = im.FiatAmount + (im.FiatAmount * markup).ToSpecificDecimal(4);
            decimal transactionFiatFee = (im.FiatAmount * feeRate).ToSpecificDecimal(4);
            decimal transactionFee     = (transactionFiatFee / exchangeRate).ToSpecificDecimal(coin.DecimalPlace);
            decimal cryptoAmount       = (failTotalAmount / exchangeRate).ToSpecificDecimal(coin.DecimalPlace);

            var fromWallet = walletDAC.GetUserWallet(user.Id, im.CoinId);
            if (fromWallet == null || fromWallet.Balance < cryptoAmount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }

            var toWallet = walletDAC.GetUserWallet(storeAccount.Id, im.CoinId);
            if (toWallet == null)
            {
                toWallet = new UserWalletComponent().GenerateWallet(storeAccount.Id, im.CoinId);
            }
            #endregion

            #region entity
            DateTime   dtNow = DateTime.UtcNow;
            StoreOrder order = new StoreOrder
            {
                Id                 = Guid.NewGuid(),
                OrderNo            = IdentityHelper.OrderNo(),
                Timestamp          = dtNow,
                Status             = OrderStatus.Completed,
                MerchantInfoId     = merchantInfo.Id,
                MerchantInfoName   = merchantInfo.MerchantName,
                UserAccountId      = user.Id,
                CryptoId           = im.CoinId,
                CryptoCode         = coin.Code,
                CryptoAmount       = cryptoAmount,
                CryptoActualAmount = cryptoAmount - transactionFee,
                ExchangeRate       = exchangeRate,
                Markup             = markup,
                FiatCurrency       = storeAccount.FiatCurrency,
                FiatAmount         = im.FiatAmount,
                FiatActualAmount   = failTotalAmount,
                FeeRate            = feeRate,
                TransactionFee     = transactionFee,
                PaymentTime        = dtNow
            };
            UserWalletStatement fromStatement = new UserWalletStatement
            {
                WalletId      = fromWallet.Id,
                Action        = UserWalletStatementAction.StoreOrderOut,
                Amount        = -order.CryptoAmount,
                Balance       = fromWallet.Balance - order.CryptoAmount,
                FrozenAmount  = 0,
                FrozenBalance = fromWallet.FrozenBalance,
                Timestamp     = dtNow
            };
            UserWalletStatement toStatement = new UserWalletStatement
            {
                WalletId      = toWallet.Id,
                Action        = UserWalletStatementAction.StoreOrderIn,
                Amount        = order.CryptoActualAmount,
                Balance       = toWallet.Balance + order.CryptoActualAmount,
                FrozenAmount  = 0,
                FrozenBalance = toWallet.FrozenBalance,
                Timestamp     = dtNow
            };
            #endregion

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await storeOrderDAC.CreateAsync(order);

                await utDAC.InsertAsync(new UserTransaction
                {
                    Id           = Guid.NewGuid(),
                    AccountId    = fromWallet.UserAccountId,
                    CryptoId     = order.CryptoId,
                    CryptoCode   = order.CryptoCode,
                    Type         = UserTransactionType.StoreOrderConsume,
                    DetailId     = order.Id.ToString(),
                    Status       = (byte)order.Status,
                    Timestamp    = order.PaymentTime.Value,
                    Amount       = order.CryptoAmount,
                    OrderNo      = order.OrderNo,
                    MerchantName = order.MerchantInfoName
                });

                await utDAC.InsertAsync(new UserTransaction
                {
                    Id           = Guid.NewGuid(),
                    AccountId    = toWallet.UserAccountId,
                    CryptoId     = order.CryptoId,
                    CryptoCode   = order.CryptoCode,
                    Type         = UserTransactionType.StoreOrderIncome,
                    DetailId     = order.Id.ToString(),
                    Status       = (byte)order.Status,
                    Timestamp    = order.Timestamp,
                    Amount       = order.CryptoActualAmount,
                    OrderNo      = order.OrderNo,
                    MerchantName = order.MerchantInfoName
                });

                walletDAC.Decrease(fromWallet.Id, order.CryptoAmount);
                walletDAC.Increase(toWallet.Id, order.CryptoActualAmount);
                statementDAC.Insert(fromStatement);
                statementDAC.Insert(toStatement);
                scope.Complete();
            }

            var pushObj = new { order.Id, order.UserAccountId, order.CryptoCode };

            RabbitMQSender.SendMessage("StoreOrderPayed", new { order.Id, MerchantInfoId = merchantInfo.MerchantAccountId, order.UserAccountId, order.CryptoCode });

            return(new PayOrderOM
            {
                Amount = order.CryptoAmount.ToString(coin.DecimalPlace),
                Currency = coin.Code,
                OrderId = order.Id.ToString(),
                OrderNo = order.OrderNo,
                Timestamp = dtNow.ToUnixTime().ToString()
            });
        }