亚马逊MWS 端点及 MarketplaceId 值
使用NextToken请求更多页面
使用亚马逊MWS客户端库【签名及请求方式】
订单ListOrders
官方提供的工具类
import java.io.UnsupportedEncodingException;
import java.URI;
import java.URISyntaxException;
import java.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apachemons.codec.binary.Base64;
/* 官方提供的参数格式化 */
private static String calculateStringToSignV2(Map<String, String> parameters, String serviceUrl) throws SignatureException, URISyntaxException {
// Sort the parameters alphabetically by storing in TreeMap structure
Map<String, String> sorted = new TreeMap<String, String>();
sorted.putAll(parameters);
// Set endpoint value
URI endpoint = new URI(serviceUrl.toLowerCase());
// Create flattened (String) representation
StringBuilder data = new StringBuilder();
data.append("GET\n");// *这里用GET方式
data.append(endpoint.getHost());
data.append("\n/Orders/2013-09-01");// *这里需要调整
data.append("\n");
Iterator<Entry<String, String>> pairs = sorted.entrySet().iterator();
while (pairs.hasNext()) {
Map.Entry<String, String> pair = pairs.next();
if (pair.getValue() != null) {
data.append(pair.getKey() + "=" + pair.getValue());
} else {
data.append(pair.getKey() + "=");
}
// Delimit parameters with ampersand (&)
if (pairs.hasNext()) {
data.append("&");
}
}
return data.toString();
}
/* 官方提供的用给定的密钥对文本签名并转换为base64 */
private static String sign(String data, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException, IllegalStateException, UnsupportedEncodingException {
String CHARACTER_ENCODING = "UTF-8";
String ALGORITHM = "HmacSHA256";
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(secretKey.getBytes(CHARACTER_ENCODING), ALGORITHM));
byte[] signature = mac.doFinal(data.getBytes(CHARACTER_ENCODING));
String signatureBase64 = new String(Base64.encodeBase64(signature), CHARACTER_ENCODING);
return new String(signatureBase64);
}
/* 官方提供的URL编码方式 */
private static String urlEncode(String rawValue) {
String value = (rawValue == null) ? "" : rawValue;
String encoded = null;
try {
encoded = URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
} catch (UnsupportedEncodingException e) {
System.err.println("Unknown encoding: " + "UTF-8");
e.printStackTrace();
}
return encoded;
}
/* 拼接请求参数 */
public static String splicing(String baseUrl, final Map<?, ?> values) {
StringBuilder stringBUilder = new StringBuilder();
stringBUilder.append(baseUrl);
if (!values.isEmpty()) {
for (Entry<?, ?> entry : values.entrySet()) {
String name = entry.getKey().toString();
String value = entry.getValue().toString();
stringBUilder.append(name).append("=").append(value).append("&");
}
}
return stringBUilder.deleteCharAt(stringBUilder.length() - 1).toString();
}
以ListOrders为例:
// Change this secret key to yours
String secretKey = "Your secret key";
// Use the endpoint for your marketplace 理论上同一地区的任意端点对应所有的marketplace
String serviceUrl = "https://mws.amazonservices.jp/Orders/2013-09-01?";
String MarketplaceId = "A1VC38T7YXB528";
// Create set of parameters needed and store in a map
TreeMap<String, String> parameters = new TreeMap<>();
// Add required parameters. Change these as needed.
parameters.put("AWSAccessKeyId", "Your Access Key Id");
parameters.put("Action", "ListOrders");
parameters.put("MWSAuthToken", "Your MWS Auth Token");
parameters.put("SellerId", "Your Seller Id");
parameters.put("MarketplaceId.Id.1", MarketplaceId);// 这个值会有多个,循环单个处理即可
// 以下两个条件二选一
parameters.put("CreatedAfter", "2020-10-31T16:00:00.000Z");// 该日期之后创建的订单
// parameters.put("LastUpdatedAfter", "2020-10-31T16:00:00.000Z");该日期之后更新的订单
/***********************************************************/
/* 下面这些参数是公共的 */
parameters.put("SignatureMethod", "HmacSHA256");
parameters.put("SignatureVersion", "2");
// parameters.put("SubmittedFromDate","2013-05-01T12:00:00Z");不知道这个是干啥的,可以不要
parameters.put("Timestamp", "2013-05-02T16:00:00Z");
parameters.put("Version", "2013-09-01");
for (Map.Entry<String, String> entry : parameters.entrySet()) {
parameters.put(entry.getKey(), urlEncode(entry.getValue()));
}
// Format the parameters as they will appear in final format (without the signature parameter)
// 不含签名的参数格式化
String formattedParameters = calculateStringToSignV2(parameters, serviceUrl);
String signature = sign(formattedParameters, secretKey);
// Add signature to the parameters and display final results
parameters.put("Signature", urlEncode(signature));
System.out.println(calculateStringToSignV2(parameters, serviceUrl));// 含签名的参数格式化,可忽略
/*
显示成这个样子:
GET
mws.amazonservices.jp
/Orders/2013-09-01
AWSAccessKeyId=0PExampleR2&Action=ListOrders&CreatedAfter=2020-08-31T16%3A00%3A00.000Z&MWSAuthToken=amzn.mws.4ea38b7b-f563-7709-4bae-87aeaEXAMPLE&MarketplaceId.Id.1=A1VC38T7YXB528&SellerId=A1ExampleE6&Signature=65HWoPRfzMGEX98YSb4F6A9hPBMg6p7HR%2FsWcHc5n1A%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-09-12T12%3A21%3A35Z&Version=2013-09-01
*/
String url = splicing(serviceUrl, parameters);// 拼接好的url
System.out.println(url);
// https://mws.amazonservices.jp/Orders/2013-09-01?AWSAccessKeyId=0PExampleR2&Action=ListOrders&CreatedAfter=2020-08-31T16%3A00%3A00.000Z&MWSAuthToken=amzn.mws.4ea38b7b-f563-7709-4bae-87aeaEXAMPLE&MarketplaceId.Id.1=A1VC38T7YXB528&SellerId=A1ExampleE6&Signature=65HWoPRfzMGEX98YSb4F6A9hPBMg6p7HR%2FsWcHc5n1A%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-09-12T12%3A21%3A35Z&Version=2013-09-01
说明:url请求返回的数据大概就是下面这个样子的
<ListOrdersResponse xmlns="https://mws.amazonservices/Orders/2013-09-01">
<ListOrdersResult>
<NextToken>
muBa1ynLH9aaJqJYLDm0ZAmQW6clShhM+A==
</NextToken>
<Orders>...</Orders>
<CreatedBefore>2020-10-13T03:06:19.995Z</CreatedBefore>
</ListOrdersResult>
<ResponseMetadata>
<RequestId>6778775f-52f3-4690-8965-e97165e2468f</RequestId>
</ResponseMetadata>
</ListOrdersResponse>
1.Orders下面有一个或多个Order,转json后,就是Map或List
2.NextToken只有在有下一页的时候才有
ListOrdersByNextToken:使用 NextToken 参数返回下一页订单
String secretKey = "Your secret key";
String serviceUrl = "https://mws.amazonservices.jp/Orders/2013-09-01?";
String MarketplaceId = "A1VC38T7YXB528";
TreeMap<String, String> parameters = new TreeMap<>();
parameters.put("AWSAccessKeyId", "Your Access Key Id");
parameters.put("Action", "ListOrdersByNextToken");
parameters.put("MWSAuthToken", "Your MWS Auth Token");
parameters.put("SellerId", "Your Seller Id");
// parameters.put("MarketplaceId.Id.1", MarketplaceId);// 可有可无最好去掉
// parameters.put("CreatedAfter", "2020-10-31T16:00:00.000Z");// 可有可无最好去掉
parameters.put("NextToken", "muBa1ynLH9aaJqJYLDm0ZAmQW6clShhM+A=="); // 必填
/***********************************************************/
返回结果如下,同样的NextToken只有在有下一页的时候才有
<ListOrdersByNextTokenResponse xmlns="https://mws.amazonservices/Orders/2013-09-01">
<ListOrdersByNextTokenResult>
<NextToken>
muBa1ynLH9aaJqJYLDm0ZAmQazDrhw3CtUlSsPW6clShhM+A==
</NextToken>
<Orders>...</Orders>
<CreatedBefore>2020-10-13T03:06:19.995Z</CreatedBefore>
</ListOrdersByNextTokenResult>
<ResponseMetadata>
<RequestId>279c6d5d-8035-4272-bfb6-8731550572b7</RequestId>
</ResponseMetadata>
</ListOrdersByNextTokenResponse>
ListOrderItems:根据您指定的 AmazonOrderId 返回订单商品
String secretKey = "Your secret key";
String serviceUrl = "https://mws.amazonservices.jp/Orders/2013-09-01?";
String MarketplaceId = "A1VC38T7YXB528";
TreeMap<String, String> parameters = new TreeMap<>();
parameters.put("AWSAccessKeyId", "Your Access Key Id");
parameters.put("Action", "ListOrderItems");
parameters.put("MWSAuthToken", "Your MWS Auth Token");
parameters.put("SellerId", "Your Seller Id");
// parameters.put("MarketplaceId.Id.1", MarketplaceId);// 可有可无最好去掉
// parameters.put("CreatedAfter", "2020-10-31T16:00:00.000Z");// 可有可无最好去掉
parameters.put("AmazonOrderId", "订单id");// 必填
/***********************************************************/
返回结果如下,同样的NextToken只有在有下一页的时候才有,OrderItems下有一个或多个OrderItem
<ListOrderItemsResponse xmlns="https://mws.amazonservices/Orders/2013-09-01">
<ListOrderItemsResult>
<NextToken>MRgZW55IGNhcm5hbCBwbGVhc3VyZS6=</NextToken>
<AmazonOrderId>150-2856065-2281615</AmazonOrderId>
<OrderItems>...</OrderItems>
</ListOrderItemsResult>
<ResponseMetadata>
<RequestId>ae3474bc-5392-4f6f-a513-d3f91e2e4aed</RequestId>
</ResponseMetadata>
</ListOrderItemsResponse>
对于下一页的订单商品ListOrderItemsByNextToken,使用方式和订单一样,一个订单下的商品多到分页并不常见。
根据您指定的 AmazonOrderId 值返回订单GetOrder,使用方式和订单一样。
看一下官方对时间戳的介绍:在请求中使用的时戳(或过期时间)必须是 dateTime 对象。时戳最好采用国际标准时间(即格林尼治时间)时区格式,例如“2009-03-03T18:12:22Z”或“2009-02-23T18:12:22.093-07:00”。请注意,如果您不在时戳内包含时区信息(“Z”代表 UTC,或者时间差值),亚马逊 MWS 会假设所用时区为 UTC。
也就是说亚马逊的时间戳用的是UTC(Universal Time Coordinated 协调世界时),它比GMT(Greenwich Mean Time 格林尼治标准时间)更加精准 。北京时间是东八区时间,比UTC时间快了8个小时,其实这里的时间戳是当前时间减去8小时后的时间。
更多推荐
亚马逊接口
发布评论