# **1** 温馨提示

!>常见问题
- Q: 为什么点击同意授权没有反应，第二次点击就提示'重复的订单号'了？
- A: 本数据服务适用于已安装支付宝软件的手机，所以请保证生成的h5地址是在手机浏览器（或者贵方的app产品（需要app端支持alipayqr这个schema,并且需保证贵方app产品的user-agent为原生，h5会根据ua去判断操作系统是安卓还是ios去唤醒支付宝app），不能在微信打开）打开,详细流程请看4.5界面相关 
- Q: 为什么老是报token已失效？ 
- A：token是全局的，2个小时会自动失效。新的token生成老的会立即失效。
    token的管理： 建议贵方最好单独起个线程去管理，每隔一小时50分钟来取一次token，然后存到数据库或者缓存里，每次有用到直接去数据库或缓存里取
 
- A: 如问题还未解决，请联系技术支持


!>欢迎你成为旭咪数据服务的合作方，在开始接口调用之前请先确保完成以下事项：
>1. 完成 `合作方入驻` 流程，并已经完成本产品`签约`；
2. 你需要获取一个 `appKey` 和 `appSecret`；
3. 通信协议只支持 `HTTPS`
4. 整个流程可以分为`用户授权`和`获取数据`, `用户授权`方式为唤醒支付宝`APP`进行授权, `获取数据`只支持`API`
5. `订单号（order_id）`是合作方与旭咪数据服务系统产生业务交互的唯一凭证，生成规则参考 `4.2`；
6. 关于第三方如何知道唤醒并且进行授权的支付宝是否是本人的问题，详情参考`4.6`；




# **2** 开始接入

## **2.1** H5接入
!> 访问之前需要生成订单号，生成过程见附录。

 <table>
   <tr>
      <td>DOMAIN</td>
      <td colspan=4>网关</td>
   </tr>
   <tr>
      <td>PATH</td>
      <td  colspan=4>zmop/index</td>
   </tr>
   <tr>
      <td>METHOD</td>
      <td colspan=4>GET</td>
   </tr>
   <tr>
      <td rowspan=15>GET参数</td>
      <td>参数名</td>
      <td>参数类型</td>
      <td>参数描述</td>
      <td>可空</td>
   </tr>
   <tr>
         <td>appKey</td>
         <td>string</td>
         <td>平台发放给开发者的标识开发者身份的标识符</td>
         <td>NO</td>
     </tr>
   <tr>
      <td>order_id</td>
      <td>string</td>
      <td>订单号</td>
      <td>NO</td>
   </tr>
   <tr>
      <td>redirect</td>
      <td>string</td>
      <td>用户授权结束之后, 接收授权结果的异步回调地址, 须urlEncode,</td>
      <td>NO</td>
   </tr>
   <tr>
      <td>extras</td>
      <td>string</td>
      <td>合作方自定义数据, 会作为异步回调地址的参数返回给合作方</td>
      <td>YES</td>
   </tr>
   <tr>
      <td>cert_no</td>
      <td>string</td>
      <td>用户的身份证号</td>
      <td>YES</td>
   </tr>
   <tr>
      <td>cert_name</td>
      <td>string</td>
      <td>用户的姓名</td>
      <td>YES</td>
   </tr>
   <tr>
      <td>cert_phone</td>
      <td>string</td>
      <td>用户的手机号</td>
      <td>YES</td>
   </tr>
   <tr>
      <td>readonly</td>
      <td>string</td>
      <td>默认为`0`, 当值为`1`时, 传入的用户三要素不能被用户修改</td>
      <td>YES</td>
   </tr>
      <tr>
      <td>customUrl</td>
      <td>string</td>
      <td>用户授权结束展示的页面, 默认为我方的结果页, 须urlEncode </td>
      <td>YES</td>
   </tr>
   <tr>
      <td>modify_no</td>
      <td>string</td>
      <td>不管readonly是否为1, 该值为1, 表示用户可以修改身份证</td>
      <td>YES</td>
   </tr>
         <tr>
      <td>modify_name</td>
      <td>string</td>
      <td>不管readonly是否为1, 该值为1, 表示用户可以修改姓名</td>
      <td>YES</td>
   </tr>
         <tr>
      <td>modify_phone</td>
      <td>string</td>
      <td>不管readonly是否为1, 该值为1, 表示用户可以修改手机号</td>
      <td>YES</td>
   </tr>
            <tr>
      <td>desensitized</td>
      <td>string</td>
      <td>该值为`1`, 表示在页面上显示的用户三要素是脱敏的(当用户自己修改或输入是不脱敏的)</td>
      <td>YES</td>
   </tr>
</table>


## **2.2** 用户授权结束通知

**通知说明**
>-当用户授权结束之后, 采用`服务端通知`到合作方, `只通知一次, 需返回状态码为200的http响应`
-通知地址为传入的redirect。注意：`redirec`里不要有`#`等特殊字符，且要包含协议名（`http`或`https`）

**请求方式：**
- Method: POST
- Content-type: application/json
- Charset: UTF-8

**参数：**

|参数名|必选|类型|说明|
|:----    |:---|:----- |-----   |
|status |是  |string |订单号对应状态(success/fail)   |
|msg  |是  |string | 任务结果的描述|
|order_id |是  |string | 任务订单号    |
|extras |否  |string |  合作方自定义数据|

 **请求示例**
```json
    {
        "status": "success",
        "msg": "操作成功",
        "order_id": "20180************tfLVD232",
        "extras": "esljdsd"
    }
```

## **2.3** 用户授权结束页面

**说明**
>当用户授权结束之后, 默认结果页为我方的页面, 如需自定义页面, 可在进入H5时传入`customUrl`。注意：`customUrl`里不要有`#`等特殊字符，且要包含协议名（`http`或`https`）

**`customUrl`上拼接以下参数:**

|参数名|必选|类型|说明|
|:----    |:---|:----- |-----   |
|status |是  |string |订单号对应状态(success/fail)   |
|msg  |是  |string | 任务结果的描述|
|order_id |是  |string | 任务订单号    |
|extras |否  |string |  合作方自定义数据|



# **3**  获取用户数据

**简要描述：**

- 根据订单号获取用户数据
- 需要签名，签名参数为params里面的参数，签名算法见`附录4.1`

## **3.1** 获取访问令牌token

>**请求URL：** 
- ` zmop/getToken `
  
------------

>**请求方式：**


>- Method: POST
- Content-Type: application/json
- Charset: UTF-8

------------


> **参数：** 
>
|参数名|必选|类型|说明|
|:----    |:---|:----- |-----   |
|sign |是  |String |签名   |
|appKey |是  |String |公钥   |
|timestamp |是  |String | 时间戳 （单位：ms）   |

------------

 >**请求示例**


``` json

{
	"sign":"SDSKKL5KJJKLL6JK1L",
	"params":{
		"appKey":"3FD179425381644F95424B66BE06E3E4",
		"timestamp":"1494828184314"
	}
}
```


 >**返回示例1**

``` json
{
  "code": 0,
  "data": {
    "token": "cd4283827366490eb037bf1b4b28dadc"
  }
}
```

 >**返回示例2**

``` json
{
  "code": -1,
  "msg": "参数错误"
}
```

 >**返回参数说明** 

>|参数名|类型|说明|
|:-----  |:-----|-----                           |
|token |String   |访问令牌(Token的有效期为2小时，当Token未失效时调用该接口，则返回新的Token，有效期重新计算，老的Token同时失效) |
|code |String   |状态码 |
|msg |String   |错误信息 |


------------



## **3.2** 获取芝麻分数据


**请求URL：**
- `zmop/data/score `

**请求方式：**
- Method: POST
- Content-type: application/json
- Charset: UTF-8

**参数：**

|参数名|必选|类型|说明|
|:----    |:---|:----- |-----   |
|appKey |是  |string |公钥   |
|timestamp |是  |string | 时间戳 （单位：ms）   |
|sign     |是  |string | 签名    |
|token     |是  |string | 访问令牌    |
|order_id |是  |string | 任务订单号    |
|refresh |否  |string | 默认为`0`, 值为`1`时表示获取最新的数据, 需用户未取消授权, 否则返回`鉴权失败`|


 **请求示例1**
 ``` json
  {
    "sign":"89D89A1D07E875C649D6A2D03F8E650A",
    "params":{
        "appKey": "88A03809137291F333BF2689AB85850E",
        "timestamp":"3412xxxxxx01234567",
        "token":"xx",
        "order_id":"20180408121212555qwe23qwe1232sde"
    }
  }
```

 **请求示例2**
 ``` json
  {
    "sign":"89D89A1D07E875C649D6A2D03F8E650A",
    "refresh":"1",
    "params":{
        "appKey": "88A03809137291F333BF2689AB85850E",
        "timestamp":"3412xxxxxx01234567",
        "token":"xx",
        "order_id":"20180408121212555qwe23qwe1232sde"
    }
  }
```

 **返回示例1**

``` json
  {
    "code": "0",
    "data": {
		//此处参考附录 4.3
		...
		
	}
  }
```
 **返回示例2**

``` json
  {
    "code": -1,
    "msg": "无此订单数据"
  }
```

 **返回参数说明**

|参数名|类型|说明|
|:-----  |:-----|-----                           |
|data |String   |数据结构参照4.3 |
|code |String   |状态码  |
|msg |String   |错误信息  |


 >**备注**

 >  状态码对应的错误信息
- 0   -> 成功
- -1  -> 系统异常
- -1  -> 参数错误
- -1  -> 时间戳超时
- -1  -> 无效的appKey
- -1  -> 签名错误
- -1  -> 您未开通权限
- -1  -> 无此订单号
- -1  -> 鉴权失败
- -1  -> token已失效

## **3.3** 获取行业关注名单数据


**请求URL：**
- `zmop/data/watch_list `

**请求方式：**
- Method: POST
- Content-type: application/json
- Charset: UTF-8

**参数：**

|参数名|必选|类型|说明|
|:----    |:---|:----- |-----   |
|appKey |是  |string |公钥   |
|timestamp |是  |string | 时间戳 （单位：ms）   |
|sign     |是  |string | 签名    |
|token     |是  |string | 访问令牌    |
|order_id |是  |string | 任务订单号    |
|refresh |否  |string | 默认为`0`, 值为`1`时表示获取最新的数据, 需用户未取消授权, 否则返回`鉴权失败`|


 **请求示例1**
 ``` json
  {
    "sign":"89D89A1D07E875C649D6A2D03F8E650A",
    "params":{
        "appKey": "88A03809137291F333BF2689AB85850E",
        "timestamp":"3412xxxxxx01234567",
        "token":"xx",
        "order_id":"20180408121212555qwe23qwe1232sde"
    }
  }
```


 **返回示例1**

``` json
  {
    "code": "0",
    "data": {
		//此处参考附录 4.4
		...
		
	}
  }
```
 **返回示例2**

``` json
  {
    "code": -1,
    "msg": "无此订单数据"
  }
```

 **返回参数说明**

|参数名|类型|说明|
|:-----  |:-----|-----                           |
|data |String   |数据结构参照4.4 |
|code |String   |状态码  |
|msg |String   |错误信息  |

 >**备注**

 >  状态码对应的错误信息
- 0   -> 成功
- -1  -> 系统异常
- -1  -> 参数错误
- -1  -> 时间戳超时
- -1  -> 无效的appKey
- -1  -> 签名错误
- -1  -> 您未开通权限
- -1  -> 无此订单号
- -1  -> 鉴权失败
- -1  -> token已失效



# **4** 附录

## **4.1** 签名算法

签名生成的通用步骤如下：

第一步，设所有发送或者接收到的数据为集合M，将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。

特别注意以下重要规则：

- 参数名ASCII码从小到大排序（字典序）；
- 如果参数的值为空不参与签名；
- 参数名区分大小写；

第二步，在stringA最后拼接上appSecret得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。

举例：
假设传送的参数如下：
``` json
appKey : 88A03809137291F333BF2689AB85850E,
timestamp : 1494649888152
```


第一步：对参数按照key=value的格式，并按照参数名ASCII字典序排序如下：
``` javascript
stringA="appKey=092217B6B52ED02D46EFFFA7CFA20940&timestamp=1494649888152";
```
第二步：拼接API密钥：
``` javascript
stringSignTemp=stringA+"&appSecret=192006250b4c09247ec02edce69f6a2d"
sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
```


## **4.2** 订单号


 释义
>`订单号（order_id）`是合作方（或机构）与旭咪数据服务系统产生业务交互的唯一凭证，具体表现为一个长度为 `32` 位的字符串，仅能包含 `0-9A-Za-z_-` 等字符。每一个订单号（order_id）表明了合作方（或机构）与旭咪数据服务系统产生了一次确定的业务交互，旭咪数据服务系统给出了一个确定的返回结果，并以此作为与旭咪数据服务系统明细对账的唯一依据



生成规则
>订单号（order_id）:前 `17` 位为精确到`毫秒`的时间值（yyyyMMddHHmmssSSS）作为前缀，以合作方（或机构）自行生成的不重复字符串作为后缀，组成 `32` 位的字符串。


## **4.3** 芝麻分数据结构


**数据字典**

|参数名|类型|说明|
|:-----  |:-----|-----                           |
|order_id |String   |订单号 |
|create_time |String   |从芝麻信用获取芝麻分的时间  |
|which_month |String   |最新芝麻分所属月|
|score |String   |芝麻分  |


### 数据样例

```json
{
    "score": "746",
    "which_month": "2018-04",
    "create_time": "2018-04-28 11:26:02",
    "order_id": "2018042710535*****QcPMRFLn8b7qYb"
  }
```


## **4.4** 行业关注名单数据结构

**数据字典**

|名称|类型|描述|
|:----    |:--- |-----   |
|order_id |String   |订单号 |
|create_time |String   |从芝麻信用获取数据的时间  |
|details |Array | 行业关注名单信息列表，由芝麻信用进行维护和升级    |
|isMatched |Boolean | true=命中 在关注名单中 false=未命中     |

**行业关注名单详细(details)信息详情:**

|名称|类型|描述|
|:----    |:---- |:-----   |
|biz_code |String   | 风险信息行业编码 |
|level |string   | 风险等级    |
|type     |String   | 	行业名单风险类型    |
|code     |String   | 风险编码     |
|refresh_time |Date | 数据刷新时间     |
|settlement |Boolean | 结清状态     |
|status     |String  | 用户本人对该条负面记录有异议时，表示该异议处理流程的状态     |
|statement |String | 当用户进行异议处理，并核查完毕之后，仍有异议时，给出的声明|
|extend_info     |Array | 扩展信息     |

**扩展信息(extend_info)信息详情:**

|名称|类型|描述|
|:----    |:--- |-----   |
|key |String | 补充信息字段的英文编码 |
|value |String | 	补充信息字段的信息内容    |
|description |String | 补充信息字段的中文描述     |


### 数据样例

```json
{
  "create_time": "2018-04-28 11:26:02",
  "order_id": "2018042710535*****QcPMRFLn8b7qYb",
  "details": [{   //行业关注名单信息列表，由芝麻信用进行维护和升级
    "biz_code": "AH",  //风险信息行业编码
    "code": "AH001002",  //风险编码
    "extend_info": [{    //扩展信息
      "description": "编号", //补充信息字段的中文描述
      "key": "id",  //	补充信息字段的英文编码
      "value": "testlwztestlwz0d090d794bd563ba6053244b35fb2ccc" //补充信息字段的信息内容
    }],
    "level": 0,  //风险等级
    "refresh_time": 1465488000000,  //	数据刷新时间
    "settlement": true, //结清状态
    "type": "AH001"  //行业名单风险类型
  }],
  "is_matched": true    //true=命中 在关注名单中 false=未命中
}

```

## 4.5 界面相关

>  查询流程，可点击放大查看


> ![step1](media/1.jpg)

## 4.6 关于判断授权支付宝是否是本人的相关问题

>  关于判断授权支付宝是否是本人的相关问题，我们询问了芝麻官方，给我们的答复是这个样子的：芝麻只会返回登录支付宝app的用户的分数

> ![answer](media/answer.png)

> 为此，我们提供了一个解决方案：在授权成功后，合作方可以选择去验证授权时传入的姓名是否和登录支付宝账户的用户姓名是否一致，一致则会正常通知，不一致则通知授权姓名与支付宝账户姓名不一致。



