Example #1
0
 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);
        }