# 第三方订单回调
接口地址:http://gateway--cnki--net--https.cnki.mdjsf.utuvpn.utuedu.com:9000/openx/jssdk/order/v1/callback
请求方式:POST
请求数据类型:application/json
响应数据类型:*/*
接口描述: 第三方订单回调
请求示例:
{
"appId": "1731****16030",
"openId": "k8FYCJDK1JjB****C3rkI83cY9",
"payTime": "2025-08-12 12:30:00",
"payType": "WECHAT",
"payExtra": "M6/spyB1h5Ijm/wOjeECuHne********kcBNuQ=="
}
请求参数:
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 |
|---|---|---|---|---|
| appId | 第三方应用在研学开放平台申请的应用ID | body | true | string |
| openId | 第三方平台获取研学开放平台用户信息返回的用户标识,详见:知网研学开放平台文档-认证中心-根据Token获取用户信息 (opens new window) | body | true | string |
| payExtra | 支付主体信息,包含订单详细信息的加密字符串,支付核心数据,生成方式见下文备注。 | body | true | string |
| payTime | 支付时间,格式 yyyy-MM-dd HH:mm:ss | body | true | string |
| payType | 支付方式 ,WECAHT 代表微信,ALIPAY 代表支付宝,OTHER代表其他 | body | true | string |
| Authorization | 接口请求的凭证,获取方式详见:知网研学开放平台文档-认证中心-客户端模式获取JWT (opens new window) | header | true | string |
| Content-Type | application/json | header | true | string |
注意事项:Authorization参数是携带在请求的header中,格式示例(注意Bearer 后有空格):
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCaWF...
备注:支付主体payExtra生成规则如下:
对order_no、product_id、product_name、total_fee、duration_days五个支付主体信息使用键值对的格式(即key1=value1&key2=value2…)拼接成字符串,结果类似:order_no=dsfzf20250907&product_id=jakhdjskadjkh23sdsf93s&product_name=测试月卡&total_fee=20.13&duration_days=30,之后对拼接后的字符串进行AES加密。
| 字段 | 释义 | 类型 | 是否必须 |
|---|---|---|---|
| order_no | 支付订单编号 | String | 是 |
| product_id | 商品ID | String | 是 |
| product_name | 商品名称 | String | 是 |
| total_fee | 总支付费用,字符串类型的数字,精度为小数点后两位,比如29.99 | String | 是 |
| duration_days | 权益持续时间,字符串类型的正整数,单位天,没有可以传"0" | String | 是 |
加密的示例代码如下(秘钥为开发者在研学开放平台申请的ApiKey):
/**
* 加密Map
*
* @param data 要加密的数据
* @return 加密后的字符串
* @throws Exception
*/
public static String encryptMap(Map<String, String> data, String secretKey) throws Exception {
// 元素排序
Map<String, String> sortedData = new TreeMap<>(data);
StringBuilder dataToEncrypt = new StringBuilder();
for (Map.Entry<String, String> entry : sortedData.entrySet()) {
dataToEncrypt.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
// 去掉最后一个多余的&
if (dataToEncrypt.length() > 0) {
dataToEncrypt.setLength(dataToEncrypt.length() - 1);
}
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(dataToEncrypt.toString().getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 解密Map
*
* @param encryptedData 加密后的字符串
* @return 解密后的Map
* @throws Exception
*/
public static Map<String, String> decrypt(String encryptedData, String secretKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
String decryptedString = new String(decryptedBytes, StandardCharsets.UTF_8);
Map<String, String> decryptedMap = new TreeMap<>();
String[] pairs = decryptedString.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
if (idx > 0) {
decryptedMap.put(pair.substring(0, idx), pair.substring(idx + 1));
}
}
return decryptedMap;
}
public static void main(String[] args) {
Map<String, String> data = new HashMap<>();
data.put("order_no", "ds****f20250907");
data.put("product_id", "1741***071581");
data.put("product_name", "测试月卡");
data.put("total_fee", "23.22");
data.put("duration_days", "30");
try {
String encrypt = encryptMap(data, "Nmq******H0Rp");
System.out.println("加密结果:" + encrypt);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
加密算法:AES
工作模式:ECB
填充方式:PKCS5Padding
以上是Java语言实现的加密算法,其它语言加密请保证相同的算法、工作模式、填充方式。
注意编码格式为:UTF_8。
请妥善保存应用秘钥ApiKey!
响应状态:
| 状态码 | 说明 |
|---|---|
| 200 | OK |
| 500 | 系统异常! |
| 400505 | 应用不存在! |
| 400523 | xxxx参数不能为空! |
| 400530 | 时间格式异常! |
| 400531 | 订单信息解密失败! |
| 400529 | 三方支付信息缺失! |
响应参数:
| 参数名称 | 参数说明 | 类型 | schema |
|---|---|---|---|
| code | 接口返回状态码 | integer(int32) | integer(int32) |
| content | 接口返回数据 | object | |
| count | 接口返回数据条数,用于分页查询 | integer(int32) | integer(int32) |
| message | 接口返回信息 | string | |
| success | 接口返回是否成功 | boolean | |
| total | 接口返回数据条数,用于分页查询 | integer(int32) | integer(int32) |
响应示例:
{
"success": true,
"message": "SUCCESS",
"content": null,
"count": null,
"total": null,
"code": 200
}
← 获取三方用户权益信息 三方平台订单回退说明 →