public bool RecordTransaction(Transaction t) { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); if (conn.Execute("spTransactionRecord", TransToDynParm(t), commandType: CommandType.StoredProcedure) > 0) return true; else return false; } }
public bool TransferFundsForTransaction(Transaction t) { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); if (conn.Execute("ModifyCustomerAccountsForTransaction", new { DebitCustomerID = t.DebitCustomerID, CreditCustomerID = t.CreditCustomerID, Amount = t.Amount }, commandType: CommandType.StoredProcedure) > 0) return true; else return false; } }
private DynamicParameters TransToDynParm(Transaction t) { DynamicParameters p = new DynamicParameters(); p.Add("@TransactionBatchID", t.TransactionBatchID, DbType.String, ParameterDirection.Input); p.Add("@DebitCustomerID", t.DebitCustomerID, DbType.Int64, ParameterDirection.Input); p.Add("@CreditCustomerID", t.CreditCustomerID, DbType.Int64, ParameterDirection.Input); p.Add("@Type", (int)t.Type, DbType.Int32, ParameterDirection.Input); p.Add("@Amount", t.Amount, DbType.Decimal, ParameterDirection.Input); p.Add("@Reason", (int)t.Reason, DbType.Int32, ParameterDirection.Input); p.Add("@Source", (int)t.Source, DbType.Int32, ParameterDirection.Input); p.Add("@AgentID", t.AgentID, DbType.Int64, ParameterDirection.Input); p.Add("@Comment", t.Comment, DbType.String, ParameterDirection.Input); p.Add("@State", (int)t.State, DbType.Int32, ParameterDirection.Input); p.Add("@ForeignTransactionID", t.ForeignTransactionID, DbType.String, ParameterDirection.Input); p.Add("@BillingProcessorType", t.BillingProcessorType, DbType.Int32, ParameterDirection.Input); return p; }
/* * Billing for a completed challenge: * * For each bidder on the Challenge: * Do they have the Actual Bid Amount in their Account Balance? * yes: * create a transaction record: debit bidder, credit victor: Net Bid Amount * set transaction to status: Accepted * set transaction to source: FundedFromBalance * post the transaction * * no: * attempt to add funds from the billing processor: Total Bid Amount * did the funding add succeed? * yes: * create a transaction record: debit bidder, credit victor: Net Bid Amount * create a transaction record: debit bidder, credit Fees Collected: Fees Amount * set both transactions' billing processor foreign transaction ID * set both transactions to status: Accepted * set both transactions to source: FundedByBillingProcessor * post transactions in batch * * no: * create a transaction record: debit bidder, credit victor: Net Bid Amount * create a transaction record: debit bidder, credit Fees Collected: Fees Amount * * set both transactions to status: ProcessorDeclined * post transactions in batch * * Did all of the transactions go through? * yes: * set the ChallengeStatus State to Paid * set the Challenge State to Paid * no: * set the ChallengeStatus State to PartialPaid * set the Challenge State to PartialPaid * */ private void PerformBillingForCompletedChallenge(long ChallengeID, long CustomerID) { List<ChallengeBid> bids = RepoFactory.GetChallengeBidRepo().Get(ChallengeID); IAccountRepository accountRepo=RepoFactory.GetAccountRepo(); ITransactionRepository transRepo=RepoFactory.GetTransactionRepo(); ChallengeStatus chalStatus=RepoFactory.GetChallengeStatusRepo().Get(CustomerID, ChallengeID); long feesAccountID = 0; int bidsPaid = 0; if (chalStatus.Status != (int)ChallengeStatus.StatusCodes.Completed) { System.Diagnostics.Trace.WriteLine("BILLING: Cust" + CustomerID.ToString() + "_Chal" + ChallengeID.ToString() + " - Caught a non-completed challenge status attempting to be billed"); return; } foreach (ChallengeBid b in bids) { Customer cust=RepoFactory.GetCustomerRepo().GetWithID(b.CustomerID); decimal custBalance = accountRepo.BalanceForCustomerAccount(b.CustomerID); if (custBalance >= b.Amount) { Transaction t = new Transaction() { Amount=(b.Amount - b.ComputedFees), DebitCustomerID=b.CustomerID, CreditCustomerID=chalStatus.CustomerID, State=TransactionState.PendingInternalTransfer, Source=TransactionSource.FundedFromBalance, Reason=TransactionReason.CustomerAwardedBounty }; if (accountRepo.TransferFundsForTransaction(t)) { t.State = TransactionState.Successful; bidsPaid++; } transRepo.RecordTransaction(t); } else { Transaction netBountyTransaction = new Transaction() { Amount=(b.Amount-b.ComputedFees), DebitCustomerID=b.CustomerID, CreditCustomerID=chalStatus.CustomerID, State=TransactionState.PendingFunds, Source=TransactionSource.FundedFromBillingProcessor, Reason=TransactionReason.CustomerAwardedBounty }; Transaction feesTransaction = new Transaction() { Amount=b.ComputedFees, DebitCustomerID=b.CustomerID, CreditCustomerID=feesAccountID, State=TransactionState.PendingFunds, Source=TransactionSource.FundedFromBillingProcessor, Reason=TransactionReason.CustomerAddedFunds }; IBillingProcessor billingProcessor = BillingProcessorFactory.GetBillingProcessor((BillingProcessorFactory.SupportedBillingProcessor)cust.BillingType); BillingProcessorResult chargeResult = billingProcessor.Charge(cust.BillingID, b.Amount); netBountyTransaction.ForeignTransactionID = chargeResult.ForeignTransactionID; feesTransaction.ForeignTransactionID = chargeResult.ForeignTransactionID; if (chargeResult.Result == BillingProcessorResult.BillingProcessorResultCode.Paid) { // we got the money!! BOOYAH. stick it in their account. // TODO: We should make sure this succeeds or we could see negative account balances. accountRepo.ModifyCustomerAccountBalance(cust.ID, b.Amount); netBountyTransaction.State = TransactionState.PendingInternalTransfer; feesTransaction.State = TransactionState.PendingInternalTransfer; // attempt the funds transfer. // if we move the money successfully, update the transaction state. if (accountRepo.TransferFundsForTransaction(netBountyTransaction)) netBountyTransaction.State = TransactionState.Successful; if (accountRepo.TransferFundsForTransaction(feesTransaction)) feesTransaction.State = TransactionState.Successful; if(netBountyTransaction.State==TransactionState.Successful && feesTransaction.State==TransactionState.Successful) bidsPaid++; //only if the entire thing was successful } else { // we no get the money. netBountyTransaction.State = TransactionState.ProcessorDecline; feesTransaction.State = TransactionState.ProcessorDecline; // since they don't have the money, don't perform any transfers. } List<Transaction> transBatch = new List<Transaction>(2); transBatch.Add(netBountyTransaction); transBatch.Add(feesTransaction); // TODO: This transaction ID might not be unique if we have to keep retrying this batch. transRepo.RecordTransactionBatch(transBatch, "Chal"+chalStatus.ChallengeID+"+Cust"+chalStatus.CustomerID+"+"+System.DateTime.Now.Ticks.ToString()); } } if (bidsPaid >= bids.Count) chalStatus.Status = (int)ChallengeStatus.StatusCodes.Paid; else if (bidsPaid < bids.Count) chalStatus.Status = (int)ChallengeStatus.StatusCodes.PartialPaid; RepoFactory.GetChallengeStatusRepo().Update(chalStatus); // plz work }
public bool RecordTransaction(Transaction t) { return false; }
public bool TransferFundsForTransaction(Transaction t) { return (context.ModifyCustomerAccountsForTransaction(t.DebitAccountID, t.CreditAccountID, t.Amount) != 0); }