HMAC 验证失败,代码为 403
HMAC validation Failure with code 403
过去三天我一直在探索 payeezy api。我只是从 C# 应用程序发出一个简单的 http web 请求。我已经按照提到的所有步骤进行操作,并正确地验证了每一个步骤。以下是每个项目的详细信息。
- API 密钥 :- 我已经验证了我的 api 密钥是正确的。
- API 秘密 :- 这也是正确的。
- 商户代币 :- 也经过验证。
Nonce :- 我已经创建了加密强随机数,如下所示。
RandomNumberGenerator rng = new RNGCryptoServiceProvider();
byte[] nonceData = new byte[18];
rng.GetBytes(nonceData);
string nonce = BitConverter.ToUInt64(nonceData,0).ToString();
时间戳:-
string timestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
有效负载:-
{"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"}}
然后我创建了如下 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);
}
}
- 现在我收到 hmac 验证错误。我生成的 hmac 字符串是 64 位的,而在您的网站上的文档和沙箱下是 86 位的。
你能帮我解决这个问题吗,因为我在过去三天一直被困在这个问题上。
谢谢
这些是“HMAC 验证失败”的常见原因:
- API 密钥 and/or API 密钥不正确。
- API 密钥、API 秘密、商家令牌中的前导或尾随空格。
- HTTP header 中的时间戳不是以毫秒为单位。
- HTTP header 中的时间戳不代表 EPOCH 时间。
- HTTP header 中的时间戳不在我们服务器时间的 5 分钟内。
- 系统时间不准确。
这是生成 HMAC 的示例 C# 代码:
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;
}
}
}
}
}
我一直在进行集成,效果很好;也许你可以看一看
https://github.com/clifton-io/Clifton.Payment
祝你好运:)
过去三天我一直在探索 payeezy api。我只是从 C# 应用程序发出一个简单的 http web 请求。我已经按照提到的所有步骤进行操作,并正确地验证了每一个步骤。以下是每个项目的详细信息。
- API 密钥 :- 我已经验证了我的 api 密钥是正确的。
- API 秘密 :- 这也是正确的。
- 商户代币 :- 也经过验证。
Nonce :- 我已经创建了加密强随机数,如下所示。
RandomNumberGenerator rng = new RNGCryptoServiceProvider(); byte[] nonceData = new byte[18]; rng.GetBytes(nonceData); string nonce = BitConverter.ToUInt64(nonceData,0).ToString();
时间戳:-
string timestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
有效负载:-
{"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"}}
然后我创建了如下 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); } }
- 现在我收到 hmac 验证错误。我生成的 hmac 字符串是 64 位的,而在您的网站上的文档和沙箱下是 86 位的。
你能帮我解决这个问题吗,因为我在过去三天一直被困在这个问题上。 谢谢
这些是“HMAC 验证失败”的常见原因:
- API 密钥 and/or API 密钥不正确。
- API 密钥、API 秘密、商家令牌中的前导或尾随空格。
- HTTP header 中的时间戳不是以毫秒为单位。
- HTTP header 中的时间戳不代表 EPOCH 时间。
- HTTP header 中的时间戳不在我们服务器时间的 5 分钟内。
- 系统时间不准确。
这是生成 HMAC 的示例 C# 代码:
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;
}
}
}
}
}
我一直在进行集成,效果很好;也许你可以看一看 https://github.com/clifton-io/Clifton.Payment
祝你好运:)