/// <summary> /// Vérification du numéro de carte bancaire /// </summary> /// <param name="user">Compte utilisateur</param> /// <param name="cardHolder">Numéro de carte</param> /// <param name="expirationDate">Date d'expiration</param> /// <param name="onlineCheck">Tester la carte via RBS</param> /// <param name="cardHolder">Détenteur de la carte</param> /// <param name="pos">Marché</param> /// <param name="timeout">timeout</param> /// <param name="service">service</param> /// <param name="customercode">code client</param> /// <param name="travellercode">code voyageur</param> /// <param name="token">code token</param> /// <param name="lodgedCard">Flag lodged card or not</param> /// <param name="firstCardReference">First card reference</param> /// <returns>ReturnIndicator</returns> public static CardInfos CheckCardNumber(UserInfo user, string cardnumber, DateTime expirationDate, bool onlineCheck, string cardHolder, string pos, int timeout, string service, string customercode, string travellercode, string token, int lodgedCard, string firstCardReference) { // On va valider cette carte CardInfos ri = new CardInfos(); if (onlineCheck) { // On demande une vérification // depuis le service en ligne ri.SetOnlineCheckRequested(onlineCheck); } //--> EGE-62034 : Revamp - CCE - Change Financial flow update if (lodgedCard == 1) { ri.SetNavisionLodgedCard(); } //<-- EGE-62034 : Revamp - CCE - Change Financial flow update // On gère les rejets classiques if (String.IsNullOrEmpty(cardnumber)) { // Pan vide ri.SetUnValidMsg(user, user.GetMessages().GetString("EmptyPAN", true)); return(ri); } if (cardnumber.Length < MinimalLength) { // Pan trop court ri.SetUnValidMsg(user, user.GetMessages().GetString("UnvalidPAN", cardnumber, true)); return(ri); } if (IsInvalidRegEx(cardnumber)) { // Pan non digits ri.SetUnValidMsg(user, user.GetMessages().GetString("PANNotDigits", cardnumber, true)); return(ri); } // On va essayer de déterminer le type de carte // grace au numéro de la carte int cardId = GetCardID(cardnumber); if (cardId == Invalid) { // On ne connait pas ce type de carte ri.SetUnValidMsg(user, user.GetMessages().GetString("UnknownCardType", true)); return(ri); } // On garde en mémoire le numéro de carte ri.SetCardNumber(cardnumber); // On a déterminé le type de carte // allons maintenant vérifier si cette carte // est valide en effectuant un contrôle de Luhn if (!LuhnValidate(user, cardnumber)) { // Cette carte est invalide ri.SetUnValidMsg(user, user.GetMessages().GetString("UnvalidPAN", ri.GetTruncatedPAN(), true)); return(ri); } // A-t-on besoin de vérifier la date d'expiration if (!Util.IsEmptyDate(expirationDate)) { DateTime now = DateTime.Today; // On doit vérifier la date d'expiration if (now > expirationDate) { // Cette carte a expiré ri.SetUnValidMsg(user, user.GetMessages().GetString("ExpiredPAN", ri.GetTruncatedPAN(), true)); return(ri); } // La date d'expiration ne peut aller au dela // de 10 ans if (Util.DateDiffInYears(now, expirationDate) > 10) { // La date d'expiration est invalide ri.SetUnValidMsg(user, user.GetMessages().GetString("InvalidExpirationDate", Util.GetShortExpirationDate(expirationDate), true)); return(ri); } // La carte n'a pas encore expirée ri.SetExpirationDate(expirationDate); } // Card is valid ri.SetCardValid(true); ri.SetCardType(GetCardName(cardId)); ri.SetShortCardType(GetShortCardName(cardId)); ri.SetNavisionCardType(GetNavisionCardType(cardId)); ri.SetNavisionCardName(GetNavisionCardName(cardId)); ri.SetPOS(Util.CorrectPos(user, pos)); ri.SetFirstCardReference(firstCardReference); ri.SetTruncatedPAN(TruncatePan(cardnumber)); ri.SetMII(cardnumber); ri.SetMIIIssuerCategory(GetMIIIssuerCategory(cardId)); ri.SetCustomerCode(customercode); switch (cardId) { case AmericanExpress: ri.SetNavisionPaymentBTA(); break; case Airplus: ri.SetNavisionPaymentAirPlus(); break; //case DinersClub : ri.SetNavisionPaymentDiners() ; break; default: break; } // We are here..we can do online validation or even connect to BackOffice system // only if we have market if (String.IsNullOrEmpty(ri.GetPOS())) { //Services.WriteOperationStatusToLog(user, String.Format(" - Info : Empty POS..cannot call online validationfor card type = {0}, truncated PAN {1}", ri.GetCardType(), ri.GetTruncatedPAN())); // We cannot continue, we don't have market return(ri); } //Services.WriteOperationStatusToLog(user, String.Format(" - Info : Connecting to BackOffice system to retrieve financial settings for Truncated PAN= {0}, POS = {1}, card type = {2}, Lodged= {3} ...", ri.GetTruncatedPAN(), ri.GetPOS(), ri.GetNavisionCardName(), ri.GetNavisionLodgedCard())); // Connect to backoffice system // and retrieve informations such as merchant and enhanced flows // online validation NavServiceUtils.GetPaymentSettings(user, ri); //Services.WriteOperationStatusToLog(user, (String.Format("Financial settings retrieved for card type ={0}, truncated PAN= {1}, Merchant flow = {2}, Enhanced flow = {3}, Online check = {4}" // , ri.GetCardType(),ri.GetTruncatedPAN(), ri.GetNavisionFinancialFlow(), ri.GetNavisionEnhancedFlow(), ri.GetOnlineValidation()))); // Cette carte est valide // Si c'est une carte BIBIT alors, il faut // vérifier via le service RBS si nécéssaire if (!ri.IsCallOnLineValidationForSure(user)) { // On n'a pas besoin de valider en ligne cette carte // Services.WriteOperationStatusToLog(user, String.Format(" - Info : No need to do online validation for card type = {0}, truncated PAN = {1}, POS = {2}", ri.GetCardType(), ri.GetTruncatedPAN(), ri.GetPOS())); ; return(ri); } //Services.WriteOperationStatusToLog(user, String.Format(" - Info : We need to do online validation for card type = {0}, truncated PAN = {1}, POS = {2}", ri.GetCardType(), ri.GetTruncatedPAN(), ri.GetPOS())); // We are here we need to fo online validation // On complète les informations ri.SetService(service); ri.SetTravellerCode(travellercode); ri.SetHolderName(cardHolder); ri.SetToken(token); // Mais avant de procéder, il est nécéssaire de vérifier si une vérification n'a pas été faite // les 24 dernières heures // pour cela, nous devons disposer du cryptogramme lors de la recherche dans le cache bool CheckCacheInFO = false; if (BibitVerifier.RBSRequestCacheOn) { // En fonction de la méthode d'appel,nous n'allons // pas utiliser le même serveur d'encryption switch (user.GetApplication()) { case UserInfo.APPLICATION_FO_TOKENIZATION: case UserInfo.APPLICATION_CARD_VALIDATION: ri.SetEncryptedPan(Services.EncryptFOCard(user, ri.GetCardNumber())); CheckCacheInFO = true; break; default: ri.SetEncryptedPan(Services.EncryptBOCard(user, ri.GetCardNumber())); break; } CachedValidationResult cache = null; // On a le cryptogramme du PAN // Nous allons maintenant lire le cache... if (CheckCacheInFO) { cache = Services.GetCachedFOBibitResponse(user, ri.GetEncryptedPan()); } else { cache = Services.GetCachedBibitResponse(user, ri.GetEncryptedPan()); } if (cache.GetStatus() == CachedValidationResult.CacheStatus.FoundValid) { Services.WriteOperationStatusToLog(user, String.Format(" - Info : Card truncated PAN={0}, was found in the cache", ri.GetTruncatedPAN())); // La carte a déjà été validée ri.SetBibitValidFromCache(true); ri.SetBibitValidFromCacheDate(cache.GetLastAccessTime()); return(ri); } } // Nous devons valider via le service en ligne ProviderVerifierResult br = CheckCard(user, ri, cardId, timeout); if (br == null) { // We cannot find provider to validate the credit card // We have to stop here return(ri); } //Services.WriteOperationStatusToLog(user, String.Format(" - Info : Online validation done (Valid = {0}) for card type = {1}, truncated PAN = {2}, POS = {3}" // , br.IsSuccess(), ri.GetCardType(), ri.GetTruncatedPAN(), ri.GetPOS())); if (!br.IsSuccess()) { // credit card is unvalid ri.SetCardValid(false); ri.SetUnValidMsg(user, br.GetOrderCode(), br.GetInformationMessage(), br.GetCompleteResponse(), user.GetMessages().GetString("Bibit.RejectedCard", ri.GetTruncatedPAN(), true) + br.GetInformationMessage()); return(ri); } // La carte est valide // ou on a eu un soucis de Timeout // ou d'erreurs au niveau du service de validation ri.SetInformationCode(br.GetInformationCode()); ri.SetInformationMessage(br.GetInformationMessage()); if (br.GetInformationCode() != null) { // On va tracer cette erreur dans la table des traces des carte rejetées // typiquement un soucis de timeout Services.LogRejectedCreditCard(user, ri, br.GetOrderCode(), br.GetInformationCode(), br.GetInformationMessage(), br.GetCompleteResponse()); return(ri); } // La carte a été validée via RBS if (BibitVerifier.RBSRequestCacheOn) { // On va mettre en cache cet état if (CheckCacheInFO) { // dans le cache du Front Office Services.CacheFOBibitResponseStatus(user, ri.GetEncryptedPan()); } else { // dans le cache du BackOffice Services.CacheBibitResponseStatus(user, ri.GetEncryptedPan()); } } return(ri); }
/// <summary> /// Vérification des cartes BIBIT /// via un service RBS (Royal Bank of Scotland) /// </summary> /// <param name="user">Compte utilisateur</param> /// <param name="card">Informations carte</param> /// <param name="timeOut">Timeout (s)</param> /// <returns>BibitVerifierResult</returns> public static ProviderVerifierResult CheckCard(UserInfo user, CardInfos card, int timeOut) { ProviderVerifierResult retval = new ProviderVerifierResult(); try { // Do we need to do zero amount validation? bool doZeroValidation = (card.GetOnlineValidation() == CardInfos.CardOnlineValidations.ZERO_AMOUNT); // Construction de la requête RBSPaymentServiceRequest rs = new RBSPaymentServiceRequest(user, card, doZeroValidation); Services.WriteOperationStatusToLog(user, String.Format(" - Info : Online validation : Try {0} for card type = {1}, truncated PAN = {2}, POS = {3}", (doZeroValidation ? "Zero Amount" : "One Amount"), card.GetCardType(), card.GetTruncatedPAN(), card.GetPOS())); // Appel du service et récupération de la réponse // if the zero amount is enabled then we will send zero amount first // if the card was refused, then we will try with one amount string response = HttpUtil.HttpPost(user, RBSServiceUrl, RBSServiceLogin, RBSServicePassword, rs.GetXML(), timeOut); // Traitement de la réponse RBSPaymentServiceResponse res = new RBSPaymentServiceResponse(response); Services.WriteOperationStatusToLog(user, String.Format(" - Info : Online validation : {0} validation done (Valid = {1}) for card type = {2}, truncated PAN = {3}, POS = {4}", (doZeroValidation ? "Zero Amount" : "One Amount"), res.isSuccess(), card.GetCardType(), card.GetTruncatedPAN(), card.GetPOS())); // We have our response // that's not the end. If the card was refused and we have send zero amount validation // if that case, we need to try with one amount if (!res.isSuccess() && doZeroValidation) { Services.WriteOperationStatusToLog(user, String.Format(" - Info : Online validation - Zero Amount Validation : the card was refused..we will try with One amount for card type = {0}, truncated PAN = {1}, POS = {2}", card.GetCardType(), card.GetTruncatedPAN(), card.GetPOS())); // the card was refused with Zero amount // let's try with one amount rs = new RBSPaymentServiceRequest(user, card, false); // let's try again with one amount response = HttpUtil.HttpPost(user, RBSServiceUrl, RBSServiceLogin, RBSServicePassword, rs.GetXML(), timeOut); // let's parse response res = new RBSPaymentServiceResponse(response); Services.WriteOperationStatusToLog(user, String.Format(" - Info : Online validation - One Amount validation after Zero done (Valid = {0}) for card type = {1}, truncated PAN = {2}, POS = {3}" , res.isSuccess(), card.GetCardType(), card.GetTruncatedPAN(), card.GetPOS())); } // et retour du statut // on va egalement retourner la réponse entière du service RBS // de plus on ajoute le numéro de la transaction retval.SetSuccess(res.isSuccess()); retval.SetCompleteResponse(res.GetInputResponse()); retval.SetOrderCode(rs.GetOrderCode()); } catch (WebException ex) { // Récupération de l'exception string code = Const.StatusConnectionError; if (ex.Status.Equals(WebExceptionStatus.Timeout)) { // On a eu un timeout // il faut tracer cette erreur dans une table // avant de lever l'exception code = Const.StatusTimeOut; } retval.SetInformationCode(code); retval.SetInformationMessage(ex.Message); } catch (Exception e) { // Erreur lors de la vérication de la carte // via le service RBS // L'erreur peut être un TimeOut // Dans tous les cas, on doit ignorer cette exception // et informer le client que la carte est valide retval.SetInformationCode(Const.StatusConnectionError); retval.SetInformationMessage(e.ToString()); } return(retval); }
/// <summary> /// Return Financial and enhanced flow /// from navision /// </summary> /// <param name="user">User information</param> /// <param name="ci">Card information</param> /// <returns>Updated card information</returns> public static void GetPaymentSettings(UserInfo user, CardInfos ci) { Navision nws = null; try { // instanciate a new webservice nws = new Navision(); // prepare return NAV_CardTypeProviders res = new NAV_CardTypeProviders(); // call the method nws.GetMerchantAndEnhancedFlow(NavWsLogin, NavWsPassword, ci.GetPOS(), ci.GetNavisionCardName() , Util.ConvertIntToBool(ci.GetNavisionLodgedCard()), ci.GetCardNumber().Substring(0, 6), ref res); //nws.GetMerchantAndEnhancedFlow("s-sqlsvc-nav", "G3kt*138!", "france", "VISA", false, "411111", ref res); // Let's check if we have an exception code NavException10 navExcep = res.NavException[0]; // retrieve exception code string exceptionCode = navExcep.NavExceptionCode[0]; if (!String.IsNullOrEmpty(exceptionCode)) { // We have an exception // Let's see how kind of error we have here switch (exceptionCode) { case ERROR_CODE_PROVIDER_NOT_FOUND: // Provider not found..no mapping for this card // We will put default values ci.SetNavisionFinancialFlow(string.Empty); ci.SetNavisionEnhancedFlow(string.Empty); ci.SetOnlineValidation(CREDIT_CARD_NO_ONLINE_VALIDATION); return; case ERROR_CODE_CARD_TYPE_UNKNOWN: // unknow card type // just raise the issue to the caller throw new Exception(user.GetMessages().GetString("CardTypeNotAllowedByNavision", ci.GetTruncatedPAN(), ci.GetCardType(), true)); default: throw new Exception(navExcep.NavExceptionDesc[0]); } } // everything is fine // we have the mapping NAV_CardTypeProvider ret = res.NAV_CardTypeProvider[0]; // let's put values ci.SetNavisionFinancialFlow(ret.FinancialFlow); ci.SetNavisionEnhancedFlow(ret.EnhancedFlow); ci.SetOnlineValidation(ret.OnlineCheck); } finally { if (nws != null) { nws.Dispose(); } } }
public RBSPaymentServiceRequest(UserInfo user, CardInfos card, bool sendZeroAmount) { // Initialisation SetValues(user, card.GetPOS(), card.GetCardNumber(), card.GetExpirationDate(), card.GetHolderName(), card.GetRBSPaymentMethod(), sendZeroAmount); }