Signing Requests
Signing Requests
All operations are secured with an HMAC-SHA256 one-way hash that is performed using a shared secret key between Zip and the merchant. This secret key will be provided to you.
Signatures are generated based on the request type.
- POST JSON Requests sign the entire request body contents.
- POST Form Requests sign all the keys + values contained in the form request in alphabetical order except for the signature.
- GET Requests sign all the keys + values contained in the query string in alphabetical order except for the signature.
The header or query parameter name is always X-QP-Signature
Implementing this is language specific. Here are examples that can generate these hashes for you:
public class HmacSha256Signature
{
private static Encoding encoding = Encoding.UTF8;
/// If your entire request body is passed in as bytes (e.g. POST JSON request), this will give you the correct hash
public string Compute(string secretKey, byte[] bytes)
{
using (var hmacsha256 = new HMACSHA256(encoding.GetBytes(secretKey)))
{
var hash = hmacsha256.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
}
/// Given a dictionary that contains all the values from a GET or form POST request, this will return your correct hash
public string Compute(string secretKey, IDictionary<string, string> values)
{
var builder = new StringBuilder();
// Form Keys Sorted Alphabetically
foreach (var item in values.OrderBy(i => i.Key))
{
if (!item.Key.Equals(Constants.SignatureKey, StringComparison.OrdinalIgnoreCase))
{
builder.Append(item.Key);
builder.Append(item.Value);
}
}
var message = builder.ToString();
return this.Compute(secretKey, encoding.GetBytes(message));
}
public string Compute(string secretKey, string json)
{
var bytes = encoding.GetBytes(json);
return this.Compute(secretKey, bytes);
}
/// This can take any object and turn it into a dictionary to be used for hash creation
public IDictionary<string, string> GenerateKeyValues(object model)
{
var jsonObject = JObject.FromObject(model, JsonSerializer.Create(Constants.KeyGenSerializerSettings));
var jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
var keyValues = jTokens.Aggregate(
new Dictionary<string, string>(),
(
properties,
jToken) =>
{
properties.Add(jToken.Path, jToken.ToString());
return properties;
});
return keyValues;
}
}
$signature = base64_encode(hash_hmac('sha256', $data, $secret, true));
Updated over 1 year ago