# 第三方订单回退
接口地址:http://gateway--cnki--net--https.cnki.mdjsf.utuvpn.utuedu.com:9000/openx/jssdk/order/v1/rollback
请求方式:POST
请求数据类型:application/json
响应数据类型:*/*
接口描述: 第三方订单回退
请求示例:
{
"appId": "1757*****8985",
"payExtra": "GIdO0im4RP****G63soG2xBzLvx8GG++cOql77HeyCU="
}
请求参数:
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 |
|---|---|---|---|---|
| appId | 第三方应用在研学开放平台申请的应用ID | body | true | string |
| payExtra | 订单信息,包含订单详编码的加密字符串,生成方式见下文备注。 | 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使用键值对的格式(即key=value)拼接成字符串,结果类似:order_no=dsfzf20250907,之后对拼接后的字符串进行AES加密。
| 字段 | 释义 | 类型 | 是否必须 |
|---|---|---|---|
| order_no | 支付订单编号 | 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", "dsfzf20250907");
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参数不能为空! |
| 400533 | 第三订单不存在! |
| 400531 | 订单信息解密失败! |
| 400529 | 三方支付信息缺失! |
| 400534 | 第三方订单未支付! |
响应参数:
| 参数名称 | 参数说明 | 类型 | 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
}