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 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="user"></param> /// <param name="im"></param> /// <returns></returns> public PayOrderOM Pay(UserAccount user, PayIM im) { if (im.Amount <= 0) { throw new CommonException(ReasonCode.GENERAL_ERROR, MessageResources.AmountGreater); } new SecurityComponent().VerifyPin(user, im.Pin); var isAllowExpense = user.IsAllowExpense ?? true; if (!isAllowExpense) { throw new CommonException(ReasonCode.Not_Allow_Expense, MessageResources.PaymentForbidden); } var coin = new CryptocurrencyDAC().GetById(im.CoinId); if (!coin.Status.HasFlag(CryptoStatus.Pay) || coin.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } var merchantAccount = GetMerchantAccountByIdOrCode(im.MerchantId, im.MerchantCode); if (merchantAccount == null) { throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode); } if (!merchantAccount.IsAllowAcceptPayment || merchantAccount.Status == AccountStatus.Locked) { throw new CommonException(ReasonCode.Not_Allow_AcceptPayment, MessageResources.MerchantExceptionTransClose); } var country = new CountryComponent().GetById(merchantAccount.CountryId); var orderData = new Order { Id = Guid.NewGuid(), OrderNo = IdentityHelper.OrderNo(), MerchantAccountId = merchantAccount.Id, CryptoId = coin.Id, CryptoCode = coin.Code, FiatAmount = im.Amount, PaymentType = im.PaymentType, FiatCurrency = merchantAccount.FiatCurrency, Status = OrderStatus.Completed, ExpiredTime = DateTime.UtcNow.AddMinutes(30), Markup = merchantAccount.Markup, ExchangeRate = GetExchangeRate(merchantAccount.CountryId, merchantAccount.FiatCurrency, coin), UnifiedExchangeRate = GetExchangeRate(merchantAccount.CountryId, country.FiatCurrency ?? "USD", coin), UnifiedFiatCurrency = country.FiatCurrency ?? "USD", MerchantIP = null, PaymentTime = DateTime.UtcNow, UserAccountId = user.Id, Timestamp = DateTime.UtcNow }; var order = Generate(merchantAccount, coin, country.FiatCurrency ?? "USD", im.Amount, im.PaymentType); order.UserAccountId = user.Id; var userWallet = new UserWalletDAC().GetByAccountId(user.Id, im.CoinId); if (userWallet.Balance < order.CryptoAmount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } order.Status = OrderStatus.Completed; order.PaymentTime = DateTime.UtcNow; var merchantWallet = new MerchantWalletDAC().GetByAccountId(order.MerchantAccountId, order.CryptoId); if (merchantWallet == null || !merchantWallet.SupportReceipt) { throw new ApplicationException(MessageResources.MerchantNotSupperCrypto); } if (merchantAccount.WithdrawalFeeType != WithdrawalFeeType.FiiiCoin) { var calcModel = CalculateAmount(im.Amount, merchantAccount.Markup, merchantAccount.Receivables_Tier, orderData.ExchangeRate, coin); orderData.ActualFiatAmount = calcModel.FiatTotalAmount; orderData.CryptoAmount = calcModel.CryptoAmount; orderData.TransactionFee = calcModel.TransactionFee; orderData.ActualCryptoAmount = calcModel.ActualCryptoAmount; var model = CalculateUnifiedAmount(orderData.CryptoAmount, orderData.ActualCryptoAmount, orderData.UnifiedExchangeRate); orderData.UnifiedFiatAmount = model.UnifiedFiatAmount; orderData.UnifiedActualFiatAmount = model.UnifiedActualFiatAmount; var orderWithdrawalFee = new OrderWithdrawalFee { Timestamp = DateTime.UtcNow, CryptoId = orderData.CryptoId, Amount = 0 }; Execute(orderWithdrawalFee); } else { var orderWithdrawalFee = CalculateOrderAmount(ref orderData, new RedisOrderDTO() { CountryId = merchantAccount.CountryId, FiatAmount = im.Amount }, merchantAccount, coin); var wallet = new MerchantWalletDAC().GetByAccountId(merchantAccount.Id, new CryptocurrencyDAC().GetByCode("FIII").Id); if (orderWithdrawalFee.Amount != 0) { using (var scope = new TransactionScope()) { var dbOrder = new OrderDAC().Create(orderData); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = userWallet.UserAccountId, CryptoId = userWallet.CryptoId, CryptoCode = userWallet.CryptoCode, Type = UserTransactionType.Order, DetailId = dbOrder.Id.ToString(), Status = (byte)dbOrder.Status, Timestamp = dbOrder.Timestamp, Amount = dbOrder.CryptoAmount, OrderNo = dbOrder.OrderNo, MerchantName = merchantAccount.MerchantName }); orderWithdrawalFee.OrderId = dbOrder.Id; var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee); new MerchantWalletDAC().Decrease(wallet.Id, orderWithdrawalFee.Amount); new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount); new UserWalletDAC().Decrease(userWallet.Id, orderData.ActualCryptoAmount); new UserWalletStatementDAC().Insert(new UserWalletStatement { Action = UserWalletStatementAction.Consume, Amount = orderData.CryptoAmount, Balance = userWallet.Balance - orderData.CryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = userWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Receipt, Amount = orderData.ActualCryptoAmount, Balance = merchantWallet.Balance + orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = merchantWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Withdrawal, Amount = orderWithdrawalFee.Amount, Balance = merchantWallet.Balance - orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = wallet.Id }); scope.Complete(); } } else { Execute(orderWithdrawalFee); } } void Execute(OrderWithdrawalFee orderWithdrawalFee) { using (var scope = new TransactionScope()) { var dbOrder = new OrderDAC().Create(orderData); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = userWallet.UserAccountId, CryptoId = userWallet.CryptoId, CryptoCode = userWallet.CryptoCode, Type = UserTransactionType.Order, DetailId = dbOrder.Id.ToString(), Status = (byte)dbOrder.Status, Timestamp = dbOrder.Timestamp, Amount = dbOrder.CryptoAmount, OrderNo = dbOrder.OrderNo, MerchantName = merchantAccount.MerchantName }); orderWithdrawalFee.OrderId = dbOrder.Id; var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee); new UserWalletDAC().Decrease(userWallet.Id, orderData.CryptoAmount); new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount); new UserWalletStatementDAC().Insert(new UserWalletStatement { Action = UserWalletStatementAction.Consume, Amount = orderData.CryptoAmount, Balance = userWallet.Balance - orderData.CryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = userWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Receipt, Amount = orderData.ActualCryptoAmount, Balance = merchantWallet.Balance + orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = merchantWallet.Id }); scope.Complete(); } } UserMSMQ.PubOrderPayed(orderData.Id, 0); //PushConsume(order.Id); UserMSMQ.PubConsumeOrder(orderData.Id); return(new PayOrderOM { Amount = orderData.CryptoAmount.ToString(coin.DecimalPlace), Currency = new CryptocurrencyDAC().GetById(order.CryptoId).Code, OrderId = orderData.Id.ToString(), OrderNo = orderData.OrderNo, Timestamp = orderData.PaymentTime?.ToUnixTime().ToString() }); }
public OrderDetailDTO GetByOrderNo(Guid merchantAccountId, string orderNo) { var order = new OrderDAC().GetByOrderNo(orderNo); var merchantAccount = new MerchantAccountDAC().GetById(merchantAccountId); var pos = new POSDAC().GetById(merchantAccount.POSId.Value); if (order == null) { throw new CommonException(10000, Resources.订单不存在); } if (order.MerchantAccountId != merchantAccountId) { throw new CommonException(10000, Resources.只能查看自己的订单); } var coin = new CryptocurrencyDAC().GetById(order.CryptoId); var er = order.ExchangeRate; var cer = GetExchangeRate(merchantAccount.CountryId, order.FiatCurrency, coin); var iRate = ((cer - er) / er) * 100; // 手续费 var fee = new OrderWithdrawalFeeDAC().GetByOrderId(order.Id); var feeCoin = new Cryptocurrency(); if (fee != null) { feeCoin = new CryptocurrencyDAC().GetById(fee.CryptoId); } var result = new OrderDetailDTO { Id = order.Id, OrderNo = order.OrderNo, OrderStatus = order.Status, Timestamp = order.Timestamp.ToUnixTime(), CryptoStatus = coin.Status, CryptoCode = coin.Code, CryptoAmount = order.CryptoAmount.ToString(coin.DecimalPlace), FiatCurrency = order.FiatCurrency, FiatAmount = order.FiatAmount.ToString(2), Markup = order.Markup, ActualFiatAmount = order.ActualFiatAmount.ToString(2), TransactionFee = (fee == null || fee.Amount == 0) ? order.TransactionFee.ToString(coin.DecimalPlace) : fee.Amount.ToString(feeCoin.DecimalPlace), ActualCryptoAmount = order.ActualCryptoAmount.ToString(coin.DecimalPlace), UserAccount = order.UserAccountId.HasValue ? GetUserMastMaskedCellphone(order.UserAccountId.Value) : string.Empty, SN = pos.Sn, ExchangeRate = er.ToString(4), CurrentExchangeRate = coin.Enable == 1 ? $"1 {coin.Code} = {cer.ToString(4)} {order.FiatCurrency}" : "--", IncreaseRate = coin.Enable == 1 ? (iRate > 0 ? $"+{iRate.ToString(2)}%" : iRate.ToString(2) + "%") : "--", FeeCryptoCode = (fee == null || fee.Amount == 0) ? coin.Code : feeCoin.Code, CryptoEnable = coin.Enable }; if (result.OrderStatus == OrderStatus.Refunded) { var refund = new RefundDAC().GetByOrderId(result.Id); if (refund?.Timestamp != null) { result.RefundTimestamp = refund.Timestamp.ToUnixTime(); } } return(result); }
//private static readonly bool IsPushProduction = Convert.ToBoolean(ConfigurationManager.AppSettings.Get("PushProduction")); public PayOrderOM PayExistedOrder(UserAccount user, string orderNo, string pin) { new SecurityComponent().VerifyPin(user, pin); var isAllowExpense = user.IsAllowExpense ?? true; if (!isAllowExpense) { throw new CommonException(ReasonCode.Not_Allow_Expense, MessageResources.PaymentForbidden); } var order = RedisHelper.Get <RedisOrderDTO>($"fiiipos:order:{orderNo}"); RedisHelper.KeyDelete($"fiiipos:order:{orderNo}"); if (order == null) { throw new ApplicationException(MessageResources.OrderNotFound); } //if (new OrderDAC().GetByOrderNo(orderNo) != null) //{ // throw new ApplicationException(Resources.订单已完成或者已退款); //} if (order.UserId != Guid.Empty) { if (order.UserId != user.Id) { throw new ApplicationException(MessageResources.AccountNotMatch); } } var coin = new CryptocurrencyDAC().GetById(order.CryptoId); if (!coin.Status.HasFlag(CryptoStatus.Pay) || coin.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } var userWallet = new UserWalletDAC().GetByAccountId(user.Id, order.CryptoId); if (userWallet == null) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var exchangeRate = GetExchangeRate(order.CountryId, order.FiatCurrency, coin); decimal fiatTotalAmount = (order.FiatAmount * (1 + order.Markup)).ToSpecificDecimal(4); decimal cryptoAmount = (fiatTotalAmount / exchangeRate).ToSpecificDecimal(coin.DecimalPlace); if (userWallet.Balance < cryptoAmount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var merchantAccount = new MerchantAccountDAC().GetById(order.MerchantGuid); if (!merchantAccount.IsAllowAcceptPayment || merchantAccount.Status == AccountStatus.Locked) { throw new CommonException(ReasonCode.Not_Allow_Withdrawal, MessageResources.MerchantExceptionTransClose); } var merchantWallet = new MerchantWalletDAC().GetByAccountId(order.MerchantGuid, order.CryptoId); if (merchantWallet == null || !merchantWallet.SupportReceipt) { throw new ApplicationException(MessageResources.MerchantNotSupperCrypto); } var country = new CountryComponent().GetById(merchantAccount.CountryId); var orderData = new Order { Id = Guid.NewGuid(), OrderNo = order.OrderNo, MerchantAccountId = merchantAccount.Id, CryptoId = coin.Id, CryptoCode = coin.Code, FiatAmount = order.FiatAmount, PaymentType = order.Type, FiatCurrency = order.FiatCurrency, Status = OrderStatus.Completed, ExpiredTime = DateTime.UtcNow.AddMinutes(30), Markup = merchantAccount.Markup, ExchangeRate = GetExchangeRate(merchantAccount.CountryId, order.FiatCurrency, coin), UnifiedExchangeRate = GetExchangeRate(merchantAccount.CountryId, country.FiatCurrency ?? "USD", coin), UnifiedFiatCurrency = country.FiatCurrency ?? "USD", MerchantIP = order.ClientIP, PaymentTime = DateTime.UtcNow, Timestamp = DateTime.UtcNow, UserAccountId = user.Id }; if (merchantAccount.WithdrawalFeeType != WithdrawalFeeType.FiiiCoin) { var calcModel = CalculateAmount(order.FiatAmount, merchantAccount.Markup, merchantAccount.Receivables_Tier, orderData.ExchangeRate, coin); orderData.ActualFiatAmount = calcModel.FiatTotalAmount; orderData.CryptoAmount = calcModel.CryptoAmount; orderData.TransactionFee = calcModel.TransactionFee; orderData.ActualCryptoAmount = calcModel.ActualCryptoAmount; var model = CalculateUnifiedAmount(orderData.CryptoAmount, orderData.ActualCryptoAmount, orderData.UnifiedExchangeRate); orderData.UnifiedFiatAmount = model.UnifiedFiatAmount; orderData.UnifiedActualFiatAmount = model.UnifiedActualFiatAmount; var orderWithdrawalFee = new OrderWithdrawalFee() { Timestamp = DateTime.UtcNow }; orderWithdrawalFee.CryptoId = orderData.CryptoId; orderWithdrawalFee.Amount = 0; Execute(orderWithdrawalFee); } else { var orderWithdrawalFee = CalculateOrderAmount(ref orderData, order, merchantAccount, coin); var wallet = new MerchantWalletDAC().GetByAccountId(merchantAccount.Id, new CryptocurrencyDAC().GetByCode("FIII").Id); if (orderWithdrawalFee.Amount != 0) { using (var scope = new TransactionScope()) { var dbOrder = new OrderDAC().Create(orderData); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = userWallet.UserAccountId, CryptoId = userWallet.CryptoId, CryptoCode = userWallet.CryptoCode, Type = UserTransactionType.Order, DetailId = dbOrder.Id.ToString(), Status = (byte)dbOrder.Status, Timestamp = dbOrder.Timestamp, Amount = dbOrder.CryptoAmount, OrderNo = dbOrder.OrderNo, MerchantName = merchantAccount.MerchantName }); orderWithdrawalFee.OrderId = dbOrder.Id; var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee); new MerchantWalletDAC().Decrease(wallet.Id, orderWithdrawalFee.Amount); new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount); new UserWalletDAC().Decrease(userWallet.Id, cryptoAmount); new UserWalletStatementDAC().Insert(new UserWalletStatement { Action = UserWalletStatementAction.Consume, Amount = orderData.CryptoAmount, Balance = userWallet.Balance - orderData.CryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = userWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Receipt, Amount = orderData.ActualCryptoAmount, Balance = merchantWallet.Balance + orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = merchantWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Withdrawal, Amount = orderWithdrawalFee.Amount, Balance = merchantWallet.Balance - orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = wallet.Id }); scope.Complete(); } } else { Execute(orderWithdrawalFee); } } void Execute(OrderWithdrawalFee orderWithdrawalFee) { using (var scope = new TransactionScope()) { var dbOrder = new OrderDAC().Create(orderData); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = userWallet.UserAccountId, CryptoId = userWallet.CryptoId, CryptoCode = userWallet.CryptoCode, Type = UserTransactionType.Order, DetailId = dbOrder.Id.ToString(), Status = (byte)dbOrder.Status, Timestamp = dbOrder.Timestamp, Amount = dbOrder.CryptoAmount, OrderNo = dbOrder.OrderNo, MerchantName = merchantAccount.MerchantName }); orderWithdrawalFee.OrderId = dbOrder.Id; var id = new OrderWithdrawalFeeDAC().Insert(orderWithdrawalFee); new UserWalletDAC().Decrease(userWallet.Id, cryptoAmount); new MerchantWalletDAC().Increase(merchantWallet.Id, orderData.ActualCryptoAmount); new UserWalletStatementDAC().Insert(new UserWalletStatement { Action = UserWalletStatementAction.Consume, Amount = orderData.CryptoAmount, Balance = userWallet.Balance - orderData.CryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Remark = null, Timestamp = DateTime.UtcNow, WalletId = userWallet.Id }); new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement { Action = MerchantWalletStatementAction.Receipt, Amount = orderData.ActualCryptoAmount, Balance = merchantWallet.Balance + orderData.ActualCryptoAmount, Remark = null, Timestamp = DateTime.UtcNow, WalletId = merchantWallet.Id }); scope.Complete(); } } UserMSMQ.PubOrderPayed(orderData.Id, 0); //PushConsume(orderData.Id); UserMSMQ.PubConsumeOrder(orderData.Id); return(new PayOrderOM { Amount = orderData.CryptoAmount.ToString(coin.DecimalPlace), Currency = new CryptocurrencyDAC().GetById(order.CryptoId).Code, OrderId = orderData.Id.ToString(), OrderNo = orderData.OrderNo, Timestamp = orderData.PaymentTime?.ToUnixTime().ToString() }); }