Пример #1
0
        public string FiiiPOSTransferInto(MerchantAccount account, Cryptocurrency coin, decimal amount)
        {
            var walletDac = new MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(account.Id, coin.Id);
            MerchantExTransferOrder order;

            using (var scope = new TransactionScope())
            {
                if (wallet == null)
                {
                    wallet = new MerchantWalletComponent().GenerateWallet(account.Id, coin.Id);
                }

                walletDac.Increase(wallet.Id, amount);

                order = new MerchantExTransferOrder
                {
                    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 MerchantExTransferOrderDAC().Create(order);

                scope.Complete();
            }

            try
            {
                FiiiEXTransferMSMQ.PubMerchantTransferFromEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("PubMerchantTransferFromEx - error", ex);
            }
            return(order.OrderNo);
        }
Пример #2
0
        public TransferFiiiExConditionDTO FiiiPOSTransferFiiiExCondition(Guid accountId, int cryptoId)
        {
            var crypto    = new CryptocurrencyDAC().GetById(cryptoId);
            var walletDac = new MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(accountId, crypto.Id);

            var fiiiExBalance = this.FiiiExBalance(FiiiType.FiiiPOS, accountId, crypto);

            var minQuantity =
                (1M / (decimal)Math.Pow(10, crypto.DecimalPlace)).ToString(crypto.DecimalPlace);

            return(new TransferFiiiExConditionDTO
            {
                Balance = (wallet?.Balance ?? 0M).ToString(crypto.DecimalPlace),
                MinQuantity = minQuantity,
                FiiiExBalance = fiiiExBalance.ToString(crypto.DecimalPlace),
                FiiiExMinQuantity = minQuantity
            });
        }
        public DepositAddressInfo GetDepositAddressById(Guid accountId, int cryptoId)
        {
            var crypto = new CryptocurrencyDAC().GetById(cryptoId);

            if (crypto == null)
            {
                throw new CommonException(ReasonCode.RECORD_NOT_EXIST, Resources.支持的币种);
            }

            if (!crypto.Status.HasFlag(CryptoStatus.Deposit))
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            if (crypto.Enable == (byte)CurrencyStatus.Forbidden)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            var dac    = new MerchantWalletDAC();
            var wallet = dac.GetByAccountId(accountId, cryptoId) ?? GenerateWallet(accountId, cryptoId, crypto.Code);

            if (string.IsNullOrEmpty(wallet.Address))
            {
                var accountDAC = new MerchantAccountDAC();
                var account    = accountDAC.GetById(accountId);

                var result = new FiiiFinanceAgent().CreateWallet(crypto.Code, account.Id, AccountTypeEnum.Merchant, account.Email, $"{account.PhoneCode}{account.Cellphone}");
                if (string.IsNullOrWhiteSpace(result.Address))
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.FailedGenerateAddress);
                }

                wallet.Address = result.Address;
                wallet.Tag     = result.DestinationTag;

                dac.UploadAddress(wallet.Id, wallet.Address, wallet.Tag);
            }

            return(new DepositAddressInfo {
                Address = wallet.Address, Tag = wallet.Tag, NeedTag = crypto.NeedTag
            });
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
0
        public TransferResult FiiiPOSTransferToEx(Guid accountId, int cryptoId, decimal amount, string pinToken)
        {
            var securityVerify = new SecurityVerification(SystemPlatform.FiiiPOS);

            securityVerify.VerifyToken(accountId, pinToken, SecurityMethod.Pin);

            var openAccountDac = new OpenAccountDAC();
            var openAccount    = openAccountDac.GetOpenAccount(FiiiType.FiiiPOS, accountId);

            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 MerchantWalletDAC();
            var wallet    = walletDac.GetByAccountId(accountId, 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划转失败);
            }
            MerchantExTransferOrder order;

            using (var scope = new TransactionScope())
            {
                walletDac.Decrease(wallet.Id, amount);
                order = new MerchantExTransferOrder
                {
                    Timestamp  = DateTime.UtcNow,
                    OrderNo    = CreateOrderNo(),
                    OrderType  = ExTransferType.ToEx,
                    AccountId  = accountId,
                    WalletId   = wallet.Id,
                    CryptoId   = crypto.Id,
                    CryptoCode = crypto.Code,
                    Amount     = amount,
                    Status     = 1,
                    Remark     = null,
                    ExId       = recordId
                };

                order = new MerchantExTransferOrderDAC().Create(order);
                scope.Complete();
            }

            try
            {
                FiiiEXTransferMSMQ.PubMerchantTransferToEx(order.Id, 0);
            }
            catch (Exception ex)
            {
                LogHelper.Info("FiiiPOSTransferToEx - 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 List <MerchantSupportReceiptWalletDTO> SupportReceiptList(Guid accountId)
        {
            var account = new MerchantAccountDAC().GetById(accountId);
            var dac     = new MerchantWalletDAC();

            var cryptoList = new CryptocurrencyDAC().GetAllActived();

            var fiiiCrypto = cryptoList.First(w => w.Code == FIIICOIN_CODE);
            var fiiiWallet = dac.GetByAccountId(account.Id, fiiiCrypto.Id) ?? GenerateWallet(accountId, fiiiCrypto.Id, fiiiCrypto.Code, FIIICOIN_SEQUENCE, true);

            if (!fiiiWallet.SupportReceipt || fiiiWallet.Sequence != FIIICOIN_SEQUENCE)
            {
                dac.Support(account.Id, fiiiWallet.CryptoId, FIIICOIN_SEQUENCE);
            }

            List <MerchantWallet> supportReceiptList;
            var pos = new POSDAC().GetById(account.POSId.Value);

            if (pos.IsWhiteLabel)
            {
                var whiteCrypto = cryptoList.First(w => w.Code == pos.FirstCrypto);
                var whiteWallet = dac.GetByAccountId(account.Id, whiteCrypto.Id);
                if (whiteWallet == null)
                {
                    GenerateWallet(accountId, whiteCrypto.Id, whiteCrypto.Code, WHITECOIN_SEQUENCE, true);
                }
                else if (!whiteWallet.SupportReceipt || whiteWallet.Sequence != WHITECOIN_SEQUENCE)
                {
                    dac.Support(account.Id, whiteWallet.CryptoId, WHITECOIN_SEQUENCE);
                }

                supportReceiptList = dac.SupportReceiptList(accountId).OrderBy(e => e.Sequence).ToList();
            }
            else
            {
                var whiteCryptoList = cryptoList.Where(e => e.IsWhiteLabel == 1).ToList();
                supportReceiptList = dac.SupportReceiptList(accountId).OrderBy(e => e.Sequence).ToList();
                supportReceiptList.RemoveAll(e => whiteCryptoList.Exists(a => a.Id == e.CryptoId));
            }

            var marketPriceList = new PriceInfoDAC().GetPrice(account.FiatCurrency);

            return(supportReceiptList.Select(e =>
            {
                var crypto = cryptoList.FirstOrDefault(w => w.Id == e.CryptoId);
                if (crypto == null)
                {
                    return null;
                }
                return new MerchantSupportReceiptWalletDTO
                {
                    WalletId = e.Id,
                    CryptoId = crypto.Id,
                    CryptoStatus = crypto.Status,
                    CryptoCode = crypto.Code,
                    CryptoName = crypto.Name,
                    IconURL = crypto.IconURL,
                    DecimalPlace = crypto.DecimalPlace,
                    Markup = account.Markup,
                    MarketPrice = marketPriceList.FirstOrDefault(m => crypto.Code == m.CryptoName)?.Price.ToString(4),
                    Balance = string.Equals("FIII", crypto.Code, StringComparison.CurrentCultureIgnoreCase) ? e.Balance : 0,
                    IsDefault = e.CryptoId == fiiiCrypto.Id || (pos.IsWhiteLabel && crypto.Code == pos.FirstCrypto) ? 1 : 0,
                    CryptoEnable = crypto.Enable
                };
            }).Where(w => w != null).ToList());
        }
        public void SettingCrytocurrencies(Guid accountId, List <int> cryptoIds)
        {
            var mwDac      = new MerchantWalletDAC();
            var mwList     = mwDac.GetByAccountId(accountId).ToList();
            var cryptoList = new CryptocurrencyDAC().GetByIds(cryptoIds.ToArray());

            // FIII 不参与排序
            var fiiiCrypto = cryptoList.FirstOrDefault(e => e.Code == FIIICOIN_CODE);

            if (fiiiCrypto != null)
            {
                cryptoIds.Remove(fiiiCrypto.Id);
                var fiiiWallet = mwList.FirstOrDefault(e => e.CryptoId == fiiiCrypto.Id);
                if (fiiiWallet != null)
                {
                    mwList.Remove(fiiiWallet);
                }
            }

            // 白标POS机的白标币不参与排序
            var account = new MerchantAccountDAC().GetById(accountId);
            var pos     = new POSDAC().GetById(account.POSId.Value);

            if (pos.IsWhiteLabel)
            {
                var whiteCrypto = cryptoList.FirstOrDefault(e => e.Code == pos.FirstCrypto);
                if (whiteCrypto != null)
                {
                    cryptoIds.Remove(whiteCrypto.Id);
                    var whiteWallet = mwList.FirstOrDefault(e => e.CryptoId == whiteCrypto.Id);
                    if (whiteWallet != null)
                    {
                        mwList.Remove(whiteWallet);
                    }
                }
            }


            for (int i = 0; i < cryptoIds.Count; i++)
            {
                int seq    = i + 1;
                var crypto = cryptoList.FirstOrDefault(e => e.Id == cryptoIds[i]);
                if (crypto == null)
                {
                    continue;
                }

                var wallet = mwList.FirstOrDefault(e => e.CryptoId == cryptoIds[i]);
                // 新增
                if (wallet == null)
                {
                    GenerateWallet(accountId, crypto.Id, crypto.Code, seq, true);
                    continue;
                }
                // 启用
                if (!wallet.SupportReceipt || wallet.Sequence != seq)
                {
                    mwDac.Support(accountId, crypto.Id, seq);
                }
                mwList.Remove(wallet);
            }

            mwList.RemoveAll(e => !e.SupportReceipt);
            // 禁用
            foreach (var wallet in mwList)
            {
                mwDac.Reject(accountId, wallet.CryptoId);
            }
        }
Пример #9
0
        public async Task <ScanMerchantQRCodeOM> ScanMerchantQRCode(UserAccount user, string code)
        {
            var codeEntity = QRCode.Deserialize(code);

            if (codeEntity.SystemPlatform != SystemPlatform.FiiiPOS || codeEntity.QrCodeEnum != QRCodeEnum.MerchantScanPay)
            {
                throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode);
            }
            Guid merchantId         = Guid.Parse(codeEntity.QRCodeKey);
            ScanMerchantQRCodeOM om = new ScanMerchantQRCodeOM();

            var merchantAccount = GetMerchantAccountByIdOrCode(merchantId, null);

            //if (merchantAccount.POSId == null)
            //{
            //    throw new CommonException(ReasonCode.INVALID_QRCODE, MessageResources.InvalidQRCode);
            //}

            if (merchantAccount.Status == AccountStatus.Locked || !merchantAccount.IsAllowAcceptPayment)
            {
                throw new CommonException(ReasonCode.MERCHANT_ACCOUNT_DISABLED, MessageResources.MerchantAccountDisabled);
            }

            Guid.TryParse(merchantAccount.Photo, out Guid merchantAvatar);

            var uwDAC = new UserWalletDAC();
            var mwDAC = new MerchantWalletDAC();

            var userWallets     = uwDAC.GetUserWallets(user.Id);
            var merchantWallets = mwDAC.GetByAccountId(merchantAccount.Id);
            var coins           = new CryptocurrencyDAC().GetAllActived();
            var priceList       = new PriceInfoDAC().GetPrice(merchantAccount.FiatCurrency);

            //判断Pos机是否白标用户
            bool showWhiteLable = false;

            if (merchantAccount.POSId.HasValue)
            {
                var pos = new POSDAC().GetById(merchantAccount.POSId.Value);
                if (pos.IsWhiteLabel)
                {
                    showWhiteLable = true;
                }
            }

            if (!showWhiteLable)
            {
                var whilteLabelCryptoCode = new POSDAC().GetWhiteLabelCryptoCode();
                coins.RemoveAll(t => t.Code == whilteLabelCryptoCode);
            }

            return(await Task.FromResult(new ScanMerchantQRCodeOM
            {
                MerchantId = merchantAccount.Id,
                MerchantName = merchantAccount.MerchantName,
                Avatar = merchantAvatar,
                L1VerifyStatus = (byte)merchantAccount.L1VerifyStatus,
                L2VerifyStatus = (byte)merchantAccount.L2VerifyStatus,
                FiatCurrency = merchantAccount.FiatCurrency,
                MarkupRate = merchantAccount.Markup.ToString(CultureInfo.InvariantCulture),
                WaletInfoList = coins.Select(a =>
                {
                    var userWallet = userWallets.FirstOrDefault(b => b.CryptoId == a.Id);
                    decimal rate = 0;
                    rate = priceList.Where(t => t.CryptoID == a.Id).Select(t => t.Price).FirstOrDefault();
                    return GetItem(userWallet, a, merchantWallets, rate);
                }).OrderByDescending(a => a.MerchantSupported).ThenBy(a => a.PayRank).Select(a => new WalletItem
                {
                    Code = a.Code,
                    NewStatus = a.NewStatus,
                    ExchangeRate = a.ExchangeRate,
                    FrozenBalance = a.FrozenBalance,
                    IconUrl = a.IconUrl,
                    Id = a.Id,
                    MerchantSupported = a.MerchantSupported,
                    Name = a.Name,
                    UseableBalance = a.UseableBalance,
                    FiatBalance = a.FiatBalance,
                    DecimalPlace = a.DecimalPlace,
                    CryptoEnable = a.CryptoEnable
                }).ToList()
            }));
        }
Пример #10
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);
        }