Ошибка API отчетности Sagepay Не удалось проверить значение <signature>

Я очень новичок в.Net и мне нужна помощь, так что, пожалуйста, не обращайте внимания. Я пытаюсь создать бэк-офисную систему с интеграцией с sagepay, используя администратор sagepay и API отчетности. Я нашел пример кода в Интернете, который был очень полезен, однако я получаю вышеуказанную ошибку, когда пытаюсь вызвать API. Вот пример кода ниже, который делает вызов. Мне было интересно, если кто-то может показать мне, где я иду не так?

       private string BuildCommandString(string command, string vendor, string user, string xmldata, string password = null, string signature = null)
    {
        return string.Format("<command>{0}</command><vendor>{1}</vendor><user>{2}</user>{3}{4}{5}",
            command,
            Vendor,
            User,
            xmldata ?? string.Empty,
            (string.IsNullOrEmpty(password) == false ? "<password>" + password + "</password>" : string.Empty),
            (string.IsNullOrEmpty(signature) == false ? "<signature>" + signature + "</signature>" : string.Empty));
    }

    /// <summary>
    /// Perform the main call for the API and collect the response
    /// </summary>
    /// <param name="command">api command name</param>
    /// <param name="xmldata">optional extra data for api</param>
    /// <returns>new SagePayResponse or null if communication error</returns>
    protected SagePayResponse ProcessAPI(string command, string xmldata)
    {
        // get the requiest
        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Url);
        httpRequest.Method = "POST";

        // build data
        string data = BuildCommandString(command, Vendor, User, xmldata, Password);
        // apply signature
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(data));
        string sig = BitConverter.ToString(hash).Replace("-", string.Empty);

        // rebuild with signature
        data = "XML=<vspaccess>" + BuildCommandString(command, Vendor, User, xmldata, null, sig) + "</vspaccess>";

        // get the data
        byte[] bytes = Encoding.UTF8.GetBytes(data);
        httpRequest.ContentType = "application/x-www-form-urlencoded";
        httpRequest.ContentLength = data.Length;

        // get the request stream
        Stream requestStream = httpRequest.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.Length);
        requestStream.Close();

        // call the sagepay url and get response
        SagePayResponse sagePayResponse = null;
        HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
        try
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                Stream responseStream = response.GetResponseStream();
                //string contentType = response.ContentType;
                StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
                try
                {
                    //Console.WriteLine("response ok");
                    sagePayResponse = new SagePayResponse(reader.ReadToEnd());
                }
                finally
                {
                    reader.Close();
                }
            }
        }
        finally
        {
            response.Close();
        }

        return sagePayResponse;
    }

2 ответа

@ Mandar Jogalekar Надеюсь, это поможет

protected class SagePayResponse
    {
        /// <summary>
        /// Raw xml response object
        /// </summary>
        private XmlDocument m_responseXml;

        /// <summary>
        /// Create a new response object from the xml string
        /// </summary>
        /// <param name="responseXml"></param>
        public SagePayResponse(string responseXml)
        {
            // create our xml doc
            m_responseXml = new XmlDocument();
            m_responseXml.LoadXml(responseXml);

            // find an error node
            XmlNode node = m_responseXml.SelectSingleNode("//vspaccess/errorcode");
            int errorCode = 0;
            if (node != null && int.TryParse(node.InnerText, out errorCode) == true && errorCode != 0)
            {
                // there was an error and we have a non-zero error code
                ErrorCode = errorCode;
            }
            // pick out any error description
            node = m_responseXml.SelectSingleNode("//vspaccess/error");
            if (node != null && node.InnerText.Length != 0)
            {
                ErrorText = node.InnerText;
            }
            // pick out the timestamp
            node = m_responseXml.SelectSingleNode("//vspaccess/timestamp");
            if (node != null && node.InnerText.Length != 0)
            {
                DateTime dt;
                if (DateTime.TryParseExact(node.InnerText, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt) == true)
                {
                    Timestamp = DateTime.SpecifyKind(dt, DateTimeKind.Utc).ToLocalTime();
                }
            }
        }

Если другим нужна помощь по SagePay Reporting & Admin API, вы можете найти пакет NuGet здесь:

https://www.nuget.org/packages/Joe.Opayo.Admin.Api.Client/1.1.0

Клиентское приложение позволяет использовать такой код:

      var client = new OpayoAdminApiClient();
var isTest = true;
var request = new OpayoApiRequest(ApiCommandType.GetTransactionDetail, "password", isTest, "user-name", "vendor-name");
var commandSpecificXml = "<vendortxcode>01Jan2010Transaction12345</vendortxcode>"; 
return await client.ProcessApiCommandAsync<TransactionDetail>(request, commandSpecificXml);
Другие вопросы по тегам