Files
order_site/docs/行业电子凭证/0.基础技术.md
T
2026-06-30 15:57:58 +08:00

375 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
基础技术
更新时间:2025-03-26
阅读数:5713
本处介绍开放平台的基础协议和通用接入方式
1.环境说明
两套环境相互独立,数据不可相互使用
环境 环境地址 说明
线上环境 https://open.kwaixiaodian.com 线上环境可直接使用
线下环境 https://gw-merchant-staging.test.gifshow.com 测试环境调用需要提供出口IP,并联系快手对接人添加ip白名单
2.授权流程
2.1 如何获取token
首先需要拿到appkey、appsecret、signSecret信息,线下环境找快手提供,线上环境到“开放平台-控制台-应用中心-应用详情”查看,请求示例如下
https://gw-merchant-staging.test.gifshow.com/integration/virtual/topup/mobile/order/callback?access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhJAErnBVtjx5FPdE0AITaSq4xlW6XaTOaV_McGinj-hFivkyxAw1SZ3i28bLEa6xP-C4UuKlRz6uh3lukYRLDcAdRoSeCxQKnQhAPTTL4YL0_NqmqD-IiApwDDKEL1wBW7EbWH0ZRDO3UUNSCxMwkuF7nb57Fn7AygFMAE&appkey=ks683702719562282620&method=integration.virtual.topup.mobile.order.callback&param=%7B%22orderId%22%3A%22100%22%2C%22businessTime%22%3A%222021-06-08T14%3A16%3A01%2B0800%22%2C%22mobile%22%3A%2215990013607%22%2C%22status%22%3A%22FAILED%22%2C%22amount%22%3A%225000%22%2C%22bizType%22%3A20%7D&signMethod=MD5&timestamp=1623132961782&version=1&sign=c091ca3414a9d6429a0fda47c383d202
注:如果回调失败需要以指数周期(1m、2m、4m、8m...)重试
注意:
测试环境需要把自己的出口ip给到快手,配置白名单,否则无权限访问。配置对接人:屈国庆,王哲,杨天问
测试环境和线上环境,是两套token,不可混用。测试token,如下方式获取。线上token通过上面sdk调用,有效期48h。
Token授权码:参考文档(2.2节 商家开发者角色)
授权一定要用店主的主账号来授权,否则token换取到的sellerId就是子账号的id
线上token验证:https://open.kwaixiaodian.com/commonTool/tokenAuth/accessToken?cateId=0&typeIndex=1,需要快手app扫描登录
测试环境获取token的步骤(参考文档(2.2节 商家开发者角色)):
测试环境:优先使用集成中心自己调试
线上环境:需要按照开放平台的授权文档,通过你的店铺由店主授权(不要用子账号授权),然后用你的redirect_uri来接收code。
用授权码code换取长时令牌refreshToken以及访问令牌accessToken
示例:https://gw-merchant-staging.test.gifshow.com/oauth2/access_token?app_id=ks683702719562282620&app_secret=zSCiWmGOk_diMCU9k3zHcg&grant_type=code&code=bab4f0378269db7a1603de9d5a381615d7d2c451ffbb32f8ede78ac8f05b6171f7d4eb8c
用长时令牌refreshToken刷新访问令牌accessToken
示例:
https://gw-merchant-staging.test.gifshow.com/oauth2/refresh_token?app_id=ks683702719562282620&app_secret=zSCiWmGOk_diMCU9k3zHcg&grant_type=refresh_token&refresh_token=ChJvYXV0aC5yZWZyZXNoVG9rZW4SkAGpBE83BKP9TeiwbEP1-IIQL2G08s8rU-OETIzfs5wFN2HeZgUaR_mfGjKHjHzfV-sicHG4IZmxVKlxQhdAZIdf01AR51ZtPN7sHY3eeW6RMnx8LPKo92V1yk-GnkXiiPMWpn9Vmhq0dk_U_aKh5Jwg7mMySO8IEDoz-fPk9Rc2rjUK3inqxNd7rqTQ9fz316oaEsFIUEDt4EyD090nGWRnwQ5g3SIgY-ctBM_4jrFXxBA9EF1jMaP6as57lNYIyOZf9Qlqq64oBTAB
后面就可以一直用第三步来刷新accessToken
3.签名算法
3.1 协议
https协议,支持GET/POST,调用地址、appkey、signSecret由快手提供,返回结果为json字符串。
3.2 签名
官方签名说明
快手电商开放平台的所有开放API调用都需要进行加签,服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。当前平台支持的签名算法为MD5(signMethod=MD5)
下面将详细介绍签名流程:
对所有API系统参数和请求参数(不包括sign参数和byte[]类型的参数),根据参数名称进行字典顺序排序;
排序前的顺序是:appkey=ks123version=1method=open.xxx.xxxsignMethod=MD5access_token=xxxxtimestamp=1583271919000param={"title":"短袖", "relItemId":123456, "categoryId":12}
排序后的顺序是:appkey=ks123&param={"categoryId":12,"relItemId":123456,"title":"短袖"}&signMethod=MD5&timestamp=1583271919000&version=1&signSecret=abc
保留=符号,用&符号将多个参数及其值组装在一起,根据上面的示例得到的排序结果为:access_token=xxx&appkey=ks123&method=open.xxx.xxx&param={"title":"短袖", "relItemId":123456, "categoryId":12}&signMethod=MD5&timestamp=1583271919000&version=1
排序好参数后,在末尾加入signSecret(在应用创建审核通过后由平台分配,在“应用中心-应用列表-应用详情”中可见)进行对应算法的签名计算
MD5(access_token=xxx&appkey=ks123&method=open.xxx.xxx.xxx&param={"title":"短袖", "relItemId":123456, "categoryId":12}&signMethod=MD5&timestamp=1583271919000&version=1&signSecret=xxxxxx)=sign
签名加好后,将sign添加到请求参数中,并对param内容进行encode(双引号"和冒号:也需要encode),这里注意请求参数里面是不包括signSecret的,signSecret只是作为加签因子用于签名sign的计算,
所以千万不要将signSecret当作请求参数传输,请求参数内容见第3点API调用参数说明的表格内容,请求url样例:
https://open.kwaixiaodian.com/open/xxx/xxx?access_token=xxx&appkey=ks123&method=open.xxx.xxx.xxx&param=%7B%22title%22%3A%22%E7%9F%AD%E8%A2%96%22%2C%20%22relItemId%22%3A123456%2C%20%22categoryId%22%3A12%7D&version=1&signMethod=MD5&timestamp=1583271919000&sign=af2d80958e77e17f1d973003b7b7aec2
说明:param是json对象,需要排序
4.API调用
确认完成了授权流程后进行API的调用测试,内容详情可见《API调用说明》,也可使用平台提供的API测试工具测试
=======
API调用说明
更新时间:2024-10-10
阅读数:40538
1.前期准备
首先需要入驻快手电商开放平台成为开发者,并在开发者账号下创建应用,详情请看《开放平台入驻指南》
2.API调用方式
2.1 域名信息
环境
域名
测试环境
https://gw-merchant-staging.test.gifshow.com(仅内测,不对外开放)
生产环境(推荐)
https://openapi.kwaixiaodian.com
生产环境(备用)
https://open.kwaixiaodian.com
2.2 OAUTH认证
web端授权方式,商家/子账号员工/开发者可通过授权链接获取用户授权,授权通过后即可通过token调用授权API,详见《授权说明》
2.3 SDK下载
快手电商开放平台提供了所有线上API和消息的SDK,目前支持java 1.6及以上版本,推荐广大开发者使用。
3.API调用参数说明
请求url样例:https://openapi.kwaixiaodian.com/open/xxx/xxx/xxx?appkey=ksxxxxx&method=open.xxx.xxx.xxx&version=1&param=xxxxxxx&access_token=xxxxxxxxxxxxxx&timestamp=158888888888&signMethod=MD5&sign=xxxxxx
请求Content-type仅支持application/x-www-form-urlencoded,如果是post请求,请将param参数放到body里,防止url 过长导致请求失败
url字段
是否必须
描述
https://openapi.kwaixiaodian.com
开放平台环境的域名,对应2.1域名信息
/open/xxx/xxx/xx
请求的API,用/替换名称中的.
appkey=ksxxxxx
平台分配的appkey,即client_id即appId
method=open.xxx.xxx.xxx
请求的API,详见各API名称
version=1
请求的API版本号,目前版本都为1
param=xxxxxxxx
业务参数,详见各API的入参内容
access_token=xxxxxxxxxx
授权API必填,详见开发指南的授权说明文档
timestamp=1583271919000
发起请求的Unix时间戳,单位为毫秒
signMethod=HMAC_SHA256
签名算法,支持HMAC_SHA256和MD5 推荐使用HMAC_SHA256
sign=xxxxxxxx
API入参的签名计算结果(2020.10.16开始灰度,10.31正式生效)
4.签名算法说明
快手电商开放平台的所有开放API调用都需要进行加签,服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。目前支持的签名算法有两种:MD5(signMethod=MD5)HMAC_SHA256signMethod=HMAC_SHA256),下面将以MD5算法为例详细介绍签名流程,使用HMAC_SHA256算法直接替换即可:
注意:是先进行参数签名计算,然后再对参数进行url encode。如果参数是放在请求body里的,那么url encode是非必须的。
对所有API系统参数和请求参数(不包括sign参数和byte[]类型的参数),根据参数名称进行字典顺序排序;
排序前的顺序是:appkey=ks123version=1method=open.xxx.xxxsignMethod=MD5access_token=xxxxtimestamp=1583271919000param={"title":"短袖", "relItemId":123456, "categoryId":12}
排序后的顺序是:access_token=xxxx, appkey=ks123method=open.xxx.xxxparam={"title":"短袖", "relItemId":123456, "categoryId":12}signMethod=MD5timestamp=1583271919000version=1。
保留=符号,用&符号将多个参数及其值组装在一起,根据上面的示例得到的排序结果为:access_token=xxx&appkey=ks123&method=open.xxx.xxx&param={"title":"短袖", "relItemId":123456, "categoryId":12}&signMethod=MD5&timestamp=1583271919000&version=1。
排序好参数后,在末尾加入signSecret(在应用创建审核通过后由平台分配,在“应用中心-应用列表-应用详情”中可见)进行对应算法的签名计算
如果使用MD5算法,则MD5(access_token=xxx&appkey=ks123&method=open.xxx.xxx.xxx&param={"title":"短袖", "relItemId":123456, "categoryId":12}&signMethod=MD5&timestamp=1583271919000&version=1&signSecret=xxxxxx)=sign;如果使用HMAC_SHA256算法,则HMAC_SHA256(access_token=xxx&appkey=ks123&method=open.xxx.xxx.xxx&param={"title":"短袖", "relItemId":123456, "categoryId":12}&signMethod=HMAC_SHA256&timestamp=1583271919000&version=1&signSecret=xxxxxx)=sign
签名加好后,将sign添加到请求参数中,并对param内容进行encode(双引号"和冒号:也需要encode),这里注意请求参数里面是不包括signSecret的,signSecret只是作为加签因子用于签名sign的计算,所以千万不要将signSecret当作请求参数传输,请求参数内容见第3点API调用参数说明的表格内容,请求url样例:
https://openapi.kwaixiaodian.com/open/xxx/xxx?access_token=xxx&appkey=ks123&method=open.xxx.xxx.xxx&param=%7B%22title%22%3A%22%E7%9F%AD%E8%A2%96%22%2C%20%22relItemId%22%3A123456%2C%20%22categoryId%22%3A12%7D&version=1&signMethod=MD5&timestamp=1583271919000&sign=af2d80958e77e17f1d973003b7b7aec2
//签名计算
public static String sign(String param, String signSecret, SignMethodEnum signMethod) {
StringBuffer sb = new StringBuffer();
sb.append(param).append("&").append(SIGN_SECRET).append("=").append(signSecret);
String inputStr = sb.toString();
switch (signMethod) {
//HMAC_SHA256算法
case HMAC_SHA256:
return HMACSHA256SignUtils.sign(inputStr, signSecret);
//默认md5算法
case MD5:
default:
return org.apache.commons.codec.digest.DigestUtils.md5Hex(inputStr);
}
}
// 加签方法
public static String sign(Map<String, String> requestParamMap, String signSecret, SignMethodEnum signMethod) {
return sign(getSignParam(requestParamMap), signSecret, signMethod);
}
public static String getSignParam(Map<String, String> requestParamMap) {
String method = checkAndGetParam(requestParamMap, METHOD);
String appKey = checkAndGetParam(requestParamMap, APPKEY);
String accessToken = checkAndGetParam(requestParamMap, ACCESS_TOKEN);
String version = requestParamMap.get(VERSION);
String signMethod = requestParamMap.get(SIGN_METHOD);
String timestamp = requestParamMap.get(TIMESTAMP);
String param = requestParamMap.get(PARAM);
Map<String, String> signMap = new HashMap<String, String>();
// 必传参数
signMap.put(METHOD, method);
signMap.put(APPKEY, appKey);
signMap.put(ACCESS_TOKEN, accessToken);
//可选参数
if (signMethod != null) {
signMap.put(SIGN_METHOD, signMethod);
}
if (version != null) {
signMap.put(VERSION, version);
}
if (timestamp != null) {
signMap.put(TIMESTAMP, timestamp);
}
if (param != null) {
signMap.put(PARAM, param);
}
String signParam =sortAndJoin(signMap);
return signParam;
}
public static String checkAndGetParam(Map<String, String> paramMap, String paramKey) {
String value = paramMap.get(paramKey);
if (StringUtils.isBlank(value)) {
throw new IllegalArgumentException(paramKey + " not exist");
}
return value;
}
// 排序
public static String sortAndJoin(Map<String, String> params) {
TreeMap<String, String> paramsTreeMap = new TreeMap();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() == null) {
continue;
}
paramsTreeMap.put(entry.getKey(), entry.getValue());
}
String signCalc = "";
for (Map.Entry<String, String> entry : paramsTreeMap.entrySet()) {
signCalc = String.format("%s%s=%s&", signCalc, entry.getKey(), entry.getValue(), "&");
}
if (signCalc.length() > 0) {
signCalc = signCalc.substring(0, signCalc.length() - 1);
}
return signCalc;
}
private class HMACSHA256SignUtils {
protected static final Logger logger = Logger.getLogger(HMACSHA256SignUtils.class.getName());
/**
* hmac_sha256取hash Base64编码
*/
public static String sign(String params, String secret) {
String result = "";
try {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
byte[] sha256HMACBytes = sha256HMAC.doFinal(params.getBytes());
String hash = Base64.encodeBase64String(sha256HMACBytes);
return hash;
} catch (Exception e) {
logger.warning("HMACSHA256SignUtils sign failed, params=" + params + ", error=" + e.getMessage());
}
return result;
}
}
5.权限组列表
权限组用于控制APP调用API和接受消息的权限范围,只有当APP拥有该API所属的权限组才可以调用API,只有当APP拥有该消息所属的权限组才可以消费消息,列表中说明了现有的权限组以及对应的权限组的API和消息。快手电商开放平台会根据开发者创建的应用类型授予默认的权限组,若开发者需要申请额外的权限组,请发邮件到open@kuaishou.com并说明理由。
Scope
描述
备注
user_base
授权之后的默认权限
所有应用默认拥有此权限组
user_info
用户基本信息
所有应用默认拥有此权限组
merchant_user
商家用户信息
用户API权限
merchant_item
读取或更新店铺的商品数据
商品API和商品消息权限
merchant_order
读取或更新店铺的订单信息
订单API和订单消息权限
merchant_refund
读取或更新店铺的售后信息
退款单API和退款单消息权限
merchant_distribution
读取或更新分销信息
分销API权限
merchant_logistics
读取或更新物流信息
物流API权限
merchant_servicemarket
读取应用在服务市场的信息
服务市场API权限
merchant_comment
读取或更新订单评价信息
评价API权限
merchant_cs
读取或更新店铺的客服信息
客服API权限