/// <summary> /// 网关支付 /// </summary> /// <param name="tuple"> /// Guid为fiiipay用户的id,long为POSMerchantBindRecords的主键 /// </param> public void ShopPaymentRefund(Guid id) { var record = new GatewayRefundOrderDAC().GetById(id); var order = new GatewayOrderDAC().GetByOrderId(record.OrderId); var cryptoCurrency = new CryptocurrencyDAC().GetById(order.CryptoId); var regId = RedisHelper.StringGet($"FiiiPay:Notice:UserId:{order.UserAccountId}"); var lang = RedisHelper.StringGet(REDIS_LANGUAGE_DBINDEX, $"FiiiPay:Language:{order.UserAccountId}") ?? "en"; string titleKey = "GatewayOrderPaymentRefundTitle"; string subTitleKey = "GatewayOrderPaymentRefundSubTitle"; if (!(_resourcePropertyNames.Contains(titleKey) && _resourcePropertyNames.Contains(subTitleKey))) { throw new Exception("没有找到资源"); } var title = ResourceHelper.FiiiPay.GetFormatResource(titleKey, new CultureInfo(lang), cryptoCurrency.Code); var subTitle = ResourceHelper.FiiiPay.GetResource(subTitleKey, new CultureInfo(lang)); string noticeId = ""; MessagesComponent.AddMessage(order.UserAccountId.Value, UserType.User, record.Id.ToString(), FiiiPayPushType.TYPE_GATEWAY_ORDER_PAYMENT_REFUND, titleKey, subTitleKey, cryptoCurrency.Code, title, subTitle, out noticeId); RegPush(FiiiPayPushType.TYPE_GATEWAY_ORDER_PAYMENT_REFUND, new List <string> { regId }, record.Id, title, subTitle, noticeId); LogHelper.Info($"--------{lang}------{title}----------{subTitle}"); }
/// <summary> /// 支付网关退款成功 /// </summary> /// <param name="id"></param> public MessageGatewayPaymentOM MessagePaymentRefund(UserAccount account, Guid id) { var refundOrder = new GatewayRefundOrderDAC().GetById(id); var order = new GatewayOrderDAC().GetByOrderId(refundOrder.OrderId); var cryptoCurrency = new CryptocurrencyDAC().GetById(order.CryptoId); var currentExchangeRate = GetExchangeRate(account.CountryId, order.FiatCurrency, cryptoCurrency); return(new MessageGatewayPaymentOM() { TradeStatus = 1, CryptoCode = cryptoCurrency.Code, CurrentExchangeRate = currentExchangeRate, FiatCode = order.FiatCurrency, IncreaseRate = (currentExchangeRate - order.ExchangeRate) / order.ExchangeRate, Markup = order.Markup, MerchantName = order.MerchantName, MerchantOrderNo = order.OrderNo, OrderNo = order.TradeNo, PaymentCryptoAmount = order.ActualCryptoAmount, PaymentFiatAmount = order.ActualFiatAmount ?? 0m, TradeExchangeRate = order.ExchangeRate, TradeTime = order.Timestamp.ToUnixTime().ToString(), RefundTime = refundOrder.Timestamp.ToUnixTime().ToString() }); }
public GatewayOrderDetailOM Detail(Guid orderId, UserAccount user, bool isZH) { var order = new GatewayOrderDAC().GetByOrderId(orderId); if ((order == null || !order.UserAccountId.HasValue || order.UserAccountId != user.Id)) { throw new ApplicationException(MessageResources.OrderNotFound); } var coin = new CryptocurrencyDAC().GetById(order.CryptoId); var er = order.ExchangeRate; var cer = GetExchangeRate(user.CountryId, order.FiatCurrency, coin); var iRate = ((cer - er) / er) * 100; var om = new GatewayOrderDetailOM { Code = coin.Code, CryptoAmount = order.ActualCryptoAmount.ToString(coin.DecimalPlace), FiatAmount = order.ActualFiatAmount?.ToString(2) ?? string.Empty, ExchangeRate = $"1 {coin.Code} = {order.ExchangeRate.ToString(4)} {order.FiatCurrency}", FiatCurrency = order.FiatCurrency, MarkUp = $"{(order.Markup * 100).ToString(2)}%", MerchantName = order.MerchantName, Id = order.Id, Status = new UserStatementComponent().GetStatusStr((int)BillType.GatewayOrder, (int)order.Status, isZH), Timestamp = order.Timestamp.ToUnixTime().ToString(), Type = Resources.BillTypeNetOrder, OrderNo = order.OrderNo, TradeNo = order.TradeNo, RefundTimestamp = order.Status == GatewayOrderStatus.Refunded ? new GatewayRefundOrderDAC().GetByOrderId(order.Id)?.Timestamp.ToUnixTime().ToString() : "", CurrentExchangeRate = $"1 {coin.Code} = {cer.ToString(4)} {order.FiatCurrency}", IncreaseRate = iRate > 0 ? $"+{iRate.ToString(2)}" : iRate.ToString(2) }; return(om); }
/// <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(); } }
private GatewayOrder ExcutePay(GatewayOrderOM orderDetail, Guid id) { var cryptoCurrency = new CryptocurrencyDAC().GetByCode(orderDetail.Crypto); if (cryptoCurrency == null || cryptoCurrency?.Id == null) { throw new CommonException(CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency"); } //var uwComponent = new UserWalletComponent(); var userWallet = new UserWalletDAC().GetUserWallet(orderDetail.UserAccountId.Value, cryptoCurrency.Id); if (userWallet.Balance < orderDetail.ActualCryptoAmount) { throw new CommonException(INSUFFICIENT_BALANCE, Resources.余额不足); } var uwDAC = new UserWalletDAC(); var uwsDAC = new UserWalletStatementDAC(); var goDAC = new GatewayOrderDAC(); bool needAddOrder = true; var gatewayOrder = goDAC.GetByTradeNo(orderDetail.Id.ToString()); if (gatewayOrder != null) { if (gatewayOrder.Status != GatewayOrderStatus.Pending) { throw new CommonException(ORDER_HAD_COMPLETE, Resources.订单已完成或者已退款); } needAddOrder = false; } else { gatewayOrder = new Entities.GatewayOrder() { OrderNo = CreateOrderno(), TradeNo = orderDetail.Id.ToString(), Id = id, CryptoId = cryptoCurrency.Id, MerchantAccountId = orderDetail.MerchantAccountId, FiatAmount = orderDetail.FiatAmount, MerchantName = orderDetail.MerchantName, UserAccountId = orderDetail.UserAccountId, CryptoAmount = orderDetail.CryptoAmount, ActualCryptoAmount = orderDetail.ActualCryptoAmount, FiatCurrency = orderDetail.FiatCurrency, Markup = orderDetail.MarkupRate, ActualFiatAmount = orderDetail.ActualFiatAmount, Status = GatewayOrderStatus.Completed, ExchangeRate = orderDetail.ExchangeRate, ExpiredTime = orderDetail.ExpiredTime, TransactionFee = orderDetail.TransactionFee, Timestamp = DateTime.UtcNow, PaymentTime = DateTime.UtcNow, Remark = orderDetail.Remark }; } using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { if (needAddOrder) { goDAC.Insert(gatewayOrder); } uwDAC.Decrease(userWallet.Id, orderDetail.ActualCryptoAmount); uwsDAC.Insert(new UserWalletStatement { WalletId = userWallet.Id, Action = UserWalletStatementAction.TansferOut, Amount = -orderDetail.ActualCryptoAmount, Balance = userWallet.Balance - orderDetail.ActualCryptoAmount, FrozenAmount = 0, FrozenBalance = userWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); scope.Complete(); } return(gatewayOrder); }
//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 GatewayOrderInfoOM PrePay(string code, UserAccount account) { var codeEntity = QRCode.Deserialize(code); if (codeEntity.SystemPlatform != SystemPlatform.Gateway || codeEntity.QrCodeEnum != QRCodeEnum.GateWayPay) { throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode); } var orderDetail = GetGatewayOrderDetail(codeEntity.QRCodeKey); if (orderDetail == null) { throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode); } var cryptoCurrency = new CryptocurrencyDAC().GetByCode(orderDetail.Crypto); if (cryptoCurrency == null || cryptoCurrency?.Id == null) { throw new CommonException(ReasonCode.CRYPTO_NOT_EXISTS, "Error: Invalid Cryptocurrency"); } var goDAC = new GatewayOrderDAC(); var gatewayOrder = goDAC.GetByTradeNo(orderDetail.Id.ToString()); if (gatewayOrder != null) { if (gatewayOrder.Status != GatewayOrderStatus.Pending) { throw new CommonException(ReasonCode.ORDER_HAD_COMPLETE, MessageResources.OrderComplated); } } else { gatewayOrder = new GatewayOrder() { OrderNo = IdentityHelper.OrderNo(), TradeNo = orderDetail.Id.ToString(), Id = Guid.NewGuid(), CryptoId = cryptoCurrency.Id, MerchantAccountId = orderDetail.MerchantAccountId, FiatAmount = orderDetail.FiatAmount, MerchantName = orderDetail.MerchantName, UserAccountId = account.Id, CryptoAmount = orderDetail.CryptoAmount, ActualCryptoAmount = orderDetail.ActualCryptoAmount, FiatCurrency = orderDetail.FiatCurrency, Markup = orderDetail.MarkupRate, ActualFiatAmount = orderDetail.ActualFiatAmount, Status = GatewayOrderStatus.Pending, ExchangeRate = orderDetail.ExchangeRate, ExpiredTime = orderDetail.ExpiredTime, TransactionFee = orderDetail.TransactionFee, Timestamp = DateTime.UtcNow, Remark = orderDetail.Remark }; goDAC.Insert(gatewayOrder); } return(new GatewayOrderInfoOM() { Timestamp = DateTime.UtcNow.ToUnixTime().ToString(), OrderId = gatewayOrder.Id, MerchantName = gatewayOrder.MerchantName, CryptoCode = cryptoCurrency.Code, ActurlCryptoAmount = gatewayOrder.ActualCryptoAmount }); }
/// <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 OrderDetailOM Detail(UserAccount user, Guid id, bool isZH) { var order = new OrderDAC().GetOrderByOrderId(id); var gatewayOrder = new GatewayOrderDAC().GetByOrderId(id); if ((order == null || order.UserAccountId != user.Id) && (gatewayOrder == null || gatewayOrder.UserAccountId != user.Id)) { throw new ApplicationException(MessageResources.OrderNotFound); } //if (order == null) //{ // var coin = new CryptocurrencyDAC().GetById(gatewayOrder.CryptoId); // var er = order.ExchangeRate; // var cer = GetExchangeRate(user.CountryId, order.FiatCurrency, coin); // var iRate = ((cer - er) / er) * 100; // om = new Detail1OM // { // Code = coin.Code, // CryptoAmount = gatewayOrder.ActualCryptoAmount.ToString(coin.DecimalPlace), // FiatAmount = gatewayOrder.ActualFiatAmount?.ToString(2) ?? string.Empty, // ExchangeRate = $"1 {coin.Code} = {gatewayOrder.ExchangeRate.ToString(2)} {gatewayOrder.FiatCurrency}", // FiatCurrency = gatewayOrder.FiatCurrency, // MarkUp = $"{(gatewayOrder.Markup * 100).ToString(2)}%", // MerchantName = gatewayOrder.MerchantName, // Id = gatewayOrder.Id, // Status = new UserStatementComponent().GetStatusStr(2, (int)gatewayOrder.Status, isZH), // Timestamp = gatewayOrder.Timestamp.ToUnixTime().ToString(), // Type = Resources.交易类型支付, // RefundTimestamp = gatewayOrder.Status == GatewayOrderStatus.Refunded ? new RefundGatewayOrderDAC().GetByOrderId(gatewayOrder.Id)?.Timestamp.ToUnixTime().ToString() : "", // OrderNo = gatewayOrder.OrderNo, // CurrentExchangeRate = $"1 {coin.Code} = {cer.ToString(2)} {gatewayOrder.FiatCurrency}", // IncreaseRate = iRate > 0 ? $"+{iRate.ToString(2)}" : iRate.ToString(2) // }; //} //else OrderDetailOM om; { var coin = new CryptocurrencyDAC().GetById(order.CryptoId); var er = order.ExchangeRate; var cer = GetExchangeRate(user.CountryId, order.FiatCurrency, coin); var iRate = ((cer - er) / er) * 100; om = new OrderDetailOM { Code = coin.Code, CryptoAmount = order.CryptoAmount.ToString(coin.DecimalPlace), FiatAmount = order.FiatAmount.ToString(2), ExchangeRate = $"1 {coin.Code} = {order.ExchangeRate.ToString(4)} {order.FiatCurrency}", FiatCurrency = order.FiatCurrency, MarkUp = $"{(order.Markup * 100).ToString(2)}%", MerchantName = new MerchantAccountDAC().GetById(order.MerchantAccountId).MerchantName, Id = order.Id, Status = new UserStatementComponent().GetStatusStr(2, (int)order.Status, isZH), Timestamp = order.PaymentTime.Value.ToUnixTime().ToString(), Type = Resources.Payment, RefundTimestamp = order.Status == OrderStatus.Refunded ? new RefundDAC().GetByOrderId(order.Id)?.Timestamp.ToUnixTime().ToString() : "", OrderNo = order.OrderNo, CurrentExchangeRate = coin.Enable == 1 ? $"1 {coin.Code} = {cer.ToString(4)} {order.FiatCurrency}" : "--", IncreaseRate = coin.Enable == 1 ? (iRate > 0 ? $"+{iRate.ToString(2)}" : iRate.ToString(2)) : "--" }; } return(om); }