Exemplo n.º 1
0
        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();
                }
            }
        }
Exemplo n.º 2
0
        /// <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();
            }
        }
Exemplo n.º 3
0
        public bool BillerRefund(string orderNo)
        {
            var orderDac = new BillerOrderDAC();
            var order    = FiiiPayDB.DB.Queryable <BillerOrders>().Where(t => t.OrderNo.Equals(orderNo)).First();

            if (order == null)
            {
                throw new CommonException(10000, "Order does not exist!");
            }

            var merchantWalletDAC = new MerchantWalletDAC();
            var userWalletDAC     = new UserWalletDAC();

            var userWallet = userWalletDAC.GetByAccountId(order.AccountId, order.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(10001, "A currency that is not supported by the user");
            }
            using (var scope = new TransactionScope())
            {
                userWalletDAC.Increase(order.AccountId, order.CryptoId, order.CryptoAmount);
                new UserWalletStatementDAC().Insert(new UserWalletStatement
                {
                    WalletId  = userWallet.Id,
                    Action    = "REFUND",
                    Amount    = order.CryptoAmount,
                    Balance   = userWallet.Balance + order.CryptoAmount,
                    Timestamp = DateTime.UtcNow,
                    Remark    = $"Refund from billerorder({order.OrderNo})"
                });

                order.Status = BillerOrderStatus.Fail;
                orderDac.UpdateStatus(order);

                new RefundDAC().Insert(new Refund
                {
                    OrderId   = order.Id,
                    Status    = RefundStatus.Completed,
                    Timestamp = DateTime.UtcNow
                });
                scope.Complete();
            }
            return(true);
        }
Exemplo n.º 4
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"));
        }
Exemplo n.º 5
0
        public string FiiiPayTransferInto(UserAccount account, Cryptocurrency coin, decimal amount)
        {
            var walletDac = new UserWalletDAC();
            var wallet    = walletDac.GetByAccountId(account.Id, coin.Id);
            UserExTransferOrder order;

            using (var scope = new TransactionScope())
            {
                if (wallet == null)
                {
                    wallet = new UserWalletComponent().GenerateWallet(account.Id, coin.Id);
                }

                walletDac.Increase(wallet.Id, amount);

                order = new UserExTransferOrder
                {
                    Timestamp  = DateTime.UtcNow,
                    OrderNo    = CreateOrderNo(),
                    OrderType  = ExTransferType.FromEx,
                    AccountId  = account.Id,
                    WalletId   = wallet.Id,
                    CryptoId   = coin.Id,
                    CryptoCode = coin.Code,
                    Amount     = amount,
                    Status     = 1,
                    Remark     = null,
                    ExId       = null
                };

                new UserExTransferOrderDAC().Create(order);

                scope.Complete();
            }

            try
            {
                FiiiEXTransferMSMQ.PubUserTransferFromEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("PubUserTransferFromEx - error", ex);
            }
            return(order.OrderNo);
        }
Exemplo n.º 6
0
        public TransferResult Transfer(InvestorAccount account, int countryId, string cellphone, decimal amount, string pinToken)
        {
            new SecurityVerification(SystemPlatform.FiiiCoinWork).VerifyToken(pinToken, SecurityMethod.Pin);

            CountryDAC     countryDac     = new CountryDAC();
            UserAccountDAC userAccountDac = new UserAccountDAC();
            Country        country        = countryDac.GetById(countryId);

            if (country == null)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, R.AccountNotExist);
            }
            UserAccount userAccount = userAccountDac.GetByCountryIdAndCellphone(countryId, cellphone);

            if (userAccount == null)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, R.AccountNotExist);
            }

            InvestorAccountDAC accountDac = new InvestorAccountDAC();

            if (account.Balance < amount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, R.余额不足);
            }

            UserWalletDAC userWalletDac = new UserWalletDAC();

            UserWallet userWallet = userWalletDac.GetByAccountId(userAccount.Id, FiiiCoinUtility.Cryptocurrency.Id);

            InvestorOrder investorOrder;
            UserDeposit   userDeposit;

            using (var scope = new TransactionScope())
            {
                if (userWallet == null)
                {
                    userWallet = new UserWalletComponent().GenerateWallet(userAccount.Id, FiiiCoinUtility.Cryptocurrency.Id);
                }
                accountDac.Decrease(account.Id, amount);
                investorOrder = new InvestorOrderDAC().Insert(new InvestorOrder
                {
                    Id                 = Guid.NewGuid(),
                    OrderNo            = CreateOrderNo(),
                    TransactionType    = InvestorTransactionType.Transfer,
                    Status             = 1,
                    InverstorAccountId = account.Id,
                    UserAccountId      = userAccount.Id,
                    CryptoId           = FiiiCoinUtility.Cryptocurrency.Id,
                    CryptoAmount       = amount,
                    Timestamp          = DateTime.UtcNow
                });
                new InvestorWalletStatementDAC().Insert(new InvestorWalletStatement
                {
                    Id           = Guid.NewGuid(),
                    InvestorId   = account.Id,
                    TagAccountId = userAccount.Id,
                    Action       = InvestorTransactionType.Transfer,
                    Amount       = -amount,
                    Balance      = account.Balance - amount,
                    Timestamp    = DateTime.UtcNow
                });
                // 2018-06-26: new rules IncreaseFrozen -> Increase
                userWalletDac.Increase(userWallet.Id, amount);
                userDeposit = new UserDepositDAC().Insert(new UserDeposit
                {
                    UserAccountId = userAccount.Id,
                    UserWalletId  = userWallet.Id,
                    FromAddress   = null,
                    FromTag       = null,
                    ToAddress     = null,
                    ToTag         = null,
                    Amount        = amount,
                    Status        = TransactionStatus.Confirmed,
                    Timestamp     = DateTime.UtcNow,
                    OrderNo       = CreateOrderNo(),
                    TransactionId = account.Id.ToString(),
                    SelfPlatform  = true,
                    RequestId     = null
                });


                scope.Complete();
            }

            InvestorMSMQ.PubUserDeposit(userDeposit.Id, 0);

            return(new TransferResult
            {
                OrderId = investorOrder.Id,
                OrderNo = investorOrder.OrderNo,
                TargetAccount = GetMaskedCellphone(country.PhoneCode, userAccount.Cellphone),
                Timestamp = DateTime.UtcNow.ToUnixTime()
            });
        }
Exemplo n.º 7
0
        public bool Refund(string orderNo)
        {
            var orderDac = new OrderDAC();

            var order = orderDac.GetByOrderNo(orderNo);

            if (order == null)
            {
                throw new CommonException(10000, "Order does not exist!");
            }

            if (order.Status != OrderStatus.Completed)
            {
                throw new CommonException(10001, "Order state exception!");
            }

            if (DateTime.UtcNow.AddDays(-3000) > order.PaymentTime)
            {
                throw new CommonException(10000, "Orders cannot be refundable for more than three days!");
            }

            var merchantWalletDAC = new MerchantWalletDAC();
            var userWalletDAC     = new UserWalletDAC();

            var merchantWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, order.CryptoId);

            if (merchantWallet == null)
            {
                throw new CommonException(10001, "The currency that the merchant does not support!");
            }

            if (merchantWallet.Balance < order.ActualCryptoAmount)
            {
                throw new CommonException(10001, "Not sufficient funds!");
            }

            var userWallet = userWalletDAC.GetByAccountId(order.UserAccountId.Value, order.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(10001, "A currency that is not supported by the user");
            }

            var merchantAccount = new MerchantAccountDAC().GetById(order.MerchantAccountId);

            var orderWithdrawalFee = new OrderWithdrawalFeeDAC().GetByOrderId(order.Id);

            if (orderWithdrawalFee != null)
            {
                var merchantOrderWithdrawalFeeWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, orderWithdrawalFee.CryptoId);
                using (var scope = new TransactionScope())
                {
                    merchantWalletDAC.Decrease(order.MerchantAccountId, order.CryptoId, order.ActualCryptoAmount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantWallet.Id,
                        Action    = "REFUND",
                        Amount    = -order.ActualCryptoAmount,
                        Balance   = merchantWallet.Balance - order.ActualCryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    merchantWalletDAC.Increase(order.MerchantAccountId, orderWithdrawalFee.CryptoId, orderWithdrawalFee.Amount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantOrderWithdrawalFeeWallet.Id,
                        Action    = "REFUND",
                        Amount    = orderWithdrawalFee.Amount,
                        Balance   = merchantWallet.Balance - orderWithdrawalFee.Amount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount);
                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId      = userWallet.Id,
                        Action        = "REFUND",
                        Amount        = order.CryptoAmount,
                        Balance       = userWallet.Balance + order.CryptoAmount,
                        FrozenAmount  = 0,
                        FrozenBalance = userWallet.FrozenBalance,
                        Timestamp     = DateTime.UtcNow,
                        Remark        = $"Refund from order({order.OrderNo})"
                    });

                    order.Status    = OrderStatus.Refunded;
                    order.Timestamp = DateTime.UtcNow;
                    orderDac.UpdateStatus(order);

                    new UserTransactionDAC().Insert(new UserTransaction
                    {
                        Id           = Guid.NewGuid(),
                        AccountId    = order.UserAccountId.Value,
                        CryptoId     = userWallet.CryptoId,
                        CryptoCode   = userWallet.CryptoCode,
                        Type         = UserTransactionType.Refund,
                        DetailId     = order.Id.ToString(),
                        Status       = (byte)order.Status,
                        Timestamp    = DateTime.UtcNow,
                        Amount       = order.CryptoAmount,
                        OrderNo      = order.OrderNo,
                        MerchantName = merchantAccount?.MerchantName
                    });

                    new RefundDAC().Insert(new Refund
                    {
                        OrderId   = order.Id,
                        Status    = RefundStatus.Completed,
                        Timestamp = DateTime.UtcNow
                    });

                    scope.Complete();
                }
            }
            else
            {
                using (var scope = new TransactionScope())
                {
                    merchantWalletDAC.Decrease(order.MerchantAccountId, order.CryptoId, order.ActualCryptoAmount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantWallet.Id,
                        Action    = "REFUND",
                        Amount    = -order.ActualCryptoAmount,
                        Balance   = merchantWallet.Balance - order.ActualCryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount);
                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId      = userWallet.Id,
                        Action        = "REFUND",
                        Amount        = order.CryptoAmount,
                        Balance       = userWallet.Balance + order.CryptoAmount,
                        FrozenAmount  = 0,
                        FrozenBalance = userWallet.FrozenBalance,
                        Timestamp     = DateTime.UtcNow,
                        Remark        = $"Refund from order({order.OrderNo})"
                    });

                    order.Status = OrderStatus.Refunded;
                    //order.Timestamp = DateTime.UtcNow;
                    orderDac.UpdateStatus(order);

                    new UserTransactionDAC().Insert(new UserTransaction
                    {
                        Id           = Guid.NewGuid(),
                        AccountId    = order.UserAccountId.Value,
                        CryptoId     = userWallet.CryptoId,
                        CryptoCode   = userWallet.CryptoCode,
                        Type         = UserTransactionType.Refund,
                        DetailId     = order.Id.ToString(),
                        Status       = (byte)order.Status,
                        Timestamp    = DateTime.UtcNow,
                        Amount       = order.CryptoAmount,
                        OrderNo      = order.OrderNo,
                        MerchantName = merchantAccount?.MerchantName
                    });

                    new RefundDAC().Insert(new Refund
                    {
                        OrderId   = order.Id,
                        Status    = RefundStatus.Completed,
                        Timestamp = DateTime.UtcNow
                    });

                    scope.Complete();
                }
            }
            return(true);
        }
Exemplo n.º 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 });
            //}
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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
            });
        }
Exemplo n.º 11
0
        public void DistributeRewards(FiiiPayRewardMessage message, DateTime dt)
        {
            if (fiiicoinId == 0)
            {
                var fiiicoin = new CryptocurrencyDAC().GetByCode("FIII");
                fiiicoinId = fiiicoin.Id;
            }
            MerchantAccountDAC maDAC = new MerchantAccountDAC();
            var merchant             = maDAC.GetByUsername(message.Account);

            if (merchant == null)
            {
                throw new CommonException(10000, $"无效的商家名:{message.Account}");
            }

            InviteRecord invitor = GetInvitor(merchant.Id);

            if (invitor == null)
            {
                throw new CommonException(10000, "没有邀请人");
            }

            var invitedList = new InviteRecordDAC().GetFiiiPosRecordsByInvitorId(invitor.InviterAccountId, InviteType.Fiiipos);
            var rewardRate  = GetRewardPercentage(invitedList == null ? 0 : invitedList.Count);

            if (rewardRate == 0)
            {
                throw new CommonException(10000, "没有达到奖励条件");
            }

            decimal t            = (decimal)Math.Pow(10, -8);
            long    nTotalReward = (long)Math.Floor(message.ActualReward * rewardRate);

            if (nTotalReward == 0)
            {
                throw new CommonException(10000, "奖励金额为0");
            }
            decimal rewardAmount     = nTotalReward * t;
            var     distributeRecord = new RewardDistributeRecords
            {
                UserAccountId     = invitor.InviterAccountId,
                MerchantAccountId = merchant.Id,
                SN             = message.SN,
                OriginalReward = message.ActualReward,
                Percentage     = rewardRate,
                ActualReward   = rewardAmount,
                Timestamp      = dt
            };

            long    profitId      = 0;
            decimal oldBalance    = 0;
            var     invitorWallet = uwDAC.GetByAccountId(invitor.InviterAccountId, fiiicoinId);

            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                if (invitorWallet == null)
                {
                    invitorWallet = CreateWallet(invitor.InviterAccountId, fiiicoinId, rewardAmount);
                }
                else
                {
                    oldBalance = invitorWallet.Balance;
                    uwDAC.Increase(invitorWallet.Id, rewardAmount);
                }
                profitId = pfDAC.Insert(new ProfitDetail()
                {
                    InvitationId = invitor.Id,
                    CryptoAmount = rewardAmount,
                    AccountId    = invitor.InviterAccountId,
                    Status       = InviteStatusType.IssuedActive,
                    Type         = ProfitType.InvitePiiiPos,
                    OrderNo      = CreateOrderno(),
                    Timestamp    = dt,
                    CryptoId     = invitorWallet.CryptoId
                });
                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = invitorWallet.Id,
                    Action        = UserWalletStatementAction.Reward,
                    Amount        = rewardAmount,
                    Balance       = oldBalance + rewardAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = invitorWallet.FrozenBalance,
                    Timestamp     = dt,
                    Remark        = "System"
                });

                distributeRecord.ProfitId = profitId;
                rdrDAC.Insert(distributeRecord);

                new TempDataDAC().MessageComplated(message.Id);

                scope.Complete();
            }
        }
Exemplo n.º 12
0
        public void Refund(Guid accountId, string orderNo, string pinToken)
        {
            var merchantAccountDAC = new MerchantAccountDAC();
            var merchantAccount    = merchantAccountDAC.GetById(accountId);

            if (merchantAccount == null)
            {
                return;
            }

            new SecurityVerification(SystemPlatform.FiiiPOS).VerifyToken(merchantAccount.Id, pinToken, SecurityMethod.Pin);
            var orderDac = new OrderDAC();

            var order = orderDac.GetByOrderNo(orderNo);

            if (order == null)
            {
                throw new CommonException(10000, Resources.订单不存在);
            }

            if (merchantAccount.Id != order.MerchantAccountId)
            {
                return;
            }

            if (order.Status != OrderStatus.Completed)
            {
                throw new CommonException(10000, Resources.订单状态异常);
            }

            if (DateTime.UtcNow.AddDays(-3) > order.PaymentTime.Value)
            {
                throw new CommonException(10000, Resources.订单超过三天不能退款);
            }

            var merchantWalletDAC = new MerchantWalletDAC();
            var userWalletDAC     = new UserWalletDAC();

            var merchantWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, order.CryptoId);

            if (merchantWallet == null)
            {
                throw new CommonException(10000, Resources.商户不支持的币种);
            }

            if (merchantWallet.Balance < order.ActualCryptoAmount)
            {
                throw new CommonException(10000, Resources.余额不足);
            }

            var userWallet = userWalletDAC.GetByAccountId(order.UserAccountId.Value, order.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(10000, Resources.用户不支持的币种);
            }
            var orderWithdrawalFee = new OrderWithdrawalFeeDAC().GetByOrderId(order.Id);

            if (orderWithdrawalFee != null && orderWithdrawalFee.Amount > 0)
            {
                var merchantOrderWithdrawalFeeWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, orderWithdrawalFee.CryptoId);
                using (var scope = new TransactionScope())
                {
                    merchantWalletDAC.Decrease(merchantAccount.Id, order.CryptoId, order.ActualCryptoAmount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantWallet.Id,
                        Action    = "REFUND",
                        Amount    = -order.ActualCryptoAmount,
                        Balance   = merchantWallet.Balance - order.ActualCryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    merchantWalletDAC.Increase(merchantAccount.Id, orderWithdrawalFee.CryptoId, orderWithdrawalFee.Amount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantOrderWithdrawalFeeWallet.Id,
                        Action    = "REFUND",
                        Amount    = orderWithdrawalFee.Amount,
                        Balance   = merchantWallet.Balance - orderWithdrawalFee.Amount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount);
                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId  = userWallet.Id,
                        Action    = "REFUND",
                        Amount    = order.CryptoAmount,
                        Balance   = userWallet.Balance + order.CryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund from order({order.OrderNo})"
                    });

                    order.Status    = OrderStatus.Refunded;
                    order.Timestamp = DateTime.UtcNow;
                    orderDac.UpdateStatus(order);

                    new RefundDAC().Insert(new Refund
                    {
                        OrderId   = order.Id,
                        Status    = RefundStatus.Completed,
                        Timestamp = DateTime.UtcNow
                    });

                    scope.Complete();
                }
            }
            else
            {
                using (var scope = new TransactionScope())
                {
                    merchantWalletDAC.Decrease(merchantAccount.Id, order.CryptoId, order.ActualCryptoAmount);
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        WalletId  = merchantWallet.Id,
                        Action    = "REFUND",
                        Amount    = -order.ActualCryptoAmount,
                        Balance   = merchantWallet.Balance - order.ActualCryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund to order({order.OrderNo})"
                    });

                    userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount);
                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId  = userWallet.Id,
                        Action    = "REFUND",
                        Amount    = order.CryptoAmount,
                        Balance   = userWallet.Balance + order.CryptoAmount,
                        Timestamp = DateTime.UtcNow,
                        Remark    = $"Refund from order({order.OrderNo})"
                    });

                    order.Status = OrderStatus.Refunded;
                    //order.Timestamp = DateTime.UtcNow;
                    orderDac.UpdateStatus(order);

                    new RefundDAC().Insert(new Refund
                    {
                        OrderId   = order.Id,
                        Status    = RefundStatus.Completed,
                        Timestamp = DateTime.UtcNow
                    });

                    scope.Complete();
                }
            }

            MerchantMSMQ.PubRefundOrder(order.OrderNo, 0);
        }
Exemplo n.º 13
0
        /// <summary>
        /// 订单退款
        /// </summary>
        /// <param name="merchantId"></param>
        /// <param name="orderNo"></param>
        /// <param name="pin"></param>
        /// <returns>-1=账号不存在 -2=PIN码错误 -3=订单不存在 -4=商家账户不对 -5=订单状态不符合要求 -6=商家不支持的币种 -7=商家金额不够 -8=用户钱包不支持币种 -9=回滚 -10=日期超过3天</returns>
        public int RefundOrder(Guid merchantId, string orderNo, string pin)
        {
            OrderDAC orderDac = new OrderDAC();

            MerchantAccount merchantAccount = new MerchantAccountDAC().GetById(merchantId);

            if (merchantAccount == null)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.ACCOUNT_NOT_EXISTS, "账号不存在");
            }

            if (!PasswordHasher.VerifyHashedPassword(merchantAccount.PIN, pin))
            {
                throw new CommonException(ReasonCode.PIN_ERROR, "PIN码错误");   //Wrong PIN enterred
            }
            Order order = orderDac.GetByOrderNo(orderNo);

            if (order == null)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDERNO_NOT_EXISTS, "找不到该订单"); //The order not exist
            }
            if (merchantAccount.Id != order.MerchantAccountId)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDERNO_NOTBE_ACCOUNT, "不是该用户的订单");
            }

            if (order.Status != OrderStatus.Completed)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDER_COMPLETED, "订单已完成,不能退款");  //Wrong order status.
            }
            if (DateTime.UtcNow.AddDays(-3) > order.PaymentTime.Value)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.EMAIL_CODE_EXPIRE, "订单支付已超过3天,不能退款");//订单超过3天
            }
            var merchantWalletDAC = new MerchantWalletDAC();
            var userWalletDAC     = new UserWalletDAC();

            var merchantWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, order.CryptoId);

            if (merchantWallet == null)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_MERCHANT_WALLET_NOT_EXISTS, "找不到该商家的钱包"); //Merchant account not support this cryptocurrency
            }
            if (merchantWallet.Balance < order.ActualCryptoAmount)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_BALANCE_LOW, "余额不足,无法退款");  //Balance not enough
            }
            var userWallet = userWalletDAC.GetByAccountId(order.UserAccountId.Value, order.CryptoId);

            if (userWallet == null)
            {
                throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_USER_WALLET_NOT_EXISTS, "找不到订单用户的钱包");  //User account not support this cryptocurrency
            }
            int result = -9;

            using (var scope = new TransactionScope())
            {
                merchantWalletDAC.Decrease(merchantAccount.Id, order.CryptoId, order.ActualCryptoAmount);
                new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                {
                    WalletId  = merchantWallet.Id,
                    Action    = "REFUND",
                    Amount    = -order.ActualCryptoAmount,
                    Balance   = merchantWallet.Balance - order.ActualCryptoAmount,
                    Timestamp = DateTime.UtcNow,
                    Remark    = $"Refund to order({order.OrderNo})"
                });

                userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount);
                new UserWalletStatementDAC().Insert(new UserWalletStatement
                {
                    WalletId  = userWallet.Id,
                    Action    = "REFUND",
                    Amount    = order.CryptoAmount,
                    Balance   = userWallet.Balance + order.CryptoAmount,
                    Timestamp = DateTime.UtcNow,
                    Remark    = $"Refund from order({order.OrderNo})"
                });

                order.Status = OrderStatus.Refunded;

                orderDac.UpdateStatus(order);

                new RefundDAC().Insert(new Refund
                {
                    OrderId   = order.Id,
                    Status    = RefundStatus.Completed,
                    Timestamp = DateTime.UtcNow
                });

                result = 1;
                scope.Complete();
            }

            if (result > 0) //发送退款通知
            {
                RabbitMQSender.SendMessage("RefundOrder", order.OrderNo);
            }

            return(result);
        }
Exemplo n.º 14
0
        public TransferResult FiiiPayTransferFromEx(UserAccount account, int cryptoId, decimal amount, string pin)
        {
            new SecurityComponent().VerifyPin(account, pin);

            var openAccountDac = new OpenAccountDAC();
            var openAccount    = openAccountDac.GetOpenAccount(FiiiType.FiiiPay, account.Id);

            if (openAccount == null)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, R.FiiiExAccountNotExist);
            }

            var crypto = new CryptocurrencyDAC().GetById(cryptoId);

            if (crypto == null)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, R.CurrencyForbidden);
            }

            var balance = this.FiiiExBalance(FiiiType.FiiiPay, account.Id, crypto);

            if (balance < amount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足);
            }

            //10091=参数不符合要求 10013=用户信息不存在 10024=用户币不存在 10025=用户币种余额不足 0=成功
            int result = FiiiExCoinOut(openAccount.OpenId, crypto.Code, amount, out string recordId);

            if (result == 10025)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足);
            }
            if (result != 0)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.从FiiiEx划转失败);
            }

            var walletDac = new UserWalletDAC();
            var wallet    = walletDac.GetByAccountId(account.Id, crypto.Id);
            UserExTransferOrder order;

            using (var scope = new TransactionScope())
            {
                if (wallet == null)
                {
                    wallet = new UserWalletComponent().GenerateWallet(account.Id, crypto.Id);
                }

                walletDac.Increase(wallet.Id, amount);
                order = new UserExTransferOrder
                {
                    Timestamp  = DateTime.UtcNow,
                    OrderNo    = CreateOrderNo(),
                    OrderType  = ExTransferType.FromEx,
                    AccountId  = account.Id,
                    WalletId   = wallet.Id,
                    CryptoId   = crypto.Id,
                    CryptoCode = crypto.Code,
                    Amount     = amount,
                    Status     = 1,
                    Remark     = null,
                    ExId       = recordId
                };

                order = new UserExTransferOrderDAC().Create(order);
                scope.Complete();
            }


            try
            {
                FiiiEXTransferMSMQ.PubUserTransferFromEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("PubUserTransferFromEx - error", ex);
            }
            return(new TransferResult
            {
                Id = order.Id,
                Amount = order.Amount.ToString(crypto.DecimalPlace),
                OrderNo = order.OrderNo,
                Timestamp = order.Timestamp.ToUnixTime(),
                CryptoCode = crypto.Code
            });
        }
Exemplo n.º 15
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");
            }
        }
Exemplo n.º 16
0
        public void DistributeRewards(FiiiPayRewardMessage message, int fiiicoinId)
        {
            MerchantAccountDAC maDAC = new MerchantAccountDAC();
            var merchant             = maDAC.GetByUsername(message.Account);

            if (merchant == null)
            {
                throw new CommonException(10000, $"无效的商家名:{message.Account}");
            }

            InviteRecord invitor = GetInvitor(merchant.Id);

            if (invitor == null)
            {
                throw new CommonException(10000, "没有邀请人");
            }

            var invitedList = new InviteRecordDAC().GetFiiiPosRecordsByInvitorId(invitor.InviterAccountId, InviteType.Fiiipos);
            var rewardRate  = GetRewardPercentage(invitedList == null ? 0 : invitedList.Count);

            if (rewardRate == 0)
            {
                throw new CommonException(10000, "没有达到奖励条件");
            }

            decimal t            = (decimal)Math.Pow(10, -8);
            long    nTotalReward = (long)Math.Floor(message.Reward * rewardRate);

            if (nTotalReward == 0)
            {
                throw new CommonException(10000, "奖励金额为0");
            }
            decimal  rewardAmount = nTotalReward * t;
            DateTime dtNow        = DateTime.UtcNow;

            if (message.CurrentDate > 0)
            {
                dtNow = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(message.CurrentDate);
            }
            var distributeRecord = new RewardDistributeRecords
            {
                UserAccountId     = invitor.InviterAccountId,
                MerchantAccountId = merchant.Id,
                SN             = message.SN,
                OriginalReward = message.Reward,
                Percentage     = rewardRate,
                ActualReward   = rewardAmount,
                Timestamp      = dtNow
            };

            long    profitId;
            decimal oldBalance    = 0;
            var     invitorWallet = uwDAC.GetByAccountId(invitor.InviterAccountId, fiiicoinId);

            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30)))
            {
                if (invitorWallet == null)
                {
                    invitorWallet = CreateWallet(invitor.InviterAccountId, fiiicoinId, rewardAmount);
                }
                else
                {
                    oldBalance = invitorWallet.Balance;
                    uwDAC.Increase(invitorWallet.Id, rewardAmount);
                }

                var profitDetail = new ProfitDetail
                {
                    InvitationId = invitor.Id,
                    CryptoAmount = rewardAmount,
                    AccountId    = invitor.InviterAccountId,
                    Status       = InviteStatusType.IssuedActive,
                    Type         = ProfitType.InvitePiiiPos,
                    OrderNo      = CreateOrderno(),
                    Timestamp    = dtNow,
                    CryptoId     = invitorWallet.CryptoId,
                    CryptoCode   = "FIII"
                };
                profitId = pfDAC.Insert(profitDetail);

                uwsDAC.Insert(new UserWalletStatement
                {
                    WalletId      = invitorWallet.Id,
                    Action        = UserWalletStatementAction.Reward,
                    Amount        = rewardAmount,
                    Balance       = oldBalance + rewardAmount,
                    FrozenAmount  = 0,
                    FrozenBalance = invitorWallet.FrozenBalance,
                    Timestamp     = dtNow
                });

                transDAC.Insert(new UserTransaction
                {
                    AccountId    = invitor.InviterAccountId,
                    Amount       = rewardAmount,
                    CryptoCode   = "FIII",
                    CryptoId     = fiiicoinId,
                    DetailId     = profitId.ToString(),
                    Id           = Guid.NewGuid(),
                    MerchantName = string.Empty,
                    OrderNo      = profitDetail.OrderNo,
                    Status       = 2,
                    Timestamp    = dtNow,
                    Type         = UserTransactionType.Profit
                });

                distributeRecord.ProfitId = profitId;
                rdrDAC.Insert(distributeRecord);

                scope.Complete();
            }

            if (profitId > 0)
            {
                try
                {
                    MessagePushService.PubUserInviteSuccessed(profitId, 0);
                }
                catch (Exception ex)
                {
                    throw new CommonException(10000, ex.Message);
                }
            }
        }
Exemplo n.º 17
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()
            });
        }