/// <summary> /// Adds the referred redemption event to the reward subsystem. /// </summary> /// <param name="rewardOperations"> /// The object to use to perform reward operations. /// </param> /// <param name="context"> /// The context of the worker action being executed. /// </param> /// <returns> /// The ResultCode describing the result of the operation. /// </returns> /// <exception cref="ArgumentNullException"> /// * Parameter record cannot be null. /// -OR- /// * Parameter rewardOperations cannot be null. /// -OR- /// * Parameter context cannot be null. /// </exception> public static ResultCode RewardReferredRedemption(IRewardOperations rewardOperations, CommerceContext context) { if (rewardOperations == null) { throw new ArgumentNullException("rewardOperations", "Parameter rewardOperations cannot be null."); } if (context == null) { throw new ArgumentNullException("context", "Parameter context cannot be null."); } ResultCode result = ResultCode.Success; context.Log.Verbose("Attempting to reward for a referred redemption."); result = rewardOperations.AddReferredRedemptionReward(); if (result != ResultCode.Success) { context.Log.Warning("Unable to add referred redemption reward for this settlement event.\r\n\r\nResultCode: {0}" + "\r\n\r\nExplanation: {1}", (int)result, result, ResultCodeExplanation.Get(result)); } return(result); }
/// <summary> /// Adds the redemption event to the reward subsystem. /// </summary> /// <param name="rewardOperations"> /// The object to use to perform reward operations. /// </param> /// <param name="context"> /// The context of the worker action being executed. /// </param> /// <returns> /// The ResultCode describing the result of the operation. /// </returns> /// <exception cref="ArgumentNullException"> /// * Parameter record cannot be null. /// -OR- /// * Parameter rewardOperations cannot be null. /// -OR- /// * Parameter context cannot be null. /// </exception> public static ResultCode RewardRedemption(IRewardOperations rewardOperations, CommerceContext context) { if (rewardOperations == null) { throw new ArgumentNullException("rewardOperations", "Parameter rewardOperations cannot be null."); } if (context == null) { throw new ArgumentNullException("context", "Parameter context cannot be null."); } ResultCode result = ResultCode.Success; context.Log.Verbose("Attempting to add redemption reward."); context[Key.RewardId] = CommerceWorkerConfig.Instance.FirstEarnRewardId; context[Key.FirstEarnRewardAmount] = CommerceWorkerConfig.Instance.FirstEarnRewardAmount; context[Key.FirstEarnRewardExplanation] = CommerceWorkerConfig.Instance.FirstEarnRewardExplanation; context.Log.Verbose("Adding redemption reward to data store."); result = rewardOperations.AddRedemptionReward(); if (result != ResultCode.Success) { context.Log.Warning("Unable to add redemption reward for this transaction.\r\n\r\nResultCode: {0}" + "\r\n\r\nExplanation: {1}", (int)result, result, ResultCodeExplanation.Get(result)); } return(result); }
/// <summary> /// Applies the Earn reward according to RewardPayoutRecord parameters. /// </summary> /// <returns></returns> public OrchestratedExecutionResult Apply() { OrchestratedExecutionResult result = OrchestratedExecutionResult.NonTerminalError; CommerceContext context = new CommerceContext("Updating reward status", CommerceWorkerConfig.Instance); context[Key.RewardPayoutId] = RewardPayoutRecord.RewardPayoutId; context[Key.RewardPayoutStatus] = RewardPayoutStatus.NoEligibleUser; string actionDescription = String.Empty; if (RewardPayoutRecord.PayeeType == PayeeType.User) { if (RewardPayoutRecord.PayeeId != Guid.Empty) { if (RewardPayoutRecord.Rescinded == false) { result = OrchestratedExecutionResult.Success; context[Key.RewardPayoutStatus] = RewardPayoutStatus.Paid; actionDescription = "was paid"; } else { context[Key.RewardPayoutStatus] = RewardPayoutStatus.Rescinded; Log.Information("A rescinded reward cannot be paid out."); actionDescription = "could not be paid because the reward has been rescinded"; } } else { Log.Warning("Payee ID cannot be Guid.Empty."); actionDescription = "could not be paid because no eligible user could be found"; } } else { Log.Warning("Earn Rewards cannot be applied to payees of type {0}.", RewardPayoutRecord.PayeeType); actionDescription = String.Format("could not be paid because payees of type {0} cannot receive Earn Rewards", RewardPayoutRecord.PayeeType); } Log.Verbose("Updating reward payout record status to indicate the reward {0}.", actionDescription); IRewardOperations rewardOperations = CommerceOperationsFactory.RewardOperations(context); ResultCode resultCode = rewardOperations.UpdateRewardPayoutStatus(); if (resultCode != ResultCode.Success && resultCode != ResultCode.PayoutStatusTooAdvanced) { result = OrchestratedExecutionResult.NonTerminalError; Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)resultCode, context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); } return(result); }
/// <summary> /// Test whether Visa Incoming call is authorized. To be developed. /// </summary> /// <returns> /// True/False based on incoming request /// </returns> //private static bool IsAuthorized(CommerceContext context) //{ // //TODO: Lock down security once the interop is working. // context.Log.Error("Still not locked the endpoint yet {0}", null, "visa endpoint"); // return true; //} /// <summary> /// Process the Incoming Visa EndpointMessage Request /// </summary> /// <param name="context"> /// Commerce Context /// </param> /// <param name="callTimer"> /// Call Timer /// </param> /// <param name="executorInvoker"> /// Executor handler /// </param> /// <returns> /// HttpStatus code /// </returns> private HttpStatusCode ProcessVisaEndpointMessage(CommerceContext context, Stopwatch callTimer, Func <ResultCode> executorInvoker) { HttpStatusCode result = HttpStatusCode.Unauthorized; context.Log.Information("Processing {0} call.", context.ApiCallDescription); CallCompletionStatus callCompletionStatus = CallCompletionStatus.Error; #if !IntDebug && !IntRelease if (ValidateIP(context) == true) #endif { try { ResultCode resultCode = executorInvoker(); if (resultCode == ResultCode.Success || resultCode == ResultCode.Created || resultCode == ResultCode.DuplicateTransaction) { callCompletionStatus = CallCompletionStatus.Success; context.Log.Information("{0} call processed successfully.", context.ApiCallDescription); result = HttpStatusCode.OK; } else { //if (resultCode == ResultCode.None) //TODO: need to be more discrimitive result = HttpStatusCode.InternalServerError; callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; context.Log.Warning( "{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)resultCode, context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); } } catch (Exception ex) { context.Log.Critical("{0} call ended with an error.", ex, context.ApiCallDescription); result = HttpStatusCode.InternalServerError; } } callTimer.Stop(); context.PerformanceInformation.Add("Total", String.Format("{0} ms", callTimer.ElapsedMilliseconds)); context.Log.CallCompletion(context.ApiCallDescription, callCompletionStatus, context.PerformanceInformation); return(result); }
/// <summary> /// Executes the task. /// </summary> /// <returns> /// The result of the execution of the task. /// </returns> public OrchestratedExecutionResult Execute() { OrchestratedExecutionResult result = OrchestratedExecutionResult.NonTerminalError; switch (RewardPayoutRecord.RewardType) { case RewardType.Undefined: case RewardType.StatementCredit: Log.Verbose("Updating reward payout record status to indicate the reward is pending."); CommerceContext context = new CommerceContext("Updating reward status", CommerceWorkerConfig.Instance); context[Key.RewardPayoutId] = RewardPayoutRecord.RewardPayoutId; context[Key.RewardPayoutStatus] = RewardPayoutStatus.Pending; IRewardOperations rewardOperations = CommerceOperationsFactory.RewardOperations(context); ResultCode resultCode = rewardOperations.UpdateRewardPayoutStatus(); if (resultCode != ResultCode.Success) { result = OrchestratedExecutionResult.NonTerminalError; Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)resultCode, context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); } else { result = OrchestratedExecutionResult.Success; } break; case RewardType.EarnCredit: ApplyEarnCredit applyEarnCredit = new ApplyEarnCredit(RewardPayoutRecord, Log); result = applyEarnCredit.Apply(); break; default: Log.Error("Invalid reward type {0} in reward payout record.", null, RewardPayoutRecord.RewardType); break; } return(result); }
/// <summary> /// Process the Incoming Amex Auth Request /// </summary> /// <param name="context"> /// Commerce Context /// </param> /// <param name="callTimer"> /// Call Timer /// </param> /// <param name="executorInvoker"> /// Executor handler /// </param> /// <returns> /// HttpStatus code /// </returns> private static HttpStatusCode ProcessAmexAuthCall(CommerceContext context, Stopwatch callTimer, Func <ResultCode> executorInvoker) { HttpStatusCode result = HttpStatusCode.OK; context.Log.Verbose("Processing {0}.", context.ApiCallDescription); CallCompletionStatus callCompletionStatus; try { ResultCode resultCode = executorInvoker(); if (resultCode == ResultCode.Success || resultCode == ResultCode.Created || resultCode == ResultCode.DuplicateTransaction) { callCompletionStatus = CallCompletionStatus.Success; context.Log.Information("{0} processed successfully.", context.ApiCallDescription); } else { callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; context.Log.Warning("{0} processed unsuccessfully.\r\nResultCode: {1}\r\nExplanation: {2}", (int)resultCode, context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); } } catch (Exception ex) { callCompletionStatus = CallCompletionStatus.Error; context.Log.Critical("{0} ended with an error.", ex, context.ApiCallDescription); result = HttpStatusCode.InternalServerError; } callTimer.Stop(); context.PerformanceInformation.Add("Total", string.Format("{0} ms", callTimer.ElapsedMilliseconds)); context.Log.CallCompletion(context.ApiCallDescription, callCompletionStatus, context.PerformanceInformation); return(result); }
public HttpResponseMessage OnAuthorization(Transaction request) { if (request == null) { throw new ArgumentNullException("request", "Parameter request cannot be null."); } // Build a context object to pass down the pipeline. Stopwatch callTimer = Stopwatch.StartNew(); Context = new CommerceContext("Incoming MasterCard Authorization Request"); MasterCardAuthorizationResponse response = new MasterCardAuthorizationResponse(); Context[Key.Transaction] = request; Context[Key.Response] = response; Context[Key.CallTimer] = callTimer; // Process the call and log its result. Context.Log.Information("Processing {0} call.", Context.ApiCallDescription); //TODO: If we ever circle back and switch to client certificate authentication, uncomment this and remove ValidateIP. //CustomIdentity clientIdentity = (CustomIdentity)Thread.CurrentPrincipal.Identity; //Context.Log.Verbose("Presented client certificate has subject \"{0}\" and thumbprint \"{1}\".", // clientIdentity.Name, clientIdentity.PresentedClientToken); ResultCode resultCode = ResultCode.Unauthorized; response.ResponseCode = ((int)resultCode).ToString(); CallCompletionStatus callCompletionStatus = CallCompletionStatus.Error; if (ValidateIP() == true) { try { MasterCardAuthorizationExecutor executor = new MasterCardAuthorizationExecutor(Context); resultCode = executor.Execute(); // Determine call completion status from executor result and log it. if (resultCode == ResultCode.Created || resultCode == ResultCode.DuplicateTransaction) { resultCode = ResultCode.Success; callCompletionStatus = CallCompletionStatus.Success; Context.Log.Information("{0} call processed successfully.", Context.ApiCallDescription); } else { callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; Context.Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)resultCode, Context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); } } catch (Exception ex) { Context.Log.Critical("{0} call ended with an error.", ex, Context.ApiCallDescription); resultCode = ResultCode.UnknownError; callCompletionStatus = CallCompletionStatus.Error; } } // Build the response. HttpResponseMessage message = new HttpResponseMessage(MapResultToStatusCode(resultCode)); message.Content = new ObjectContent <MasterCardAuthorizationResponse>(response, new XmlMediaTypeFormatter()); // Log the result of the call. callTimer.Stop(); Context.PerformanceInformation.Add("Total", String.Format("{0} ms", callTimer.ElapsedMilliseconds)); Context.Log.CallCompletion(Context.ApiCallDescription, callCompletionStatus, Context.PerformanceInformation); return(message); }
/// <summary> /// Pings the FirstDataService. /// </summary> /// <param name="request"> /// The ping request. /// </param> /// <returns> /// A ping response. /// </returns> /// <exception cref="ArgumentNullException"> /// Parameter request cannot be null. /// </exception> public pubPingResponse1 pubPing(pubPingRequest1 request) { if (request == null) { throw new ArgumentNullException("request", "Parameter request cannot be null."); } Stopwatch callTimer = Stopwatch.StartNew(); pubPingResponse1 result = new pubPingResponse1(new pubPingResponse { reqID = request.pubPingRequest.reqID }); // Build a context object to pass down the pipeline. CommerceContext context = new CommerceContext("First Data ping"); context[Key.Request] = request.pubPingRequest; context[Key.Response] = result.pubPingResponse; context.Log.Exhaustive("Processing {0} call.", context.ApiCallDescription); CallCompletionStatus callCompletionStatus = CallCompletionStatus.Error; HttpStatusCode httpStatusCode = HttpStatusCode.OK; try { HttpClientCertificate httpClientCertificate = HttpContext.Current.Request.ClientCertificate; context.Log.Exhaustive("Presented client certificate has serial number \"{0}\".", httpClientCertificate.SerialNumber); if (General.IsPresentedCertValid(httpClientCertificate, CommerceServiceConfig.Instance.FirstDataClientCertificateSerialNumbers) == true) { FirstDataPingExecutor firstDataPingExecutor = new FirstDataPingExecutor(context); firstDataPingExecutor.Execute(); context.Log.Exhaustive("{0} call processed successfully.", context.ApiCallDescription); callCompletionStatus = CallCompletionStatus.Success; } else { callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; #if !IntDebug && !IntRelease context.Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)ResultCode.InvalidClientCertificate, context.ApiCallDescription, ResultCode.InvalidClientCertificate, ResultCodeExplanation.Get(ResultCode.InvalidClientCertificate)); #endif httpStatusCode = HttpStatusCode.Unauthorized; } } catch (Exception ex) { context.Log.Critical("{0} call ended with an error.", ex, context.ApiCallDescription); httpStatusCode = HttpStatusCode.InternalServerError; } callTimer.Stop(); context.PerformanceInformation.Add("Total", String.Format("{0} ms", callTimer.ElapsedMilliseconds)); context.Log.ExhaustiveCallCompletion(context.ApiCallDescription, callCompletionStatus, context.PerformanceInformation); // Throw exception if the operation did not succeed. if (httpStatusCode != HttpStatusCode.OK) { throw new WebFaultException <pubPingResponse1>(result, httpStatusCode); } return(result); }
/// <summary> /// If the calling thread is the currently authorized thread, processes the redeemed deal record received from a partner /// against the redeemed deals in the data store. /// </summary> /// <param name="partner"> /// The Partner from which the redeemed deal record originated. /// </param> /// <param name="record"> /// The redeemed deal record to process. /// </param> /// <param name="redeemedDealOperations"> /// The object to use to perform redeemed deal operations. /// </param> /// <param name="context"> /// The context of the worker action being executed. /// </param> /// <param name="threadId"> /// The ID of the thread attempting to perform this action. /// </param> /// <returns> /// The ResultCode describing the result of the operation. /// </returns> /// <exception cref="ArgumentNullException"> /// * Parameter redeemedDealOperations cannot be null. /// -OR- /// * Parameter context cannot be null. /// </exception> public static ResultCode ProcessPartnerRedeemedDealRecord(Partner partner, SettlementDetail record, IRedeemedDealOperations redeemedDealOperations, CommerceContext context) { if (redeemedDealOperations == null) { throw new ArgumentNullException("redeemedDealOperations", "Parameter redeemedDealOperations cannot be null."); } if (context == null) { throw new ArgumentNullException("context", "Parameter context cannot be null."); } ResultCode result = ResultCode.None; try { context.Log.Verbose("Processing partner redeemed deal record."); context[Key.Partner] = partner; context[Key.SettlementDetail] = record; result = redeemedDealOperations.ProcessPartnerRedeemedDealRecord(); if (result == ResultCode.Success) { context.Log.Verbose("Partner redeemed deal record processed successfully."); } else { context.Log.Warning("Partner redeemed deal record unsuccessfully processed.\r\n\r\nResultCode: {0}" + "\r\n\r\nExplanation: {1}", (int)result, result, ResultCodeExplanation.Get(result)); } } catch (Exception ex) { context.Log.Critical("Partner redeemed deal record processing ended with an error.", ex); } return(result); }
/// <summary> /// Processes the call from First Data. /// </summary> /// <param name="context"> /// The context of the call. /// </param> /// <param name="callTimer"> /// The Stopwatch used to time the call. /// </param> /// <param name="executorInvoker"> /// The callback that invokes the executor to execute call logic. /// </param> /// <returns> /// The HTTP status code to place within the response. /// </returns> private static HttpStatusCode ProcessFirstDataCall(CommerceContext context, Stopwatch callTimer, Func <ResultCode> executorInvoker) { HttpStatusCode result = HttpStatusCode.OK; context.Log.Information("Processing {0} call.", context.ApiCallDescription); CallCompletionStatus callCompletionStatus; try { HttpClientCertificate httpClientCertificate = HttpContext.Current.Request.ClientCertificate; context.Log.Verbose("Presented client certificate has serial number \"{0}\".", httpClientCertificate.SerialNumber); if (General.IsPresentedCertValid(httpClientCertificate, CommerceServiceConfig.Instance.FirstDataClientCertificateSerialNumbers) == true) { ResultCode resultCode = executorInvoker(); if (resultCode == ResultCode.Success || resultCode == ResultCode.Created) { callCompletionStatus = CallCompletionStatus.Success; context.Log.Information("{0} call processed successfully.", context.ApiCallDescription); } else { callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; #if !IntDebug && !IntRelease context.Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)resultCode, context.ApiCallDescription, resultCode, ResultCodeExplanation.Get(resultCode)); #endif if (resultCode == ResultCode.None || resultCode == ResultCode.UnknownError) { result = HttpStatusCode.InternalServerError; } } } else { callCompletionStatus = CallCompletionStatus.SuccessWithWarnings; #if !IntDebug && !IntRelease context.Log.Warning("{0} call unsuccessfully processed.\r\n\r\nResultCode: {1}\r\n\r\nExplanation: {2}", (int)ResultCode.InvalidClientCertificate, context.ApiCallDescription, ResultCode.InvalidClientCertificate, ResultCodeExplanation.Get(ResultCode.InvalidClientCertificate)); #endif result = HttpStatusCode.Unauthorized; } } catch (Exception ex) { callCompletionStatus = CallCompletionStatus.Error; context.Log.Critical("{0} call ended with an error.", ex, context.ApiCallDescription); result = HttpStatusCode.InternalServerError; } callTimer.Stop(); context.PerformanceInformation.Add("Total", String.Format("{0} ms", callTimer.ElapsedMilliseconds)); context.Log.CallCompletion(context.ApiCallDescription, callCompletionStatus, context.PerformanceInformation); return(result); }