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); } } }
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); } } }