Ошибка проверки HMAC с кодом 403

Я изучаю payeezy api последние три дня. Я просто делаю простой веб-запрос http из приложения С#. Я выполнил все упомянутые шаги и правильно проверил все и все. Ниже подробная информация по каждому пункту.

  1. Ключ API: - Я проверил правильность своего ключа API.
  2. Секрет API: - Это тоже правильно.
  3. токен продавца: - Он также проверен.
  4. Nonce: - Я создал криптографически стойкое случайное число следующим образом.

    RandomNumberGenerator rng = new RNGCryptoServiceProvider();
    byte[] nonceData = new byte[18];
    rng.GetBytes(nonceData);
    string nonce = BitConverter.ToUInt64(nonceData,0).ToString();  
    
  5. Отметка времени: -

    string timestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
    
  6. Полезная нагрузка: -

    {"merchant_ref":"Astonishing-Sale","transaction_type":"authorize","method":"credit_card","amount":"1299","currency_code":"USD","credit_card":{"type":"visa","cardholder_name":"John Smith","card_number":"4788250000028291","exp_date":"1020","cvv":"123"}}
    
  7. Затем я создал HMAC следующим образом.

    private string CreateAuthorization(string data, string secret)
    {
        // data is in following format.
        //  data = apiKey + nonce + timestamp + token + payload;
        secret = secret ?? "";
        using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
        {
            byte[] hashdata = hmacsha256.ComputeHash(Encoding.UTF32.GetBytes(data));
            return Convert.ToBase64String(hashdata);
        }
    }
    
  8. Теперь я получаю ошибку проверки hmac. Моя сгенерированная строка hmac 64-битная, а на вашем веб-сайте в документах и ​​песочнице - 86-битная.

Не могли бы вы помочь мне в этом, так как я застрял в этом вопросе за последние три дня. Спасибо


person Abdul Ghaffar    schedule 07.08.2015    source источник


Ответы (2)


Вот распространенные причины ошибки проверки HMAC:

  1. Ключ API и/или секрет API неверны.
  2. Начальные или конечные пробелы в ключе API, секрете API, токене продавца.
  3. Временная метка в заголовке HTTP не указана в миллисекундах.
  4. Отметка времени в заголовке HTTP не представляет время EPOCH.
  5. Временная метка в заголовке HTTP отличается от времени нашего сервера на 5 минут.
  6. Системное время не точное.

Вот пример кода C# для генерации HMAC:

public byte[] CalculateHMAC(string data, string secret)
    {
        HMAC hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);
        byte[] hmac2Hex = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(data));

        string hex = BitConverter.ToString(hmac2Hex);
        hex = hex.Replace("-","").ToLower();
        byte[] hexArray = Encoding.UTF8.GetBytes(hex);
        return hexArray;
    }

protected void Button1_Click(object sender, EventArgs e)
{                     
    string jsonString = "{ \"merchant_ref\": \"MVC Test\", \"transaction_type\": \"authorize\", \"method\": \"credit_card\", \"amount\": \"1299\", \"currency_code\": \"USD\", \"credit_card\": { \"type\": \"visa\", \"cardholder_name\": \"Test Name\", \"card_number\": \"4005519200000004\", \"exp_date\": \"1020\", \"cvv\": \"123\" } }";

    Random random = new Random();
    string nonce = (random.Next(0, 1000000)).ToString();

    DateTime date = DateTime.UtcNow;
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    TimeSpan span = (date - epoch);
    string time = span.TotalSeconds.ToString();

    string token = Request.Form["token"];//Merchant token
    string apiKey = Request.Form["apikey"];//apikey
    string apiSecret = Request.Form["apisecret"];//API secret
    string hashData = apiKey+nonce+time+token+jsonString;

    string base64Hash = Convert.ToBase64String(CalculateHMAC(hashData, apiSecret));

    string url = "https://api-cert.payeezy.com/v1/transactions";

    //begin HttpWebRequest
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);

    webRequest.Method = "POST";
    webRequest.Accept = "*/*";
    webRequest.Headers.Add("timestamp", time);
    webRequest.Headers.Add("nonce", nonce);
    webRequest.Headers.Add("token", token);
    webRequest.Headers.Add("apikey", apiKey);
    webRequest.Headers.Add("Authorization", base64Hash );
    webRequest.ContentLength = jsonString.Length;
    webRequest.ContentType = "application/json";

    StreamWriter writer = null;
    writer = new StreamWriter(webRequest.GetRequestStream());
    writer.Write(jsonString);
    writer.Close();

    string responseString;
    try
        {
            using(HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
                {
                    responseString = responseStream.ReadToEnd();
                    request_label.Text = "<h3>Request</h3><br />" + webRequest.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(jsonString);
                    response_label.Text = "<h3>Response</h3><br />" + webResponse.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(responseString);
                }
            }
        }
    catch (WebException ex)
    {
        if (ex.Response != null) 
        {
            using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response) 
            {
                using (StreamReader reader = new StreamReader(errorResponse.GetResponseStream())) 
                {
                    string remoteEx = reader.ReadToEnd();
                    error.Text = remoteEx;
                }
            }
        }           
    }
}
person Rohit    schedule 07.08.2015
comment
Я скопировал ваш код и ввел только свои значения для токена, apiKey и apiSecret, но все равно получаю ошибку проверки HMAC :( - person Abdul Ghaffar; 07.08.2015
comment
Я сравнил общее количество миллисекунд с веб-сайта Payeezy и то, которое я генерирую. Ниже приведены итоги. 1) Payeezy: 1439268787215 2) Мой: 1439268783429 Небольшая разница связана со временем, прошедшим при копировании с сайта VS и Payeezy. - person Abdul Ghaffar; 11.08.2015

Я работаю над интеграцией, и она отлично работает; возможно, вы можете заглянуть https://github.com/clifton-io/Clifton.Payment

В частности, вам нужно посмотреть здесь: https://github.com/clifton-io/Clifton.Payment/blob/cc4053b0bfe05f2453dc508e96a649fc138b973c/Clifton.Payment/Gateway/Payeezy/PayeezyGateway.cs#L66

Удачи :)

person Brian Clifton    schedule 16.08.2015