private Order Generate(MerchantAccount account, Cryptocurrency coin, string unifiedFiatCurrency, string fiatCurrency, decimal amount, PaymentType paymentType, string merchantClientIP = null) { var order = new Order { Id = Guid.NewGuid(), OrderNo = NumberGenerator.GenerateUnixOrderNo(), MerchantAccountId = account.Id, CryptoId = coin.Id, CryptoCode = coin.Code, FiatAmount = amount, PaymentType = paymentType, FiatCurrency = fiatCurrency, Status = OrderStatus.Pending, Timestamp = DateTime.UtcNow, ExpiredTime = DateTime.UtcNow.AddMinutes(30), Markup = account.Markup, ExchangeRate = GetExchangeRate(account.CountryId, fiatCurrency, coin), UnifiedExchangeRate = GetExchangeRate(account.CountryId, unifiedFiatCurrency, coin), UnifiedFiatCurrency = unifiedFiatCurrency, MerchantIP = merchantClientIP }; var calcModel = CalculateAmount(amount, account.Markup, account.Receivables_Tier, order.ExchangeRate, coin); order.ActualFiatAmount = calcModel.FiatTotalAmount; order.CryptoAmount = calcModel.CryptoAmount; order.TransactionFee = calcModel.TransactionFee; order.ActualCryptoAmount = calcModel.ActualCryptoAmount; var model = CalculateUnifiedAmount(order.CryptoAmount, order.ActualCryptoAmount, order.UnifiedExchangeRate); order.UnifiedFiatAmount = model.UnifiedFiatAmount; order.UnifiedActualFiatAmount = model.UnifiedActualFiatAmount; return(order); }
private void MiningReceived(WalletFactory _walletFactory, DepositFactory _depositFactory, WalletStatementFactory _walletStatementFactory, TransactionFactory _transactionFactory, long requestId, string transactionId, Guid accountId, decimal amount) { if (RedisHelper.KeyExists(miningReceivedKey + requestId))//防止没写进数据库之前,相同的请求调用 { throw new CommonException(20001, "Error: Repeated requests"); } var excistDeposit = _depositFactory.GetByRequestId(accountId, requestId); if (excistDeposit != null) { throw new CommonException(20001, "Error: Repeated requests"); } RedisHelper.StringSet(miningReceivedKey + requestId, "1", new TimeSpan(0, 0, 30)); var crypto = new CryptocurrencyDAC().GetByCode("FIII"); if (crypto == null) { throw new CommonException(20000, "Error: Invalid cryptocurrency"); } var wallet = _walletFactory.GetByAccountId(accountId, crypto.Id); var timestamp = DateTime.UtcNow; using (var scope = new TransactionScope()) { if (wallet == null) { wallet = GenerateWallet(_walletFactory, accountId, crypto.Id, crypto.Code); } var deposit = new Deposit { AccountId = accountId, WalletId = wallet.Id, FromType = DepositFromType.PosMining, ToAddress = wallet.Address, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = timestamp, RequestId = requestId, OrderNo = NumberGenerator.GenerateUnixOrderNo(), TransactionId = transactionId, CryptoCode = crypto.Code }; _depositFactory.Insert(deposit); _transactionFactory.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = accountId, CryptoId = crypto.Id, CryptoCode = crypto.Code, Type = UserTransactionType.Deposit, DetailId = deposit.Id.ToString(), Status = (byte)deposit.Status, Timestamp = deposit.Timestamp, Amount = amount, OrderNo = deposit.OrderNo }); _walletFactory.Increase(wallet.Id, amount); //_walletFactory.DecreaseFreeze(wallet.Id, -amount); _walletStatementFactory.Insert(new WalletStatement { Action = Entities.UserWalletStatementAction.AwardDeposit, Amount = amount, Balance = wallet.Balance + amount, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Remark = null, Timestamp = timestamp, WalletId = wallet.Id }); scope.Complete(); } }
//private readonly Dictionary<string, int> _notificationErrorCount = new Dictionary<string, int>(); public void Payment(string message) { var orderModel = JsonConvert.DeserializeObject <MallPaymentOrder>(message); var userWalletDac = new UserWalletDAC(); var walletStatementDac = new UserWalletStatementDAC(); var gatewayOrderDac = new GatewayOrderDAC(); var mallDac = new MallPaymentOrderDAC(); var cryptoDac = new CryptocurrencyDAC(); var extsis = gatewayOrderDac.GetByOrderNo(orderModel.OrderId); if (extsis != null && extsis.Status == GatewayOrderStatus.Completed) { _log.Info("Order message " + message + " hased Payment."); return; } var cryptoFiii = cryptoDac.GetByCode("FIII"); var fiiiWallet = userWalletDac.GetByAccountId(orderModel.UserAccountId, cryptoFiii.Id); if (fiiiWallet.Balance < orderModel.CryptoAmount) { _log.ErrorFormat("message {0}, Insufficient balance", message); } try { var fiiiPrice = GetMarketPrice("USD", "FIII"); var fiiiFiatAmount = Math.Round(orderModel.CryptoAmount * fiiiPrice, 2); var trdeNo = NumberGenerator.GenerateUnixOrderNo(); var id = Guid.NewGuid(); using (var scope = new TransactionScope()) { userWalletDac.Decrease(fiiiWallet.Id, orderModel.CryptoAmount); walletStatementDac.Insert(new UserWalletStatement { WalletId = fiiiWallet.Id, Action = UserWalletStatementAction.Consume, Amount = -orderModel.CryptoAmount, Balance = fiiiWallet.Balance - orderModel.CryptoAmount, FrozenAmount = 0, FrozenBalance = fiiiWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); var gatewayFiiiOrder = new GatewayOrder { Id = id, OrderNo = orderModel.OrderId, MerchantAccountId = Guid.Empty, MerchantName = "FiiiShop", CryptoId = cryptoFiii.Id, CryptoCode = "FIII", FiatAmount = fiiiFiatAmount, FiatCurrency = "USD", Status = GatewayOrderStatus.Completed, ExpiredTime = DateTime.UtcNow.AddMinutes(30), Markup = 0M, ExchangeRate = fiiiPrice, PaymentTime = DateTime.UtcNow, Timestamp = DateTime.UtcNow, UserAccountId = orderModel.UserAccountId, ActualCryptoAmount = orderModel.CryptoAmount, ActualFiatAmount = fiiiFiatAmount, CryptoAmount = orderModel.CryptoAmount, TransactionFee = 0, Remark = null, TradeNo = trdeNo }; gatewayOrderDac.Insert(gatewayFiiiOrder); mallDac.UpdateStatus(orderModel.Id, (byte)OrderStatus.Completed); mallDac.UpdateTradeNo(orderModel.Id, trdeNo); scope.Complete(); } RabbitMQSender.SendMessage("ShopPayment", id); SendNotificationMessage(TradeType.Payment, orderModel.Id, orderModel.OrderId, trdeNo, "success"); } catch (Exception exception) { //SendNotificationMessage(TradeType.Payment, orderModel.Id, orderModel.OrderId, string.Empty, "error"); _log.Error("Payment error, exception : " + exception.Message); } }
public void Refund(string message) { var orderModel = JsonConvert.DeserializeObject <MallPaymentOrder>(message); var userWalletDac = new UserWalletDAC(); var walletStatementDac = new UserWalletStatementDAC(); var gatewayOrderDac = new GatewayOrderDAC(); var mallDac = new MallPaymentOrderDAC(); var refundDac = new GatewayRefundOrderDAC(); var gatewayOrder = gatewayOrderDac.GetByTradeNo(orderModel.TradeNo); if (gatewayOrder.Status == GatewayOrderStatus.Pending) { _log.Error("Order message " + message + " not payment."); return; } if (gatewayOrder.Status == GatewayOrderStatus.Refunded) { _log.Info("Order message " + message + " has refund."); return; } var fiiiWallet = userWalletDac.GetByCryptoCode(orderModel.UserAccountId, "FIII"); try { var id = Guid.NewGuid(); var refundTradeNo = NumberGenerator.GenerateUnixOrderNo(); using (var scope = new TransactionScope()) { mallDac.UpdateStatus(orderModel.Id, (byte)OrderStatus.Refunded); mallDac.UpdateRefundTradeNo(orderModel.Id, refundTradeNo); gatewayOrderDac.UpdateStatus(gatewayOrder.Id, (byte)OrderStatus.Refunded); userWalletDac.Increase(fiiiWallet.Id, gatewayOrder.CryptoAmount); walletStatementDac.Insert(new UserWalletStatement { WalletId = fiiiWallet.Id, Action = UserWalletStatementAction.Refund, Amount = orderModel.CryptoAmount, Balance = fiiiWallet.Balance + gatewayOrder.CryptoAmount, FrozenAmount = 0, FrozenBalance = fiiiWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); refundDac.Insert(new GatewayRefundOrder { Id = id, OrderId = gatewayOrder.Id, Remark = "", Status = RefundStatus.Completed, Timestamp = DateTime.UtcNow, RefundTradeNo = refundTradeNo }); scope.Complete(); } RabbitMQSender.SendMessage("ShopPaymentRefund", id); SendNotificationMessage(TradeType.Refund, orderModel.Id, orderModel.OrderId, refundTradeNo, "success"); } catch (Exception exception) { _log.Error("Refund error, exception : " + exception.Message); //SendNotificationMessage(TradeType.Refund, orderModel.Id, orderModel.OrderId, string.Empty, "error"); } }
public string CreateOrder(Guid merchantAccountId, string fiatCurrency, int cryptoId, decimal amount, PaymentType paymentType, string userToken, string clientIP) { var accountDAC = new MerchantAccountDAC(); var account = accountDAC.GetById(merchantAccountId); if (!account.IsAllowAcceptPayment) { throw new CommonException(ReasonCode.Not_Allow_Withdrawal, Resources.禁止收款); } var coin = new CryptocurrencyDAC().GetById(cryptoId); if (!coin.Status.HasFlag(CryptoStatus.Pay)) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden); } if (coin.Enable == (byte)CurrencyStatus.Forbidden) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden); } var order = new RedisOrderDTO() { FiatAmount = amount, CryptoId = cryptoId, FiatCurrency = fiatCurrency, MerchantGuid = account.Id, OrderNo = NumberGenerator.GenerateUnixOrderNo(), CountryId = account.CountryId, Markup = account.Markup, Type = paymentType, UserId = Guid.Empty }; Guid?userAccountId = null; if (!string.IsNullOrEmpty(userToken)) { if (!userToken.StartsWith(Constant.PAYMENT_CODE_PREFIX)) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.无效的用户Token); } var paymentInfo = RedisHelper.Get <PaymentCodeDTO>( Constant.REDIS_PAYMENT_CODE_DBINDEX, $"{Constant.REDIS_PAYMENT_CODE_PREFIX}{userToken}"); if (paymentInfo == null) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.无效的用户Token); } userAccountId = paymentInfo.UserId; } if (userAccountId.HasValue) { order.UserId = userAccountId.Value; SendPayOrderModel model = new SendPayOrderModel(); model.OrderNo = order.OrderNo; model.UserAccountId = userAccountId.Value.ToString(); MerchantMSMQ.PubPayOrder(model, 0); } RedisHelper.StringSet($"fiiipos:order:{ order.OrderNo}", JsonConvert.SerializeObject(order), TimeSpan.FromMinutes(30)); return(order.OrderNo); }
private string CreateOrderno() { return(NumberGenerator.GenerateUnixOrderNo()); }
public void Deposit(Guid accountId, string transactionId, decimal amount, string cryptoName, DateTime timestamp, string address, string tag) { var account = _accountFactory.GetById(accountId); if (account == null) { throw new CommonException(20000, "Error: Invalid Account ID"); } var crypto = _cryptocurrencyDac.GetByCode(cryptoName); if (crypto == null) { throw new CommonException(20000, "Error: Invalid Cryptocurrency"); } var wallet = _walletFactory.GetByAccountId(accountId, crypto.Id); Deposit deposit; using (var scope = new TransactionScope()) { if (wallet == null) { wallet = GenerateWallet(accountId, crypto.Id, crypto.Code); } deposit = new Deposit { AccountId = account.Id, WalletId = wallet.Id, FromAddress = address, FromTag = tag, ToAddress = wallet.Address, ToTag = wallet.Tag, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = timestamp, OrderNo = NumberGenerator.GenerateUnixOrderNo(), TransactionId = transactionId }; deposit = _depositFactory.Insert(deposit); _walletFactory.Increase(wallet.Id, amount); _walletStatementFactory.Insert(new WalletStatement { Action = MerchantWalletStatementAction.Deposit, Amount = amount, Balance = wallet.Balance + amount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = wallet.Id }); scope.Complete(); } try { _redisMqFactory.PubDeposit(deposit.Id); if (!string.IsNullOrEmpty(account.Email)) { string subject = string.Format(Resources.DepositTitle, cryptoName); string content = string.Format(Resources.DepositEmailContent, amount, cryptoName); new EmailAgent().Send(account.Email, subject, content, 5); } } catch (Exception ex) { _log.Error(ex); } }
public void DepositCompleted(Guid accountId, long depositRequestId, string cryptoName, string transactionId, decimal amount, string address, string tag) { var account = _accountFactory.GetById(accountId); if (account == null) { throw new CommonException(20000, "Error: Invalid Account ID"); } var crypto = _cryptocurrencyDac.GetByCode(cryptoName); if (crypto == null) { throw new CommonException(20000, "Error: Invalid Cryptocurrency"); } var deposit = _depositFactory.GetByRequestId(accountId, depositRequestId); var wallet = _walletFactory.GetByAccountId(accountId, crypto.Id); //充值订单存在 完成订单 if (deposit != null) { if (deposit.Status == TransactionStatus.Confirmed) { return; } if (deposit.Status != TransactionStatus.Pending) { throw new CommonException(20000, "Error: Invalid Deposit Status"); } using (var scope = new TransactionScope()) { _walletFactory.Increase(deposit.WalletId, deposit.Amount); _depositFactory.CompletedByRequestId(accountId, wallet.Id, depositRequestId); _transactionFactory.UpdateStatus(UserTransactionType.Deposit, deposit.Id.ToString(), accountId, (byte)TransactionStatus.Confirmed); _walletStatementFactory.Insert(new WalletStatement { Action = MerchantWalletStatementAction.Deposit, Amount = amount, Balance = wallet.Balance + amount, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = wallet.Id }); scope.Complete(); } } //充值订单不存在 创建一条已完成订单 else { if (string.IsNullOrEmpty(transactionId)) { throw new CommonException(20000, "Invalid TransactionId"); } using (var scope = new TransactionScope()) { if (wallet == null) { wallet = GenerateWallet(account.Id, crypto.Id, crypto.Code); } deposit = _depositFactory.Insert(new Deposit { AccountId = account.Id, WalletId = wallet.Id, FromAddress = address, FromTag = tag, ToAddress = wallet.Address, ToTag = wallet.Tag, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = DateTime.UtcNow, OrderNo = NumberGenerator.GenerateUnixOrderNo(), TransactionId = transactionId, RequestId = depositRequestId, CryptoCode = crypto.Code, FromType = DepositFromType.Deposit }); _transactionFactory.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = account.Id, CryptoId = crypto.Id, CryptoCode = crypto.Code, Type = UserTransactionType.Deposit, DetailId = deposit.Id.ToString(), Status = (byte)deposit.Status, Timestamp = deposit.Timestamp, Amount = amount, OrderNo = deposit.OrderNo }); _walletFactory.Increase(wallet.Id, amount); _walletStatementFactory.Insert(new WalletStatement { Action = MerchantWalletStatementAction.Deposit, Amount = amount, Balance = wallet.Balance + amount, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = wallet.Id }); scope.Complete(); } } try { _redisMqFactory.PubDeposit(deposit.Id); //if (!string.IsNullOrEmpty(account.Email)) //{ // string subject = string.Format(Resources.DepositTitle, cryptoName); // string content = string.Format(Resources.DepositEmailContent, deposit.Amount.Value, cryptoName); // new EmailAgent().Send(account.Email, subject, content, 5); //} } catch (Exception ex) { _log.Error(ex); } }
public void DepositPending(Guid accountId, long requestId, string transactionId, decimal amount, string cryptoName, string address, string tag) { if (string.IsNullOrEmpty(transactionId)) { throw new CommonException(20000, "Invalid TransactionId"); } var crypto = _cryptocurrencyDac.GetByCode(cryptoName); if (crypto == null) { throw new CommonException(20000, "Error: Invalid Cryptocurrency"); } var account = _accountFactory.GetById(accountId); if (account == null) { throw new CommonException(20000, "Error: Invalid Account ID"); } //防止重复处理 var deposit = _depositFactory.GetByRequestId(accountId, requestId); if (deposit != null) { throw new CommonException(20000, "Error: Duplicate RequestId"); } var wallet = _walletFactory.GetByAccountId(accountId, crypto.Id); using (var scope = new TransactionScope()) { if (wallet == null) { wallet = GenerateWallet(accountId, crypto.Id, crypto.Code); } var depositObj = _depositFactory.Insert(new Deposit { AccountId = account.Id, WalletId = wallet.Id, FromAddress = address, FromTag = tag, ToAddress = wallet.Address, ToTag = wallet.Tag, Amount = amount, Status = TransactionStatus.Pending, Timestamp = DateTime.UtcNow, OrderNo = NumberGenerator.GenerateUnixOrderNo(), TransactionId = transactionId, RequestId = requestId, CryptoCode = crypto.Code, FromType = DepositFromType.Deposit }); _transactionFactory.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = account.Id, CryptoId = crypto.Id, CryptoCode = crypto.Code, Type = UserTransactionType.Deposit, DetailId = depositObj.Id.ToString(), Status = (byte)depositObj.Status, Timestamp = depositObj.Timestamp, Amount = amount, OrderNo = depositObj.OrderNo }); scope.Complete(); } }
//private MerchantWithdrawal WithdrawalToMerchantAccount(MerchantWallet fromWallet, MerchantWithdrawal fromWithdraw, MerchantWallet toWallet) //{ // MerchantDeposit deposit = null; // using (var scope = new TransactionScope()) // { // //提币 // fromWithdraw.Status = TransactionStatus.Confirmed; // fromWithdraw.TransactionId = toWallet.MerchantAccountId.ToString("N"); // fromWithdraw.SelfPlatform = true;//平台内提币 // fromWithdraw = new MerchantWithdrawalDAC().Create(fromWithdraw); // var fromWithdrawFee = new MerchantWithdrawalFee // { // Amount = fromWithdraw.Amount, // Timestamp = DateTime.UtcNow, // Fee = fromWithdraw.Amount * WithdrawalMasterSetting.ToMerchantHandleFeeTier, // WithdrawalId = fromWithdraw.Id // }; // new MerchantWithdrawalFeeDAC().Create(fromWithdrawFee); // new MerchantWalletDAC().Decrease(fromWallet.Id, fromWithdraw.Amount); // new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement // { // WalletId = fromWallet.Id, // Action = MerchantWalletStatementAction.Withdrawal, // Amount = -fromWithdraw.Amount, // Balance = fromWallet.Balance - fromWithdraw.Amount, // Timestamp = DateTime.UtcNow // }); // //充币 // var amount = fromWithdraw.Amount - fromWithdrawFee.Fee; // if (amount <= 0) // { // throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数); // } // deposit = new MerchantDepositDAC().Insert(new MerchantDeposit // { // MerchantAccountId = toWallet.MerchantAccountId, // MerchantWalletId = toWallet.Id, // FromAddress = fromWallet.Address, // ToAddress = toWallet.Address, // Amount = fromWithdraw.Amount - fromWithdrawFee.Fee, // Status = TransactionStatus.Confirmed, // Timestamp = DateTime.UtcNow, // OrderNo = CreateOrderno(), // TransactionId = fromWallet.MerchantAccountId.ToString("N"), // SelfPlatform = true // }); // new MerchantWalletDAC().Increase(toWallet.Id, amount); // new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement // { // WalletId = toWallet.Id, // Action = MerchantWalletStatementAction.Deposit, // Amount = amount, // Balance = toWallet.Balance + amount, // Timestamp = DateTime.UtcNow // }); // scope.Complete(); // } // var withdrawId = fromWithdraw.Id; // var depositId = deposit.Id; // var t1 = Task.Run(() => new FiiiPOSPushComponent().PushWithdrawCompleted(withdrawId)); // var t2 = Task.Run(() => new FiiiPOSPushComponent().PushDeposit(depositId)); // Task.WaitAll(t1, t2); // return fromWithdraw; //} private MerchantWithdrawal WithdrawalToUserAccount(MerchantWallet fromWallet, MerchantWithdrawal fromWithdraw, UserWallet toWallet, decimal fee) { UserDeposit deposit; using (var scope = new TransactionScope()) { //提币 fromWithdraw.Status = TransactionStatus.Confirmed; fromWithdraw.TransactionId = toWallet.UserAccountId.ToString("N"); fromWithdraw.SelfPlatform = true;//平台内提币 fromWithdraw = new MerchantWithdrawalDAC().Create(fromWithdraw); var fromWithdrawFee = new MerchantWithdrawalFee { Amount = fromWithdraw.Amount, Timestamp = DateTime.UtcNow, Fee = fee, WithdrawalId = fromWithdraw.Id }; new MerchantWithdrawalFeeDAC().Create(fromWithdrawFee); new MerchantWalletDAC().Decrease(fromWallet.Id, fromWithdraw.Amount); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { WalletId = fromWallet.Id, Action = MerchantWalletStatementAction.Withdrawal, Amount = -fromWithdraw.Amount, Balance = fromWallet.Balance - fromWithdraw.Amount, Timestamp = DateTime.UtcNow }); //充币 var amount = fromWithdraw.Amount - fromWithdrawFee.Fee; new UserWalletDAC().Increase(toWallet.Id, amount); new UserWalletStatementDAC().Insert(new UserWalletStatement { WalletId = toWallet.Id, Action = UserWalletStatementAction.Deposit, Amount = amount, Balance = toWallet.Balance + amount, FrozenAmount = 0, FrozenBalance = toWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); deposit = new UserDepositDAC().Insert(new UserDeposit { UserAccountId = toWallet.UserAccountId, UserWalletId = toWallet.Id, FromAddress = fromWallet.Address, FromTag = fromWallet.Tag, ToAddress = toWallet.Address, ToTag = toWallet.Tag, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = DateTime.UtcNow, OrderNo = NumberGenerator.GenerateUnixOrderNo(), TransactionId = fromWallet.MerchantAccountId.ToString("N"), SelfPlatform = true, CryptoCode = toWallet.CryptoCode }); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = toWallet.UserAccountId, CryptoId = toWallet.CryptoId, CryptoCode = toWallet.CryptoCode, Type = UserTransactionType.Deposit, DetailId = deposit.Id.ToString(), Status = (byte)deposit.Status, Timestamp = deposit.Timestamp, Amount = amount, OrderNo = deposit.OrderNo }); scope.Complete(); } var withdrawId = fromWithdraw.Id; var depositId = deposit.Id; MerchantMSMQ.PubMerchantWithdrawCompleted(withdrawId, 0); MerchantMSMQ.PubUserDeposit(depositId, 0); return(fromWithdraw); }
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)); }