# 拼车助手

# 1. 版本历史

版本 日期 修订人 修改内容 审核人
V0.1 2024.08.25 初稿
V0.2 2024.12.09 服务商行程导入
V0.3 2025.01.02 拼车助手行程导出
V0.4 2025.03.19 申请增加起终点信息

# 2. 基础说明

# 2.1 接口协议

除非特殊指定,默认请求方式均为 HTTPS/POST 方式。

# 2.2 返回数据格式

除非特殊指定,默认返回数据格式均为 JSON 格式。

# 2.3 字符编码

除非特殊指定,默认字符编码均为 UTF-8 编码格式。

# 2.4 请求格式

接口内如果没有特殊说明的,请求格式一律统一为 application/json 。

# 2.5 重试机制

调⽤出行服务接口时,返回码 Code 不成功,要有重试机制(具体见错误码表)。

# 2.6 通用参数

字段名 字段类型 最大长度 必填 说明
accessKey String 32 腾讯出行服务分配给服务商调用的 accessKey
seqId String 36 请求流水号,调用方自动生成一个随机 ID,建议使用 uuid
timestamp Long 20 请求发送时的时间戳(unix 时间戳) 毫秒
nonce String 10 10 位随机字符串
sign String 32 验证签名参数

# 2.7 通用返回值

字段名 字段类型 最大长度 必填 说明
code Integer 11 服务响应状态,参见错误码表
message String 64 服务响应状态说明,参见错误码表
data Object - 具体的接口对应不同的对象详见具体的接口

# 2.8 鉴权说明

步骤 1 从请求串中获得 accessKey、seqId、timestamp, nonce 通用字段以及其他的业务段和鉴权结果字段 sign。

步骤 2 根据签名算法,对参与签名的内容进行签名; 按照除 sign 外参数名称排序(字典升序排列)成”key1=value1&key2=value2&....”的原始字符串 src1;参数值为 null 不参与签名。 将原始字符串+分配给调用方的 apiSercret 形成字符串 src2; 将 src2 进行 md5 后转成大写形成签名内容 dest

步骤 3 将步骤 2 中得到的签名内容 dest 与请求中的 sign 字段内容做比较,如果相同则验证成功,否则判定请求非法。

举例: 假设/order/status 接口文档中业务字段为[slon, slat],分配的 apiSercret=DZaslH9B9ycqRrE77laCPB2Om, 请求参数如下: accessKey=PSUBZLHOKUO6HV52A5CAUSSE5KSB6Y, seqId=b8b4f0b8-01fb-4c06-80b9-3ab895a8c616, timestamp=1554695343, slat=39.998299, slon=116.285561 则需要签名的内容: accessKey=PSUBZLHOKUO6HV52A5CAUSSE5KSB6Y&seqId=b8b4f0b8-01fb-4c06-80b9-3ab895a8c616&slat=39.998299&slon=116.285561&timestamp=1554695343&apiSercret=DZaslH9B9ycqRrE77laCPB2Om

步骤 4 计算的 MD5 值为 8a983278e5366eb93feb0d4143e1c522,大写值为 8A983278E5366EB93FEB0D4143E1C522。

步骤 5 将步骤 4 中得到的 MD5 值,与请求中 sign 字段的值比较。两者相同请求合法。

# 2.9 签名示例代码

以下代码仅为示例,以实际联调过程中双方沟通结论为准。

服务商接收到腾讯侧请求,无需转换对象,直接将这个请求JSON串传入requestSign(String requestStr, String secret)方法计算得到签名sign。 注:为保证结果一致,建议使用相同的JSON工具。

import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 验签
 */
public class SignUtil {

    private static final String MD5 = "MD5";

    /**
     * 请求签名算法入口
     * @param requestStr
     * @param secret
     * @return
     */
    public static String requestSign(String requestStr, String secret) {
        Map<String, Object> paramsMap = JsonTool.toObj(requestStr, TreeMap.class);
        Map<String, String> params = new HashMap<>();
        String[] keys = paramsMap.keySet().toArray(new String[0]);
        for (String key : keys) {
            if (org.apache.commons.lang3.StringUtils.isNotBlank(key)) {
                String value = paramsMap.get(key).toString();
                if (null != value) {
                    params.put(key.trim(), value);
                }
            }
        }
        params.remove("sign");
        return sign(params, secret);
    }

    /**
     * 签名算法核心
     * @param params
     * @param secret
     * @return
     */
    public static String sign(Map<String, String> params, String secret) {
        // 第一步:检查参数是否已经排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        // 第二步:把所有参数名和参数值串在一起
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            if (StringUtils.isNotBlank(key)) {
                String value = params.get(key);
                if (null != value) {
                    sb.append(key.concat("="));
                    sb.append(value.concat("&"));
                }
            }
        }
        sb.append("apiSercret=" + secret);
        return toHex(getMd5(sb.toString()));
    }

    private static String toHex(byte[] byteArray) {
        if (null == byteArray) {
            return null;
        }
        StringBuilder md5Str = new StringBuilder();
        for (byte b : byteArray) {
            md5Str.append(String.format("%02x", b));
        }
        return md5Str.toString().toUpperCase();
    }

    private static byte[] getMd5(String str) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance(MD5);
            messageDigest.reset();
            messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            return new byte[0];
        }
        return messageDigest.digest();
    }
}

JSON工具类:

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * json tools
 */
public class JsonTool {

    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.setDefaultPropertyInclusion(Include.NON_NULL);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
    }

    public static String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception ex) {
            throw new RuntimeException("序列化异常");
        }
    }

    public static <T> T toObj(String json, Class<T> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception ex) {
            throw new RuntimeException("反序列化异常");
        }
    }

}

# 2.10 注意事项

1、需要签名的字段与请求串中字段先后顺序没有关系,只与进行签名的内容有关,必须按照文档中的顺序拼接。
2、apiSercret 内容为双方保密内容,不在请求中传输,严禁公开。
3、通用字段 accessKey,seqId,timestamp,nonce 参与所有接口的签名。
4、字段值是 JSON 类型的,把字段值 json 串参与签名, 不用拆分里面字段。

# 2.11 数据加密

在双方进行HTTP接口交互时,为保证数据安全,须对请求参数和响应数据中的敏感数据(如手机号)加密传输,接收数据后解密使用。双方联调时提供具体加密策略。

# 2.12 接口分类

  • 主调接口(调用方:腾讯出行,被调方:各服务商),主调接口由服务商实现。
  • 被调接口(调用方:各服务商,被调方:腾讯出行),被调接口由腾讯实现。

# 3. 业务主调接口列表

  • 请求地址

由服务商提供(正式环境、测试环境)

  • 请求方式 POST

# 主调接口通用参数

字段名 字段类型 最大长度 必填 说明
seqId String 36 请求流水号
timestamp Long 36 请求时间戳
spId Integer 36 服务商ID

# LocationInfo

参数名称 类型 说明 是否必填
lng Double 经度
lat Double 纬度
cityCode String 城市code
cityName String 城市名称
adCode String 城区code
phoneAreaCode String 区域code
name String 地址名称
address String 详细地址
districtName String 区/县(级市)名
townName String 乡镇/街道(四级行政区划) 否,建议传递

# 3.1 (二期)乘客行程创建同步服务商

# 请求地址
  • /passenger/trip/create
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧乘客行程ID
startAddr LocationInfo 行程起点
endAddr LocationInfo 行程终点
earliestDepartureTime Long 行程最早出发时间
latestDepartureTime Long 行程最晚出发时间
seatNum Integer 乘客需要座位数
remark String 备注信息
userCode String 腾讯侧userCode
supportPhone Boolean 发单人是否支持电话联系
nickName String 乘客昵称(用户授权手机号时存在)
# 请求示例
{
  "seqId": "abc123",
  "timestamp": 1234567891019,
  "tripId": "trip123456",
  "startAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "天安门",
    "address": "天安门广场",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "天安门"
  },
  "endAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "故宫",
    "address": "故宫博物院",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "故宫"
  },
  "earliestDepartureTime": 1633036800000,
  "latestDepartureTime": 1633040400000,
  "seatNum": 2,
  "remark": "请提前到达",
  "userCode": "user123456",
  "supportPhone": true,
  "nickName": "张三"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.tripId String 行程ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "tripId": "spTrip123456"
  }
}

# 3.2 (二期)乘客行程修改同步服务商

# 请求地址
  • /passenger/trip/modify
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧乘客行程ID
startAddr LocationInfo 行程起点
endAddr LocationInfo 行程终点
earliestDepartureTime Long 行程最早出发时间
latestDepartureTime Long 行程最晚出发时间
seatNum Integer 乘客需要座位数
remark String 备注信息
userCode String 腾讯侧userCode
supportPhone Boolean 发单人是否支持电话联系
nickName String 乘客昵称(用户授权手机号时存在)
# 请求示例
{
  "seqId": "abc123",
  "timestamp": 1234567891019,
  "tripId": "trip123456",
  "startAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "天安门",
    "address": "天安门广场",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "天安门"
  },
  "endAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "故宫",
    "address": "故宫博物院",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "故宫"
  },
  "earliestDepartureTime": 1633036800000,
  "latestDepartureTime": 1633040400000,
  "seatNum": 2,
  "remark": "请提前到达",
  "userCode": "user123456",
  "supportPhone": true
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.tripId String 行程ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "tripId": "spTrip123456"
  }
}

# 3.3 (二期)乘客行程状态变更通知

# 请求地址
  • /passenger/trip/status
# 请求参数
参数名称 类型 说明 必须
tripId String 行程ID
tripStatus Integer 行程状态
# 请求示例
{
  "seqId": "def456",
  "timestamp": 1234567891020,
  "tripId": "trip123456",
  "tripStatus": 1
}
# 响应数据
参数名称 类型 说明 必须
userCode String 腾讯侧userCode
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.4 (二期)乘客接受司机邀请

# 请求地址
  • /passenger/invite/accept
# 请求参数
参数名称 类型 说明 必须
userCode String 腾讯侧userCode
tripId String 乘客行程ID
applyId String 腾讯侧申请单ID
# 请求示例
{
  "seqId": "mno345",
  "timestamp": 1234567891050,
  "driverId": "driver123456",
  "tripId": "passengerTrip123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.5 乘客发起占座

# 请求地址
  • /passenger/invite/driver
# 请求参数
参数名称 类型 说明 必须
userCode String 腾讯侧userCode
tripId String 车主行程ID
applyId String 用户申请单ID
nickName String 申请人昵称
seatNum Integer 乘客申请座位数
applyStartAddr LocationInfo 申请起点信息
applyEndAddr LocationInfo 申请终点信息
# 请求示例
{
  "seqId": "ghi789",
  "timestamp": 1234567891030,
  "tripId": "trip123456",
  "applyId": "apply123456",
  "nickName": "小明",
  "seatNum": 1,
  "applyStartAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "天安门",
    "address": "天安门广场",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "天安门"
  },
  "applyEndAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "故宫",
    "address": "故宫博物院",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "故宫"
  }
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.6 乘客取消占座(含接受后退出)

# 请求地址
  • /passenger/invite/cancel
# 请求参数
参数名称 类型 说明 必须
userCode String 腾讯侧userCode
tripId String 车主行程ID
applyId String 用户申请单ID
# 请求示例
{
  "seqId": "jkl012",
  "timestamp": 1234567891040,
  "tripId": "trip123456",
  "applyId": "apply123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.7 乘客发送消息请求

# 请求地址
  • /passenger/im/message/send
# 请求参数
参数名称 类型 说明 必须
userCode String 腾讯侧userCode
spDriverId String 服务商司机ID
tripId String 会话关联行程ID
messageType Integer 消息类型 文字0/图片1/定位2
messageBody MessageBody 消息内容
messageBody.text String 文本消息
messageBody.url String 图片/语音URL
messageBody.duration Integer 语音时长
spMessageId String 服务商消息ID
# 请求示例
{
  "seqId": "vwx234",
  "timestamp": 1234567891080,
  "spId": 600010,
  "userCode": "usercode123456",
  "spDriverId": "driver123456",
  "tripId": "trip123456",
  "messageType": 0,
  "messageBody": {
    "text": "你好",
    "url": "图片URL/语音URL(duration记录语音时长)",
    "duration": 0
  },
  "spMessageId": "spMessage123456",
  "tipType": 0
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data SendImMessageResData 响应数据
data.messageId String 腾讯侧消息ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "messageId": "message123456"
  }
}

# 3.8 乘客单会话已读

# 请求地址
  • /passenger/im/message/read/session
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧行程ID
driverId String 服务商车主ID
userCode String 腾讯侧参与会话的用户userCode
messageIdList List 消息ID列表
spMessageIdList List 服务商消息ID列表
# 请求示例
{
  "seqId": "yz1234",
  "timestamp": 1234567891090,
  "spId": 600010,
  "tripId": "trip123456",
  "driverId": "driver123456",
  "userCode": "usercode123456",
  "messageIdList": ["message123456"],
  "spMessageIdList": ["spMessage123456"]
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.9 乘客全部已读

# 请求地址
  • /passenger/im/message/read/all
# 请求参数
参数名称 类型 说明 必须
userCode String 腾讯侧参与会话的用户userCode
tripIds List 需要清空的行程ID列表
messageIdList List 消息ID列表
spMessageIdList List 服务商消息ID列表
# 请求示例
{
  "seqId": "yz1234",
  "timestamp": 1234567891090,
  "spId": 600010,
  "userCode": "usercode123456",
  "tripIds": ["trip123456"],
  "messageIdList": ["message123456"],
  "spMessageIdList": ["spMessage123456"]
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 3.10 乘客获取车主虚拟号请求

# 请求地址
  • /driver/phone/get
# 请求参数
参数名称 类型 说明 必须
srcPhone String 来电号码
tripId String 一喂导入的车主行程ID 是,tripId和applyId必有其一
applyId String 车主发起上车邀请的申请单ID 是,tripId和applyId必有其一
# 请求示例
{
  "seqId": "abc987",
  "timestamp": 1234567891100,
  "tripId": "trip123456",
  "userPhone": "12345678901"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.driverVirtualPhone String 虚拟号
data.expireTime Long 过期时间
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "driverVirtualPhone": "12345678901",
    "expireTime": 1633040400
  }
}

# 4. 业务被调接口列表

  • 请求地址

正式环境 https://sp.wecar.map.qq.com/carpoolassistant/

测试环境 https://test.tai.qq.com/carpoolassistant/

  • 请求方式 POST

# 被调接口通用参数

字段名 字段类型 最大长度 必填 说明
accessKey String 32 腾讯出行服务分配给服务商调用 accessKey
seqId String 36 请求流水号,调用方自动生成一个随机 ID,建议使用 uuid
timestamp Long 20 请求发送时的时间戳(unix 时间戳) 毫秒
nonce String 10 10 位随机字符串
sign String 32 验证签名参数
userCode String 32 腾讯用户Code,涉及到用户信息的操作时需传入
spId Integer 10 服务商ID

# 4.1 车主审核状态变更通知

# 请求地址
  • /v1/callback/driver/status
# 请求参数
参数名称 类型 说明 必须
userStatus Integer 1-认证成功/正常、2-车主认证审核中、3-车主认证失败、4-车主认证过期、5-车主人脸识别认证过期、6-犯罪记录未通过
authFailureReasonList List 认证失败原因枚举列表,使用腾讯侧定义枚举值 认证失败时必传
# FailureReason
参数名称 类型 说明 必须
failureType Integer 认证失败原因枚举列表,使用腾讯侧定义枚举值
failureDesc String 认证失败原因枚举列表,使用腾讯侧定义枚举值
# 请求示例
{
  "accessKey": "QWERTYASDFGZXC",
  "seqId": "12345678910111213141516",
  "timestamp": 1234567891011,
  "nonce": "qwertyuiop",
  "userCode": "a1b2c7d5e9f8g1h",
  "userStatus": 1,
  "sign": "A1B2C3D4E5F6G7H8I9J0"
}
# 响应数据
参数名称 类型 说明 必须
- - - -
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.2 服务商同步创建车主行程

# 请求地址
  • /v1/callback/driver/trip/create
# 请求参数
参数名称 类型 说明 必须
spDriverTripId String 服务商车主行程ID
spDriverInfo DriverInfo 服务商车主信息
startAddr LocationInfo 行程起点
endAddr LocationInfo 行程终点
earliestDepartureTime Long 行程最早出发时间
latestDepartureTime Long 行程最晚出发时间
seatNum Integer 座位数
price Integer 总价格
seatUnitPrice Integer 单座位价格
remark String 备注信息
# DriverInfo
参数名称 类型 说明 必须
driverId String 服务商车主ID
driverName String 服务商车主昵称(如尾号8888)
drivingAge String 服务商车主驾龄
plateNo String 服务商车牌号
tripNum Integer 累计完单数
# 请求示例
{
  "seqId": "xyz789",
  "timestamp": 1234567891012,
  "spId": 1001,
  "spDriverTripId": "trip123456",
  "spDriverId": {
    "driverId": "driver123456",
    "driverName": "张三",
    "drivingAge": "5年",
    "plateNo": "粤B88888",
    "tripNum": 100
  },
  "startAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "起点名称",
    "address": "起点详细地址",
    "cityName": "北京市",
    "districtName": "东城区",
    "townName": "东华门街道"
  },
  "endAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "终点名称",
    "address": "终点详细地址",
    "cityName": "北京市",
    "districtName": "东城区",
    "townName": "东华门街道"
  },
  "earliestDepartureTime": 1234567891013,
  "latestDepartureTime": 1234567891014,
  "seatNum": 4,
  "price": 500,
  "seatUnitPrice": 50,
  "remark": "备注信息"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data SpDriverTripCreateResData 响应数据
# SpDriverTripCreateResData
参数名称 类型 说明 必须
driverTripId String 腾讯侧车主行程ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "driverTripId": "driverTrip123456"
  }
}

# 4.3 服务商修改车主行程

# 请求地址
  • /v1/callback/driver/trip/modify
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧行程ID
spDriverTripId String 服务商车主行程ID
spDriverInfo DriverInfo 服务商车主信息
startAddr LocationInfo 行程起点
endAddr LocationInfo 行程终点
earliestDepartureTime Long 行程最早出发时间
latestDepartureTime Long 行程最晚出发时间
seatNum Integer 座位数
price Integer 总价格
seatUnitPrice Integer 单座位价格
remark String 备注信息
# 请求示例
{
  "seqId": "def789",
  "timestamp": 1234567891016,
  "spId": 1001,
  "tripId": "order123456",
  "spDriverId": {
    "driverId": "driver123456",
    "driverName": "张三",
    "drivingAge": "5年",
    "plateNo": "粤B88888",
    "tripNum": 100
  },
  "startAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "起点名称",
    "address": "起点详细地址",
    "cityName": "北京市",
    "districtName": "东城区",
    "townName": "东华门街道"
  },
  "endAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "终点名称",
    "address": "终点详细地址",
    "cityName": "北京市",
    "districtName": "东城区",
    "townName": "东华门街道"
  },
  "earliestDepartureTime": 1234567891017,
  "latestDepartureTime": 1234567891018,
  "seatNum": 4,
  "seatUnitPrice": 50,
  "remark": "修改备注信息"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.4 服务商同步的车主行程状态变更(具有取消功能)

# 请求地址

/v1/callback/driver/trip/status

# 请求参数
字段名 类型 描述 是否必填
tripId String 腾讯侧行程ID
spTripId String 服务商行程ID
tripStatus Integer 行程状态(具体状态值需定义)
# tripStatus行程状态值定义
状态值 描述
201 创建行程(进行中)
901 行程已完成
902 行程已过期
910 行程已取消
# 返回参数
# BaseRes
字段名 类型 描述
code Integer 返回码,0表示成功,非0表示失败
message String 返回信息
# 示例请求
{
  "seqId": "abc123",
  "timestamp": 1633036800000,
  "spId": 1001,
  "tripId": "trip_001",
  "tripStatus": 201
}
# 示例响应
{
  "code": 0,
  "message": "成功"
}

# 4.5 服务商车主接受乘客占座邀请

# 请求地址
  • /v1/callback/driver/invite/accept
# 请求参数
参数名称 类型 说明 必须
applyId String 申请单ID
tripId String 行程ID
# 请求示例
{
  "seqId": "jkl345",
  "timestamp": 1234567891020,
  "spId": 600010,
  "applyId": "driverTrip123456",
  "tripId": "trip123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.6 服务商车主将乘客踢出行程

# 请求地址
  • /v1/callback/driver/trip/kick
# 请求参数
参数名称 类型 说明 必须
tripId String 服务商同步到腾讯侧生成的车主行程ID
applyId String 乘客申请单ID
# 请求示例
{
  "seqId": "pqr901",
  "timestamp": 1234567891022,
  "spId": 1001,
  "tripId": "driverTrip123456",
  "applyId": "apply123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.7 (二期)服务商车主向乘客发起上车邀请

# 请求地址
  • /v1/callback/driver/invite/request
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧乘客行程ID
spDriverInfo DriverInfo 服务商车主信息
seatUnitPrice Integer 车主邀请乘客时的每座价格,单位:分
applyStartAddr LocationInfo 申请起点信息
applyEndAddr LocationInfo 申请终点信息
# 请求示例
{
  "seqId": "ghi012",
  "timestamp": 1234567891019,
  "spId": 600010,
  "tripId": "passengerTrip123456",
  "spDriverInfo": {
    "driverId": "driver123456",
    "driverName": "张三",
    "drivingAge": 5,
    "plateNo": "粤B88888",
    "tripNum": 100
  },
  "seatUnitPrice": 50,
  "applyStartAddr": {
    "lng": 116.397128,
    "lat": 39.916527,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "天安门",
    "address": "天安门广场",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "天安门"
  },
  "applyEndAddr": {
    "lng": 116.405285,
    "lat": 39.904989,
    "cityCode": "110000",
    "adCode": "110101",
    "phoneAreaCode": "010",
    "name": "故宫",
    "address": "故宫博物院",
    "cityName": "北京",
    "districtName": "东城区",
    "townName": "故宫"
  }
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.applyId String 申请单ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "applyId": "apply123456"
  }
}

# 4.8 (二期)服务商车主取消/撤销上车邀请

# 请求地址
  • /v1/callback/driver/invite/cancel
# 请求参数
参数名称 类型 说明 必须
spDriverId String 服务商车主ID
tripId String 腾讯侧乘客行程ID
applyId String 申请单ID
# 请求示例
{
  "seqId": "ghi012",
  "timestamp": 1234567891019,
  "spId": 600010,
  "spDriverId": "driver123456",
  "tripId": "passengerTrip123456",
  "applyId": "apply123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.8 服务商车主发送IM消息给乘客

# 请求地址
  • /v1/callback/im/message/send
# 请求参数
参数名称 类型 说明 必须
spDriverId String 服务商司机ID
tripId String 会话关联行程ID
messageType Integer 消息类型 文字0/图片1/定位2
messageBody MessageBody 消息内容
messageBody.text String 文本消息
messageBody.url String 图片/语音URL
messageBody.duration Integer 语音时长
spMessageId String 服务商生成的消息ID
# 请求示例
{
  "seqId": "stu234",
  "timestamp": 1234567891023,
  "spId": 1001,
  "userCode": "driverTrip123456",
  "spDriverId": "driver001",
  "tripId": "trip123456",
  "messageType": 0,
  "messageBody": "你好,欢迎上车!",
  "spMessageId": "msg123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.messageId String 腾讯侧消息ID
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "messageId": "msg123456"
  }
}

# 4.9 服务商车主单会话已读

# 请求地址
  • /v1/callback/im/message/read/session
# 请求参数
参数名称 类型 说明 必须
tripId String 腾讯侧行程ID
spDriverId String 服务商车主ID
userCode String 腾讯侧参与会话的用户userCode
messageIdList List 腾讯侧消息ID列表
spMessageIdList List 服务商消息ID列表
# 请求示例
{
  "seqId": "stu234",
  "timestamp": 1234567891023,
  "spId": 1001,
  "tripId": "trip123456",
  "spDriverId": "driver001",
  "userCode": "driverTrip123456",
  "messageIdList": ["string1", "string2"],
  "spMessageIdList": ["string1", "string2"]
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.10 服务商车主全部已读

# 请求地址
  • /v1/callback/im/message/read/all
# 请求参数
参数名称 类型 说明 必须
spDriverId String 服务商车主ID
# 请求示例
{
  "seqId": "stu234",
  "timestamp": 1234567891023,
  "spId": 1001,
  "spDriverId": "driver001"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 4.11 司机获取乘客虚拟号请求

# 请求地址
  • /v1/callback/passenger/phone/get
# 请求参数
参数名称 类型 说明 必须
srcPhone String 来电号码
tripId String 乘客行程ID(腾讯导出场景乘客行程ID) 是,tripId和applyId必选其一
applyId String 乘客申请单ID(腾讯申请占座时的申请ID) 是,tripId和applyId必选其一
# 请求示例
{
  "seqId": "abc987",
  "timestamp": 1234567891100,
  "tripId": "trip123456"
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
data Object 响应数据
data.virtualPhone String 虚拟号
data.expireTime Long 过期时间
# 响应示例
{
  "code": 0,
  "message": "成功",
  "data": {
    "virtualPhone": "12345678901",
    "expireTime": 1633040400
  }
}

# 4.12 服务商通话记录同步

  • 车主给乘客打电话无需再调用腾讯侧虚拟号接口,直接使用下单接口的手机号绑定虚拟号即可,并将通话状态同步到腾讯侧
# 请求地址
  • /v1/callback/call/record/sync
# 请求参数
参数名称 类型 说明 必须
spDriverInfo DriverInfo 服务商车主信息
tripId String 腾讯行程ID
srcPhone String 主叫号码
destPhone String 被叫号码
caller Integer 主叫人 1-乘客,2-车主
callTime Long 呼叫时间,毫秒级时间戳
callStatus Integer 呼叫状态,见枚举值
# DriverInfo
字段名 类型 说明
driverId String 车主ID
driverName String 车主昵称
drivingAge String 驾龄
plateNo String 车牌号
tripNum Integer 累计完单数
driverRegisterTime Long 车主注册时间
# 通话状态枚举值
状态 描述
UNKNOWN(0) 未知/默认
CALLING(1) 呼叫中,未拨通
RINGING(2) 已拨通,响铃中(一直停留在这个状态即表示未接听)
ACCEPTED(3) 已接听
REJECTED(4) 已拒接
NORMAL_HANGUP(5) 正常挂断
CALL_FAILED(6) 呼叫失败/异常(兜底未拨通)
# 请求示例
{
  "spDriverId": "driver_123456",
  "tripId": "trip_987654321",
  "srcPhone": "13800138000",
  "destPhone": "13900139000",
  "caller": 1,
  "callTime": 1672500000000,
  "callStatus": 2
}
# 响应数据
参数名称 类型 说明 必须
code Integer 响应状态码
message String 响应信息
# 响应示例
{
  "code": 0,
  "message": "成功"
}

# 5. 附录

# 5.1 车主审核失败原因枚举

# 5.1.1 身份证错误信息

腾讯枚举值 错误描述
1001 身份证姓名错误(可注明具体原因)
1002 身份证号错误(可注明具体原因)
1003 年龄不足18岁,暂不支持认证车主
1004 年龄超过65岁,暂不支持认证车主
1005 实名审核未通过

# 5.1.2 驾驶证错误信息

腾讯枚举值 错误描述
2001 身份信息类错误(可注明具体原因)
2002 初次领证日期异常,请修改
2003 你还在实习期内,暂不支持认证车主
2004 驾驶证有效开始日期异常,请重新上传
2005 该驾驶证已失效,请上传有效期内的证件
2006 暂无实名/驾驶证审核记录
2007 暂无驾驶证信息

# 5.1.3 行驶证错误信息

腾讯枚举值 错误描述
3001 车牌号填写有误,请检查
3002 车辆品牌型号有误,请检查
3003 车辆使用性质有误,请检查
3004 车辆颜色有误,请检查
3005 行驶证注册时间不得超过15年
3006 注册日期异常,请上传有效期内的证件
3007 暂无车辆审核记录

# 5.1.4 其他

腾讯枚举值 错误描述
9001 其他(可注明具体原因)

# 5.2 接口错误码

错误码 描述
0 成功
-1 服务内部错误
1 回调请求签名校验不通过
2 回调请求参数错误
20 回调处理失败

# 5.3 服务商ID

spId 错误描述
600010 一喂顺风车