public MerchantSupportReceiptWalletDTO GetSupportReceiptByFiatCurrency(Guid accountId, string fiatCurrency, int coinId)
        {
            var account = new MerchantAccountDAC().GetById(accountId);
            var crypto  = new CryptocurrencyDAC().GetById(coinId);

            var marketPriceComponent = new MarketPriceComponent();
            var marketPrice          = marketPriceComponent.GetMarketPrice(fiatCurrency, crypto.Code);

            var supportReceiptWallets = new MerchantWalletDAC().SupportReceiptList(accountId);
            var singleSupportWallet   = supportReceiptWallets.FirstOrDefault(e => e.CryptoId == crypto.Id);

            if (singleSupportWallet == null)
            {
                return(new MerchantSupportReceiptWalletDTO());
            }

            return(new MerchantSupportReceiptWalletDTO
            {
                WalletId = singleSupportWallet.Id,
                CryptoId = crypto.Id,
                CryptoStatus = crypto.Status,
                CryptoCode = crypto.Code,
                CryptoName = crypto.Name,
                IconURL = crypto.IconURL,
                DecimalPlace = crypto.DecimalPlace,
                Markup = account.Markup,
                MarketPrice = marketPrice?.Price.ToString("F"),
                CryptoEnable = crypto.Enable
            });
        }
Esempio n. 2
0
        private GetMerchantDetailOM GetFiiiPosMerchantDetail(MerchantInformation merchantDetail)
        {
            var weekArray = Enum.GetValues(typeof(Week));

            var weekList = new List <int>();

            foreach (var item in weekArray)
            {
                if (merchantDetail.Week.HasFlag((Enum)item))
                {
                    weekList.Add((int)Math.Log((int)item, 2) + 1);
                }
            }

            var currencyList  = new MerchantWalletDAC().SupportReceiptList(merchantDetail.MerchantAccountId);
            var cryptoDict    = new CryptocurrencyDAC().GetAll().ToDictionary(item => item.Code);
            var imageList     = new MerchantOwnersFigureDAC().GetOwnersFiguresById(merchantDetail.Id);
            var recommendList = new MerchantRecommendDAC().GetRecommendsById(merchantDetail.Id);

            var result = new GetMerchantDetailOM()
            {
                AccountType             = (int)Entities.Enums.AccountType.Merchant,
                IsAllowExpense          = merchantDetail.IsAllowExpense,
                AvailableCryptoCodeList = currencyList.Select(item => item.CryptoCode).ToList(),
                AvailableCryptoIconList = currencyList.Select(item =>
                {
                    if (cryptoDict.ContainsKey(item.CryptoCode))
                    {
                        return(cryptoDict[item.CryptoCode].IconURL.ToString());
                    }
                    return(string.Empty);
                }).Where(item => !string.IsNullOrEmpty(item)).ToList(),
                Address       = merchantDetail.Address,
                EndDate       = merchantDetail.EndTime,
                StartDate     = merchantDetail.StartTime,
                BussinessHour = merchantDetail.WeekTxt,
                ImageUrls     = imageList.Select(item => item.FileId).ToList(),
                Location      = new Location()
                {
                    Longitude = merchantDetail.Lng, Latitude = merchantDetail.Lat
                },
                Introduce      = merchantDetail.Introduce,
                RecommendGoods = recommendList.Select(item => new Goods()
                {
                    Content = item.RecommendContent, Image = new ImageWithCompressImage()
                    {
                        Compress = item.ThumbnailId, Origin = item.RecommendPicture
                    }
                }).ToList(),
                Tags      = merchantDetail.Tags.Split(','),
                Title     = merchantDetail.MerchantName,
                Phone     = merchantDetail.Phone,
                PhoneCode = merchantDetail.PhoneCode,
                Weeks     = weekList
            };

            return(result);
        }
Esempio n. 3
0
        public List <GetMerchantInfoOM> GetMerchantInfoList(GetMerchantInfoListIM im)
        {
            if (im.PageSize > 20)
            {
                im.PageSize = 20;
            }
            List <MerchantBriefInformation> list;

            if (im.Location == null)
            {
                list = new MerchantInformationDAC().QueryMerchantListByCountryId(im.Filter.CountryId, im.PageIndex, im.PageSize, im.Filter.KeyWord,
                                                                                 im.Filter.Category);
            }
            else
            {
                list = new MerchantInformationDAC().QueryNearbyMerchantList(im.Location.Latitude, im.Location.Longitude, im.Filter.CountryId, im.PageSize, im.PageIndex, im.Filter.KeyWord, im.Filter.Category);
            }

            var mwDAC      = new MerchantWalletDAC();
            var mscDAC     = new MerchantSupportCryptoDAC();
            var cryptoList = new CryptoComponent().GetList();

            return(list.Select(item =>
            {
                List <int> supportCryptoIdList = new List <int>();
                if (item.AccountType == (byte)AccountType.Merchant)
                {
                    supportCryptoIdList = mwDAC.SupportReceiptList(item.MerchantAccountId).Select(t => t.CryptoId).ToList();
                }
                else
                {
                    supportCryptoIdList = mscDAC.GetList(item.Id).Select(t => t.CryptoId).ToList();
                }

                return new GetMerchantInfoOM()
                {
                    AccountType = item.AccountType,
                    IsAllowExpense = item.IsAllowExpense,
                    Address = item.Address,
                    AvailableCryptoIconList = cryptoList.Where(c => supportCryptoIdList.Contains(c.Id)).Select(t => t.IconURL.ToString()).ToList(),
                    Distance = item.Distance.ToSpecificDecimal(2).ToString(CultureInfo.InvariantCulture),
                    OriginIconId = item.FileId,
                    CompressIconId = item.ThumbnailId ?? Guid.Empty,
                    Id = item.MerchantInformationId,
                    Location = new Location()
                    {
                        Longitude = item.Lng, Latitude = item.Lat
                    },
                    Tags = item.Tags.Split(',').ToList(),
                    Title = item.MerchantName
                };
            }).ToList());
        }
Esempio n. 4
0
        public PrePayOM PrePay(UserAccount user, PrePayIM im)
        {
            var merchantAccount = GetMerchantAccountByIdOrCode(im.MerchantId, im.MerchantCode);
            var userWallets     = new UserWalletDAC().GetUserWallets(user.Id);
            var merchantWallets = new MerchantWalletDAC().GetByAccountId(merchantAccount.Id);
            var coins           = new CryptocurrencyDAC().GetAllActived();
            var priceList       = new PriceInfoDAC().GetPrice(merchantAccount.FiatCurrency);

            bool showWhiteLable = false;

            if (merchantAccount.POSId.HasValue)
            {
                var pos = new POSDAC().GetById(merchantAccount.POSId.Value);
                if (pos.IsWhiteLabel)
                {
                    showWhiteLable = true;
                }
            }

            if (!showWhiteLable)
            {
                var whilteLabelCryptoCode = new POSDAC().GetWhiteLabelCryptoCode();
                coins.RemoveAll(t => t.Code == whilteLabelCryptoCode);
            }

            return(new PrePayOM
            {
                FiatCurrency = merchantAccount.FiatCurrency,
                MarkupRate = merchantAccount.Markup.ToString(CultureInfo.InvariantCulture),
                WaletList = coins.Select(a =>
                {
                    var userWallet = userWallets.FirstOrDefault(b => b.CryptoId == a.Id);
                    decimal rate = 0;
                    rate = priceList.Where(t => t.CryptoID == a.Id).Select(t => t.Price).FirstOrDefault();
                    return GetItem(userWallet, a, merchantWallets, rate);
                }).OrderByDescending(a => a.MerchantSupported).ThenBy(a => a.PayRank).Select(a => new WalletItem
                {
                    Code = a.Code,
                    NewStatus = a.NewStatus,
                    ExchangeRate = a.ExchangeRate,
                    FrozenBalance = a.FrozenBalance,
                    IconUrl = a.IconUrl,
                    Id = a.Id,
                    MerchantSupported = a.MerchantSupported,
                    Name = a.Name,
                    UseableBalance = a.UseableBalance,
                    FiatBalance = a.FiatBalance,
                    DecimalPlace = a.DecimalPlace,
                    CryptoEnable = a.CryptoEnable
                }).ToList()
            });
        }
        public WithdrawalConditionInfo GetWithdrawalInfo(Guid accountId, int cryptoId)
        {
            var result = new WithdrawalConditionInfo();

            var profileAgent = new MerchantProfileAgent();
            var profile      = profileAgent.GetMerchantProfile(accountId);
            var crypto       = new CryptocurrencyDAC().GetById(cryptoId);

            result.NeedTag = crypto.NeedTag;

            var wallet = new MerchantWalletDAC().GetByAccountId(accountId, cryptoId) ?? GenerateWallet(accountId, cryptoId, crypto.Code);

            //余额
            result.Balance = wallet.Balance.ToString(crypto.DecimalPlace);

            int level = profile.L2VerifyStatus == VerifyStatus.Certified ? 2 : profile.L1VerifyStatus == VerifyStatus.Certified ? 1 : 0;

            var masterSetting = GetMerchantWithdrawalMasterSettingWithCrypto(crypto, level);

            //最小提币量
            result.MinWithdrawalAmount = masterSetting.ToOutsideMinAmount.ToString(CultureInfo.InvariantCulture);
            // to fiiipay min withdraw amount
            result.ToFiiiPayMinWithdrawalAmount = masterSetting.ToUserMinAmount.ToString(CultureInfo.InvariantCulture);
            //手续费率
            result.HandleFeeTier = (crypto.Withdrawal_Tier ?? 0).ToString(CultureInfo.InvariantCulture);
            result.HandleFee     = (crypto.Withdrawal_Fee ?? 0).ToString(CultureInfo.InvariantCulture);
            result.DecimalPlace  = crypto.DecimalPlace;
            //限额
            result.VerifyLevel   = level;
            result.PerTxLimit    = masterSetting.PerTxLimit.ToString(crypto.DecimalPlace);
            result.PerDayLimit   = masterSetting.PerDayLimit.ToString(crypto.DecimalPlace);
            result.PerMonthLimit = masterSetting.PerMonthLimit.ToString(crypto.DecimalPlace);
            var     dac               = new MerchantWithdrawalDAC();
            var     today             = DateTime.UtcNow.Date;
            decimal dailyWithdrawal   = dac.DailyWithdrawal(accountId, cryptoId, today);
            decimal monthlyWithdrawal = dac.MonthlyWithdrawal(accountId, cryptoId, new DateTime(today.Year, today.Month, 1));
            decimal dayUsable         = masterSetting.PerDayLimit - dailyWithdrawal;
            decimal monthUsable       = masterSetting.PerMonthLimit - monthlyWithdrawal;

            dayUsable = Math.Min(dayUsable, monthUsable);

            result.PerDayUsable   = (dayUsable < 0 ? 0 : dayUsable).ToString(crypto.DecimalPlace);
            result.PerMonthUsable = (monthUsable < 0 ? 0 : monthUsable).ToString(crypto.DecimalPlace);

            return(result);
        }
Esempio n. 6
0
        public override Wallet Insert(Wallet wallet)
        {
            var merchantWallet = new MerchantWallet
            {
                MerchantAccountId = wallet.AccountId,
                CryptoId          = wallet.CryptoId,
                Status            = MerchantWalletStatus.Displayed,
                Balance           = wallet.Balance,
                FrozenBalance     = wallet.FrozenBalance,
                Address           = wallet.Address,
                SupportReceipt    = false,
            };

            merchantWallet = new MerchantWalletDAC().Insert(merchantWallet);
            wallet.Id      = merchantWallet.Id;
            return(wallet);
        }
        public TransactionFeeDTO TransactionFeeRate(int coinId, string address, string tag)
        {
            var  userWalletDAC     = new UserWalletDAC();
            var  merchantWalletDAC = new MerchantWalletDAC();
            var  coin             = new CryptocurrencyDAC().GetById(coinId);
            var  isUserWallet     = userWalletDAC.IsUserWalletAddress(address);
            var  isMerchantWallet = merchantWalletDAC.IsMerchantWalletAddress(address);
            bool isFiiiAccount    = isUserWallet || isMerchantWallet;

            if (isFiiiAccount)
            {
                var withdrawMasterSetting = GetMerchantWithdrawalMasterSetting();
                var result = new TransactionFeeDTO
                {
                    TransactionFee     = "0",
                    TransactionFeeRate = withdrawMasterSetting.ToUserHandleFeeTier.ToString(CultureInfo.InvariantCulture)
                };

                var userWallet = userWalletDAC.GetByAddressAndCrypto(coinId, address, tag);
                if (userWallet?.CryptoId == coinId)
                {
                    result.CryptoAddressType = CryptoAddressType.FiiiPay;
                    return(result);
                }

                var merchantWallet = new MerchantWalletDAC().GetByAddress(address, tag);
                if (merchantWallet?.CryptoId == coinId)
                {
                    result.CryptoAddressType = CryptoAddressType.FiiiPOS;
                    return(result);
                }

                result.CryptoAddressType = CryptoAddressType.InsideWithError;
                return(result);
            }
            else
            {
                return(new TransactionFeeDTO
                {
                    CryptoAddressType = CryptoAddressType.Outside,
                    TransactionFee = (coin.Withdrawal_Fee ?? 0).ToString(CultureInfo.InvariantCulture),
                    TransactionFeeRate = (coin.Withdrawal_Tier ?? 0).ToString(CultureInfo.InvariantCulture)
                });
            }
        }
Esempio n. 8
0
        public string FiiiPOSTransferInto(MerchantAccount account, Cryptocurrency coin, decimal amount)
        {
            var walletDac = new MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(account.Id, coin.Id);
            MerchantExTransferOrder order;

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

                walletDac.Increase(wallet.Id, amount);

                order = new MerchantExTransferOrder
                {
                    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 MerchantExTransferOrderDAC().Create(order);

                scope.Complete();
            }

            try
            {
                FiiiEXTransferMSMQ.PubMerchantTransferFromEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("PubMerchantTransferFromEx - error", ex);
            }
            return(order.OrderNo);
        }
Esempio n. 9
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);
        }
        public MerchantWallet GenerateWallet(Guid accountId, int cryptoId, string cryptoCode, int sequence = 10000, bool supportReceipt = false)
        {
            var merchantWallet = new MerchantWallet
            {
                MerchantAccountId = accountId,
                CryptoId          = cryptoId,
                CryptoCode        = cryptoCode,
                Status            = MerchantWalletStatus.Displayed,
                Balance           = 0,
                FrozenBalance     = 0,
                SupportReceipt    = supportReceipt,
                Sequence          = sequence
            };

            merchantWallet = new MerchantWalletDAC().Insert(merchantWallet);

            return(merchantWallet);
        }
Esempio n. 11
0
        public override Wallet GetByAccountId(Guid accountId, int cryptoId)
        {
            var baseWallet = new MerchantWalletDAC().GetByAccountId(accountId, cryptoId);

            if (baseWallet == null)
            {
                return(null);
            }
            return(new Wallet
            {
                Id = baseWallet.Id,
                AccountId = baseWallet.MerchantAccountId,
                CryptoId = baseWallet.CryptoId,
                Balance = baseWallet.Balance,
                FrozenBalance = baseWallet.FrozenBalance,
                Address = baseWallet.Address
            });
        }
Esempio n. 12
0
        public TransactionFeeRateOM TransactionFeeRate(int coinId, string address, string tag)
        {
            var  userWalletDAC     = new UserWalletDAC();
            var  merchantWalletDAC = new MerchantWalletDAC();
            var  coin             = new CryptocurrencyDAC().GetById(coinId);
            var  mastSettings     = new MasterSettingDAC().SelectByGroup("UserWithdrawal");
            var  isUserWallet     = userWalletDAC.IsUserWalletAddress(address);
            var  isMerchantWallet = merchantWalletDAC.IsMerchantWalletAddress(address);
            bool isFiiiAccount    = isUserWallet || isMerchantWallet;

            if (isFiiiAccount)
            {
                var userWallet = userWalletDAC.GetByAddressAndCrypto(coinId, address, tag);
                var result     = new TransactionFeeRateOM
                {
                    CryptoAddressType  = CryptoAddressType.FiiiPay,
                    TransactionFee     = "0",
                    TransactionFeeRate = mastSettings.First(e => e.Name == "UserWithdrawal_ToUser").Value
                };
                if (userWallet != null)
                {
                    return(result);
                }

                var merchantWallet = merchantWalletDAC.GetByAddressAndCrypto(coinId, address, tag);
                if (merchantWallet != null)
                {
                    result.CryptoAddressType = CryptoAddressType.FiiiPOS;
                    return(result);
                }

                result.CryptoAddressType = CryptoAddressType.InsideWithError;
                return(result);
            }
            else
            {
                return(new TransactionFeeRateOM
                {
                    CryptoAddressType = CryptoAddressType.Outside,
                    TransactionFee = (coin.Withdrawal_Fee ?? 0).ToString(CultureInfo.InvariantCulture),
                    TransactionFeeRate = (coin.Withdrawal_Tier ?? 0).ToString(CultureInfo.InvariantCulture)
                });
            }
        }
        public DepositAddressInfo GetDepositAddressById(Guid accountId, int cryptoId)
        {
            var crypto = new CryptocurrencyDAC().GetById(cryptoId);

            if (crypto == null)
            {
                throw new CommonException(ReasonCode.RECORD_NOT_EXIST, Resources.支持的币种);
            }

            if (!crypto.Status.HasFlag(CryptoStatus.Deposit))
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            if (crypto.Enable == (byte)CurrencyStatus.Forbidden)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            var dac    = new MerchantWalletDAC();
            var wallet = dac.GetByAccountId(accountId, cryptoId) ?? GenerateWallet(accountId, cryptoId, crypto.Code);

            if (string.IsNullOrEmpty(wallet.Address))
            {
                var accountDAC = new MerchantAccountDAC();
                var account    = accountDAC.GetById(accountId);

                var result = new FiiiFinanceAgent().CreateWallet(crypto.Code, account.Id, AccountTypeEnum.Merchant, account.Email, $"{account.PhoneCode}{account.Cellphone}");
                if (string.IsNullOrWhiteSpace(result.Address))
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.FailedGenerateAddress);
                }

                wallet.Address = result.Address;
                wallet.Tag     = result.DestinationTag;

                dac.UploadAddress(wallet.Id, wallet.Address, wallet.Tag);
            }

            return(new DepositAddressInfo {
                Address = wallet.Address, Tag = wallet.Tag, NeedTag = crypto.NeedTag
            });
        }
        public List <MerchantWalletDTO> GetMerchantWalletList(Guid merchantAccountId)
        {
            var account    = new MerchantAccountDAC().GetById(merchantAccountId);
            var cryptoList = new CryptocurrencyDAC().GetAllActived();

            cryptoList.MoveTop(t => t.Code == FIIICOIN_CODE);

            var pos = new POSDAC().GetById(account.POSId.Value);

            if (!pos.IsWhiteLabel)
            {
                cryptoList.RemoveAll(t => t.IsWhiteLabel == 1);
            }
            else
            {
                cryptoList.MoveTop(t => t.Code == pos.FirstCrypto);
            }

            var walletList   = new MerchantWalletDAC().GetByAccountId(merchantAccountId);
            var currencyId   = new CurrenciesDAC().GetByCode(account.FiatCurrency).ID;
            var exchangeRate = new PriceInfoDAC().GetByCurrencyId(currencyId).ToDictionary(item => item.CryptoID);

            return(cryptoList.Select(e =>
            {
                var wallet = walletList.FirstOrDefault(w => w.CryptoId == e.Id);
                return new MerchantWalletDTO
                {
                    WalletId = wallet?.Id ?? 0,
                    CryptoId = e.Id,
                    CryptoStatus = e.Status,
                    CryptoCode = e.Code,
                    CryptoName = e.Name,
                    IconURL = e.IconURL,
                    DecimalPlace = e.DecimalPlace,
                    Balance = (wallet?.Balance ?? 0).ToString(e.DecimalPlace),
                    FrozenBalance = (wallet?.FrozenBalance ?? 0).ToString(e.DecimalPlace),
                    FiatExchangeRate = (exchangeRate.ContainsKey(e.Id) ? exchangeRate[e.Id].Price : 0m).ToString(4),
                    FiatBalance = (((wallet?.Balance ?? 0) + (wallet?.FrozenBalance ?? 0)) * (exchangeRate.ContainsKey(e.Id) ? exchangeRate[e.Id].Price : 0m)).ToString(4),
                    FiatCode = account.FiatCurrency,
                    CryptoEnable = e.Enable
                };
            }).ToList());
        }
Esempio n. 15
0
        public TransferFiiiExConditionDTO FiiiPOSTransferFiiiExCondition(Guid accountId, int cryptoId)
        {
            var crypto    = new CryptocurrencyDAC().GetById(cryptoId);
            var walletDac = new MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(accountId, crypto.Id);

            var fiiiExBalance = this.FiiiExBalance(FiiiType.FiiiPOS, accountId, crypto);

            var minQuantity =
                (1M / (decimal)Math.Pow(10, crypto.DecimalPlace)).ToString(crypto.DecimalPlace);

            return(new TransferFiiiExConditionDTO
            {
                Balance = (wallet?.Balance ?? 0M).ToString(crypto.DecimalPlace),
                MinQuantity = minQuantity,
                FiiiExBalance = fiiiExBalance.ToString(crypto.DecimalPlace),
                FiiiExMinQuantity = minQuantity
            });
        }
Esempio n. 16
0
        public List <MerchantTransferDTO> TransferStatement(Guid merchantAccountId, long merchantWalletId, int pageIndex, int pageSize)
        {
            var dac  = new MerchantWalletDAC();
            var list = dac.GetMerchantTransferStatementById(merchantAccountId, merchantWalletId, pageIndex, pageSize);

            var cryptoList = new CryptocurrencyDAC().GetAll();

            return(list.Select(e =>
            {
                var crypto = cryptoList.FirstOrDefault(c => c.Id == e.CryptoId);

                return new MerchantTransferDTO
                {
                    Id = e.Id,
                    TransactionType = e.TransferType,
                    TransactionStatus = e.Status,
                    CryptoCode = crypto?.Code,
                    Amount = e.Amount.ToString(crypto?.DecimalPlace ?? 0),
                    Timestamp = e.Timestamp.ToUnixTime()
                };
            }).ToList());
        }
Esempio n. 17
0
        public void PushDepositCancel(long id)
        {
            var deposit = new MerchantDepositDAC().GetById(id);
            var wallet  = new MerchantWalletDAC().GetById(deposit.MerchantWalletId);
            var crypto  = new CryptocurrencyDAC().GetById(wallet.CryptoId);

            var regId       = RedisHelper.StringGet($"{FiiiPOS_APP_Notice_MerchantId}:{deposit.MerchantAccountId}");
            var lang        = RedisHelper.StringGet(REDIS_LANGUAGE_DBINDEX, $"{FiiiPOS_APP_Language_MerchantId}:{deposit.MerchantAccountId}") ?? "en";
            var titleKey    = "DepositCancelTitle";
            var subTitleKey = "DepositCancelSubTitle";
            var title       = ResourceHelper.FiiiPos.GetFormatResource(titleKey, lang, crypto.Code);
            var subTitle    = ResourceHelper.FiiiPos.GetFormatResource(subTitleKey, lang, crypto.Code);

            string noticeId = "";

            //写MongoDB [充币失败]
            MessagesComponent.AddMessage(deposit.MerchantAccountId, UserType.Merchant, id.ToString(), FiiiPayPushType.TYPE_DEPOSIT_CANCEL, titleKey, subTitleKey, crypto.Code, title, subTitle, out noticeId);

            RegPush(FiiiPayPushType.TYPE_DEPOSIT_CANCEL, new List <string> {
                regId
            }, id, title, subTitle, noticeId);
            LogHelper.Info($"--------{lang}------{title}----------{subTitle}");
        }
Esempio n. 18
0
        public void PushWithdrawReject(long id)
        {
            var withdraw = new MerchantWithdrawalDAC().GetById(id);
            var wallet   = new MerchantWalletDAC().GetById(withdraw.MerchantWalletId);
            var crypto   = new CryptocurrencyDAC().GetById(wallet.CryptoId);

            var regId       = RedisHelper.StringGet($"{FiiiPOS_APP_Notice_MerchantId}:{withdraw.MerchantAccountId}");
            var lang        = RedisHelper.StringGet(REDIS_LANGUAGE_DBINDEX, $"{FiiiPOS_APP_Language_MerchantId}:{withdraw.MerchantAccountId}") ?? "en";
            var titleKey    = "WithdrawalRejectTitle";
            var subTitleKey = "WithdrawalRejectSubTitle";
            var title       = ResourceHelper.FiiiPos.GetFormatResource(titleKey, lang, crypto.Code);
            var subTitle    = ResourceHelper.FiiiPos.GetResource(subTitleKey, lang);

            string noticeId = "";

            //写MongoDB [提币失败]
            MessagesComponent.AddMessage(withdraw.MerchantAccountId, UserType.Merchant, id.ToString(), FiiiPayPushType.TYPE_WITHDRAWAL_Reject, titleKey, subTitleKey, crypto.Code, title, subTitle, out noticeId);

            RegPush(FiiiPayPushType.TYPE_WITHDRAWAL_Reject, new List <string> {
                regId
            }, id, title, subTitle, noticeId);
            LogHelper.Info($"--------{lang}------{title}----------{subTitle}");
        }
        public MerchantWalletDTO GetWalletInfoById(Guid accountId, int cryptoId)
        {
            var crypto       = new CryptocurrencyDAC().GetById(cryptoId);
            var wallet       = new MerchantWalletDAC().GetByAccountId(accountId, cryptoId);
            var merchant     = new MerchantAccountDAC().GetById(accountId);
            var currencyId   = new CurrenciesDAC().GetByCode(merchant.FiatCurrency).ID;
            var exchangeRate = new PriceInfoDAC().GetByCurrencyId(currencyId).ToDictionary(item => item.CryptoID);

            return(new MerchantWalletDTO
            {
                WalletId = wallet?.Id ?? 0,
                CryptoId = crypto.Id,
                CryptoCode = crypto.Code,
                CryptoName = crypto.Name,
                IconURL = crypto.IconURL,
                DecimalPlace = crypto.DecimalPlace,
                Balance = (wallet?.Balance ?? 0).ToString(crypto.DecimalPlace),
                FrozenBalance = (wallet?.FrozenBalance ?? 0).ToString(crypto.DecimalPlace),
                FiatExchangeRate = (exchangeRate.ContainsKey(crypto.Id) ? exchangeRate[crypto.Id].Price : 0m).ToString(4),
                FiatBalance = (((wallet?.Balance ?? 0) + (wallet?.FrozenBalance ?? 0)) * (exchangeRate.ContainsKey(crypto.Id) ? exchangeRate[crypto.Id].Price : 0m)).ToString(4),
                FiatCode = merchant.FiatCurrency
            });
        }
        public MerchantTotalAssetsDTO GetMerchantTotalAssets(Guid accountId)
        {
            var account    = new MerchantAccountDAC().GetById(accountId);
            var walletList = new MerchantWalletDAC().GetByAccountId(accountId);

            decimal totalPrice = 0m;

            if (walletList.Count > 0)
            {
                var cryptoList = new CryptocurrencyDAC().GetAllActived();
                if (account.POSId.HasValue)
                {
                    var pos = new POSDAC().GetById(account.POSId.Value);
                    if (!pos.IsWhiteLabel)
                    {
                        cryptoList.RemoveAll(t => t.IsWhiteLabel == 1);
                    }
                }

                var marketPriceList = new MarketPriceComponent().GetMarketPrice(account.FiatCurrency);

                totalPrice = walletList.Sum(e =>
                {
                    var coin        = cryptoList.FirstOrDefault(c => c.Id == e.CryptoId);
                    var marketPrice = marketPriceList.FirstOrDefault(m => m.CryptoName == coin?.Code);

                    return((e.Balance + e.FrozenBalance) * (marketPrice?.Price ?? 0));
                });
            }

            return(new MerchantTotalAssetsDTO
            {
                FiatCurrency = account.FiatCurrency,
                Amount = totalPrice.ToString("N", CultureInfo.InvariantCulture),
                IsAllowWithDrawal = account.IsAllowWithdrawal
            });
        }
Esempio n. 21
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);
        }
Esempio n. 22
0
        public TransferResult FiiiPOSTransferToEx(Guid accountId, int cryptoId, decimal amount, string pinToken)
        {
            var securityVerify = new SecurityVerification(SystemPlatform.FiiiPOS);

            securityVerify.VerifyToken(accountId, pinToken, SecurityMethod.Pin);

            var openAccountDac = new OpenAccountDAC();
            var openAccount    = openAccountDac.GetOpenAccount(FiiiType.FiiiPOS, accountId);

            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 walletDac = new MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(accountId, crypto.Id);

            if (wallet.Balance < amount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足);
            }
            //10091=参数不符合要求 10013=用户信息不存在 10020=币不存在 0=成功
            int result = FiiiExCoinIn(openAccount.OpenId, crypto.Code, amount, out string recordId);

            if (result != 0)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.从FiiiEx划转失败);
            }
            MerchantExTransferOrder order;

            using (var scope = new TransactionScope())
            {
                walletDac.Decrease(wallet.Id, amount);
                order = new MerchantExTransferOrder
                {
                    Timestamp  = DateTime.UtcNow,
                    OrderNo    = CreateOrderNo(),
                    OrderType  = ExTransferType.ToEx,
                    AccountId  = accountId,
                    WalletId   = wallet.Id,
                    CryptoId   = crypto.Id,
                    CryptoCode = crypto.Code,
                    Amount     = amount,
                    Status     = 1,
                    Remark     = null,
                    ExId       = recordId
                };

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

            try
            {
                FiiiEXTransferMSMQ.PubMerchantTransferToEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("FiiiPOSTransferToEx - error", ex);
            }

            return(new TransferResult
            {
                Id = order.Id,
                Amount = order.Amount.ToString(crypto.DecimalPlace),
                OrderNo = order.OrderNo,
                Timestamp = order.Timestamp.ToUnixTime(),
                CryptoCode = crypto.Code
            });
        }
Esempio n. 23
0
        public async Task <ScanMerchantQRCodeOM> ScanMerchantQRCode(UserAccount user, string code)
        {
            var codeEntity = QRCode.Deserialize(code);

            if (codeEntity.SystemPlatform != SystemPlatform.FiiiPOS || codeEntity.QrCodeEnum != QRCodeEnum.MerchantScanPay)
            {
                throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode);
            }
            Guid merchantId         = Guid.Parse(codeEntity.QRCodeKey);
            ScanMerchantQRCodeOM om = new ScanMerchantQRCodeOM();

            var merchantAccount = GetMerchantAccountByIdOrCode(merchantId, null);

            //if (merchantAccount.POSId == null)
            //{
            //    throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode);
            //}

            if (merchantAccount.Status == AccountStatus.Locked || !merchantAccount.IsAllowAcceptPayment)
            {
                throw new CommonException(ReasonCode.MERCHANT_ACCOUNT_DISABLED, MessageResources.MerchantAccountDisabled);
            }

            Guid.TryParse(merchantAccount.Photo, out Guid merchantAvatar);

            var uwDAC = new UserWalletDAC();
            var mwDAC = new MerchantWalletDAC();

            var userWallets     = uwDAC.GetUserWallets(user.Id);
            var merchantWallets = mwDAC.GetByAccountId(merchantAccount.Id);
            var coins           = new CryptocurrencyDAC().GetAllActived();
            var priceList       = new PriceInfoDAC().GetPrice(merchantAccount.FiatCurrency);

            //判断Pos机是否白标用户
            bool showWhiteLable = false;

            if (merchantAccount.POSId.HasValue)
            {
                var pos = new POSDAC().GetById(merchantAccount.POSId.Value);
                if (pos.IsWhiteLabel)
                {
                    showWhiteLable = true;
                }
            }

            if (!showWhiteLable)
            {
                var whilteLabelCryptoCode = new POSDAC().GetWhiteLabelCryptoCode();
                coins.RemoveAll(t => t.Code == whilteLabelCryptoCode);
            }

            return(await Task.FromResult(new ScanMerchantQRCodeOM
            {
                MerchantId = merchantAccount.Id,
                MerchantName = merchantAccount.MerchantName,
                Avatar = merchantAvatar,
                L1VerifyStatus = (byte)merchantAccount.L1VerifyStatus,
                L2VerifyStatus = (byte)merchantAccount.L2VerifyStatus,
                FiatCurrency = merchantAccount.FiatCurrency,
                MarkupRate = merchantAccount.Markup.ToString(CultureInfo.InvariantCulture),
                WaletInfoList = coins.Select(a =>
                {
                    var userWallet = userWallets.FirstOrDefault(b => b.CryptoId == a.Id);
                    decimal rate = 0;
                    rate = priceList.Where(t => t.CryptoID == a.Id).Select(t => t.Price).FirstOrDefault();
                    return GetItem(userWallet, a, merchantWallets, rate);
                }).OrderByDescending(a => a.MerchantSupported).ThenBy(a => a.PayRank).Select(a => new WalletItem
                {
                    Code = a.Code,
                    NewStatus = a.NewStatus,
                    ExchangeRate = a.ExchangeRate,
                    FrozenBalance = a.FrozenBalance,
                    IconUrl = a.IconUrl,
                    Id = a.Id,
                    MerchantSupported = a.MerchantSupported,
                    Name = a.Name,
                    UseableBalance = a.UseableBalance,
                    FiatBalance = a.FiatBalance,
                    DecimalPlace = a.DecimalPlace,
                    CryptoEnable = a.CryptoEnable
                }).ToList()
            }));
        }
Esempio n. 24
0
        /// <summary>
        /// 用户主动支付
        /// </summary>
        /// <param name="user"></param>
        /// <param name="im"></param>
        /// <returns></returns>
        public PayOrderOM Pay(UserAccount user, PayIM im)
        {
            if (im.Amount <= 0)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, MessageResources.AmountGreater);
            }

            new SecurityComponent().VerifyPin(user, im.Pin);

            var isAllowExpense = user.IsAllowExpense ?? true;

            if (!isAllowExpense)
            {
                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 merchantAccount = GetMerchantAccountByIdOrCode(im.MerchantId, im.MerchantCode);

            if (merchantAccount == null)
            {
                throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode);
            }

            if (!merchantAccount.IsAllowAcceptPayment || merchantAccount.Status == AccountStatus.Locked)
            {
                throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantExceptionTransClose);
            }

            var country = new CountryComponent().GetById(merchantAccount.CountryId);

            var orderData = new Order
            {
                Id                  = Guid.NewGuid(),
                OrderNo             = IdentityHelper.OrderNo(),
                MerchantAccountId   = merchantAccount.Id,
                CryptoId            = coin.Id,
                CryptoCode          = coin.Code,
                FiatAmount          = im.Amount,
                PaymentType         = im.PaymentType,
                FiatCurrency        = merchantAccount.FiatCurrency,
                Status              = OrderStatus.Completed,
                ExpiredTime         = DateTime.UtcNow.AddMinutes(30),
                Markup              = merchantAccount.Markup,
                ExchangeRate        = GetExchangeRate(merchantAccount.CountryId, merchantAccount.FiatCurrency, coin),
                UnifiedExchangeRate = GetExchangeRate(merchantAccount.CountryId, country.FiatCurrency ?? "USD", coin),
                UnifiedFiatCurrency = country.FiatCurrency ?? "USD",
                MerchantIP          = null,
                PaymentTime         = DateTime.UtcNow,
                UserAccountId       = user.Id,
                Timestamp           = DateTime.UtcNow
            };

            var order = Generate(merchantAccount, coin, country.FiatCurrency ?? "USD", im.Amount, im.PaymentType);

            order.UserAccountId = user.Id;

            var userWallet = new UserWalletDAC().GetByAccountId(user.Id, im.CoinId);

            if (userWallet.Balance < order.CryptoAmount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }

            order.Status      = OrderStatus.Completed;
            order.PaymentTime = DateTime.UtcNow;

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

            if (merchantWallet == null || !merchantWallet.SupportReceipt)
            {
                throw new ApplicationException(MessageResources.MerchantNotSupperCrypto);
            }

            if (merchantAccount.WithdrawalFeeType != WithdrawalFeeType.FiiiCoin)
            {
                var calcModel =
                    CalculateAmount(im.Amount, merchantAccount.Markup, merchantAccount.Receivables_Tier, orderData.ExchangeRate, coin);

                orderData.ActualFiatAmount   = calcModel.FiatTotalAmount;
                orderData.CryptoAmount       = calcModel.CryptoAmount;
                orderData.TransactionFee     = calcModel.TransactionFee;
                orderData.ActualCryptoAmount = calcModel.ActualCryptoAmount;

                var model = CalculateUnifiedAmount(orderData.CryptoAmount, orderData.ActualCryptoAmount, orderData.UnifiedExchangeRate);
                orderData.UnifiedFiatAmount       = model.UnifiedFiatAmount;
                orderData.UnifiedActualFiatAmount = model.UnifiedActualFiatAmount;
                var orderWithdrawalFee = new OrderWithdrawalFee
                {
                    Timestamp = DateTime.UtcNow,
                    CryptoId  = orderData.CryptoId,
                    Amount    = 0
                };

                Execute(orderWithdrawalFee);
            }
            else
            {
                var orderWithdrawalFee = CalculateOrderAmount(ref orderData, new RedisOrderDTO()
                {
                    CountryId = merchantAccount.CountryId, FiatAmount = im.Amount
                }, merchantAccount, coin);
                var wallet = new MerchantWalletDAC().GetByAccountId(merchantAccount.Id, new CryptocurrencyDAC().GetByCode("FIII").Id);
                if (orderWithdrawalFee.Amount != 0)
                {
                    using (var scope = new TransactionScope())
                    {
                        var dbOrder = new OrderDAC().Create(orderData);
                        new UserTransactionDAC().Insert(new UserTransaction
                        {
                            Id           = Guid.NewGuid(),
                            AccountId    = userWallet.UserAccountId,
                            CryptoId     = userWallet.CryptoId,
                            CryptoCode   = userWallet.CryptoCode,
                            Type         = UserTransactionType.Order,
                            DetailId     = dbOrder.Id.ToString(),
                            Status       = (byte)dbOrder.Status,
                            Timestamp    = dbOrder.Timestamp,
                            Amount       = dbOrder.CryptoAmount,
                            OrderNo      = dbOrder.OrderNo,
                            MerchantName = merchantAccount.MerchantName
                        });
                        orderWithdrawalFee.OrderId = dbOrder.Id;
                        var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee);

                        new MerchantWalletDAC().Decrease(wallet.Id, orderWithdrawalFee.Amount);
                        new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount);
                        new UserWalletDAC().Decrease(userWallet.Id, orderData.ActualCryptoAmount);
                        new UserWalletStatementDAC().Insert(new UserWalletStatement
                        {
                            Action        = UserWalletStatementAction.Consume,
                            Amount        = orderData.CryptoAmount,
                            Balance       = userWallet.Balance - orderData.CryptoAmount,
                            FrozenAmount  = 0,
                            FrozenBalance = userWallet.FrozenBalance,
                            Remark        = null,
                            Timestamp     = DateTime.UtcNow,
                            WalletId      = userWallet.Id
                        });
                        new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                        {
                            Action    = MerchantWalletStatementAction.Receipt,
                            Amount    = orderData.ActualCryptoAmount,
                            Balance   = merchantWallet.Balance + orderData.ActualCryptoAmount,
                            Remark    = null,
                            Timestamp = DateTime.UtcNow,
                            WalletId  = merchantWallet.Id
                        });
                        new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                        {
                            Action    = MerchantWalletStatementAction.Withdrawal,
                            Amount    = orderWithdrawalFee.Amount,
                            Balance   = merchantWallet.Balance - orderData.ActualCryptoAmount,
                            Remark    = null,
                            Timestamp = DateTime.UtcNow,
                            WalletId  = wallet.Id
                        });
                        scope.Complete();
                    }
                }
                else
                {
                    Execute(orderWithdrawalFee);
                }
            }
            void Execute(OrderWithdrawalFee orderWithdrawalFee)
            {
                using (var scope = new TransactionScope())
                {
                    var dbOrder = new OrderDAC().Create(orderData);
                    new UserTransactionDAC().Insert(new UserTransaction
                    {
                        Id           = Guid.NewGuid(),
                        AccountId    = userWallet.UserAccountId,
                        CryptoId     = userWallet.CryptoId,
                        CryptoCode   = userWallet.CryptoCode,
                        Type         = UserTransactionType.Order,
                        DetailId     = dbOrder.Id.ToString(),
                        Status       = (byte)dbOrder.Status,
                        Timestamp    = dbOrder.Timestamp,
                        Amount       = dbOrder.CryptoAmount,
                        OrderNo      = dbOrder.OrderNo,
                        MerchantName = merchantAccount.MerchantName
                    });
                    orderWithdrawalFee.OrderId = dbOrder.Id;
                    var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee);

                    new UserWalletDAC().Decrease(userWallet.Id, orderData.CryptoAmount);
                    new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount);
                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        Action        = UserWalletStatementAction.Consume,
                        Amount        = orderData.CryptoAmount,
                        Balance       = userWallet.Balance - orderData.CryptoAmount,
                        FrozenAmount  = 0,
                        FrozenBalance = userWallet.FrozenBalance,
                        Remark        = null,
                        Timestamp     = DateTime.UtcNow,
                        WalletId      = userWallet.Id
                    });
                    new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                    {
                        Action    = MerchantWalletStatementAction.Receipt,
                        Amount    = orderData.ActualCryptoAmount,
                        Balance   = merchantWallet.Balance + orderData.ActualCryptoAmount,
                        Remark    = null,
                        Timestamp = DateTime.UtcNow,
                        WalletId  = merchantWallet.Id
                    });
                    scope.Complete();
                }
            }

            UserMSMQ.PubOrderPayed(orderData.Id, 0);
            //PushConsume(order.Id);
            UserMSMQ.PubConsumeOrder(orderData.Id);

            return(new PayOrderOM
            {
                Amount = orderData.CryptoAmount.ToString(coin.DecimalPlace),
                Currency = new CryptocurrencyDAC().GetById(order.CryptoId).Code,
                OrderId = orderData.Id.ToString(),
                OrderNo = orderData.OrderNo,
                Timestamp = orderData.PaymentTime?.ToUnixTime().ToString()
            });
        }
Esempio n. 25
0
        public WithdrawOM Withdraw(UserAccount user, WithdrawIM im, string clientIP)
        {
            SecurityVerify.Verify <WithdrawVerify>(new CustomVerifier("UserWithdraw"), SystemPlatform.FiiiPay, user.Id.ToString(), (model) =>
            {
                return(model.PinVerified && model.CombinedVerified);
            });


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

            var cryptocurrency = new CryptocurrencyDAC().GetById(im.CoinId);

            if (!cryptocurrency.Status.HasFlag(CryptoStatus.Withdrawal) || cryptocurrency.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }

            CryptoAddressValidation.ValidateAddress(cryptocurrency.Code, im.Address);
            if (!string.IsNullOrEmpty(im.Tag))
            {
                CryptoAddressValidation.ValidateTag(cryptocurrency.Code, im.Tag);
            }
            //else if (cryptocurrency.NeedTag)
            //{
            //    throw new CommonException(ReasonCode.NEED_INPUT_TAG, GeneralResources.EMNeedInputTag);
            //}

            if (im.Amount <= 0)
            {
                throw new ApplicationException(MessageResources.AmountGreater);
            }

            var IsAllowWithdrawal = user.IsAllowWithdrawal ?? true;

            if (!IsAllowWithdrawal)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, MessageResources.WithdrawalDisabled);
            }

            var fromWallet = new UserWalletDAC().GetByAccountId(user.Id, im.CoinId);


            //var profile = new UserProfileAgent().GetUserProfile(user.Id);

            //标准化这个金额,防止超过8位
            im.Amount = im.Amount.ToSpecificDecimal(cryptocurrency.DecimalPlace);

            var mastSettings = new MasterSettingDAC().SelectByGroup("UserWithdrawal");

            var Withdrawal_PerTx_Limit_User_NotVerified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_NotVerified").Value);
            var Withdrawal_PerDay_Limit_User_NotVerified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_NotVerified").Value);
            var Withdrawal_PerMonth_Limit_User_NotVerified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_NotVerified").Value);

            var Withdrawal_PerTx_Limit_User_Lv1Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv1Verified").Value);
            var Withdrawal_PerDay_Limit_User_Lv1Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv1Verified").Value);
            var Withdrawal_PerMonth_Limit_User_Lv1Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv1Verified").Value);

            var Withdrawal_PerTx_Limit_User_Lv2Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv2Verified").Value);
            var Withdrawal_PerDay_Limit_User_Lv2Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv2Verified").Value);
            var Withdrawal_PerMonth_Limit_User_Lv2Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv2Verified").Value);

            var MinAmount = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_MinAmount").Value);

            var merchantWalletDac = new MerchantWalletDAC();
            var userWalletDac     = new UserWalletDAC();

            var isWithdrawToInside = (merchantWalletDac.IsMerchantWalletAddress(im.Address) || userWalletDac.IsUserWalletAddress(im.Address));

            if (isWithdrawToInside)
            {
                MinAmount = Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser_MinAmount").Value);
            }

            var exchangeRate = GetMarketPrice(user.CountryId, cryptocurrency.Code, "USD");

            var _minAmount = (MinAmount / exchangeRate).ToSpecificDecimal(cryptocurrency.DecimalPlace);

            if (im.Amount < _minAmount)
            {
                throw new ApplicationException(MessageResources.MinWidrawalError);
            }

            var     withdrawalDAC     = new UserWithdrawalDAC();
            var     today             = DateTime.UtcNow.Date;
            decimal dailyWithdrawal   = withdrawalDAC.DailyWithdrawal(user.Id, im.CoinId, today);
            decimal monthlyWithdrawal = withdrawalDAC.MonthlyWithdrawal(user.Id, im.CoinId, new DateTime(today.Year, today.Month, 1));

            var PerDayLimit   = 0M;
            var PerMonthLimit = 0M;

            if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus == VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv2Verified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv2Verified;
            }
            else if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv1Verified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv1Verified;
            }
            else if (user.L1VerifyStatus != VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_NotVerified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_NotVerified;
            }
            if ((PerDayLimit / exchangeRate - dailyWithdrawal).ToSpecificDecimal(cryptocurrency.DecimalPlace) < im.Amount)
            {
                throw new ApplicationException(MessageResources.TodayWidrawalLimit);
            }
            if ((PerMonthLimit / exchangeRate - monthlyWithdrawal).ToSpecificDecimal(cryptocurrency.DecimalPlace) < im.Amount)
            {
                throw new ApplicationException(MessageResources.MonthWithdrawalLimit);
            }

            var fromWithdraw = new UserWithdrawal
            {
                UserAccountId = user.Id,
                UserWalletId  = fromWallet.Id,
                Address       = im.Address,
                Tag           = im.Tag,
                Amount        = im.Amount,
                Status        = TransactionStatus.UnSubmit,
                Timestamp     = DateTime.UtcNow,
                OrderNo       = IdentityHelper.OrderNo(),
                CryptoCode    = fromWallet.CryptoCode,
                CryptoId      = fromWallet.CryptoId
            };

            //是否是商户地址
            var toMerchantWallet = merchantWalletDac.GetByAddressAndCrypto(im.CoinId, im.Address, im.Tag);

            if (toMerchantWallet != null)
            {
                //if (toMerchantWallet.CryptoId != im.CoinId)
                //    throw new CommonException(ReasonCode.GENERAL_ERROR, GeneralResources.EMInvalidAddress);
                //return WithdrawalToMerchantAccount(fromWallet, fromWithdraw, fromWithdrawFee, toMerchantWallet, cryptocurrency);
                //042018
                throw new CommonException(ReasonCode.CAN_NOT_WITHDRAW_TO_FiiiPOS, MessageResources.FiiiPayCantWithdrawToFiiiPOS);
            }

            //是否是用户地址
            var toUserWallet = userWalletDac.GetByAddressAndCrypto(im.CoinId, im.Address, im.Tag);

            if (toUserWallet != null)
            {
                if (toUserWallet.UserAccountId == user.Id)
                {
                    throw new CommonException(ReasonCode.CANNOT_TRANSFER_TO_YOURSELF, MessageResources.WithdrawalToSelfError);
                }

                var toFiiiPayMinWithdrawAmount = GetToFiiiPayMinAmount(Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser_MinAmount").Value), exchangeRate, cryptocurrency.DecimalPlace);
                if (im.Amount < toFiiiPayMinWithdrawAmount)
                {
                    throw new CommonException(10000, MessageResources.MinWidrawalError);
                }

                return(WithdrawalToUserAccount(fromWallet, fromWithdraw, toUserWallet));
            }

            var tier = cryptocurrency.Withdrawal_Tier ?? 0;
            var fee  = im.Amount * tier + (cryptocurrency.Withdrawal_Fee ?? 0);

            fee = fee.ToSpecificDecimal(cryptocurrency.DecimalPlace);
            var actualAmount = im.Amount - fee;

            if (fromWallet.Balance < im.Amount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            if (actualAmount <= 0)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, MessageResources.ArrivalAmountError);
            }

            //地址是FiiiPay的地址,但tag找不到
            if (cryptocurrency.NeedTag && isWithdrawToInside)
            {
                return(CancelWithdrawal(fromWithdraw));
            }

            ILog _logger = LogManager.GetLogger("LogicError");

            //如果都不是,向Finance申请提现

            //var agent = new FiiiFinanceAgent();

            var requestModel = new CreateWithdrawModel
            {
                AccountID        = user.Id,
                AccountType      = AccountTypeEnum.User,
                CryptoName       = cryptocurrency.Code,
                ReceivingAddress = im.Address,
                DestinationTag   = im.Tag,
                Amount           = actualAmount,
                IPAddress        = clientIP,
                TransactionFee   = fee
            };

            using (var scope = new TransactionScope())
            {
                try
                {
                    fromWithdraw.Id = withdrawalDAC.Create(fromWithdraw);
                    var fromWithdrawFee = new UserWithdrawalFee
                    {
                        Amount       = im.Amount,
                        Fee          = fee,
                        Timestamp    = DateTime.UtcNow,
                        WithdrawalId = fromWithdraw.Id
                    };

                    new UserTransactionDAC().Insert(new UserTransaction
                    {
                        Id         = Guid.NewGuid(),
                        AccountId  = fromWithdraw.UserAccountId,
                        CryptoId   = fromWithdraw.CryptoId,
                        CryptoCode = fromWithdraw.CryptoCode,
                        Type       = UserTransactionType.Withdrawal,
                        DetailId   = fromWithdraw.Id.ToString(),
                        Status     = (byte)fromWithdraw.Status,
                        Timestamp  = fromWithdraw.Timestamp,
                        Amount     = fromWithdraw.Amount,
                        OrderNo    = fromWithdraw.OrderNo
                    });

                    new UserWithdrawalFeeDAC().Create(fromWithdrawFee);

                    userWalletDac.Freeze(fromWallet.Id, im.Amount);

                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId      = fromWallet.Id,
                        Action        = UserWalletStatementAction.Withdrawal,
                        Amount        = 0 - im.Amount,
                        Balance       = fromWallet.Balance - im.Amount,
                        FrozenAmount  = im.Amount,
                        FrozenBalance = fromWallet.FrozenBalance + im.Amount,
                        Timestamp     = DateTime.UtcNow
                    });

                    requestModel.WithdrawalId = fromWithdraw.Id;
                    Framework.Queue.RabbitMQSender.SendMessage("WithdrawSubmit", requestModel);

                    scope.Complete();
                }
                catch (CommonException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.Info($"Withdraw CreateWithdrawRequest faild.WithdrawID:{fromWithdraw.Id},OrderNo:{fromWithdraw.OrderNo}.request Parameter - {requestModel}. Error message:{ex.Message}");
                    throw;
                }
            }

            return(new WithdrawOM
            {
                OrderId = fromWithdraw.Id,
                OrderNo = fromWithdraw.OrderNo,
                Timestamp = fromWithdraw.Timestamp.ToUnixTime().ToString()
            });
        }
        public List <MerchantSupportReceiptWalletDTO> SupportReceiptList(Guid accountId)
        {
            var account = new MerchantAccountDAC().GetById(accountId);
            var dac     = new MerchantWalletDAC();

            var cryptoList = new CryptocurrencyDAC().GetAllActived();

            var fiiiCrypto = cryptoList.First(w => w.Code == FIIICOIN_CODE);
            var fiiiWallet = dac.GetByAccountId(account.Id, fiiiCrypto.Id) ?? GenerateWallet(accountId, fiiiCrypto.Id, fiiiCrypto.Code, FIIICOIN_SEQUENCE, true);

            if (!fiiiWallet.SupportReceipt || fiiiWallet.Sequence != FIIICOIN_SEQUENCE)
            {
                dac.Support(account.Id, fiiiWallet.CryptoId, FIIICOIN_SEQUENCE);
            }

            List <MerchantWallet> supportReceiptList;
            var pos = new POSDAC().GetById(account.POSId.Value);

            if (pos.IsWhiteLabel)
            {
                var whiteCrypto = cryptoList.First(w => w.Code == pos.FirstCrypto);
                var whiteWallet = dac.GetByAccountId(account.Id, whiteCrypto.Id);
                if (whiteWallet == null)
                {
                    GenerateWallet(accountId, whiteCrypto.Id, whiteCrypto.Code, WHITECOIN_SEQUENCE, true);
                }
                else if (!whiteWallet.SupportReceipt || whiteWallet.Sequence != WHITECOIN_SEQUENCE)
                {
                    dac.Support(account.Id, whiteWallet.CryptoId, WHITECOIN_SEQUENCE);
                }

                supportReceiptList = dac.SupportReceiptList(accountId).OrderBy(e => e.Sequence).ToList();
            }
            else
            {
                var whiteCryptoList = cryptoList.Where(e => e.IsWhiteLabel == 1).ToList();
                supportReceiptList = dac.SupportReceiptList(accountId).OrderBy(e => e.Sequence).ToList();
                supportReceiptList.RemoveAll(e => whiteCryptoList.Exists(a => a.Id == e.CryptoId));
            }

            var marketPriceList = new PriceInfoDAC().GetPrice(account.FiatCurrency);

            return(supportReceiptList.Select(e =>
            {
                var crypto = cryptoList.FirstOrDefault(w => w.Id == e.CryptoId);
                if (crypto == null)
                {
                    return null;
                }
                return new MerchantSupportReceiptWalletDTO
                {
                    WalletId = e.Id,
                    CryptoId = crypto.Id,
                    CryptoStatus = crypto.Status,
                    CryptoCode = crypto.Code,
                    CryptoName = crypto.Name,
                    IconURL = crypto.IconURL,
                    DecimalPlace = crypto.DecimalPlace,
                    Markup = account.Markup,
                    MarketPrice = marketPriceList.FirstOrDefault(m => crypto.Code == m.CryptoName)?.Price.ToString(4),
                    Balance = string.Equals("FIII", crypto.Code, StringComparison.CurrentCultureIgnoreCase) ? e.Balance : 0,
                    IsDefault = e.CryptoId == fiiiCrypto.Id || (pos.IsWhiteLabel && crypto.Code == pos.FirstCrypto) ? 1 : 0,
                    CryptoEnable = crypto.Enable
                };
            }).Where(w => w != null).ToList());
        }
        public MerchantWithdrawal Withdrawal(Guid accountId, decimal amount, int cryptoId, string address, string tag, string clientIP)
        {
            SecurityVerify.Verify <WithdrawVerify>(new CustomVerifier("MerchantWithdraw"), SystemPlatform.FiiiPOS, accountId.ToString(), (model) =>
            {
                return(model.PinVerified && model.CombinedVerified);
            });

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

            CryptoAddressValidation.ValidateAddress(cryptocurrency.Code, address);

            if (!string.IsNullOrEmpty(tag))
            {
                CryptoAddressValidation.ValidateTag(cryptocurrency.Code, tag);
            }

            var account = new MerchantAccountDAC().GetById(accountId);

            if (!new ProfileComponent().ValidateLv1(accountId))
            {
                throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.需要Lv1认证才能使用相关功能);
            }

            if (!account.IsAllowWithdrawal)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, Resources.禁止提币);
            }

            if (!cryptocurrency.Status.HasFlag(CryptoStatus.Withdrawal))
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            if (cryptocurrency.Enable == (byte)CurrencyStatus.Forbidden)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            var fromWallet = new MerchantWalletDAC().GetByAccountId(accountId, cryptoId);

            if (fromWallet == null)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, Resources.禁止提币);
            }

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

            var profileAgent = new MerchantProfileAgent();
            var profile      = profileAgent.GetMerchantProfile(accountId);

            int level = profile.L2VerifyStatus == VerifyStatus.Certified ? 2 : profile.L1VerifyStatus == VerifyStatus.Certified ? 1 : 0;

            var masterSetting = GetMerchantWithdrawalMasterSettingWithCrypto(cryptocurrency, level);

            if (amount > masterSetting.PerTxLimit)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.能高于单次提币量);
            }
            var     dac             = new MerchantWithdrawalDAC();
            var     today           = DateTime.UtcNow.Date;
            decimal dailyWithdrawal = dac.DailyWithdrawal(accountId, cryptoId, today);

            if (amount > masterSetting.PerDayLimit - dailyWithdrawal)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.今日提币达到限额);
            }
            decimal monthlyWithdrawal = dac.MonthlyWithdrawal(accountId, cryptoId, new DateTime(today.Year, today.Month, 1));

            if (amount > masterSetting.PerMonthLimit - monthlyWithdrawal)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.本月提币达到限额);
            }

            var fromWithdraw = new MerchantWithdrawal
            {
                MerchantAccountId = accountId,
                MerchantWalletId  = fromWallet.Id,
                Address           = address,
                Tag        = tag,
                Amount     = amount,
                Status     = TransactionStatus.UnSubmit,
                Timestamp  = DateTime.UtcNow,
                OrderNo    = NumberGenerator.GenerateUnixOrderNo(),
                CryptoId   = fromWallet.CryptoId,
                CryptoCode = fromWallet.CryptoCode
            };

            var merchantWalletDac = new MerchantWalletDAC();
            var userWalletDac     = new UserWalletDAC();

            //是否是商户地址
            var toMerchantWallet = merchantWalletDac.GetByAddress(address, cryptocurrency.NeedTag ? tag : null);

            if (toMerchantWallet != null)
            {
                //if (toMerchantWallet.CryptoId != cryptoId)
                //    throw new CommonException(10000, string.Format(Resources.提币地址不是有效的地址, cryptocurrency.Code));
                //if (toMerchantWallet.MerchantAccountId == accountId)
                //    throw new CommonException(ReasonCode.CANNOT_TRANSFER_TO_YOURSELF, Resources.提币地址不能是自己账户的地址);
                //return WithdrawalToMerchantAccount(fromWallet, fromWithdraw, toMerchantWallet);
                // 042018
                throw new CommonException(ReasonCode.CAN_NOT_WITHDRAW_TO_FiiiPOS, Resources.FiiiPOSCantWithdrawToFiiiPOS);
            }

            //是否是用户地址
            var toUserWallet = userWalletDac.GetByAddressAndCrypto(cryptoId, address, cryptocurrency.NeedTag ? tag : null);

            if (toUserWallet != null)
            {
                if (toUserWallet.CryptoId != cryptoId)
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, FiiiPay.Framework.Component.Properties.GeneralResources.EMInvalidAddress);
                }

                if (amount < masterSetting.ToUserMinAmount)
                {
                    throw new CommonException(10000, Resources.能低于最低提币量);
                }

                var fee = (fromWithdraw.Amount * masterSetting.ToUserHandleFeeTier).ToSpecificDecimal(cryptocurrency.DecimalPlace);
                if (amount <= fee)
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数);
                }

                return(WithdrawalToUserAccount(fromWallet, fromWithdraw, toUserWallet, fee));
            }

            //平台内提币如果tag不对,创建一条失败记录
            if (cryptocurrency.NeedTag && (userWalletDac.IsUserWalletAddress(address) || merchantWalletDac.IsMerchantWalletAddress(address)))
            {
                return(CancelWithdrawal(fromWithdraw));
            }

            //如果都不是,提币到场外
            if (amount < masterSetting.ToOutsideMinAmount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.能低于最低提币量);
            }

            var baseFee  = cryptocurrency.Withdrawal_Fee ?? 0;
            var tier     = cryptocurrency.Withdrawal_Tier ?? 0;
            var fee1     = (amount * tier).ToSpecificDecimal(cryptocurrency.DecimalPlace);
            var totalFee = baseFee + fee1;

            if (amount <= totalFee)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数);
            }

            return(WithdrawalToOutside(fromWallet, fromWithdraw, cryptocurrency, account, amount, totalFee, address, tag, clientIP));
        }
        public void SettingCrytocurrencies(Guid accountId, List <int> cryptoIds)
        {
            var mwDac      = new MerchantWalletDAC();
            var mwList     = mwDac.GetByAccountId(accountId).ToList();
            var cryptoList = new CryptocurrencyDAC().GetByIds(cryptoIds.ToArray());

            // FIII 不参与排序
            var fiiiCrypto = cryptoList.FirstOrDefault(e => e.Code == FIIICOIN_CODE);

            if (fiiiCrypto != null)
            {
                cryptoIds.Remove(fiiiCrypto.Id);
                var fiiiWallet = mwList.FirstOrDefault(e => e.CryptoId == fiiiCrypto.Id);
                if (fiiiWallet != null)
                {
                    mwList.Remove(fiiiWallet);
                }
            }

            // 白标POS机的白标币不参与排序
            var account = new MerchantAccountDAC().GetById(accountId);
            var pos     = new POSDAC().GetById(account.POSId.Value);

            if (pos.IsWhiteLabel)
            {
                var whiteCrypto = cryptoList.FirstOrDefault(e => e.Code == pos.FirstCrypto);
                if (whiteCrypto != null)
                {
                    cryptoIds.Remove(whiteCrypto.Id);
                    var whiteWallet = mwList.FirstOrDefault(e => e.CryptoId == whiteCrypto.Id);
                    if (whiteWallet != null)
                    {
                        mwList.Remove(whiteWallet);
                    }
                }
            }


            for (int i = 0; i < cryptoIds.Count; i++)
            {
                int seq    = i + 1;
                var crypto = cryptoList.FirstOrDefault(e => e.Id == cryptoIds[i]);
                if (crypto == null)
                {
                    continue;
                }

                var wallet = mwList.FirstOrDefault(e => e.CryptoId == cryptoIds[i]);
                // 新增
                if (wallet == null)
                {
                    GenerateWallet(accountId, crypto.Id, crypto.Code, seq, true);
                    continue;
                }
                // 启用
                if (!wallet.SupportReceipt || wallet.Sequence != seq)
                {
                    mwDac.Support(accountId, crypto.Id, seq);
                }
                mwList.Remove(wallet);
            }

            mwList.RemoveAll(e => !e.SupportReceipt);
            // 禁用
            foreach (var wallet in mwList)
            {
                mwDac.Reject(accountId, wallet.CryptoId);
            }
        }
Esempio n. 29
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);
        }
Esempio n. 30
0
        public void SubmitWithdrawal(CreateWithdrawModel model)
        {
            if (model.AccountType == AccountTypeEnum.Merchant)
            {
                var withdrawalDAC = new MerchantWithdrawalDAC();
                var withdrawal    = withdrawalDAC.GetById(model.WithdrawalId);
                if (withdrawal == null || withdrawal.Status != Entities.Enums.TransactionStatus.UnSubmit)
                {
                    LogHelper.Info("Invalid withdrawal id or invalid withdrawal status");
                    return;
                }

                var agent = new FiiiFinanceAgent();

                try
                {
                    var requestInfo = agent.CreateWithdraw(model);

                    if (requestInfo.Code == 0)
                    {
                        withdrawalDAC.WithdrawalSubmited(model.WithdrawalId, requestInfo.RequestID,
                                                         requestInfo.TransactionId);
                    }
                    else if (requestInfo.Code == 20002 || requestInfo.Code == 300001)
                    {
                        var merchantWalletDac = new MerchantWalletDAC();
                        var merchantWallet    = merchantWalletDac.GetById(withdrawal.MerchantWalletId);
                        using (var scope = new TransactionScope())
                        {
                            try
                            {
                                withdrawalDAC.RejectById(withdrawal.Id, "Invalid address");
                                merchantWalletDac.Unfreeze(merchantWallet.Id, withdrawal.Amount);
                                new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                                {
                                    WalletId  = merchantWallet.Id,
                                    Action    = UserWalletStatementAction.Withdrawal,
                                    Amount    = withdrawal.Amount,
                                    Balance   = merchantWallet.Balance + withdrawal.Amount,
                                    Timestamp = DateTime.UtcNow
                                });
                                scope.Complete();
                            }
                            catch (Exception exception)
                            {
                                _log.Error(exception);
                            }
                        }
                    }
                    else
                    {
                        RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"UpdateTransactionId erorr, message:{JsonConvert.SerializeObject(model)}", ex);

                    RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                }
            }
            else if (model.AccountType == AccountTypeEnum.User)
            {
                var withdrawalDAC = new UserWithdrawalDAC();
                var withdrawal    = withdrawalDAC.GetById(model.WithdrawalId);
                if (withdrawal == null || withdrawal.Status != Entities.Enums.TransactionStatus.UnSubmit)
                {
                    LogHelper.Info("Invalid withdrawal id or invalid withdrawal status");
                    return;
                }

                var agent = new FiiiFinanceAgent();

                try
                {
                    var requestInfo = agent.CreateWithdraw(model);

                    if (requestInfo.Code == 0)
                    {
                        withdrawalDAC.WithdrawalSubmited(model.WithdrawalId, requestInfo.RequestID, requestInfo.TransactionId);
                    }
                    else if (requestInfo.Code == 20002 || requestInfo.Code == 300001)
                    {
                        var userWalletDac = new UserWalletDAC();
                        var userWallet    = userWalletDac.GetById(withdrawal.UserWalletId);
                        using (TransactionScope scope = new TransactionScope())
                        {
                            try
                            {
                                withdrawalDAC.RejectById(withdrawal.Id, "Invalid address");
                                userWalletDac.Unfreeze(withdrawal.UserWalletId, withdrawal.Amount);

                                new UserWalletStatementDAC().Insert(new Entities.UserWalletStatement
                                {
                                    WalletId      = userWallet.Id,
                                    Action        = Entities.UserWalletStatementAction.Withdrawal,
                                    Amount        = withdrawal.Amount,
                                    Balance       = userWallet.Balance + withdrawal.Amount,
                                    FrozenAmount  = -withdrawal.Amount,
                                    FrozenBalance = userWallet.FrozenBalance - withdrawal.Amount,
                                    Timestamp     = DateTime.UtcNow
                                });

                                scope.Complete();
                            }
                            catch (Exception exception)
                            {
                                _log.Error(exception);
                            }
                        }
                    }
                    else
                    {
                        RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"UpdateTransactionId erorr, message:{JsonConvert.SerializeObject(model)}", ex);
                    RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                }
            }
            else
            {
                LogHelper.Info("Invalid AccountType");
            }
        }