public PreDepositOM PreDeposit(UserAccount user, int cryptoId) { var dac = new UserWalletDAC(); var wallet = dac.GetByAccountId(user.Id, cryptoId) ?? new UserWalletComponent().GenerateWallet(user.Id, cryptoId); var coin = new CryptocurrencyDAC().GetById(cryptoId); if (string.IsNullOrEmpty(wallet.Address)) { var agent = new FiiiFinanceAgent(); var addressInfo = agent.CreateWallet(coin.Code, user.Id, AccountTypeEnum.User, user.Email, user.Cellphone); if (string.IsNullOrWhiteSpace(addressInfo.Address)) { throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.FailedGenerateAddress); } wallet.Address = addressInfo.Address; wallet.Tag = addressInfo.DestinationTag; dac.UploadAddress(wallet.Id, wallet.Address, wallet.Tag); } return(new PreDepositOM { Address = wallet.Address, Tag = wallet.Tag, Code = coin.Code, NeedTag = coin.NeedTag }); }
public void Refund(long id) { var redPocket = _redPocketDac.GetById(id); if (redPocket == null) { _log.Error($"Red pocket is not found. {id}"); return; } if (redPocket.RemainCount > 0) { var userWalletDAC = new UserWalletDAC(); var userWalletStatementDAC = new UserWalletStatementDAC(); var userTransactionDAC = new UserTransactionDAC(); var wallet = userWalletDAC.GetByAccountId(redPocket.AccountId, redPocket.CryptoId); if (wallet == null) { _log.Error($"Wallet exception. {redPocket.AccountId} RedPocketId={id}"); return; } using (var scope = new TransactionScope()) { userWalletDAC.Increase(wallet.Id, redPocket.Balance); userWalletStatementDAC.Insert(new UserWalletStatement { WalletId = wallet.Id, Balance = wallet.Balance + redPocket.Balance, Amount = redPocket.Balance, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Action = "Refund Red Pocket", Timestamp = DateTime.UtcNow }); _refundDac.Insert(new RedPocketRefund { Id = redPocket.Id, Amount = redPocket.Balance, OrderNo = _identity.StringId(), Timestamp = DateTime.UtcNow }); _redPocketDac.UpdateStatus(redPocket.Id, redPocket.RemainCount == redPocket.Count ? RedPocketStatus.FullRefund : RedPocketStatus.Refund); userTransactionDAC.UpdateStatus(UserTransactionType.PushRedPocket, redPocket.Id.ToString(), redPocket.AccountId, (byte)RedPocketStatus.Refund); scope.Complete(); } } }
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 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 TransferFiiiExConditionOM FiiiPayTransferFiiiExCondition(UserAccount account, int cryptoId) { var crypto = new CryptocurrencyDAC().GetById(cryptoId); var walletDac = new UserWalletDAC(); var wallet = walletDac.GetByAccountId(account.Id, crypto.Id); var fiiiExBalance = this.FiiiExBalance(FiiiType.FiiiPay, account.Id, crypto); var minQuantity = (1M / (decimal)Math.Pow(10, crypto.DecimalPlace)).ToString(crypto.DecimalPlace); return(new TransferFiiiExConditionOM { Balance = (wallet?.Balance ?? 0M).ToString(crypto.DecimalPlace), MinQuantity = minQuantity, FiiiExBalance = fiiiExBalance.ToString(crypto.DecimalPlace), FiiiExMinQuantity = minQuantity }); }
public void DistributeRewards(FiiiPayRewardMessage message, int fiiicoinId) { MerchantAccountDAC maDAC = new MerchantAccountDAC(); var merchant = maDAC.GetByUsername(message.Account); if (merchant == null) { throw new CommonException(10000, $"无效的商家名:{message.Account}"); } InviteRecord invitor = GetInvitor(merchant.Id); if (invitor == null) { throw new CommonException(10000, "没有邀请人"); } var invitedList = new InviteRecordDAC().GetFiiiPosRecordsByInvitorId(invitor.InviterAccountId, InviteType.Fiiipos); var rewardRate = GetRewardPercentage(invitedList == null ? 0 : invitedList.Count); if (rewardRate == 0) { throw new CommonException(10000, "没有达到奖励条件"); } decimal t = (decimal)Math.Pow(10, -8); long nTotalReward = (long)Math.Floor(message.Reward * rewardRate); if (nTotalReward == 0) { throw new CommonException(10000, "奖励金额为0"); } decimal rewardAmount = nTotalReward * t; DateTime dtNow = DateTime.UtcNow; if (message.CurrentDate > 0) { dtNow = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(message.CurrentDate); } var distributeRecord = new RewardDistributeRecords { UserAccountId = invitor.InviterAccountId, MerchantAccountId = merchant.Id, SN = message.SN, OriginalReward = message.Reward, Percentage = rewardRate, ActualReward = rewardAmount, Timestamp = dtNow }; long profitId; decimal oldBalance = 0; var invitorWallet = uwDAC.GetByAccountId(invitor.InviterAccountId, fiiicoinId); using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { if (invitorWallet == null) { invitorWallet = CreateWallet(invitor.InviterAccountId, fiiicoinId, rewardAmount); } else { oldBalance = invitorWallet.Balance; uwDAC.Increase(invitorWallet.Id, rewardAmount); } var profitDetail = new ProfitDetail { InvitationId = invitor.Id, CryptoAmount = rewardAmount, AccountId = invitor.InviterAccountId, Status = InviteStatusType.IssuedActive, Type = ProfitType.InvitePiiiPos, OrderNo = CreateOrderno(), Timestamp = dtNow, CryptoId = invitorWallet.CryptoId, CryptoCode = "FIII" }; profitId = pfDAC.Insert(profitDetail); uwsDAC.Insert(new UserWalletStatement { WalletId = invitorWallet.Id, Action = UserWalletStatementAction.Reward, Amount = rewardAmount, Balance = oldBalance + rewardAmount, FrozenAmount = 0, FrozenBalance = invitorWallet.FrozenBalance, Timestamp = dtNow }); transDAC.Insert(new UserTransaction { AccountId = invitor.InviterAccountId, Amount = rewardAmount, CryptoCode = "FIII", CryptoId = fiiicoinId, DetailId = profitId.ToString(), Id = Guid.NewGuid(), MerchantName = string.Empty, OrderNo = profitDetail.OrderNo, Status = 2, Timestamp = dtNow, Type = UserTransactionType.Profit }); distributeRecord.ProfitId = profitId; rdrDAC.Insert(distributeRecord); scope.Complete(); } if (profitId > 0) { try { MessagePushService.PubUserInviteSuccessed(profitId, 0); } catch (Exception ex) { throw new CommonException(10000, ex.Message); } } }
//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 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() }); }
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); }
public RedPocket Push(UserAccount userAccount, Guid accountId, int cryptoId, decimal amount, int count, string userPIN, string pin, string message = "") { if (userAccount.L1VerifyStatus != Entities.Enums.VerifyStatus.Certified) { throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied); } if (amount <= 0 || cryptoId <= 0) { throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat); } if (count <= 0) { throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat); } if (count > MaxCount) { throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxCount, MaxCount)); } if (!string.IsNullOrWhiteSpace(message) && message.Length > 46) { throw new CommonException(Argument_Error, MessageResources.RedPocket_MaxMessage); } SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, accountId.ToString(), userPIN, pin); var cryptoDAC = new CryptocurrencyDAC(); var priceDAC = new PriceInfoDAC(); var crypto = cryptoDAC.GetById(cryptoId); if (crypto == null) { throw new SystemErrorException(); } if (!crypto.Status.HasFlag(Foundation.Entities.Enum.CryptoStatus.RedPocket) || crypto.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } var min = crypto.DecimalPlace == 8 ? 0.00000001M : crypto.DecimalPlace == 6 ? 0.000001M : 0.00000001M; var minAmount = count * min; if (amount < minAmount) { throw new CommonException(Push_MinAmount, string.Format(MessageResources.RedPocket_MinAmount, minAmount, crypto.Code)); } var price = priceDAC.GetPriceByName("USD", crypto.Code); var max = crypto.DecimalPlace == 8 ? 999999999.999999999M : crypto.DecimalPlace == 6 ? 999999999.999999M : 999999999.999999999M; var maxAmount = Math.Round(MaxAmount / price, crypto.DecimalPlace); if (count > 1) { maxAmount = Math.Round(MaxAmount * count / price, crypto.DecimalPlace); } if (amount >= max || Math.Round(amount, crypto.DecimalPlace) > maxAmount) { throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxAmount, maxAmount, crypto.Code)); } var userWalletDAC = new UserWalletDAC(); var redPocketDAC = new RedPocketDAC(); var userWalletStatementDAC = new UserWalletStatementDAC(); var userTransactionDAC = new UserTransactionDAC(); var wallet = userWalletDAC.GetByAccountId(accountId, cryptoId); if (wallet == null || wallet.Balance < amount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var fiatAmount = price * amount; using (var scope = new TransactionScope()) { try { var redPocket = new RedPocket { AccountId = accountId, Status = RedPocketStatus.Actived, PassCode = GeneralPassCode(), CryptoCode = crypto.Code, Amount = amount, Balance = amount, Count = count, RemainCount = count, Message = message, Timestamp = DateTime.UtcNow, ExpirationDate = DateTime.UtcNow.AddMinutes(_expried), CryptoId = cryptoId, OrderNo = IdentityHelper.OrderNo(), FiatAmount = fiatAmount <= 0 ? 0M : Math.Round(fiatAmount, 8) }; var redPocketId = redPocketDAC.Insert(redPocket); userTransactionDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = accountId, CryptoId = redPocket.CryptoId, CryptoCode = redPocket.CryptoCode, Type = UserTransactionType.PushRedPocket, DetailId = redPocketId.ToString(), Status = (byte)redPocket.Status, Timestamp = redPocket.Timestamp, Amount = redPocket.Amount, OrderNo = redPocket.OrderNo }); userWalletDAC.Decrease(wallet.Id, amount); userWalletStatementDAC.Insert(new UserWalletStatement { WalletId = wallet.Id, Balance = wallet.Balance - amount, Amount = 0 - amount, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Action = "Push Red Pocket", Timestamp = DateTime.UtcNow }); QueueHelper.DelaySender.Send("FiiiPay_RedPocket", redPocketId); scope.Complete(); return(redPocket); } catch (Exception ex) { _log.Error(ex); throw new SystemErrorException(); } } }
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); }
/// <summary> /// 订单退款 /// </summary> /// <param name="merchantId"></param> /// <param name="orderNo"></param> /// <param name="pin"></param> /// <returns>-1=账号不存在 -2=PIN码错误 -3=订单不存在 -4=商家账户不对 -5=订单状态不符合要求 -6=商家不支持的币种 -7=商家金额不够 -8=用户钱包不支持币种 -9=回滚 -10=日期超过3天</returns> public int RefundOrder(Guid merchantId, string orderNo, string pin) { OrderDAC orderDac = new OrderDAC(); MerchantAccount merchantAccount = new MerchantAccountDAC().GetById(merchantId); if (merchantAccount == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ACCOUNT_NOT_EXISTS, "账号不存在"); } if (!PasswordHasher.VerifyHashedPassword(merchantAccount.PIN, pin)) { throw new CommonException(ReasonCode.PIN_ERROR, "PIN码错误"); //Wrong PIN enterred } Order order = orderDac.GetByOrderNo(orderNo); if (order == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDERNO_NOT_EXISTS, "找不到该订单"); //The order not exist } if (merchantAccount.Id != order.MerchantAccountId) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDERNO_NOTBE_ACCOUNT, "不是该用户的订单"); } if (order.Status != OrderStatus.Completed) { throw new CommonException(ReasonCode.FiiiPosReasonCode.ORDER_COMPLETED, "订单已完成,不能退款"); //Wrong order status. } if (DateTime.UtcNow.AddDays(-3) > order.PaymentTime.Value) { throw new CommonException(ReasonCode.FiiiPosReasonCode.EMAIL_CODE_EXPIRE, "订单支付已超过3天,不能退款");//订单超过3天 } var merchantWalletDAC = new MerchantWalletDAC(); var userWalletDAC = new UserWalletDAC(); var merchantWallet = merchantWalletDAC.GetByAccountId(order.MerchantAccountId, order.CryptoId); if (merchantWallet == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_MERCHANT_WALLET_NOT_EXISTS, "找不到该商家的钱包"); //Merchant account not support this cryptocurrency } if (merchantWallet.Balance < order.ActualCryptoAmount) { throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_BALANCE_LOW, "余额不足,无法退款"); //Balance not enough } var userWallet = userWalletDAC.GetByAccountId(order.UserAccountId.Value, order.CryptoId); if (userWallet == null) { throw new CommonException(ReasonCode.FiiiPosReasonCode.REFUND_USER_WALLET_NOT_EXISTS, "找不到订单用户的钱包"); //User account not support this cryptocurrency } int result = -9; using (var scope = new TransactionScope()) { merchantWalletDAC.Decrease(merchantAccount.Id, order.CryptoId, order.ActualCryptoAmount); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { WalletId = merchantWallet.Id, Action = "REFUND", Amount = -order.ActualCryptoAmount, Balance = merchantWallet.Balance - order.ActualCryptoAmount, Timestamp = DateTime.UtcNow, Remark = $"Refund to order({order.OrderNo})" }); userWalletDAC.Increase(order.UserAccountId.Value, order.CryptoId, order.CryptoAmount); new UserWalletStatementDAC().Insert(new UserWalletStatement { WalletId = userWallet.Id, Action = "REFUND", Amount = order.CryptoAmount, Balance = userWallet.Balance + order.CryptoAmount, Timestamp = DateTime.UtcNow, Remark = $"Refund from order({order.OrderNo})" }); order.Status = OrderStatus.Refunded; orderDac.UpdateStatus(order); new RefundDAC().Insert(new Refund { OrderId = order.Id, Status = RefundStatus.Completed, Timestamp = DateTime.UtcNow }); result = 1; scope.Complete(); } if (result > 0) //发送退款通知 { RabbitMQSender.SendMessage("RefundOrder", order.OrderNo); } return(result); }
public TransferResult FiiiPayTransferToEx(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 walletDac = new UserWalletDAC(); var wallet = walletDac.GetByAccountId(account.Id, 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失败); } UserExTransferOrder order; using (var scope = new TransactionScope()) { walletDac.Decrease(wallet.Id, amount); order = new UserExTransferOrder { Timestamp = DateTime.UtcNow, OrderNo = CreateOrderNo(), OrderType = ExTransferType.ToEx, 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.PubUserTransferToEx(order.Id, 0); } catch (Exception ex) { LogHelper.Info("PubUserTransferToEx - 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 void DistributeRewards(FiiiPayRewardMessage message, DateTime dt) { if (fiiicoinId == 0) { var fiiicoin = new CryptocurrencyDAC().GetByCode("FIII"); fiiicoinId = fiiicoin.Id; } MerchantAccountDAC maDAC = new MerchantAccountDAC(); var merchant = maDAC.GetByUsername(message.Account); if (merchant == null) { throw new CommonException(10000, $"无效的商家名:{message.Account}"); } InviteRecord invitor = GetInvitor(merchant.Id); if (invitor == null) { throw new CommonException(10000, "没有邀请人"); } var invitedList = new InviteRecordDAC().GetFiiiPosRecordsByInvitorId(invitor.InviterAccountId, InviteType.Fiiipos); var rewardRate = GetRewardPercentage(invitedList == null ? 0 : invitedList.Count); if (rewardRate == 0) { throw new CommonException(10000, "没有达到奖励条件"); } decimal t = (decimal)Math.Pow(10, -8); long nTotalReward = (long)Math.Floor(message.ActualReward * rewardRate); if (nTotalReward == 0) { throw new CommonException(10000, "奖励金额为0"); } decimal rewardAmount = nTotalReward * t; var distributeRecord = new RewardDistributeRecords { UserAccountId = invitor.InviterAccountId, MerchantAccountId = merchant.Id, SN = message.SN, OriginalReward = message.ActualReward, Percentage = rewardRate, ActualReward = rewardAmount, Timestamp = dt }; long profitId = 0; decimal oldBalance = 0; var invitorWallet = uwDAC.GetByAccountId(invitor.InviterAccountId, fiiicoinId); using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { if (invitorWallet == null) { invitorWallet = CreateWallet(invitor.InviterAccountId, fiiicoinId, rewardAmount); } else { oldBalance = invitorWallet.Balance; uwDAC.Increase(invitorWallet.Id, rewardAmount); } profitId = pfDAC.Insert(new ProfitDetail() { InvitationId = invitor.Id, CryptoAmount = rewardAmount, AccountId = invitor.InviterAccountId, Status = InviteStatusType.IssuedActive, Type = ProfitType.InvitePiiiPos, OrderNo = CreateOrderno(), Timestamp = dt, CryptoId = invitorWallet.CryptoId }); uwsDAC.Insert(new UserWalletStatement { WalletId = invitorWallet.Id, Action = UserWalletStatementAction.Reward, Amount = rewardAmount, Balance = oldBalance + rewardAmount, FrozenAmount = 0, FrozenBalance = invitorWallet.FrozenBalance, Timestamp = dt, Remark = "System" }); distributeRecord.ProfitId = profitId; rdrDAC.Insert(distributeRecord); new TempDataDAC().MessageComplated(message.Id); scope.Complete(); } }