protected void configure() { try { config = new CyberSource.Clients.Configuration(); config.KeyFilename = ConfigurationManager.AppSettings["cybs.keyFilename"].ToString(); config.KeysDirectory = Server.MapPath("~/") + "Keys"; config.MerchantID = ConfigurationManager.AppSettings["cybs.merchantID"].ToString(); config.ServerURL = ConfigurationManager.AppSettings["cybs.serverURL"].ToString(); } catch (Exception e) { throw e; } }
/// <summary> /// Sends a CyberSource transaction request. /// </summary> /// <param name="request">XmlDocument object containing the request.</param> /// <param name="config">Configuration object to use.</param> /// <returns>XmlDocument object containing the reply.</returns> public static XmlDocument RunTransaction( Configuration config, XmlDocument request) { Logger logger = null; string nspace = null; try { nspace = GetRequestNamespace(request); DetermineEffectiveMerchantID(ref config, request, nspace); SetVersionInformation(request, nspace); logger = PrepareLog(config); if (string.IsNullOrEmpty(nspace)) { throw new ApplicationException( REQUEST_MESSAGE + " is missing in the XML document."); } SetConnectionLimit(config); if (logger != null) { logger.LogRequest(request, config.Demo); } // obtain a copy of the request document enclosed in a SOAP envelope XmlDocument doc = SoapWrap(request, nspace); //Get the X509 cert and sign the SOAP Body string keyFilePath = Path.Combine(config.KeysDirectory, config.EffectiveKeyFilename); X509Certificate2 cert = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); SignDocument(cert, doc); // convert the document into an array of bytes using the // encoding specified in the XML declaration line. Encoding enc = GetEncoding(doc); byte[] requestBytes = enc.GetBytes(doc.OuterXml); // create an HttpWebRequest object and set its properties HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create( config.EffectiveServerURL); httpRequest.Method = "POST"; httpRequest.ContentLength = requestBytes.Length; httpRequest.UserAgent = ".NET XML"; // set the timeout httpRequest.Timeout = config.Timeout * 1000; if (mProxy != null) { // assign our pre-created WebProxy object to the // HttpWebRequest object's Proxy property. httpRequest.Proxy = mProxy; } // obtain the request stream and write the byte array to it. Stream stream = httpRequest.GetRequestStream(); stream.Write(requestBytes, 0, requestBytes.Length); stream.Close(); // send request and get response. WebResponse webResponse = httpRequest.GetResponse(); // read returned XML document. XmlDocument reply = ReadXml(webResponse); XmlDocument unwrapped = SoapUnwrap(reply, nspace); if (logger != null) { logger.LogReply(unwrapped, config.Demo); } // return the XML document without the SOAP envelope. return (unwrapped); } catch (WebException we) { // if we got HTTP status 500 (Internal Server Error), it could // mean, the server threw a fault, in which case, we load the // xml document from the HTTP body and throw a FaultException. // The status would be ProtocolError if we did get HTTP 500 // and Response should not be null but we check for null just // in case. if (we.Status == WebExceptionStatus.ProtocolError && we.Response != null) { HttpWebResponse response = (HttpWebResponse)we.Response; // InternalServerError corresponds to HTTP 500. And we // proceed only if there's anything in the response body. // That is, the contentLength is greater than zero. if (response.StatusCode == HttpStatusCode.InternalServerError && response.ContentLength > 0) { try { // read the fault document and throw a // FaultException. FaultException fe = new FaultException( ReadXml(response), nspace); if (logger != null) { logger.LogFault(fe.LogString); } throw; } catch (XmlException) { if (logger != null) { logger.LogException(we); } // the response body is not a valid xml document. // It is therefore not a fault. Rethrow the // WebException object. throw; } } } if (logger != null) { logger.LogException(we); } // the server did not throw a fault. Rethrow the WebException // object. throw; } catch (Exception e) { if (logger != null) { logger.LogException(e); } throw; } }
private static void DetermineEffectiveMerchantID( ref Configuration config, XmlDocument request, string nspace) { string requestMerchantID = GetMerchantID(request, nspace); if (config == null) { // let's build a config object on the fly using // the merchantID from the request. An exception will // be thrown if requestMerchantID is null and // no merchantID is found in the config file. config = BuildConfigurationForRequest(requestMerchantID); } if (requestMerchantID == null) { // No merchantID in the request; get it from the config. // NonNullMerchantID will throw an exception if // MerchantID is null. SetMerchantID(request, config.NonNullMerchantID, nspace); } // else, there is a merchantID in the request. // we do not have to do anything. We'll keep whatever // merchantID is in the Configuration object as we do // not own that object. }
/// <summary> /// Sends a CyberSource transaction request. /// </summary> /// <param name="config">Configuration object to use.</param> /// <param name="request">Hashtable containing the request fields and their values.</param> /// <returns>Hashtable containing the reply fields and their values.</returns> public static Hashtable RunTransaction( Configuration config, Hashtable request) { Logger logger=null; NVPTransactionProcessorClient proc=null; try { DetermineEffectiveMerchantID(ref config, request); SetVersionInformation(request); logger = PrepareLog(config); SetConnectionLimit(config); //Setup custom binding with HTTPS + Body Signing CustomBinding currentBinding = getWCFCustomBinding(); //Setup endpoint Address with dns identity AddressHeaderCollection headers = new AddressHeaderCollection(); EndpointAddress endpointAddress = new EndpointAddress(new Uri(config.EffectiveServerURL), EndpointIdentity.CreateDnsIdentity(config.EffectivePassword), headers); //Get instance of service using (proc = new NVPTransactionProcessorClient(currentBinding, endpointAddress)) { //Set protection level to sign only proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign; // set the timeout TimeSpan timeOut = new TimeSpan(0, 0, 0, config.Timeout, 0); currentBinding.SendTimeout = timeOut; string keyFilePath = Path.Combine(config.KeysDirectory, config.EffectiveKeyFilename); proc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); proc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; proc.ClientCredentials.ServiceCertificate.DefaultCertificate = proc.ClientCredentials.ClientCertificate.Certificate; if (logger != null) { logger.LogRequest(request, config.Demo); } // send request now, converting the hashtable request into // a string, and the string reply back into a hashtable. string resp = proc.runTransaction(Hash2String(request)); Hashtable reply = String2Hash(resp); if (logger != null) { logger.LogReply(reply, config.Demo); } return (reply); } } catch (Exception e) { if (logger != null) { logger.LogException(e); } if (proc != null) { proc.Abort(); } throw; } finally { if (proc != null) { proc.Close(); } } }
/// <summary> /// Sends a CyberSource transaction request. /// </summary> /// <param name="config">Configuration object to use.</param> /// <param name="requestMessage">RequestMessage object containing the request.</param> /// <returns>ReplyMessage containing the reply.</returns> public static ReplyMessage RunTransaction( Configuration config, RequestMessage requestMessage) { Logger logger = null; TransactionProcessorClient proc = null; try { DetermineEffectiveMerchantID(ref config, requestMessage); SetVersionInformation(requestMessage); logger = PrepareLog(config); SetConnectionLimit(config); CustomBinding currentBinding = getWCFCustomBinding(); //Setup endpoint Address with dns identity AddressHeaderCollection headers = new AddressHeaderCollection(); EndpointAddress endpointAddress = new EndpointAddress( new Uri(config.EffectiveServerURL), EndpointIdentity.CreateDnsIdentity(config.EffectivePassword), headers ); //Get instance of service using( proc = new TransactionProcessorClient(currentBinding, endpointAddress)){ //Set protection level to sign only proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign; // set the timeout TimeSpan timeOut = new TimeSpan(0, 0, 0, config.Timeout, 0); currentBinding.SendTimeout = timeOut; //add certificate credentials string keyFilePath = Path.Combine(config.KeysDirectory,config.EffectiveKeyFilename); proc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(keyFilePath,config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); proc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; // Changes for SHA2 certificates support X509Certificate2Collection collection = new X509Certificate2Collection(); collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); foreach (X509Certificate2 cert1 in collection) { if (cert1.Subject.Contains(config.MerchantID)) { proc.ClientCredentials.ClientCertificate.Certificate = cert1; proc.ClientCredentials.ServiceCertificate.DefaultCertificate = cert1; break; } } // send request now // Changes for NGT-3035 XmlNode req = SerializeObjectToXmlNode(requestMessage); if (logger != null) { logger.LogRequest(req, config.Demo); } ReplyMessage reply = proc.runTransaction(requestMessage); XmlNode rep = SerializeObjectToXmlNode(reply); if (logger != null) { logger.LogReply(rep, config.Demo); } return (reply); } } catch (Exception e) { if (logger != null) { logger.LogException(e); } if (proc != null) { proc.Abort(); } throw; } finally { if (proc != null) { proc.Close(); } } }
/// <summary> /// Sets the ConnectionLimit of the ServicePoint object for the /// URL in the Configuration object. /// </summary> /// <param name="config"> /// Configuration object containing the URL and the connection /// limit. /// </param> protected static void SetConnectionLimit(Configuration config) { if (config.ConnectionLimit != -1) { Uri uri = new Uri(config.EffectiveServerURL); ServicePoint sp = ServicePointManager.FindServicePoint(uri); sp.ConnectionLimit = config.ConnectionLimit; } }
/// <summary> /// Prepares the log file and logs transaction-start stuff /// if logging is enabled. Otherwise, it does nothing. /// </summary> /// <param name="config"> /// Configuration object for the current transaction.</param> /// <returns> /// the Logger object if logging is enabled. Returns null /// otherwise. /// </returns> protected static Logger PrepareLog(Configuration config) { Logger logger = null; if (config.EnableLog) { logger = Logger.GetInstance( config.LogDirectory, config.LogFilename, config.LogMaximumSize); if (logger != null) { logger.LogTransactionStart(config.LogString); } } return (logger); }
/// <summary> /// Builds a Configuration object using settings from the /// appsettings section of the application/web config file. /// </summary> /// <param name="merchantID"> /// If not null, this method will get the settings specific to /// this merchant id. /// </param> /// <param name="failIfNoMerchantID"> /// If set to true, an ApplicationException will be thrown if /// merchantID is null and there is no merchantID in the /// appsettings, either. /// </param> /// <returns>the built Configuration object</returns> private static Configuration InternalBuildConfiguration( string merchantID, bool failIfNoMerchantID ) { Configuration config = new Configuration(); if (merchantID == null) { merchantID = AppSettings.GetSetting( null, MERCHANT_ID ); } if (merchantID != null || failIfNoMerchantID) { // if merchantID is null, the assignment below will // throw an exception. config.MerchantID = merchantID; } string keysDirectory = AppSettings.GetSetting( merchantID, Configuration.KEYS_DIRECTORY); if (keysDirectory != null) { config.KeysDirectory = keysDirectory; } else { // look for "keysDir" for backwards-compatibility config.KeysDirectory = AppSettings.GetSetting( merchantID, Configuration.KEYS_DIR); } int boolVal = AppSettings.GetBoolSetting( merchantID, Configuration.SEND_TO_PRODUCTION); if (boolVal != -1) config.SendToProduction = (boolVal == 1); boolVal = AppSettings.GetBoolSetting( merchantID, Configuration.ENABLE_LOG); config.setLogProperties( boolVal == 1, AppSettings.GetSetting( merchantID, Configuration.LOG_DIRECTORY) ); config.ServerURL = AppSettings.GetSetting( merchantID, Configuration.SERVER_URL); if (config.ServerURL == null) { // look for "cybersourceURL" for backwards-compatibility config.ServerURL = AppSettings.GetSetting( merchantID, Configuration.CYBERSOURCE_URL); } config.KeyFilename = AppSettings.GetSetting( merchantID, Configuration.KEY_FILENAME); config.Password = AppSettings.GetSetting( merchantID, Configuration.PASSWORD); config.LogFilename = AppSettings.GetSetting( merchantID, Configuration.LOG_FILENAME); config.LogMaximumSize = AppSettings.GetIntSetting( merchantID, Configuration.LOG_MAXIMUM_SIZE); config.Timeout = AppSettings.GetIntSetting( merchantID, Configuration.TIMEOUT); boolVal = AppSettings.GetBoolSetting( merchantID, Configuration.DEMO); if (boolVal != -1) config.Demo = (boolVal == 1); config.ConnectionLimit = AppSettings.GetIntSetting( merchantID, Configuration.CONNECTION_LIMIT); return (config); }