Common parameters are required whatever API is called.
Name | Type | Mandatory/Optional | Description |
---|---|---|---|
method | String | M | API name |
app_key | String | M | Assigned by TOP |
session | String | M | Access token authorized by shop owner |
timestamp | String | M | Format is "yyyy-MM-dd HH:mm:ss" with timezone of GMT+8. The maximum time difference cannot exceed 10 minutes between client and TOP server. |
format | String | O | Response format with xml as default. Optional value:xml,json. |
v | String | M | API version with 2.0 as default. |
sign_method | String | M | Signature Algorithm, Optional value:hmac,md5. |
sign | String | M | Signature of API request parameters. |
Business parameters are defined for every API method. Please refer API description for details.
In order to prevent requests be maliciously tampered by hackers, every request has to be signed digitally. TOP server will validate the request and signature. The request with illegal signature will be rejected. Two signature methods are supported: MD5(sign_method=md5), HMAC_MD5(sign_method=hmac).
Signature workflow
before sort: foo=1, bar=2, foo_bar=3, foobar=4 after sort: bar=2, foo=1, foo_bar=3, foobar=4
bar2foo1foo_bar3foobar4
md5: md5(appsecretbar2foo1foo_bar3foobar4appsecret)
hmac_md5: hmac_md5(md5(appsecretbar2foo1foo_bar3foobar4appsecret))
hex("digest".getBytes("utf-8"))
Java
public static String signTopRequest(Map<String, String> params, String secret, String signMethod) throws IOException { // Step1: Sort String[] keys = params.keySet().toArray(new String[0]); Arrays.sort(keys); // Step2: Assemble StringBuilder query = new StringBuilder(); if (Constants.SIGN_METHOD_MD5.equals(signMethod)) { query.append(secret); } for (String key : keys) { String value = params.get(key); if (StringUtils.areNotEmpty(key, value)) { query.append(key).append(value); } } // Step3: Sign MD5/HMAC byte[] bytes; if (Constants.SIGN_METHOD_HMAC.equals(signMethod)) { bytes = encryptHMAC(query.toString(), secret); } else { query.append(secret); bytes = encryptMD5(query.toString()); } // Step4: Convert to Hex return byte2hex(bytes); } public static byte[] encryptHMAC(String data, String secret) throws IOException { byte[] bytes = null; try { SecretKey secretKey = new SecretKeySpec(secret.getBytes(Constants.CHARSET_UTF8), "HmacMD5"); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); bytes = mac.doFinal(data.getBytes(Constants.CHARSET_UTF8)); } catch (GeneralSecurityException gse) { throw new IOException(gse.toString()); } return bytes; } public static byte[] encryptMD5(String data) throws IOException { return encryptMD5(data.getBytes(Constants.CHARSET_UTF8)); } public static String byte2hex(byte[] bytes) { StringBuilder sign = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { sign.append("0"); } sign.append(hex.toUpperCase()); } return sign.toString(); }
.Net
public static string SignTopRequest(IDictionary<string, string> parameters, string secret, string signMethod) { // Step1: Sort IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters, StringComparer.Ordinal); IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator(); // Step2: Assemble StringBuilder query = new StringBuilder(); if (Constants.SIGN_METHOD_MD5.Equals(signMethod)) { query.Append(secret); } while (dem.MoveNext()) { string key = dem.Current.Key; string value = dem.Current.Value; if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) { query.Append(key).Append(value); } } // Step3. Sign MD5/HMAC byte[] bytes; if (Constants.SIGN_METHOD_HMAC.Equals(signMethod)) { HMACMD5 hmac = new HMACMD5(Encoding.UTF8.GetBytes(secret)); bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString())); } else { query.Append(secret); MD5 md5 = MD5.Create(); bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString())); } // Step4. Convert to Hex StringBuilder result = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { result.Append(bytes[i].ToString("X2")); } return result.ToString(); }
More signature demos for other programming language can be found in SDK source code provided by TOP.
Common parameters
> method = "taobao.xhotel.update" > app_key = "12345678" > session = "test" > timestamp = "2016-01-01 12:00:00" > format = "json" > v = "2.0" > sign_method = "md5"
Business parameters
> outer_id = "GJ001" > name = "GJ001"
> app_key = "12345678" > format = "json" > method = "taobao.xhotel.update" > name = "GJ001" > outer_id = "GJ001" > session = "test" > sign_method = "md5" > timestamp = "2016-01-01 12:00:00" > v = "2.0"
app_key12345678formatjsonmethodtaobao.xhotel.updateGJ001outer_idGJ001sessiontestsign_methodmd5timestamp2016-01-01 12:00:00v2.0
Assume that appSecret value is “hotel”
md5(<font color='red'>hotel</font>app_key12345678formatjsonmethodtaobao.xhotel.updateGJ001outer_idGJ001sessiontestsign_methodmd5timestamp2016-01-01 12:00:00v2.0<font color='red'>hotel</font>)
Encode all the parameter name and value using UTF-8 format and send out a HTTP request through GET/POST. The order of parameters can be arbitrary.
http://gw.api.taobao.com/router/rest?method=taobao.xhotel.update&app_key=12345678&session=test×tamp=2016-01-01+12%3a00%3a00&format=json&v=2.0&sign_method=md5&outer_id=GJ001&name=GJ001&sign=66987CB115214E59E6EC978214934FB8