3:开发指南

2021年11月05日

开发指南

一:请求协议说明:

调用流程说明

合作方调用配送开放平台API,需要按照以下步骤:
填充参数>生成签名>拼装HTTP请求>发起HTTP请求>得到HTTP响应>解析json

二:接口协议

规则 说明
测试环境请求地址 http://open.s.bingex.com
生产环境请求地址 https://open.ishansong.com
传输协议 http
参数格式 application/x-www-form-urlencoded
字符编码 utf-8
请求方式 POST

三:返回值规则

规则 说明
数据格式 application/json
字符编码 utf-8
数据结构 {"status": 状态码,"msg": 错误信息, "data": 数据}
状态码为200代表正常,其它代表不正常。

四:接口入参介绍

闪送开放平台接口参数分为系统参数和业务参数两种,其中系统参数每个接口均需传入,业务参数是否传入取决于具体接口。
1:系统参数:clientId,shopId,timestamp,sign 
2:业务参数:data
请求闪送开放平台接口时,系统参数、业务参数均在body请求体中传入

闪送开放平台接口参数列表:

参数名称 参数类型 是否必传 参数描述
clientId String yes App-key(去账户中心->应用信息查看)
shopId String yes 商户ID(去账户中心->应用信息查看)
timestamp String yes 毫秒级时间戳
data String(必须是json串) 根据具体业务接口传递 业务入参
sign String yes 签名

五:接口签名

签名说明


1:为了防止API调用过程中被黑客恶意篡改,调用任何一个API都需要携带签名,开放平台服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。

2:将所有参数按照字典顺序进行排序,排除值为空以及sign字段。

3:将参数按照(App_secret的值+"clientId”+App ID的值+"data”+data的值+shopId+"商户ID的值"+"timestamp”+timestamp的值)顺序拼接,参数对应的值不存在,参数和值都不进行拼接,参数使用utf-8编码。

4: 将拼接好的字符串进行MD5加密(32位大写加密),得到的MD5加密值最后转为"大写"赋给sign作为请求的参数。

参考方法:
一:data参数为空
appSecret:qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0
clientId=sssHhHPkzCNWG1sFs 
shopId=20000000000001715
timestamp=1634095503814

拼接成的加密串为:qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0clientIdsssHhHPkzCNWG1sFsshopId20000000000001715timestamp1634095503814
得到的MD5加密值(32位大写加密)为:20BCB8659478BDFC1B69184CABE847F2

二:data参数不为空
appSecret:qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0
clientId=sssHhHPkzCNWG1sFs 
shopId=20000000000001715
timestamp=1634095503814
data={"cityId":1101}

拼接成的加密串为:qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0clientIdsssHhHPkzCNWG1sFsdata{"cityId":1101}shopId20000000000001715timestamp1634095503814
得到的MD5加密值(32位大写加密)为:sign:CED6936005433D85EEA557623A8BA66B

六:代码示例

1、引入类

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

2、签名sign参数计算函数

    //把字节数组转换成大写md5
    public static String bytesToMD5(byte[] input) {
        String md5str = null;
        try {
            //创建一个提供信息摘要算法的对象,初始化为md5算法对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            //计算后获得字节数组
            byte[] buff = md.digest(input);
            //把数组每一字节换成16进制连成md5字符串
            md5str = bytesToHex(buff);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5str.toUpperCase();
    }

   //把字节数组转成16进位制数
    public static String bytesToHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        //把数组每一字节换成16进制连成md5字符串
        int digital;
        for (int i = 0; i < bytes.length; i++) {
            digital = bytes[i];
            if(digital < 0) {
                digital += 256;
            }
            if(digital < 16){
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString();
    }

3、post请求函数

public static String sendPost(String url, Map<String,Object> params) {
        String response = null;
        try {
            List<NameValuePair> pairs = null;
            if (params != null && !params.isEmpty()) {
                pairs = new ArrayList<NameValuePair>(params.size());
                for (String key : params.keySet()) {
                    pairs.add(new BasicNameValuePair(key, params.get(key).toString()));
                }
            }
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse httpResponse = null;
            try {
                httpClient = HttpClients.createDefault();
                HttpPost httppost = new HttpPost(url);
                if (pairs != null && pairs.size() > 0) {
                    httppost.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
                }
                httpResponse = httpClient.execute(httppost);
                response = EntityUtils
                        .toString(httpResponse.getEntity());
                System.out.println(response);
            } finally {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (httpResponse != null) {
                    httpResponse.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

4、data参数为空请求接口的代码示例(查询开通城市接口为例

    public static void main(String[] args) {
        String appSecret = "qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0";
        String clientId = "sssHhHPkzCNWG1sFs";
        String shopId = "20000000000001715";
        Long timestamp = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer(appSecret)
                .append("clientId").append(clientId)
                .append("shopId").append(shopId)
                .append("timestamp").append(timestamp);
        //计算签名
        String sign = bytesToMD5(sb.toString().getBytes());
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("clientId",clientId);
        map.put("shopId",shopId);
        map.put("timestamp",timestamp);
        map.put("sign",sign);
        //请求接口获取的结果
        String res = sendPost("http://open.s.bingex.com/openapi/merchants/v5/openCitiesLists",map);
    }

5、data参数不为空请求接口的代码示例(查询保单产品接口为例

    public static void main(String[] args) {
        String appSecret = "qBfAr1fAAFRw2Jat4i4yUaqE3Nh3NSw0";
        String clientId = "sssHhHPkzCNWG1sFs";
        String shopId = "20000000000001715";
        Long timestamp = System.currentTimeMillis();
        String data= "{\"cityId\":1101}";
        StringBuffer sb = new StringBuffer(appSecret)
                .append("clientId").append(clientId)
                .append("data").append(data)
                .append("shopId").append(shopId)
                .append("timestamp").append(timestamp);
        //计算签名
        String sign = bytesToMD5(sb.toString().getBytes());
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("clientId",clientId);
        map.put("shopId",shopId);
        map.put("timestamp",timestamp);
        map.put("sign",sign);
        map.put("data",data);
        //请求接口获取的结果
        String res = sendPost("http://open.s.bingex.com/openapi/merchants/v5/insuranceProductsList",map);
    }
关键词: