public PreTransferOM PreTransfer(UserAccount account, PreTransferIM im) { var toAccount = new UserAccountDAC().GetByCountryIdAndCellphone(im.ToCountryId, im.ToCellphone); if (toAccount == null) { throw new CommonException(ReasonCode.ACCOUNT_NOT_EXISTS, MessageResources.AccountNotExist); } if (account.Id == toAccount.Id) { throw new CommonException(ReasonCode.TRANSFER_TO_SELF, MessageResources.TransferToSelf); } var country = new CountryComponent().GetById(im.ToCountryId); var profile = new UserProfileAgent().GetUserProfile(toAccount.Id); var cryptoCurrency = new CryptocurrencyDAC().GetById(im.CoinId); var fromWallet = new UserWalletComponent().GetUserWallet(account.Id, im.CoinId); return(new PreTransferOM { ToAvatar = toAccount.Photo ?? Guid.Empty, ToAccountName = country.PhoneCode + " " + toAccount.Cellphone, ToFullname = profile == null ? "" : ("* " + profile.LastName), IsTransferAbled = !toAccount.IsAllowTransfer.HasValue || toAccount.IsAllowTransfer.Value, IsProfileVerified = toAccount.L1VerifyStatus == VerifyStatus.Certified, CoinId = cryptoCurrency.Id, CoinCode = cryptoCurrency.Code, MinCount = ((decimal)Math.Pow(10, -cryptoCurrency.DecimalPlace)).ToString("G"), CoinDecimalPlace = cryptoCurrency.DecimalPlace.ToString(), CoinBalance = (fromWallet == null ? "0" : fromWallet.Balance.ToString(cryptoCurrency.DecimalPlace)), FiatCurrency = account.FiatCurrency, Price = (GetExchangeRate(account.CountryId, account.FiatCurrency, cryptoCurrency.Code)).ToString(), ChargeFee = "0" }); }
/// <summary> /// 支付网关发起退款 /// </summary> /// <param name="tradeId"></param> public void GatewayRefund(string tradeId) { //获取订单详情 var orderDetail = new GatewayOrderDAC().GetByTradeNo(tradeId); if (orderDetail == null) { throw new Exception("Have no record of this order:tradeId=" + tradeId); } if (orderDetail.Status != GatewayOrderStatus.Completed) { throw new Exception($"The status of this order {tradeId} is not completed"); } var uwComponent = new UserWalletComponent(); var userWallet = uwComponent.GetUserWallet(orderDetail.UserAccountId.Value, orderDetail.CryptoId); var goDAC = new GatewayOrderDAC(); var rgoDAC = new GatewayRefundOrderDAC(); var uwDAC = new UserWalletDAC(); var uwsDAC = new UserWalletStatementDAC(); using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { orderDetail.Status = GatewayOrderStatus.Refunded; goDAC.Update(orderDetail); uwDAC.Increase(userWallet.Id, orderDetail.ActualCryptoAmount); uwsDAC.Insert(new UserWalletStatement { WalletId = userWallet.Id, Action = UserWalletStatementAction.TansferIn, Amount = orderDetail.ActualCryptoAmount, Balance = userWallet.Balance + orderDetail.ActualCryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); rgoDAC.Insert(new GatewayRefundOrder { Id = Guid.NewGuid(), OrderId = orderDetail.Id, Timestamp = DateTime.UtcNow, Status = RefundStatus.Completed }); scope.Complete(); } }
public string FiiiPayTransferInto(UserAccount account, Cryptocurrency coin, decimal amount) { var walletDac = new UserWalletDAC(); var wallet = walletDac.GetByAccountId(account.Id, coin.Id); UserExTransferOrder order; using (var scope = new TransactionScope()) { if (wallet == null) { wallet = new UserWalletComponent().GenerateWallet(account.Id, coin.Id); } walletDac.Increase(wallet.Id, amount); order = new UserExTransferOrder { Timestamp = DateTime.UtcNow, OrderNo = CreateOrderNo(), OrderType = ExTransferType.FromEx, AccountId = account.Id, WalletId = wallet.Id, CryptoId = coin.Id, CryptoCode = coin.Code, Amount = amount, Status = 1, Remark = null, ExId = null }; new UserExTransferOrderDAC().Create(order); scope.Complete(); } try { FiiiEXTransferMSMQ.PubUserTransferFromEx(order.Id, 0); } catch (Exception ex) { LogHelper.Info("PubUserTransferFromEx - error", ex); } return(order.OrderNo); }
public TransferResult Transfer(InvestorAccount account, int countryId, string cellphone, decimal amount, string pinToken) { new SecurityVerification(SystemPlatform.FiiiCoinWork).VerifyToken(pinToken, SecurityMethod.Pin); CountryDAC countryDac = new CountryDAC(); UserAccountDAC userAccountDac = new UserAccountDAC(); Country country = countryDac.GetById(countryId); if (country == null) { throw new CommonException(ReasonCode.GENERAL_ERROR, R.AccountNotExist); } UserAccount userAccount = userAccountDac.GetByCountryIdAndCellphone(countryId, cellphone); if (userAccount == null) { throw new CommonException(ReasonCode.GENERAL_ERROR, R.AccountNotExist); } InvestorAccountDAC accountDac = new InvestorAccountDAC(); if (account.Balance < amount) { throw new CommonException(ReasonCode.GENERAL_ERROR, R.余额不足); } UserWalletDAC userWalletDac = new UserWalletDAC(); UserWallet userWallet = userWalletDac.GetByAccountId(userAccount.Id, FiiiCoinUtility.Cryptocurrency.Id); InvestorOrder investorOrder; UserDeposit userDeposit; using (var scope = new TransactionScope()) { if (userWallet == null) { userWallet = new UserWalletComponent().GenerateWallet(userAccount.Id, FiiiCoinUtility.Cryptocurrency.Id); } accountDac.Decrease(account.Id, amount); investorOrder = new InvestorOrderDAC().Insert(new InvestorOrder { Id = Guid.NewGuid(), OrderNo = CreateOrderNo(), TransactionType = InvestorTransactionType.Transfer, Status = 1, InverstorAccountId = account.Id, UserAccountId = userAccount.Id, CryptoId = FiiiCoinUtility.Cryptocurrency.Id, CryptoAmount = amount, Timestamp = DateTime.UtcNow }); new InvestorWalletStatementDAC().Insert(new InvestorWalletStatement { Id = Guid.NewGuid(), InvestorId = account.Id, TagAccountId = userAccount.Id, Action = InvestorTransactionType.Transfer, Amount = -amount, Balance = account.Balance - amount, Timestamp = DateTime.UtcNow }); // 2018-06-26: new rules IncreaseFrozen -> Increase userWalletDac.Increase(userWallet.Id, amount); userDeposit = new UserDepositDAC().Insert(new UserDeposit { UserAccountId = userAccount.Id, UserWalletId = userWallet.Id, FromAddress = null, FromTag = null, ToAddress = null, ToTag = null, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = DateTime.UtcNow, OrderNo = CreateOrderNo(), TransactionId = account.Id.ToString(), SelfPlatform = true, RequestId = null }); scope.Complete(); } InvestorMSMQ.PubUserDeposit(userDeposit.Id, 0); return(new TransferResult { OrderId = investorOrder.Id, OrderNo = investorOrder.OrderNo, TargetAccount = GetMaskedCellphone(country.PhoneCode, userAccount.Cellphone), Timestamp = DateTime.UtcNow.ToUnixTime() }); }
/// <summary> /// 插入记录 /// </summary> /// <param name="inviteCode">邀请码</param> /// <param name="accoundId">被邀请人id</param> /// /// <param name="type">1:fiiipay 2:fiiipos</param> public void InsertRecord(InviteRecordIM im) { //判断是fiiipos还是fiiipay //1 插入数据 invite profit两个表 邀请双方都支持插入数据 钱包 流水进行更新 // 判断当前邀请人数到达五十 进行推送。。。。。。。。。。。。 //2 插入数据 invite if (!(im.Type == (int)SystemPlatform.FiiiPay || im.Type == (int)SystemPlatform.FiiiPOS)) { throw new ArgumentException("只支持fiiipay和fiiipos邀请"); } var userAccountDAC = new UserAccountDAC(); var account = userAccountDAC.GetByInvitationCode(im.InvitationCode); var settingCollection = new MasterSettingDAC().SelectByGroup("InviteReward"); var cryptoCurrencty = new CryptocurrencyDAC().GetByCode("FIII"); var cryptoId = cryptoCurrencty.Id; if (im.Type == (int)SystemPlatform.FiiiPay) { var iDAC = new InviteRecordDAC(); var pfDAC = new ProfitDetailDAC(); var uwComponent = new UserWalletComponent(); var uwDAC = new UserWalletDAC(); var uwsDAC = new UserWalletStatementDAC(); var utDAC = new UserTransactionDAC(); var inviteMoney = decimal.Parse(settingCollection.Where(item => item.Name == "Invite_Reward_Amount").Select(item => item.Value).FirstOrDefault()); var rewardMoney = decimal.Parse(settingCollection.Where(item => item.Name == "Over_People_Count_Reward_Amount").Select(item => item.Value).FirstOrDefault()); var maxCount = decimal.Parse(settingCollection.Where(item => item.Name == "Max_Reward_Amount").Select(item => item.Value).FirstOrDefault()); var orderNo1 = CreateOrderno(); var orderNo2 = CreateOrderno(); var inviteWallet = uwComponent.GetUserWallet(account.Id, cryptoId); if (inviteWallet == null) { inviteWallet = uwComponent.GenerateWallet(account.Id, cryptoId); } var beInvitedWallet = uwComponent.GetUserWallet(im.BeInvitedAccountId, cryptoId); if (beInvitedWallet == null) { beInvitedWallet = uwComponent.GenerateWallet(im.BeInvitedAccountId, cryptoId); } int inviteId; long profitId1 = 0; //邀请人奖励ID long profitId2 = 0; //被邀请人奖励ID long exProfitId1 = 0; //邀请人额外奖励ID decimal totalReward = pfDAC.GetTotalReward(account); int invitedCount = pfDAC.GetInvitedCount(account); using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { //插入数据到inviterecord表中 inviteId = iDAC.Insert(new InviteRecord() { Type = (InviteType)im.Type, AccountId = im.BeInvitedAccountId, Timestamp = DateTime.UtcNow, InviterCode = im.InvitationCode, InviterAccountId = account.Id }); if (totalReward < maxCount) { profitId1 = pfDAC.Insert(new ProfitDetail() { InvitationId = inviteId, CryptoAmount = inviteMoney, AccountId = account.Id, Status = InviteStatusType.IssuedFrozen, Type = ProfitType.InvitePiiiPay, OrderNo = orderNo1, Timestamp = DateTime.UtcNow, CryptoId = cryptoId }); utDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = account.Id, CryptoId = cryptoCurrencty.Id, CryptoCode = cryptoCurrencty.Code, Type = UserTransactionType.Profit, DetailId = profitId1.ToString(), Status = (byte)InviteStatusType.IssuedFrozen, Timestamp = DateTime.UtcNow, Amount = inviteMoney, OrderNo = orderNo1 }); uwDAC.IncreaseFrozen(inviteWallet.Id, inviteMoney); uwsDAC.Insert(new UserWalletStatement { WalletId = inviteWallet.Id, Action = UserWalletStatementAction.Invite, Amount = 0, Balance = inviteWallet.Balance, FrozenAmount = inviteMoney, FrozenBalance = inviteWallet.FrozenBalance + inviteMoney, Timestamp = DateTime.UtcNow }); // 每当满50人时则可以奖励 采用了插入操作 所以只要满足为49个就可以了 if ((invitedCount + 1) % 50 == 0) { var pd50 = new ProfitDetail() { InvitationId = inviteId, CryptoAmount = rewardMoney, AccountId = account.Id, Status = InviteStatusType.IssuedFrozen, Type = ProfitType.Reward, OrderNo = CreateOrderno(), Timestamp = DateTime.UtcNow, CryptoId = cryptoId }; exProfitId1 = pfDAC.Insert(pd50); utDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = account.Id, CryptoId = cryptoCurrencty.Id, CryptoCode = cryptoCurrencty.Code, Type = UserTransactionType.Profit, DetailId = exProfitId1.ToString(), Status = (byte)InviteStatusType.IssuedFrozen, Timestamp = DateTime.UtcNow, Amount = rewardMoney, OrderNo = pd50.OrderNo }); uwDAC.IncreaseFrozen(inviteWallet.Id, rewardMoney); uwsDAC.Insert(new UserWalletStatement { WalletId = inviteWallet.Id, Action = UserWalletStatementAction.Invite, Amount = 0, Balance = inviteWallet.Balance, FrozenAmount = rewardMoney, FrozenBalance = inviteWallet.FrozenBalance + inviteMoney + rewardMoney, Timestamp = DateTime.UtcNow }); } profitId2 = pfDAC.Insert(new ProfitDetail() { InvitationId = inviteId, CryptoAmount = inviteMoney, AccountId = im.BeInvitedAccountId, Type = ProfitType.BeInvited, Status = InviteStatusType.IssuedActive, OrderNo = orderNo2, Timestamp = DateTime.UtcNow, CryptoId = cryptoId }); utDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = im.BeInvitedAccountId, CryptoId = cryptoCurrencty.Id, CryptoCode = cryptoCurrencty.Code, Type = UserTransactionType.Profit, DetailId = profitId2.ToString(), Status = (byte)InviteStatusType.IssuedActive, Timestamp = DateTime.UtcNow, Amount = inviteMoney, OrderNo = orderNo2 }); uwDAC.Increase(beInvitedWallet.Id, inviteMoney); uwsDAC.Insert(new UserWalletStatement { WalletId = beInvitedWallet.Id, Action = UserWalletStatementAction.BeInvite, Amount = inviteMoney, Balance = beInvitedWallet.Balance + inviteMoney, FrozenAmount = 0, FrozenBalance = beInvitedWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); } scope.Complete(); } if (!(im.Type == (int)SystemPlatform.FiiiPay || im.Type == (int)SystemPlatform.FiiiPOS)) { throw new ArgumentException("只支持fiiipay和fiiipos邀请"); } if (im.Type == (int)SystemPlatform.FiiiPay) { UserMSMQ.PubUserInviteSuccessed(profitId2, 0); } //else if (im.Type == SystemPlatform.FiiiPOS) // MerchantMSMQ.PubUserInviteSuccessed(profitId2, 0); } //else //{ // var iDAC = new InviteRecordDAC(); // iDAC.Insert(new InviteRecord() { Type = im.Type, AccountId = im.BeInvitedAccountId, Timestamp = DateTime.UtcNow, InviterCode = im.InvitationCode, InviterAccountId = account.Id }); //} }
public TransferOM Transfer(UserAccount account, TransferIM im) { SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, account.Id.ToString(), account.Pin, im.Pin); if (account.L1VerifyStatus != VerifyStatus.Certified) { throw new ApplicationException(); } if (account.IsAllowTransfer.HasValue && !account.IsAllowTransfer.Value) { throw new CommonException(ReasonCode.TRANSFER_FORBIDDEN, MessageResources.TransferForbidden); } var toAccount = new UserAccountDAC().GetByCountryIdAndCellphone(im.ToCountryId, im.ToCellphone); if (toAccount == null) { throw new CommonException(ReasonCode.ACCOUNT_NOT_EXISTS, MessageResources.AccountNotExist); } if (toAccount.IsAllowTransfer.HasValue && !toAccount.IsAllowTransfer.Value) { throw new CommonException(ReasonCode.TRANSFER_FORBIDDEN, MessageResources.ToAccountTransferForbidden); } if (im.Amount >= Convert.ToDecimal(Math.Pow(10, 11))) { throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountOverflow); } var currency = new CryptocurrencyDAC().GetById(im.CoinId); if (!currency.Status.HasFlag(CryptoStatus.Transfer) || currency.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } if (im.Amount < (decimal)Math.Pow(10, -currency.DecimalPlace)) { throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountTooSmall); } var decimalDigits = im.Amount.ToString().Length - im.Amount.ToString().IndexOf('.') - 1; if (decimalDigits > currency.DecimalPlace) { throw new CommonException(ReasonCode.TRANSFER_AMOUNT_OVERFLOW, MessageResources.TransferAmountOverflow); } if (account.Id == toAccount.Id) { throw new CommonException(ReasonCode.TRANSFER_TO_SELF, MessageResources.TransferToSelf); } var uwComponent = new UserWalletComponent(); var toWallet = uwComponent.GetUserWallet(toAccount.Id, im.CoinId); if (toWallet == null) { toWallet = uwComponent.GenerateWallet(toAccount.Id, currency.Id); } var country = new CountryComponent().GetById(im.ToCountryId); DateTime dtCreateTime = DateTime.UtcNow; var fromWallet = uwComponent.GetUserWallet(account.Id, im.CoinId); if (fromWallet.Balance < im.Amount) { throw new CommonException(ReasonCode.TRANSFER_BALANCE_LOW, MessageResources.TransferBalanceLow); } UserTransfer transfer = new UserTransfer { Timestamp = dtCreateTime, OrderNo = CreateOrderno(), FromUserAccountId = account.Id, FromUserWalletId = fromWallet.Id, CoinId = currency.Id, CoinCode = currency.Code, ToUserAccountId = toAccount.Id, ToUserWalletId = toWallet.Id, Amount = im.Amount, Status = (byte)TransactionStatus.Confirmed }; var uwDAC = new UserWalletDAC(); var uwsDAC = new UserWalletStatementDAC(); var utDAC = new UserTransactionDAC(); //var pushComponent = new FiiiPayPushComponent(); using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { transfer.Id = new UserTransferDAC().Insert(transfer); utDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = transfer.FromUserAccountId, CryptoId = transfer.CoinId, CryptoCode = transfer.CoinCode, Type = UserTransactionType.TransferOut, DetailId = transfer.Id.ToString(), Status = transfer.Status, Timestamp = dtCreateTime, Amount = transfer.Amount, OrderNo = transfer.OrderNo }); utDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = transfer.ToUserAccountId, CryptoId = transfer.CoinId, CryptoCode = transfer.CoinCode, Type = UserTransactionType.TransferIn, DetailId = transfer.Id.ToString(), Status = transfer.Status, Timestamp = dtCreateTime, Amount = transfer.Amount, OrderNo = transfer.OrderNo }); uwDAC.Decrease(fromWallet.Id, transfer.Amount); uwDAC.Increase(toWallet.Id, transfer.Amount); uwsDAC.Insert(new UserWalletStatement { WalletId = fromWallet.Id, Action = UserWalletStatementAction.TansferOut, Amount = -transfer.Amount, Balance = fromWallet.Balance - transfer.Amount, FrozenAmount = 0, FrozenBalance = fromWallet.FrozenBalance, Timestamp = dtCreateTime }); uwsDAC.Insert(new UserWalletStatement { WalletId = toWallet.Id, Action = UserWalletStatementAction.TansferIn, Amount = transfer.Amount, Balance = toWallet.Balance + transfer.Amount, FrozenAmount = 0, FrozenBalance = toWallet.FrozenBalance, Timestamp = dtCreateTime }); scope.Complete(); } RabbitMQSender.SendMessage("UserTransferOutFiiiPay", transfer.Id); RabbitMQSender.SendMessage("UserTransferIntoFiiiPay", transfer.Id); //pushComponent.PushTransferOut(transfer.Id); //pushComponent.PushTransferInto(transfer.Id); return(new TransferOM { Timestamp = dtCreateTime.ToUnixTime().ToString(), TracingId = transfer.Id, TracingNo = transfer.OrderNo, AccountName = country.PhoneCode + " " + toAccount.Cellphone }); }
/// <summary> /// FiiiPay扫描第三方二维码支付 /// </summary> /// <param name="code">二维码字符</param> /// <returns></returns> public GatewayOrderInfoOM Pay(GatewayPayIM im, UserAccount account) { new SecurityComponent().VerifyPin(account, im.Pin); var gatewayOrder = new GatewayOrderDAC().GetByOrderId(im.OrderId); if (gatewayOrder.Status != GatewayOrderStatus.Pending) { throw new CommonException(ReasonCode.ORDER_HAD_COMPLETE, MessageResources.OrderComplated); } var cryptoCurrency = new CryptocurrencyDAC().GetById(gatewayOrder.CryptoId); if (cryptoCurrency == null || cryptoCurrency?.Id == null) { throw new CommonException(ReasonCode.CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency"); } var uwComponent = new UserWalletComponent(); var userWallet = uwComponent.GetUserWallet(gatewayOrder.UserAccountId.Value, gatewayOrder.CryptoId); if (userWallet == null) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } if (userWallet.Balance < gatewayOrder.CryptoAmount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var uwDAC = new UserWalletDAC(); var uwsDAC = new UserWalletStatementDAC(); var goDAC = new GatewayOrderDAC(); using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { uwDAC.Decrease(userWallet.Id, gatewayOrder.ActualCryptoAmount); uwsDAC.Insert(new UserWalletStatement { WalletId = userWallet.Id, Action = UserWalletStatementAction.TansferOut, Amount = -gatewayOrder.ActualCryptoAmount, Balance = userWallet.Balance - gatewayOrder.ActualCryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); gatewayOrder.Status = GatewayOrderStatus.Completed; gatewayOrder.PaymentTime = DateTime.UtcNow; goDAC.Update(gatewayOrder); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = userWallet.UserAccountId, CryptoId = cryptoCurrency.Id, CryptoCode = cryptoCurrency.Code, Type = UserTransactionType.Order, DetailId = gatewayOrder.Id.ToString(), Status = (byte)gatewayOrder.Status, Timestamp = DateTime.UtcNow, Amount = gatewayOrder.CryptoAmount, OrderNo = gatewayOrder.OrderNo, MerchantName = gatewayOrder.MerchantName }); scope.Complete(); } RabbitMQSender.SendMessage("FiiiPay_Gateway_PayCompleted", gatewayOrder.TradeNo); return(new GatewayOrderInfoOM() { Timestamp = gatewayOrder.PaymentTime?.ToUnixTime().ToString(), OrderId = gatewayOrder.Id, MerchantName = gatewayOrder.MerchantName, CryptoCode = cryptoCurrency.Code, ActurlCryptoAmount = gatewayOrder.ActualCryptoAmount }); }
public TransferResult FiiiPayTransferFromEx(UserAccount account, int cryptoId, decimal amount, string pin) { new SecurityComponent().VerifyPin(account, pin); var openAccountDac = new OpenAccountDAC(); var openAccount = openAccountDac.GetOpenAccount(FiiiType.FiiiPay, account.Id); if (openAccount == null) { throw new CommonException(ReasonCode.GENERAL_ERROR, R.FiiiExAccountNotExist); } var crypto = new CryptocurrencyDAC().GetById(cryptoId); if (crypto == null) { throw new CommonException(ReasonCode.GENERAL_ERROR, R.CurrencyForbidden); } var balance = this.FiiiExBalance(FiiiType.FiiiPay, account.Id, crypto); if (balance < amount) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足); } //10091=参数不符合要求 10013=用户信息不存在 10024=用户币不存在 10025=用户币种余额不足 0=成功 int result = FiiiExCoinOut(openAccount.OpenId, crypto.Code, amount, out string recordId); if (result == 10025) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足); } if (result != 0) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.从FiiiEx划转失败); } var walletDac = new UserWalletDAC(); var wallet = walletDac.GetByAccountId(account.Id, crypto.Id); UserExTransferOrder order; using (var scope = new TransactionScope()) { if (wallet == null) { wallet = new UserWalletComponent().GenerateWallet(account.Id, crypto.Id); } walletDac.Increase(wallet.Id, amount); order = new UserExTransferOrder { Timestamp = DateTime.UtcNow, OrderNo = CreateOrderNo(), OrderType = ExTransferType.FromEx, AccountId = account.Id, WalletId = wallet.Id, CryptoId = crypto.Id, CryptoCode = crypto.Code, Amount = amount, Status = 1, Remark = null, ExId = recordId }; order = new UserExTransferOrderDAC().Create(order); scope.Complete(); } try { FiiiEXTransferMSMQ.PubUserTransferFromEx(order.Id, 0); } catch (Exception ex) { LogHelper.Info("PubUserTransferFromEx - error", ex); } return(new TransferResult { Id = order.Id, Amount = order.Amount.ToString(crypto.DecimalPlace), OrderNo = order.OrderNo, Timestamp = order.Timestamp.ToUnixTime(), CryptoCode = crypto.Code }); }
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() }); }