Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
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);
        }