/// <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 = null; X509Certificate2Collection collection = new X509Certificate2Collection(); collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); foreach (X509Certificate2 cert1 in collection) { if (cert1.Subject.Contains(config.MerchantID)) { cert = cert1; break; } } 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; } }
/// <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 HandleFaultException( FaultException fe, string cybsNamespace ) { string template = GetTemplate( "ERROR" ); /* * The string returned in this sample is mostly to demonstrate * how to retrieve the exception properties. Your application * should display user-friendly messages. */ string content = String.Format( "\nA fault exception was returned with fault code " + "'{0}' and message '{1}'.", fe.Code, fe.Message ); Console.WriteLine( template, content ); if (fe.Code.Namespace.Equals( cybsNamespace ) && fe.Code.Name.Equals( "CriticalServerError" )) { /* * The transaction may have been completed by CyberSource. * If your request included a payment service, you should * notify the appropriate department in your company (e.g. by * sending an email) so that they can confirm if the request * did in fact complete by searching the CyberSource Support * Screens using the request id. * * The line below demonstrates how to retrieve the request id. */ Console.WriteLine( fe.RequestID ); } }