Example #1
0
        private void Transfer(withdrawalOrder wo)
        {
            DateTime createDateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));

            using (var ts = new TransactionScope())
            {
                try
                {
                    int agentAccountId = GetAgentAccountId(wo.accountIdFrom);

                    List <int> accountIds = new List <int> {
                        agentAccountId, wo.accountIdFrom
                    };

                    var accounts = conn.Query <account>("select * from [bitject].[dbo].[account] where id in @id", new { id = accountIds }).ToDictionary(x => x.id);

                    var agentAccount = accounts[agentAccountId];

                    var memberAccount = accounts[wo.accountIdFrom];

                    #region requestTypeId == "1" 從 agent 帳戶扣款

                    if (wo.requestTypeId == "1")
                    {
                        accountTransDetail atd = new accountTransDetail()
                        {
                            accountIdFrom    = agentAccountId,
                            accountIdTo      = wo.accountIdFrom,
                            transferCateId   = "2",
                            currencyCodeFrom = wo.currencyCodeFrom,
                            currencyCodeTo   = wo.currencyCodeFrom,
                            amountFrom       = wo.amountFrom,
                            amountTo         = wo.amountFrom,
                            exDiff           = 0,
                            fee                 = 0,
                            r8                  = 0,
                            r7                  = 0,
                            r1                  = 0,
                            createDateTime      = createDateTime,
                            exRateWithDiff      = 1M,
                            exRateWithoutDiff   = 1M,
                            exRateFrom          = 1M,
                            exSlopeFrom         = 0M,
                            exInterceptFrom     = 0M,
                            exRateTo            = 1M,
                            exSlopeTo           = 0M,
                            exInterceptTo       = 0M,
                            feeRatio            = 0M,
                            amountFromExchange  = null,
                            feeRatioInExchange  = null,
                            feeRatioOutExchange = null,
                            exRateInExchange    = null,
                            exRateOutExchange   = null,
                            memo                = null,
                            handlerId           = wo.handlerId,
                            handlerIp           = wo.handlerIp
                        };

                        int transDetailId = conn.Query <int>(transDetailInsert, atd).FirstOrDefault();

                        conn.Execute("update [bitject].[dbo].[account] set frozenBalance=@frozenBalance, balance=@balance where id=@id", new { frozenBalance = agentAccount.frozenBalance - wo.amountFrom, balance = agentAccount.balance - wo.amountFrom, id = agentAccountId });

                        conn.Execute("update [bitject].[dbo].[account] set balance=@balance where id=@id", new { balance = memberAccount.balance + wo.amountFrom, id = wo.accountIdFrom });

                        // 交易紀錄 agentAccount balance
                        var agentBalance = new accountTrans()
                        {
                            detailId            = transDetailId,
                            memberId            = agentAccount.memberId,
                            memberLevelId       = agentAccount.memberLevelId,
                            memberParentId      = agentAccount.memberParentId,
                            accountId           = agentAccount.id,
                            transferCateId      = "2", // ApiDeposit
                            transferTypeId      = "2", // Withdrawal
                            amount              = wo.amountFrom,
                            amountTypeId        = "1", // NormalBalance
                            balanceBefore       = agentAccount.balance,
                            balanceAfter        = agentAccount.balance - wo.amountFrom,
                            frozenBalanceBefore = agentAccount.frozenBalance,
                            frozenBalanceAfter  = agentAccount.frozenBalance,
                            createDateTime      = createDateTime,
                            l1 = agentAccount.l1,
                            l2 = agentAccount.l2,
                            l3 = agentAccount.l3,
                            l4 = agentAccount.l4,
                            l5 = agentAccount.l5,
                            l6 = agentAccount.l6,
                            l7 = agentAccount.l7,
                            l8 = agentAccount.l8,
                            l9 = agentAccount.l9,
                        };

                        conn.Execute(transInsert, agentBalance);

                        // 交易紀錄 agentAccount frozenBalance
                        var agentFrozenBalance = new accountTrans()
                        {
                            detailId            = wo.id,
                            memberId            = agentAccount.memberId,
                            memberLevelId       = agentAccount.memberLevelId,
                            memberParentId      = agentAccount.memberParentId,
                            accountId           = agentAccount.id,
                            transferCateId      = "4", // ExternalWithdrawal
                            transferTypeId      = "2", // Withdrawal
                            amount              = wo.amountFrom,
                            amountTypeId        = "2", // FrozenBalance
                            balanceBefore       = agentBalance.balanceAfter,
                            balanceAfter        = agentBalance.balanceAfter,
                            frozenBalanceBefore = agentAccount.frozenBalance,
                            frozenBalanceAfter  = agentAccount.frozenBalance - wo.amountFrom,
                            createDateTime      = createDateTime,
                            l1 = agentAccount.l1,
                            l2 = agentAccount.l2,
                            l3 = agentAccount.l3,
                            l4 = agentAccount.l4,
                            l5 = agentAccount.l5,
                            l6 = agentAccount.l6,
                            l7 = agentAccount.l7,
                            l8 = agentAccount.l8,
                            l9 = agentAccount.l9,
                        };

                        conn.Execute(transInsert, agentFrozenBalance);

                        // 交易紀錄 memberAccount balance depoist
                        var memberBalanceDeposit = new accountTrans()
                        {
                            detailId            = transDetailId,
                            memberId            = memberAccount.memberId,
                            memberLevelId       = memberAccount.memberLevelId,
                            memberParentId      = memberAccount.memberParentId,
                            accountId           = memberAccount.id,
                            transferCateId      = "2", // ApiDeposit
                            transferTypeId      = "1", // Deposit
                            amount              = wo.amountFrom,
                            amountTypeId        = "1", // NormalBalance
                            balanceBefore       = memberAccount.balance,
                            balanceAfter        = memberAccount.balance + wo.amountFrom,
                            frozenBalanceBefore = memberAccount.frozenBalance,
                            frozenBalanceAfter  = memberAccount.frozenBalance,
                            createDateTime      = createDateTime,
                            l1 = memberAccount.l1,
                            l2 = memberAccount.l2,
                            l3 = memberAccount.l3,
                            l4 = memberAccount.l4,
                            l5 = memberAccount.l5,
                            l6 = memberAccount.l6,
                            l7 = memberAccount.l7,
                            l8 = memberAccount.l8,
                            l9 = memberAccount.l9,
                        };

                        conn.Execute(transInsert, memberBalanceDeposit);

                        memberAccount.balance = memberAccount.balance + wo.amountFrom;
                    }
                    else if (wo.requestTypeId == "2")
                    {
                        conn.Execute("update [bitject].[dbo].[account] set frozenBalance-=@frozenBalance where id=@id", new { frozenBalance = wo.amountFrom, id = memberAccount.id });

                        var memberFrozenBalance = new accountTrans()
                        {
                            detailId            = wo.id,
                            memberId            = memberAccount.memberId,
                            memberLevelId       = memberAccount.memberLevelId,
                            memberParentId      = memberAccount.memberParentId,
                            accountId           = memberAccount.id,
                            transferCateId      = "4", // ExternalWithdrawal
                            transferTypeId      = "2", // Withdrawal
                            amount              = wo.amountFrom,
                            amountTypeId        = "2", // FrozenBalance
                            balanceBefore       = memberAccount.balance,
                            balanceAfter        = memberAccount.balance,
                            frozenBalanceBefore = memberAccount.frozenBalance,
                            frozenBalanceAfter  = memberAccount.frozenBalance - wo.amountFrom,
                            createDateTime      = createDateTime,
                            l1 = memberAccount.l1,
                            l2 = memberAccount.l2,
                            l3 = memberAccount.l3,
                            l4 = memberAccount.l4,
                            l5 = memberAccount.l5,
                            l6 = memberAccount.l6,
                            l7 = memberAccount.l7,
                            l8 = memberAccount.l8,
                            l9 = memberAccount.l9,
                        };

                        conn.Execute(transInsert, memberFrozenBalance);
                    }

                    #endregion requestTypeId == "1" 從 agent 帳戶先扣款

                    accountTransDetail atdWithdrawal = new accountTransDetail()
                    {
                        accountIdFrom    = wo.accountIdFrom,
                        accountIdTo      = wo.bankAccountIdTo,
                        transferCateId   = "4",
                        currencyCodeFrom = wo.currencyCodeFrom,
                        currencyCodeTo   = wo.currencyCodeTo,
                        amountFrom       = wo.amountFrom,
                        amountTo         = wo.amountTo,
                        exDiff           = wo.exDiff,
                        fee                 = wo.fee,
                        r8                  = wo.r8.Value,
                        r7                  = wo.r7.Value,
                        r1                  = wo.r1.Value,
                        createDateTime      = createDateTime,
                        exRateWithDiff      = wo.exRateWithDiff,
                        exRateWithoutDiff   = wo.exRateWithoutDiff,
                        exRateFrom          = wo.exRateFrom,
                        exSlopeFrom         = wo.exSlopeFrom,
                        exInterceptFrom     = wo.exInterceptFrom,
                        exRateTo            = wo.exRateTo,
                        exSlopeTo           = wo.exSlopeTo,
                        exInterceptTo       = wo.exInterceptTo,
                        feeRatio            = wo.feeRatio,
                        amountFromExchange  = wo.amountFromExchange,
                        feeRatioInExchange  = wo.feeRatioInExchange,
                        feeRatioOutExchange = wo.feeRatioOutExchange,
                        exRateInExchange    = wo.exRateInExchange,
                        exRateOutExchange   = wo.exRateOutExchange,
                        memo                = wo.memo,
                        handlerId           = wo.handlerId,
                        handlerIp           = wo.handlerIp,
                    };

                    int detailId = conn.Query <int>(transDetailInsert, atdWithdrawal).Single();

                    conn.Execute("update [bitject].[dbo].[account] set balance=@balance where id=@id", new { balance = memberAccount.balance - wo.amountFrom, id = wo.accountIdFrom });

                    var memberBalanceWithDrawal = new accountTrans()
                    {
                        detailId            = detailId,
                        memberId            = memberAccount.memberId,
                        memberLevelId       = memberAccount.memberLevelId,
                        memberParentId      = memberAccount.memberParentId,
                        accountId           = memberAccount.id,
                        transferCateId      = "4", // ExternalWithdrawal
                        transferTypeId      = "2", // Withdrawal
                        amount              = wo.amountFrom,
                        amountTypeId        = "1", // NormalBalance
                        balanceBefore       = memberAccount.balance,
                        balanceAfter        = memberAccount.balance - wo.amountFrom,
                        frozenBalanceBefore = memberAccount.frozenBalance,
                        frozenBalanceAfter  = memberAccount.frozenBalance,
                        createDateTime      = createDateTime,
                        l1 = memberAccount.l1,
                        l2 = memberAccount.l2,
                        l3 = memberAccount.l3,
                        l4 = memberAccount.l4,
                        l5 = memberAccount.l5,
                        l6 = memberAccount.l6,
                        l7 = memberAccount.l7,
                        l8 = memberAccount.l8,
                        l9 = memberAccount.l9,
                    };

                    conn.Execute(transInsert, memberBalanceWithDrawal);

                    conn.Execute("update [bitject].[dbo].[withdrawalOrder] set status='3' , exchangeHandlingDateTime =@exchangeHandlingDateTime where id=@id", new { id = wo.id, exchangeHandlingDateTime = createDateTime });

                    ts.Complete();
                }
                catch (Exception ex)
                {
                    glbf.SetLog(ex.Message);
                }
            }
        }
Example #2
0
        JToken Transfer(JToken jt_req)
        {
            JToken jt_result = new JObject();

            int     handlerId      = (int)jt_req["handlerId"];
            string  handlerIp      = Convert.ToString(jt_req["handlerIp"]);
            string  transferCateId = (string)jt_req["transferCateId"];
            int     accountIdFrom  = (int)jt_req["accountIdFrom"];
            int     accountIdTo    = (int)jt_req["accountIdTo"];
            decimal amount         = (decimal)jt_req["amount"];
            string  amountOwner    = (string)jt_req["amountOwner"];
            string  memo           = (string)jt_req["memo"];
            decimal feeRatio       = 0;
            string  feeOwner       = Model.Account.Define.TransferSides.Sender;

            using (var ts = new TransactionScope())
            {
                try
                {
                    DateTime createDateTime = DateTime.Now;

                    List <int> accountIds = new List <int>()
                    {
                        accountIdFrom, accountIdTo
                    };

                    var accounts = conn.Query <account>("select * from bitject.dbo.account with(nolock) where id in @accountIds", new { accountIds = accountIds }).ToDictionary(x => x.id);

                    var accountFrom = accounts[accountIdFrom];
                    var accountTo   = accounts[accountIdTo];

                    decimal amountFrom;
                    decimal amountTo;
                    decimal fee;
                    decimal exDiff;

                    List <string> currencyCodes = new List <string>()
                    {
                        accountFrom.currencyCode, accountTo.currencyCode
                    };

                    var exchangeRates = conn.Query <exchangeRate>("select * from bitject.dbo.exchangeRate with(nolock) where currencyCode in @currencyCodes", new { currencyCodes = currencyCodes }).ToDictionary(x => x.currencyCode);

                    var exchangeRateFrom = exchangeRates[accountFrom.currencyCode];
                    var exchangeRateTo   = exchangeRates[accountTo.currencyCode];

                    int decimalDigitFrom = Model.Global.GlobalVar.CurrencyCodeDecimalDigitsMap[accountFrom.currencyCode];

                    int decimalDigitTo = Model.Global.GlobalVar.CurrencyCodeDecimalDigitsMap[accountTo.currencyCode];

                    decimal exRateWithDiff = 1;

                    decimal exRateWithoutDiff = exchangeRateFrom.exRate / exchangeRateTo.exRate;;

                    if (exchangeRateFrom.currencyCode != exchangeRateTo.currencyCode)
                    {
                        exRateWithDiff = (exchangeRateFrom.exRate * (1 - exchangeRateFrom.exSlope) - exchangeRateFrom.exIntercept) / (exchangeRateTo.exRate * (1 + exchangeRateTo.exSlope) + exchangeRateTo.exIntercept);
                    }

                    if (amountOwner == Model.Account.Define.TransferSides.Sender)
                    {
                        if (feeOwner == Model.Account.Define.TransferSides.Sender)
                        {
                            fee = amount * feeRatio;

                            amountFrom = (amount + fee).RoundUp(decimalDigitFrom);

                            amountTo = (amount * exRateWithDiff).RoundDown(decimalDigitTo);

                            exDiff = amount * (exRateWithoutDiff - exRateWithDiff) / exRateWithoutDiff;
                        }
                        else
                        {
                            amountFrom = amount;

                            exDiff = amount * (exRateWithoutDiff - exRateWithDiff) / exRateWithoutDiff;

                            fee = amount * feeRatio;

                            amountTo = ((amount - fee) * exRateWithDiff).RoundDown(decimalDigitTo);
                        }
                    }
                    else
                    {
                        if (feeOwner == Model.Account.Define.TransferSides.Sender)
                        {
                            amountTo = amount;

                            fee = amountTo / exRateWithDiff * feeRatio;

                            amountFrom = (amountTo / exRateWithDiff * (1 + feeRatio)).RoundUp(decimalDigitFrom);

                            exDiff = amountTo / exRateWithDiff * (exRateWithoutDiff - exRateWithDiff) / exRateWithoutDiff;
                        }
                        else
                        {
                            amountFrom = (amount / exRateWithDiff).RoundUp(decimalDigitFrom);

                            exDiff = amount / exRateWithDiff * (exRateWithoutDiff - exRateWithDiff) / exRateWithoutDiff;

                            fee = amount / exRateWithDiff * feeRatio;

                            amountTo = (amount - fee * exRateWithoutDiff).RoundDown(decimalDigitTo);
                        }
                    }

                    if (amountFrom > (accountFrom.balance - accountFrom.frozenBalance))
                    {
                        jt_result["result"] = "fail";
                        jt_result["msg"]    = "餘額不足";
                        jt_result["column"] = "amount";

                        return(jt_result);
                    }

                    //var memberObjTo = conn.Query<member>("select * from bitject.dbo.member with(nolock) where id = " + memberIdTo).FirstOrDefault();

                    // 計算代理獲利(from fee)
                    decimal r1 = fee;

                    decimal r7 = 0;

                    decimal r8 = 0;

                    //if ( == Model.Account.Define.FeeModes.Stack)
                    //{
                    //    r7 = r1;
                    //    r8 = r7 * ownPercentAgent / ownPercentUpAgent;
                    //}
                    //else if (sqlStruct.FeeMode == Model.Account.Define.FeeModes.Divid)
                    //{
                    //    r7 = r1 * (1 - ownPercentAgent);
                    //    r8 = r1 * (1 - ownPercentUpAgent);
                    //}

                    conn.Execute("update account set balance -= " + amountFrom + " where id = " + accountIdFrom);

                    conn.Execute("update account set balance += " + amountTo + " where id = " + accountIdTo);

                    accountTransDetail atd = new accountTransDetail()
                    {
                        accountIdFrom    = accountIdFrom,
                        accountIdTo      = accountIdTo,
                        transferCateId   = transferCateId,
                        currencyCodeFrom = accountFrom.currencyCode,
                        currencyCodeTo   = accountTo.currencyCode,
                        amountFrom       = amountFrom,
                        amountTo         = amountTo,
                        exDiff           = exDiff,
                        fee                 = fee,
                        r8                  = r8,
                        r7                  = r7,
                        r1                  = r1,
                        createDateTime      = createDateTime,
                        exRateWithDiff      = exRateWithDiff,
                        exRateWithoutDiff   = exRateWithoutDiff,
                        exRateFrom          = exchangeRateFrom.exRate,
                        exSlopeFrom         = exchangeRateFrom.exSlope,
                        exInterceptFrom     = exchangeRateFrom.exIntercept,
                        exRateTo            = exchangeRateTo.exRate,
                        exSlopeTo           = exchangeRateTo.exSlope,
                        exInterceptTo       = exchangeRateTo.exIntercept,
                        feeRatio            = feeRatio,
                        amountFromExchange  = 0,
                        feeRatioInExchange  = 0,
                        feeRatioOutExchange = 0,
                        exRateInExchange    = 0,
                        exRateOutExchange   = 0,
                        handlerId           = handlerId,
                        handlerIp           = handlerIp,
                        memo                = memo,
                    };

                    int detailId = conn.Query <int>(transDetailInsert, atd).Single();

                    accountTrans accountTransFromObj = new accountTrans()
                    {
                        detailId            = detailId,
                        memberId            = accountFrom.memberId,
                        memberLevelId       = accountFrom.memberLevelId,
                        memberParentId      = accountFrom.memberParentId,
                        accountId           = accountFrom.id,
                        transferCateId      = transferCateId,
                        transferTypeId      = Model.Account.Define.TransferTypeIds.Withdrawal,
                        amountTypeId        = Model.Account.Define.AccountTransAmoutTypeId.NormalBalance,
                        amount              = amountFrom,
                        balanceBefore       = accountFrom.balance,
                        balanceAfter        = accountFrom.balance - amountFrom,
                        frozenBalanceBefore = accountFrom.frozenBalance,
                        frozenBalanceAfter  = accountFrom.frozenBalance,
                        createDateTime      = createDateTime,
                        l1 = accountFrom.l1,
                        l2 = accountFrom.l2,
                        l3 = accountFrom.l3,
                        l4 = accountFrom.l4,
                        l5 = accountFrom.l5,
                        l6 = accountFrom.l6,
                        l7 = accountFrom.l7,
                        l8 = accountFrom.l8,
                        l9 = accountFrom.l9,
                    };

                    accountTrans accountTransToObj = new accountTrans()
                    {
                        detailId            = detailId,
                        memberId            = accountTo.memberId,
                        memberLevelId       = accountTo.memberLevelId,
                        memberParentId      = accountTo.memberParentId,
                        accountId           = accountTo.id,
                        transferCateId      = transferCateId,
                        transferTypeId      = Model.Account.Define.TransferTypeIds.Deposit,
                        amountTypeId        = Model.Account.Define.AccountTransAmoutTypeId.NormalBalance,
                        amount              = amountTo,
                        balanceBefore       = accountTo.balance,
                        balanceAfter        = accountTo.balance + amountTo,
                        frozenBalanceBefore = accountTo.frozenBalance,
                        frozenBalanceAfter  = accountTo.frozenBalance,
                        createDateTime      = createDateTime,
                        l1 = accountTo.l1,
                        l2 = accountTo.l2,
                        l3 = accountTo.l3,
                        l4 = accountTo.l4,
                        l5 = accountTo.l5,
                        l6 = accountTo.l6,
                        l7 = accountTo.l7,
                        l8 = accountTo.l8,
                        l9 = accountTo.l9,
                    };

                    conn.Execute(transInsert, new object[] { accountTransFromObj, accountTransToObj });

                    ts.Complete();

                    jt_result["result"] = "success";
                    jt_result["msg"]    = "轉帳成功,從 #" + accountFrom.id + " 轉出 " + accountFrom.currencyCode + " " + amountFrom + " 至 #" + accountTo.id + " " + accountTo.currencyCode + " " + amountTo;

                    return(jt_result);
                }
                catch (Exception ex)
                {
                    jt_result["result"] = "fail";
                    jt_result["msg"]    = "請稍後再試 " + ex.Message;

                    return(jt_result);
                }
            }
        }