/// <summary> /// 查询所有门店信息 /// </summary> /// <param name="account"></param> public MerchantInformationES SelectMerchantInformation(Guid accountId, int countryId) { var account = new MerchantAccountDAC().GetById(accountId); if (account == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ACCOUNT_NOT_EXISTS, "商家账户未注册或不存在"); } var information = new MerchantInformationDAC().GetByMerchantAccountId(account.Id); var country = new CountryDAC().GetById(countryId); if (information == null) { throw new CommonException(ReasonCode.MERCHANT_NONE, "商家没有门店"); //return new MerchantInformationES() //{ // Countrys = new Countrys() // { // Name_CN = country.Name_CN, // Name = country.Name // } //}; } var figures = new MerchantOwnersFigureDAC().GetOwnersFiguresById(information.Id); var category = new MerchantCategoryDAC().GetByMerchantInformationId(information.Id); var recommend = new MerchantRecommendDAC().GetRecommendsById(information.Id); return(new MerchantInformationES() { MerchantName = information.MerchantName, Categorys = category.Select(item => item.Category).ToList(), Week = information.Week, StartTime = information.StartTime, EndTime = information.EndTime, Tags = information.Tags, Phone = information.Phone, Introduce = information.Introduce, Address = information.Address, Lng = information.Lng, Lat = information.Lat, VerifyStatus = information.VerifyStatus, OwnersFigures = figures.Select(item => item.FileId).ToList(), Recommends = recommend.Select(item => new Recommend() { Content = item.RecommendContent, Picture = item.RecommendPicture }).ToList(), Countrys = new Countrys() { Name_CN = country.Name_CN, Name = country.Name }, IsPublic = information.IsPublic }); }
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()); }
public PrePayOM PrePay(Guid userAccountId, Guid merchantInfoId) { var merchantInfo = new MerchantInformationDAC().GetById(merchantInfoId); if (merchantInfo.AccountType == AccountType.Merchant) { return(GetMerchantPrePayOM(userAccountId, merchantInfo)); } if (merchantInfo.AccountType == AccountType.User) { return(GetUserPrePayOM(userAccountId, merchantInfo)); } return(null); }
public async Task <StoreIncomeDetail> GetIncomeDetailAsync(Guid accountId, Guid orderId, bool isZH) { var storeOrder = await new StoreOrderDAC().GetByIdAsync(orderId); if (storeOrder == null) { throw new ApplicationException(); } var merchantInfo = new MerchantInformationDAC().GetById(storeOrder.MerchantInfoId); var storeUserAccount = new UserAccountDAC().GetById(merchantInfo.MerchantAccountId); if (storeUserAccount.Id != accountId) { throw new ApplicationException(); } var customerAccount = new UserAccountDAC().GetById(storeOrder.UserAccountId); var coin = new CryptocurrencyDAC().GetById(storeOrder.CryptoId); var priceInfo = new PriceInfoDAC().GetPriceByName(storeOrder.FiatCurrency, storeOrder.CryptoCode); var iRate = ((priceInfo - storeOrder.ExchangeRate) / storeOrder.ExchangeRate) * 100; return(new StoreIncomeDetail { Id = storeOrder.Id, Type = Resources.StoreOrderIncome, CryptoActualAmount = storeOrder.CryptoActualAmount.ToString(coin.DecimalPlace), CryptoCode = storeOrder.CryptoCode, Status = new UserStatementComponent().GetStatusStr(2, (int)storeOrder.Status, isZH), MerchantName = storeOrder.MerchantInfoName, OrderNo = storeOrder.OrderNo, UserAccountName = GetMaskedCellphone(customerAccount.PhoneCode, customerAccount.Cellphone), Timestamp = storeOrder.Timestamp.ToUnixTime().ToString(), FiatCurrency = storeOrder.FiatCurrency, FiatAmount = storeOrder.FiatAmount.ToString(2), MarkUp = $"{(storeOrder.Markup * 100).ToString(2)}%", TotalFiatAmount = storeOrder.FiatActualAmount.ToString(2), ExchangeRate = $"1 {coin.Code} = {storeOrder.ExchangeRate.ToString(4)} {storeOrder.FiatCurrency}", CurrentExchangeRate = coin.Enable == 1 ? $"1 {coin.Code} = {priceInfo.ToString(4)} {storeOrder.FiatCurrency}" : "--", IncreaseRate = coin.Enable == 1 ? (iRate > 0 ? $"+{iRate.ToString(2)}" : iRate.ToString(2)) : "--", CryptoAmount = storeOrder.CryptoAmount.ToString(coin.DecimalPlace), TransactionFee = storeOrder.TransactionFee.ToString(coin.DecimalPlace), FeeCryptoCode = storeOrder.CryptoCode }); }
private PrePayOM GetUserPrePayOM(Guid userAccountId, MerchantInformation merchantInfo) { var userDAC = new UserAccountDAC(); var merchantDAC = new MerchantInformationDAC(); var merchantUserAccount = userDAC.GetById(merchantInfo.MerchantAccountId); var supportList = new MerchantSupportCryptoDAC().GetList(merchantInfo.Id).ToList(); var userWallets = new UserWalletDAC().GetUserWallets(userAccountId); var coins = new CryptocurrencyDAC().GetAllActived(); var priceList = new PriceInfoDAC().GetPrice(merchantUserAccount.FiatCurrency); var whilteLabelCryptoCode = new POSDAC().GetWhiteLabelCryptoCode(); coins.RemoveAll(t => t.Code == whilteLabelCryptoCode); return(new PrePayOM { FiatCurrency = merchantUserAccount.FiatCurrency, MarkupRate = merchantInfo.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 GetUserSupportItem(userWallet, a, supportList, 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 GetMerchantDetailOM GetMerchantDetail(GetMerchantDetailIM im) { var merchantDetail = new MerchantInformationDAC().GetMerchantDetailById(im.Id); if (merchantDetail == null) { Error($"{nameof(GetMerchantDetail)} 查询商家信息出错 id----{Newtonsoft.Json.JsonConvert.SerializeObject(im)}"); throw new Exception("系统查询错误"); } if (merchantDetail.Status != Status.Enabled || merchantDetail.IsPublic != Status.Enabled) { throw new CommonException(ReasonCode.MERCHANT_NOT_PUBLIC, MessageResources.MerchantNotPublic); } if (merchantDetail.AccountType == Entities.Enums.AccountType.User) { return(GetFiiiPayMerchantDetail(merchantDetail)); } return(GetFiiiPosMerchantDetail(merchantDetail)); }
/// <summary> /// 更新所有门店信息 /// </summary> /// <param name="information"></param> /// <param name="ownersFigures"></param> /// <param name="merchantRecommends"></param> /// <param name="merchantCategories"></param> /// <param name="phone"></param> public void UpdateMerchantInformation(MerchantInformation information, List <MerchantOwnersFigure> ownersFigures, List <MerchantRecommend> merchantRecommends, List <MerchantCategory> merchantCategories, string phone) { if (new MerchantAccountDAC().GetById(information.MerchantAccountId) == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ACCOUNT_NOT_EXISTS, "商家账户未注册或不存在"); } //var Categories = merchantCategories; var owners = new MerchantOwnersFigureDAC().GetOwnersFiguresById(information.Id); //查询商家主图id var recommends = new MerchantRecommendDAC().GetRecommendsById(information.Id); //查询商家推荐图id var merchantInfo = new MerchantInformationDAC().GetByMerchantAccountId(information.MerchantAccountId); //判断 商家名称,经营内容,商家介绍,门店相册是否一样 var isSame = merchantInfo.MerchantName == information.MerchantName && merchantInfo.Tags == information.Tags && merchantInfo.Introduce == information.Introduce; isSame &= owners.Select(item => item.FileId).All(item => ownersFigures.ToDictionary(_ => _.FileId).ContainsKey(item)) && owners.Count == ownersFigures.Count; isSame &= recommends.Select(item => item.RecommendPicture).All(item => merchantRecommends.ToDictionary(_ => _.RecommendPicture).ContainsKey(item)) && recommends.Count == merchantRecommends.Count && recommends.Select(item => item.RecommendContent).All(item => merchantRecommends.ToDictionary(_ => _.RecommendContent).ContainsKey(item)); if (merchantInfo.VerifyStatus == FiiiPay.Entities.Enums.VerifyStatus.Disapproval) { Task.WhenAll(Task.Run(() => { Parallel.ForEach(owners, item => { try { if (!ownersFigures.Any(_ => _.FileId == item.FileId)) { Task.WhenAll(Task.Run(() => { new MasterImageAgent().Delete(item.FileId.ToString()); }), Task.Run(() => { new MasterImageAgent().Delete(item.ThumbnailId.ToString()); })); } } catch { } }); }), Task.Run(() => { Parallel.ForEach(recommends, item => { if (!merchantRecommends.Any(_ => _.RecommendPicture == item.RecommendPicture)) { Task.WhenAll(Task.Run(() => { new MasterImageAgent().Delete(item.RecommendPicture.ToString()); }), Task.Run(() => { new MasterImageAgent().Delete(item.ThumbnailId.ToString()); })); } }); }), Task.Run(() => { Parallel.ForEach(ownersFigures, item => { if (!owners.Any(_ => _.FileId == item.FileId)) { var tumnailId = new MasterImageAgent().UploadWithCompress(item.FileId); item.ThumbnailId = tumnailId == Guid.Empty ? item.FileId : tumnailId; } else { item.ThumbnailId = owners.FirstOrDefault(_ => _.FileId == item.FileId)?.ThumbnailId ?? item.FileId; } }); }), Task.Run(() => { Parallel.ForEach(merchantRecommends, item => { if (!recommends.Any(_ => _.RecommendPicture == item.RecommendPicture)) { var tumnailId = new MasterImageAgent().UploadWithCompress(item.RecommendPicture); item.ThumbnailId = tumnailId == Guid.Empty ? item.RecommendPicture : tumnailId; } else { item.ThumbnailId = recommends.FirstOrDefault(_ => _.RecommendPicture == item.RecommendPicture)?.ThumbnailId ?? item.RecommendPicture; } }); })).Wait(); using (var scope = new TransactionScope()) { new MerchantInformationDAC().Update(information.Id, information); new MerchantCategoryDAC().Delete(information.Id); merchantCategories.ForEach(item => new MerchantCategoryDAC().Insert(item)); new MerchantOwnersFigureDAC().Delete(information.Id); ownersFigures.ForEach(item => new MerchantOwnersFigureDAC().Insert(item)); new MerchantRecommendDAC().Delete(information.Id); merchantRecommends.ForEach(item => new MerchantRecommendDAC().Insert(item)); scope.Complete(); } } else if (merchantInfo.VerifyStatus == FiiiPay.Entities.Enums.VerifyStatus.Certified) { if (isSame) { using (var scope = new TransactionScope()) { new MerchantInformationDAC().UpdatePartialInformation(information.Id, information); new MerchantCategoryDAC().Delete(information.Id); merchantCategories.ForEach(item => new MerchantCategoryDAC().Insert(item)); scope.Complete(); } } else { Task.WhenAll(Task.Run(() => { Parallel.ForEach(owners, item => { try { if (!ownersFigures.Any(_ => _.FileId == item.FileId)) { Task.WhenAll(Task.Run(() => { new MasterImageAgent().Delete(item.FileId.ToString()); }), Task.Run(() => { new MasterImageAgent().Delete(item.ThumbnailId.ToString()); })); } } catch { } }); }), Task.Run(() => { Parallel.ForEach(recommends, item => { if (!merchantRecommends.Any(_ => _.RecommendPicture == item.RecommendPicture)) { Task.WhenAll(Task.Run(() => { new MasterImageAgent().Delete(item.RecommendPicture.ToString()); }), Task.Run(() => { new MasterImageAgent().Delete(item.ThumbnailId.ToString()); })); } }); }), Task.Run(() => { Parallel.ForEach(ownersFigures, item => { if (!owners.Any(_ => _.FileId == item.FileId)) { var tumnailId = new MasterImageAgent().UploadWithCompress(item.FileId); item.ThumbnailId = tumnailId == Guid.Empty ? item.FileId : tumnailId; } else { item.ThumbnailId = owners.FirstOrDefault(_ => _.FileId == item.FileId)?.ThumbnailId ?? item.FileId; } }); }), Task.Run(() => { Parallel.ForEach(merchantRecommends, item => { if (!recommends.Any(_ => _.RecommendPicture == item.RecommendPicture)) { var tumnailId = new MasterImageAgent().UploadWithCompress(item.RecommendPicture); item.ThumbnailId = tumnailId == Guid.Empty ? item.RecommendPicture : tumnailId; } else { item.ThumbnailId = recommends.FirstOrDefault(_ => _.RecommendPicture == item.RecommendPicture)?.ThumbnailId ?? item.RecommendPicture; } }); })).Wait(); using (var scope = new TransactionScope()) { new MerchantInformationDAC().Update(information.Id, information); new MerchantCategoryDAC().Delete(information.Id); merchantCategories.ForEach(item => new MerchantCategoryDAC().Insert(item)); new MerchantOwnersFigureDAC().Delete(information.Id); ownersFigures.ForEach(item => new MerchantOwnersFigureDAC().Insert(item)); new MerchantRecommendDAC().Delete(information.Id); merchantRecommends.ForEach(item => new MerchantRecommendDAC().Insert(item)); scope.Complete(); } } } }
public async Task <bool> FiiipayMerchantCreateAsync(UserAccount account, FiiiPayMerchantInfoCreateIM model) { var uaDAC = new UserAccountDAC(); if (account.L1VerifyStatus != VerifyStatus.Certified) { throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied); } var inviteAccount = uaDAC.GetByInvitationCode(model.InviteCode); bool needInviteRecord = true; if (!string.IsNullOrEmpty(model.InviteCode)) { if (inviteAccount == null) { throw new CommonException(ReasonCode.INVITORCODE_NOT_EXISTS, MessageResources.InvalidInvitation); } if (inviteAccount.InvitationCode == account.InvitationCode) { throw new CommonException(ReasonCode.INVALID_INVITECODE, MessageResources.InviteCodeCanotInputSelf); } var existInviteRecord = await new InviteRecordDAC().GetDetailByAccountIdAsync(account.Id, InviteType.FiiipayMerchant); if (existInviteRecord != null) { needInviteRecord = false; } } else { needInviteRecord = false; } var merchantCountry = new CountryDAC().GetById(model.CountryId); if (merchantCountry == null) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } if (!merchantCountry.IsSupportStore) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } Regions stateRegion; Regions cityRegion; if (model.StateId.HasValue) { stateRegion = await new RegionDAC().GetByIdAsync(model.StateId.Value); if (stateRegion == null) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } if (stateRegion.CountryId != model.CountryId) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } if (model.CityId.HasValue) { cityRegion = await new RegionDAC().GetByIdAsync(model.CityId.Value); if (cityRegion == null) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } if (cityRegion.CountryId != model.CountryId || cityRegion.ParentId != stateRegion.Id) { throw new CommonException(ReasonCode.RECORD_NOT_EXIST, MessageResources.InvalidParameters); } } } #region entities Guid merchantInfoId = Guid.NewGuid(); DateTime dtNow = DateTime.UtcNow; MerchantInformation merchantInfo = new MerchantInformation { Id = merchantInfoId, CreateTime = dtNow, FromType = InputFromType.UserInput, MerchantName = model.MerchantName, WeekTxt = model.WeekTxt, Tags = model.TagList == null ? "" : string.Join(",", model.TagList), Introduce = model.Introduce, CountryId = merchantCountry.Id, StateId = model.StateId, CityId = model.CityId, PhoneCode = account.PhoneCode, Address = model.Address, Lng = model.Lng, Lat = model.Lat, Status = Status.Stop, VerifyStatus = VerifyStatus.UnderApproval, MerchantAccountId = account.Id, Phone = model.Phone, IsPublic = Status.Stop, FileId = model.StorefrontImg[0], ThumbnailId = model.StorefrontImg[1], AccountType = AccountType.User, Markup = 0, FeeRate = 0, IsAllowExpense = false, Week = Week.Monday, ApplicantName = model.ApplicantName, UseFiiiDeduct = model.UseFiiiDeduction }; InviteRecord inviteRecord = new InviteRecord { AccountId = account.Id, InviterCode = model.InviteCode, Type = InviteType.FiiipayMerchant, InviterAccountId = inviteAccount?.Id ?? Guid.Empty, Timestamp = dtNow }; FiiipayMerchantVerifyRecord record = new FiiipayMerchantVerifyRecord { CreateTime = dtNow, MerchantInfoId = merchantInfoId, BusinessLicenseImage = model.BusinessLicenseImage, LicenseNo = model.LicenseNo, VerifyStatus = VerifyStatus.UnderApproval }; List <MerchantCategory> categorys = model.MerchantCategorys.Select(t => new MerchantCategory { MerchantInformationId = merchantInfoId, Category = t }).ToList(); List <MerchantOwnersFigure> figuresList = new List <MerchantOwnersFigure>(); if (model.FigureImgList != null) { for (int i = 0; i < model.FigureImgList.Length; i++) { figuresList.Add(new MerchantOwnersFigure { MerchantInformationId = merchantInfoId, FileId = model.FigureImgList[i][0], Sort = i, ThumbnailId = model.FigureImgList[i][1] }); } } var coinList = await new CryptocurrencyDAC().GetAllAsync(); List <MerchantSupportCrypto> supportCryptoList = model.SupportCoins.Select(t => { var c = coinList.Find(m => m.Id == t); if (c != null) { return(new MerchantSupportCrypto { MerchantInfoId = merchantInfoId, CryptoId = t, CryptoCode = c.Code }); } return(null); }).Where(x => x != null).ToList(); #endregion var mInfoDAC = new MerchantInformationDAC(); var fmVerfiyRecordDAC = new FiiipayMerchantVerifyRecordDAC(); var mCategoryDAC = new MerchantCategoryDAC(); var mFigureDAC = new MerchantOwnersFigureDAC(); var mSupportCryptoDAC = new MerchantSupportCryptoDAC(); var inviteDAC = new InviteRecordDAC(); using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { mInfoDAC.Insert(merchantInfo); fmVerfiyRecordDAC.Insert(record); if (needInviteRecord) { inviteDAC.Insert(inviteRecord); } if (categorys != null && categorys.Count > 0) { foreach (var item in categorys) { mCategoryDAC.Insert(item); } } if (figuresList != null && figuresList.Count > 0) { foreach (var item in figuresList) { mFigureDAC.Insert(item); } } if (supportCryptoList != null && supportCryptoList.Count > 0) { foreach (var item in supportCryptoList) { mSupportCryptoDAC.Insert(item); } } scope.Complete(); } return(true); }
public async Task <PayOrderOM> PayAsync(UserAccount user, StoreOrderPayIM im) { #region 验证 if (im.FiatAmount <= 0) { throw new ApplicationException(); } SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, user.Id.ToString(), user.Pin, im.Pin); if (!user.IsAllowExpense.HasValue || !user.IsAllowExpense.Value) { throw new CommonException(ReasonCode.Not_Allow_Expense, MessageResources.PaymentForbidden); } var coin = new CryptocurrencyDAC().GetById(im.CoinId); if (!coin.Status.HasFlag(CryptoStatus.Pay) || coin.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } var merchantInfo = new MerchantInformationDAC().GetById(im.MerchantInfoId); if (merchantInfo.Status != Status.Enabled || merchantInfo.VerifyStatus != VerifyStatus.Certified || merchantInfo.IsPublic != Status.Enabled) { throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantExceptionTransClose); } if (!merchantInfo.IsAllowExpense) { throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantReceiveNotAllowed); } if (merchantInfo.AccountType == AccountType.Merchant) { throw new ApplicationException(); } var storeAccount = new UserAccountDAC().GetById(merchantInfo.MerchantAccountId); if (storeAccount.Id == user.Id) { throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.PaytoSelf); } if (storeAccount == null || storeAccount.Status.Value != (byte)AccountStatus.Active) { throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantFiiipayAbnormal); } var paySetting = await new StorePaySettingDAC().GetByCountryIdAsync(merchantInfo.CountryId); if (paySetting != null) { if (im.FiatAmount > paySetting.LimitAmount) { throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, string.Format(MessageResources.TransferAmountOverflow, paySetting.LimitAmount, paySetting.FiatCurrency)); } } #endregion var walletDAC = new UserWalletDAC(); var statementDAC = new UserWalletStatementDAC(); var storeOrderDAC = new StoreOrderDAC(); var utDAC = new UserTransactionDAC(); #region 计算 decimal markup = merchantInfo.Markup; decimal feeRate = merchantInfo.FeeRate; var exchangeRate = new PriceInfoDAC().GetPriceByName(storeAccount.FiatCurrency, coin.Code); decimal failTotalAmount = im.FiatAmount + (im.FiatAmount * markup).ToSpecificDecimal(4); decimal transactionFiatFee = (im.FiatAmount * feeRate).ToSpecificDecimal(4); decimal transactionFee = (transactionFiatFee / exchangeRate).ToSpecificDecimal(coin.DecimalPlace); decimal cryptoAmount = (failTotalAmount / exchangeRate).ToSpecificDecimal(coin.DecimalPlace); var fromWallet = walletDAC.GetUserWallet(user.Id, im.CoinId); if (fromWallet == null || fromWallet.Balance < cryptoAmount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var toWallet = walletDAC.GetUserWallet(storeAccount.Id, im.CoinId); if (toWallet == null) { toWallet = new UserWalletComponent().GenerateWallet(storeAccount.Id, im.CoinId); } #endregion #region entity DateTime dtNow = DateTime.UtcNow; StoreOrder order = new StoreOrder { Id = Guid.NewGuid(), OrderNo = IdentityHelper.OrderNo(), Timestamp = dtNow, Status = OrderStatus.Completed, MerchantInfoId = merchantInfo.Id, MerchantInfoName = merchantInfo.MerchantName, UserAccountId = user.Id, CryptoId = im.CoinId, CryptoCode = coin.Code, CryptoAmount = cryptoAmount, CryptoActualAmount = cryptoAmount - transactionFee, ExchangeRate = exchangeRate, Markup = markup, FiatCurrency = storeAccount.FiatCurrency, FiatAmount = im.FiatAmount, FiatActualAmount = failTotalAmount, FeeRate = feeRate, TransactionFee = transactionFee, PaymentTime = dtNow }; UserWalletStatement fromStatement = new UserWalletStatement { WalletId = fromWallet.Id, Action = UserWalletStatementAction.StoreOrderOut, Amount = -order.CryptoAmount, Balance = fromWallet.Balance - order.CryptoAmount, FrozenAmount = 0, FrozenBalance = fromWallet.FrozenBalance, Timestamp = dtNow }; UserWalletStatement toStatement = new UserWalletStatement { WalletId = toWallet.Id, Action = UserWalletStatementAction.StoreOrderIn, Amount = order.CryptoActualAmount, Balance = toWallet.Balance + order.CryptoActualAmount, FrozenAmount = 0, FrozenBalance = toWallet.FrozenBalance, Timestamp = dtNow }; #endregion using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await storeOrderDAC.CreateAsync(order); await utDAC.InsertAsync(new UserTransaction { Id = Guid.NewGuid(), AccountId = fromWallet.UserAccountId, CryptoId = order.CryptoId, CryptoCode = order.CryptoCode, Type = UserTransactionType.StoreOrderConsume, DetailId = order.Id.ToString(), Status = (byte)order.Status, Timestamp = order.PaymentTime.Value, Amount = order.CryptoAmount, OrderNo = order.OrderNo, MerchantName = order.MerchantInfoName }); await utDAC.InsertAsync(new UserTransaction { Id = Guid.NewGuid(), AccountId = toWallet.UserAccountId, CryptoId = order.CryptoId, CryptoCode = order.CryptoCode, Type = UserTransactionType.StoreOrderIncome, DetailId = order.Id.ToString(), Status = (byte)order.Status, Timestamp = order.Timestamp, Amount = order.CryptoActualAmount, OrderNo = order.OrderNo, MerchantName = order.MerchantInfoName }); walletDAC.Decrease(fromWallet.Id, order.CryptoAmount); walletDAC.Increase(toWallet.Id, order.CryptoActualAmount); statementDAC.Insert(fromStatement); statementDAC.Insert(toStatement); scope.Complete(); } var pushObj = new { order.Id, order.UserAccountId, order.CryptoCode }; RabbitMQSender.SendMessage("StoreOrderPayed", new { order.Id, MerchantInfoId = merchantInfo.MerchantAccountId, order.UserAccountId, order.CryptoCode }); return(new PayOrderOM { Amount = order.CryptoAmount.ToString(coin.DecimalPlace), Currency = coin.Code, OrderId = order.Id.ToString(), OrderNo = order.OrderNo, Timestamp = dtNow.ToUnixTime().ToString() }); }