/// <summary> /// Determines whether the specified object has equal values to this object in all fields. /// </summary> /// <param name="obj"> /// The object whose values to compare. /// </param> /// <returns> /// True if the two objects have the same values. /// </returns> public override bool Equals(object obj) { PartnerCardInfo partnerCardInfo = (PartnerCardInfo)obj; return(PartnerId == partnerCardInfo.PartnerId && PartnerCardId == partnerCardInfo.PartnerCardId && PartnerCardSuffix == partnerCardInfo.PartnerCardSuffix); }
/// <summary> /// Claims the deal in the context for redemption with the card in the context with this partner. /// </summary> /// <returns> /// A task that will yield the result code for the operation. /// </returns> /// <remarks> /// MasterCard does not have a concept of claiming a deal, so this will succeed automatically. /// </remarks> public Task <ResultCode> ClaimDealAsync() { return(Task.Factory.StartNew(() => { ResultCode result = ResultCode.None; // Get the PartnerCardInfo for MasterCard. Card card = (Card)Context[Key.Card]; if (card.Id == 0) { throw new InvalidOperationException("Unexpected value in card.Id"); } PartnerCardInfo masterCardCardInfo = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.MasterCard); if (masterCardCardInfo == null) { result = ResultCode.UnregisteredCard; } // Get the PartnerDealInfo for MasterCard. Deal deal = (Deal)Context[Key.Deal]; if (deal.Id == 0) { throw new InvalidOperationException("Unexpected value in deal.Id"); } PartnerDealInfo MaterCardDealInfo = deal.PartnerDealInfoList.SingleOrDefault(partnerDealInfo => partnerDealInfo.PartnerId == Partner.MasterCard); if (MaterCardDealInfo == null) { result = ResultCode.UnregisteredDeal; } // Only proceed if MasterCard has both the card and the deal registered. if (result == ResultCode.None) { // MasterCard does not have a concept of claiming a deal, so just assign an ID that will be used // when searching for the best deal for a transaction. User user = (User)Context[Key.User]; Context[Key.ClaimedDeal] = new ClaimedDeal() { CardId = card.Id, GlobalDealId = deal.GlobalId, GlobalUserId = user.GlobalId, Partner = Partner.MasterCard }; result = ResultCode.Success; } return result; })); }
/// <summary> /// Enroll new user to Visa /// </summary> /// <returns></returns> private async Task <ResultCode> CreateEnrollment(string userKey) { ResultCode result = ResultCode.None; var newCardNumber = ((NewCardInfo)Context[Key.NewCardInfo]).Number; var lastFourOfNewCard = newCardNumber.Substring(12); // Build a card register request object. var request = VisaRtmDataManager.GetCreateEnrollmentRequest( community: VisaConstants.CommunityName, userkey: userKey, cardnumbers: new List <string> { newCardNumber } ); LogRequest("CreateEnrollment", request, newCardNumber, lastFourOfNewCard); // Invoke the partner to add the card. result = await PartnerUtilities.InvokePartner(Context, async() => { var response = await VisaInvoker.CreateEnrollment(request).ConfigureAwait(false); LogRequestResponse("CreateEnrollment", request, response, response.Success, newCardNumber, lastFourOfNewCard); result = ResultCode.UnknownError; if (response.Success) { result = ResultCode.Created; } else if (response.HasError()) { result = visaErrorUtility.GetResultCode(response, null); } if (result == ResultCode.Created) { PartnerCardInfo partnerCardInfo = GetVisaCardInfo((Card)Context[Key.Card]); partnerCardInfo.PartnerCardId = response.EnrollmentRecord.CardDetails[0].CardId.ToString(); partnerCardInfo.PartnerCardSuffix = "00"; var partnerUserId = response.EnrollmentRecord.UserProfileId; User user = (User)Context[Key.User]; user.AddOrUpdatePartnerUserId(Partner.Visa, partnerUserId.ToString(), true); //add partner user information to the database var userOperations = CommerceOperationsFactory.UserOperations(Context); userOperations.AddOrUpdateUser(); } return(result); }, null, Partner.None, true).ConfigureAwait(false); return(result); }
/// <summary> /// Claims the deal in the context for redemption with the card in the context with this partner. /// </summary> /// <returns> /// A task that will yield the result code for the operation. /// </returns> public Task <ResultCode> ClaimDealAsync() { return(Task.Run(() => { ResultCode result = ResultCode.None; // Get the PartnerCardInfo for Visa. Card card = (Card)Context[Key.Card]; if (card.Id == 0) { throw new InvalidOperationException("Unexpected value in card.Id"); } PartnerCardInfo visaCardInfo = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.Visa); if (visaCardInfo == null) { result = ResultCode.UnregisteredCard; return result; } // Get the PartnerDealInfo for Visa. Deal deal = (Deal)Context[Key.Deal]; if (deal.Id == 0) { throw new InvalidOperationException("Unexpected value in deal.Id"); } PartnerDealInfo visaDealInfo = deal.PartnerDealInfoList.SingleOrDefault(partnerDealInfo => partnerDealInfo.PartnerId == Partner.Visa); if (visaDealInfo == null) { result = ResultCode.UnregisteredDeal; return result; } if (result == ResultCode.None) { User user = (User)Context[Key.User]; Context[Key.ClaimedDeal] = new ClaimedDeal() { CardId = card.Id, GlobalDealId = deal.GlobalId, GlobalUserId = user.GlobalId, Partner = Partner.Visa }; result = ResultCode.Success; } return result; })); }
/// <summary> /// Retrieves the Visa PartnerCardInfo object, creating one if necessary. /// </summary> /// <param name="card"> /// The Card whose Visa PartnerCardInfo object to retrieve. /// </param> /// <returns> /// The Visa PartnerCardInfo object. /// </returns> private static PartnerCardInfo GetVisaCardInfo(Card card) { // Get the PartnerCardInfo for FirstData. PartnerCardInfo result = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.Visa); // If no FirstData PartnerCardInfo existed, add one. if (result == null) { result = new PartnerCardInfo { PartnerId = Partner.Visa }; card.PartnerCardInfoList.Add(result); } return(result); }
/// <summary> /// Retrieves the Amex PartnerCardInfo object, creating one if necessary. /// </summary> /// <param name="card"> /// The Card whose Amex PartnerCardInfo object to retrieve. /// </param> /// <returns> /// The Amex PartnerCardInfo object. /// </returns> internal static PartnerCardInfo GetAmexCardInfo(Card card) { // Get the PartnerCardInfo for FirstData. PartnerCardInfo result = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.Amex); // If no Amex PartnerCardInfo existed, add one. if (result == null) { result = new PartnerCardInfo() { PartnerId = Partner.Amex }; card.PartnerCardInfoList.Add(result); } return(result); }
/// <summary> /// Retrieves the MasterCard PartnerCardInfo object, creating one if necessary. /// </summary> /// <param name="card"> /// The Card whose MasterCard PartnerCardInfo object to retrieve. /// </param> /// <returns> /// The MasterCard PartnerCardInfo object. /// </returns> private static PartnerCardInfo GetMasterCardCardInfo(Card card) { // Get the PartnerCardInfo for MasterCard. PartnerCardInfo result = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.MasterCard); // If no MasterCard PartnerCardInfo existed, add one. if (result == null) { result = new PartnerCardInfo() { PartnerId = Partner.MasterCard }; card.PartnerCardInfoList.Add(result); } return(result); }
/// <summary> /// Add a card to Visa /// </summary> /// <param name="userkey"></param> /// <returns></returns> private async Task <ResultCode> SaveCardAsync(string userkey) { ResultCode result = ResultCode.None; var newCardNumber = ((NewCardInfo)Context[Key.NewCardInfo]).Number; var lastFourOfNewCard = newCardNumber.Substring(12); // Build a card register request object. var request = VisaRtmDataManager.GetSaveCardRequest(userkey, VisaConstants.CommunityName, newCardNumber); LogRequest("AddCard", request, newCardNumber, lastFourOfNewCard); // Invoke the partner to add the card. result = await PartnerUtilities.InvokePartner(Context, async() => { var response = await VisaInvoker.AddCard(request).ConfigureAwait(false); LogRequestResponse("AddCard", request, response, response.Success, newCardNumber, lastFourOfNewCard); result = ResultCode.UnknownError; if (response.Success) { result = ResultCode.Created; } else if (response.HasError()) { result = visaErrorUtility.GetResultCode(response, null); } if (result == ResultCode.Created) { PartnerCardInfo partnerCardInfo = GetVisaCardInfo((Card)Context[Key.Card]); partnerCardInfo.PartnerCardId = response.CardInfoResponse.CardId.ToString(); partnerCardInfo.PartnerCardSuffix = "00"; } return(result); }, null, Partner.None, true).ConfigureAwait(false); return(result); }
/// <summary> /// Adds the card in the context to the data store. /// </summary> /// <returns> /// The ResultCode corresponding to the result of the data store call. /// </returns> // AddOrReactivateCard public ResultCode AddCard() { ResultCode result; // Get the user and card objects from the context. Guid globalUserId = (Guid)Context[Key.GlobalUserId]; Card card = (Card)Context[Key.Card]; // Get the token assigned to the card by the partner. Partner partner = Partner.None; switch (card.CardBrand) { case CardBrand.AmericanExpress: partner = Partner.Amex; break; case CardBrand.MasterCard: partner = Partner.MasterCard; break; case CardBrand.Visa: partner = Partner.Visa; break; } string partnerToken = String.Empty; PartnerCardInfo partnerCardInfo = card.PartnerCardInfoList.FirstOrDefault(partnerCard => partnerCard.PartnerId == partner); if (partnerCardInfo != null) { partnerToken = partnerCardInfo.PartnerCardId; } // Get the token assigned to the card by First Data. // NOTE: This will only be necessary until Visa's WSDL v7 is implemented. string fdcToken = null; PartnerCardInfo fdcCardInfo = card.PartnerCardInfoList.FirstOrDefault(fdcCard => fdcCard.PartnerId == Partner.FirstData); if (fdcCardInfo != null) { fdcToken = fdcCardInfo.PartnerCardId; } // Add the card to the data layer. result = SqlProcedure("AddOrReactivateCard", new Dictionary <string, object> { { "@globalUserId", globalUserId }, { "@cardBrand", card.CardBrand }, { "@lastFourDigits", card.LastFourDigits }, { "@partnerToken", partnerToken }, { "@fdcToken", fdcToken } }, (sqlDataReader) => { if (sqlDataReader.Read() == true) { card.Id = sqlDataReader.GetInt32(sqlDataReader.GetOrdinal("CardId")); } }); return(result); }
/// <summary> /// Adds the card in the context for the user in the context to this partner. /// </summary> /// <returns> /// A task that will yield the result code for the operation. /// </returns> public async Task <ResultCode> AddCardAsync() { ResultCode result = ResultCode.None; // Build request AmexCardSyncRequest amexCardSyncRequest = new AmexCardSyncRequest { CardToken1 = Guid.NewGuid().ToString("N"), CardNumber = ((NewCardInfo)Context[Key.NewCardInfo]).Number }; Context.Log.Verbose("Amex AddCardAsync suggested card token: {0}", amexCardSyncRequest.CardToken1); HashSet <ResultCode> terminalCodes = new HashSet <ResultCode> { ResultCode.Created, ResultCode.Success, ResultCode.InvalidCardNumber, ResultCode.CorporateOrPrepaidCardError }; result = await PartnerUtilities.InvokePartner(Context, async() => { Context.Log.Verbose("Invoking Amex add card partner API."); AmexCardResponse response = await AmexInvoker.AddCardAsync(amexCardSyncRequest); Context.Log.Verbose("Amex add card partner API returned.\r\n {0}", JsonConvert.SerializeObject(response)); string code = null; string text = null; if (response != null && response.ResponseCode != null) { code = response.ResponseCode; text = response.ResponseDescription; switch (code) { case AmexCardSyncResponseCode.AddCardSuccess: case AmexCardSyncResponseCode.CardAndTokenPairAlreadyExists: result = ResultCode.Created; PartnerCardInfo partnerCardInfo = GetAmexCardInfo((Card)Context[Key.Card]); partnerCardInfo.PartnerCardId = response.CardToken1; partnerCardInfo.PartnerCardSuffix = "00"; break; case AmexCardSyncResponseCode.CardExistsWithDifferentToken: result = ResultCode.CardDoesNotBelongToUser; break; case AmexCardSyncResponseCode.CorporateOrPrepaidCardError: result = ResultCode.CorporateOrPrepaidCardError; break; case AmexCardSyncResponseCode.InvalidCardNumber: case AmexCardSyncResponseCode.NotAmexCard: result = ResultCode.InvalidCardNumber; break; default: result = ResultCode.UnknownError; break; } } else { result = ResultCode.UnknownError; } // Log a warning if result was not a success. if (result != ResultCode.Created) { Context.Log.Warning("Amex call failed. respCode: {0}. respText: {1}.", (int)DefaultLogEntryEventId.PartnerErrorWarning, code, text); } return(result); }, terminalCodes); return(result); }
/// <summary> /// Removes the card in the context for the user in the context from this partner. /// </summary> /// <returns> /// A task that will yield the result code for the operation. /// </returns> public async Task <ResultCode> RemoveCardAsync() { ResultCode result = ResultCode.None; Card card = (Card)Context[Key.Card]; PartnerCardInfo amexCardInfo = card.PartnerCardInfoList.SingleOrDefault(partnerCardInfo => partnerCardInfo.PartnerId == Partner.Amex); if (amexCardInfo != null) { // Build request AmexCardUnSyncRequest amexCardUnSyncRequest = new AmexCardUnSyncRequest { CardToken1 = amexCardInfo.PartnerCardId }; result = await PartnerUtilities.InvokePartner(Context, async() => { Context.Log.Verbose("Invoking partner RemoveCardAsync API."); AmexCardResponse response = await AmexInvoker.RemoveCardAsync(amexCardUnSyncRequest); Context.Log.Verbose("Partner RemoveCardAsync API returned: {0}: {1}.", response.ResponseCode, response.ResponseDescription); string code = null; string text = null; if (response != null && response.ResponseCode != null) { code = response.ResponseCode; text = response.ResponseDescription; switch (code) { case AmexCardUnSyncResponseCode.RemoveCardSuccess: case AmexCardUnSyncResponseCode.CardDoesNotExist: case AmexCardUnSyncResponseCode.NoLinkedCards: result = ResultCode.Success; break; default: result = ResultCode.UnknownError; break; } } else { result = ResultCode.UnknownError; } // Log a warning if result was not a success. if (result != ResultCode.Success) { Context.Log.Warning("Amex Data call failed. respCode: {0}. respText: {1}.", (int)DefaultLogEntryEventId.PartnerErrorWarning, code, text); } return(result); }); } return(result); }
/// <summary> /// Adds the card in the context for the user in the context to this partner. /// </summary> /// <returns> /// A task that will yield the result code for the operation. /// </returns> public async Task <ResultCode> AddCardAsync() { ResultCode result = ResultCode.None; // Build customer fields. string partnerCardId = General.GenerateShortGuid(); HashStringElement[] customerFieldsElements = new HashStringElement[2] { new HashStringElement { fieldName = MasterCardConstants.BankCustomerNumberFieldName, data = partnerCardId }, new HashStringElement { fieldName = MasterCardConstants.MemberIcaFieldName, data = MasterCardConstants.MemberIca } }; // Build the customer account fields. HashStringElement[] customerAccountFieldsElements = new HashStringElement[4] { new HashStringElement { fieldName = MasterCardConstants.BankAccountNumberFieldName, data = ((NewCardInfo)Context[Key.NewCardInfo]).Number }, new HashStringElement { fieldName = MasterCardConstants.BankProductCodeFieldName, data = MasterCardConstants.BankProductCode }, new HashStringElement { fieldName = MasterCardConstants.AccountStatusCodeFieldName, data = MasterCardConstants.AccountStatusActive }, new HashStringElement { fieldName = MasterCardConstants.ProgramIdentifierFieldName, data = MasterCardConstants.ProgramIdentifier } }; // Build a card register request object. doEnrollment cardEnrollment = new doEnrollment { sourceId = MasterCardConstants.SourceId, enrollmentTypeCode = MasterCardConstants.EnrollmentTypeCode, customerFields = customerFieldsElements, customerAccountFields = customerAccountFieldsElements }; doEnrollmentRequest cardEnrollmentRequest = new doEnrollmentRequest { doEnrollment = cardEnrollment }; LogAddCardRequestParameters(cardEnrollmentRequest); // Invoke the partner to add the card. result = await PartnerUtilities.InvokePartner(Context, async() => { Context.Log.Verbose("Invoking partner AddCard API."); DoEnrollmentResp response = await MasterCardInvoker.AddCard(cardEnrollment).ConfigureAwait(false); Context.Log.Verbose("Partner AddCard API returned: {0}: {1}.", response.returnCode, response.returnMsg); LogAddCardResponseParameters(response); // Determine the ResultCode from the response code. PartnerCardInfo partnerCardInfo = GetMasterCardCardInfo((Card)Context[Key.Card]); //TODO: Move PartnerCardSuffix into First Data-specific construct. partnerCardInfo.PartnerCardSuffix = "00"; switch (response.returnCode) { case MasterCardResponseCode.Success: result = ResultCode.Created; partnerCardInfo.PartnerCardId = partnerCardId; break; case MasterCardResponseCode.BankAccountNumberExists: result = ResultCode.Created; partnerCardInfo.PartnerCardId = response.bankCustomerNumber; break; case MasterCardResponseCode.UnsupportedBin: case MasterCardResponseCode.MessageNotFound: result = ResultCode.UnsupportedBin; break; case MasterCardResponseCode.InvalidCard: result = ResultCode.InvalidCard; break; case MasterCardResponseCode.InvalidParameters: case MasterCardResponseCode.UnknownError: result = ResultCode.UnknownError; break; } // Log a warning if result was not a success. if (result != ResultCode.Created) { Context.Log.Warning("MasterCard call failed. returnCode: {0}. returnMsg: {1}.", (int)DefaultLogEntryEventId.PartnerErrorWarning, response.returnCode, response.returnMsg); } return(result); }).ConfigureAwait(false); return(result); }
/// <summary> /// Initializes a new instance of the class derived from PartnerCardInfo, using the fields from the specified other /// PartnerCardInfo. /// </summary> /// <param name="partnerCardInfo"> /// The other PartnerCardInfo whose fields to copy. /// </param> internal PartnerCardInfo(PartnerCardInfo partnerCardInfo) { PartnerId = partnerCardInfo.PartnerId; PartnerCardId = partnerCardInfo.PartnerCardId; PartnerCardSuffix = partnerCardInfo.PartnerCardSuffix; }
/// <summary> /// Invokes AddCard with each currently registered partner. /// </summary> public async Task Invoke() { try { ResultCode resultCode = ResultCode.Created; NewCardInfo newCardInfo = (NewCardInfo)Context[Key.NewCardInfo]; Card card = (Card)Context[Key.Card]; List <ICommercePartner> partners = new List <ICommercePartner>(); //partners.Add(new FirstData(Context)); CardBrand cardBrand = (CardBrand)Enum.Parse(typeof(CardBrand), newCardInfo.CardBrand); switch (cardBrand) { case CardBrand.AmericanExpress: partners.Add(new Amex(Context)); break; case CardBrand.MasterCard: partners.Add(new MasterCard(Context)); break; case CardBrand.Visa: partners.Add(new Visa(Context)); break; } foreach (ICommercePartner partner in partners) { string partnerName = partner.GetType().Name; Context.Log.Verbose("Adding card to partner {0}.", partnerName); ResultCode partnerResult = ResultCode.None; try { partnerResult = await partner.AddCardAsync(); } catch (Exception ex) { Context.Log.Error("Add card call to partner {0} ended with an error.", ex, partnerName); } // Update overall result from result of call to partner. switch (partnerResult) { case ResultCode.Created: // At this time, FirstData PartnerCardId is used as the PanToken for the card. if (partner is FirstData) { PartnerCardInfo firstDataInfo = card.PartnerCardInfoList.SingleOrDefault(info => info.PartnerId == Partner.FirstData); if (firstDataInfo != null) { card.PanToken = firstDataInfo.PartnerCardId; } } break; case ResultCode.InvalidCard: resultCode = ResultCode.InvalidCard; break; case ResultCode.UnknownError: resultCode = ResultCode.UnknownError; break; case ResultCode.InvalidCardNumber: resultCode = ResultCode.InvalidCardNumber; break; case ResultCode.CorporateOrPrepaidCardError: resultCode = ResultCode.CorporateOrPrepaidCardError; break; case ResultCode.MaximumEnrolledCardsLimitReached: resultCode = ResultCode.MaximumEnrolledCardsLimitReached; break; case ResultCode.CardRegisteredToDifferentUser: resultCode = ResultCode.CardRegisteredToDifferentUser; break; case ResultCode.CardExpired: resultCode = ResultCode.CardExpired; break; default: throw new InvalidOperationException("Call to partner invoker returned ResultCode.None."); } } AddCardConcluder addCardConcluder = new AddCardConcluder(Context); addCardConcluder.Conclude(resultCode); } catch (Exception ex) { RestResponder.BuildAsynchronousResponse(Context, ex); } }