跳到主要内容

接入网关

开放平台接口接入规则

一、准备工作

接口对接之前,随申行会通过邮件的方式告知如下参数:

  1. 请求的域名
  2. 加签的盐值

接入方需要提供:

  1. 网络请求的出口IP

二、HTTPS请求头说明

参数名含义说明必选
X-Sign签名内容生成的方式详见 三、签名步骤
X-SignAlgorithm签名方式1-sha1 ,2-rsa固定值目前传1
X-Timestamp请求时间格式为yyyyMMddHHmmss的当前时间,仅接受5分钟内的时间
X-MerchantId商户身份编号MerchantId及盐值会以邮件形式通知
Content-Type值:application/json

三、签名步骤

  1. 准备请求体 :必须为json格式,不要添加任何空格和换行,以防验签失败。示例请求体: {"mobile":"13666643085","userId":"68805702089"}
  2. 拼接明文 :验签明文由请求体的 json 字符串 时间戳 (与请求头中X-Timestamp的值一致)、 盐值(邮件提供)的拼接组成,中间不含空格,如{"timestamp":1635490727085,"mobile":"13666643085","userId":"68805702089"}20211029150244ABCDEFG,其中最后的ABCDEFG为盐值;
  3. 生成签名 :用签名工具类的静态方法对明文加签生成签名,将签名放入头部的X-Sign用以验签,签名工具详见 附录1

四、发送请求

  1. 按照上述要求设置请求头,用post方法请求对应接口。
  2. 请求的域名会在邮件中通知,具体请求路径详见各接口说明。

五、响应参数

开放平台收到请求后,会做如下响应,若请求网络正常,https响应状态码会置为200;

注意

retCode == 0 ,代表请求的业务正常,若 retCode != 0 ,则要根据 retMsg 提示信息分析错误原因。

参数名数据类型含义说明必选
retCodeInteger响应编码错误编码定义见 附录2
返回数据Object返回的数据具体见每个接口的说明文档
retMsgString响应信息具体的错误信息
traceIdString流水号失败响应的请求的流水号

六、请求示例

代码请求示例 - 基于 Java8


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j
public class SSXDemo {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
//在此将待发送的请求体转为JSON字符串
String body = JSON.toJSONString(new JSON());
//merchantId会通过邮件发送
String merchantId = "your-merchantId";
//联调环境、产线环境的盐值会通过邮件发送
String salt = "your-salt";
//联调环境、产线环境的域名会通过邮件发送
String host = "ssx-host-test";
//请求path详见具体接口
String path = "ssx-path-test";
String url = host + path;
//请求头里的时间必须是yyyyMMddHHmmss格式的
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
//加密的原文由请求体、时间、盐值拼接得到,中间不能有空格、换行符等
String signValue = encode(body + time + salt);
Request request = new Request.Builder()
.addHeader("X-Sign", signValue)
.addHeader("X-SignAlgorithm", "1")
.addHeader("X-Timestamp", time)
.addHeader("X-MerchantId", merchantId)
.addHeader("Content-Type", "application/json")
.url(url)
.post(RequestBody.create(MediaType.parse("application/json"), body))
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
//相应求状态码,200表示请求成功
int responseCode = response.code();
//获取相应body的内容
String responseBody = response.body().string();

log.info("url={},heads = {},body ={},responseCode= {},responseBody = {}",
url, request.headers(),body,responseCode, responseBody );
}

public static String encode(String plaintext) throws NoSuchAlgorithmException, UnsupportedEncodingException {
if (StringUtils.isBlank(plaintext)){
throw new IllegalArgumentException ("加签原文不能为空");
}
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(plaintext.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char[] buf = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return String.valueOf(buf);
}
}



附录 1 :签名工具类示例

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1TranferUtils {

public static String encode(String str) {
if (null == str || 0 == str.length()) {
return "";
}
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char[] buf = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return String.valueOf(buf);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
}

附录 2:错误码及提示信息

错误码提示信息检查项
-2903001时间戳字段为空检查X-Timestamp属性是否为空
-2903002时间戳格式不合法检查X-Timestamp属性是否为yyyyMMddHHmmss格式
-2903003请求时间与系统相差太大检查X-Timestamp属性对应的时间比当前时间是否过早或过晚
-2903011加密算法类型为空检查X-SignAlgorithm是否为空
-2903012加密算法类型错误检查X-SignAlgorithm是否为1
-2903013签名为空检查X-Sign属性是否为空
-2903014签名位数不对检查X-Sign属性是否正确
-2903015验签失败检查X-Sign属性为何不一致(盐值等因素)
-2903016验签异常检查X-Sign属性为何不可用
-2903031未通过IP白名单校验与随申行确认IP白名单是否正确
-2903032IP被列入黑名单与随申行确认为何IP被加入IP黑名单
-2903033appId不存在或者白名单为空与随申行确认IP白名单
-2903041无权限访问资源与随申行确认是否有对应接口访问权限
-2903042缺少该商户请求路径配置与随申行确认是否缺少配置
-2903051调用过于频繁检查短时间请求过于频繁
-2903100校验未知异常与随申行确认为何校验失败
-2903101APPID对应的资源不存在与随申行确认是否缺少配置
-2903102APPID为空X-MerchantId属性为空