# 接入说明

本文档展示了如何通过[http](https://book.e-buy.com/books/e-buy-40/page/7f100 "基于HTTP协议的通讯方式")请求，完成于易百电子凭证系统完成对接。 本文档主要面向的读者为各有需求接入电子凭证的，有一定开发能力的技术人员。

#### 本文档中必填字段仅限于易百自制码，第三方制码可能存在部分字段无法返回。在对接时可与易百技术人员沟通

#### 配置密钥

取码对接方对接时，需跟业务同事沟通后把公钥发送到指定邮箱。易百电子凭证系统会分配app\_id, version, saleChannelId, 易百电子凭证系统公钥等信息

开发者调用接口前需自行生成RSA密钥，RSA密钥包含：

- 应用私钥(APP\_PRIVATE\_KEY)
- 应用公钥(APP\_PUBLIC\_KEY）

#### RSA私钥与公钥生成方法

##### 1.运行 openssl

```
CMD> openssl

```

##### 2.生成明文RSA私钥

```
OpenSSL> genrsa -out rsa_private_key.pem 2048

```

- 其中 `rsa_private_key.pem` 为私钥保存的文件名，`2048`位为密钥长度
- 默认情况下，openssl 输出的密钥格式为 PKCS#1-PEM

##### 3.生成明文RSA公钥

```
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

```

- 其中 `rsa_private_key.pem` 为私钥保存的文件名，`rsa_public_key.pem`为公钥保存的文件名

##### 4.如果是Java语言，私钥需要转成PKCS8格式

```
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -out rsa_private_key.pkcs8 -nocrypt

```

- 其中 `rsa_private_key.pem` 为私钥保存的文件名，`rsa_private_key.pkcs8`为私钥PKCS8格式保存的文件名

生成密钥后在电子凭证管理中心进行密钥配置，配置完成后可以获取：

- 电子凭证公钥(WHALE\_PUBLIC\_KEY)。

#### 第三步：搭建和配置开发环境

##### 1.调用方法

<table id="bkmrk-%E5%86%85%E5%AE%B9-%E8%AF%B4%E6%98%8E-%E9%80%9A%E8%AE%AF%E6%96%B9%E5%BC%8F-%E9%87%87%E7%94%A8-https-"><thead><tr><th>内容</th><th>说明</th></tr></thead><tbody><tr><td>通讯方式</td><td>采用 HTTPS 方式访问</td></tr><tr><td>提交方法</td><td>POST (application/[json](https://book.e-buy.com/books/e-buy-40/page/7f100 "网络通信时的一种数据交互格式"))</td></tr><tr><td>交互数据格式</td><td>[JSON](https://book.e-buy.com/books/e-buy-40/page/7f100 "网络通信时的一种数据交互格式")</td></tr><tr><td>字符编码</td><td>UTF-8</td></tr><tr><td>签名算法</td><td>SHA256WithRSA</td></tr><tr><td>签名验证</td><td>提交和返回数据都需要验证签名</td></tr></tbody></table>

##### 2.报文结构

**请求报文和返回报文都采用如下的报文结构**

<table id="bkmrk-%E5%BA%8F%E5%8F%B7-%E5%8F%82%E6%95%B0-%E7%B1%BB%E5%9E%8B-%E5%8F%82%E8%80%83%E6%95%B0%E6%8D%AE-%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E-%E5%A4%87"><thead><tr><th>序号</th><th>参数</th><th>类型</th><th>参考数据</th><th>参数说明</th><th>备注</th></tr></thead><tbody><tr><td>1</td><td>action</td><td>String</td><td>MakeCode</td><td>交易类型</td><td>具体接口有详细说明</td></tr><tr><td>2</td><td>app\_id</td><td>String</td><td>2014072300007148</td><td>应用ID</td><td>开放平台分配给开发者的应用ID</td></tr><tr><td>3</td><td>biz\_content</td><td>String</td><td>BASE64</td><td>报文内容BASE64</td><td>具体接口中有详细说明，本域需要采用BASE64编码</td></tr><tr><td>4</td><td>timestamp</td><td>String</td><td>1483372334</td><td>Unix时间戳</td><td>单位：秒</td></tr><tr><td>5</td><td>version</td><td>String</td><td>20171212</td><td>版本号</td><td>用于兼容不同的报文协议对应后台不同的处理方式</td></tr><tr><td>6</td><td>sign</td><td>String</td><td>7E65B60DCFA42B04</td><td>数据签名</td><td>详见：签名算法</td></tr></tbody></table>

**注意事项**

- 其中biz\_content字段是对请求参数或返回参数进行BASE64编码后得到的，例如：

<div id="bkmrk-json-%7B-%22traceno%22%3A-%229"><div><div data-codetab="0">[JSON](https://book.e-buy.com/books/e-buy-40/page/7f100 "网络通信时的一种数据交互格式")</div></div><div><div data-codetab="0">```
<span class="token punctuation">{</span>
    <span class="token property">"traceNo"</span><span class="token operator">:</span> <span class="token string">"99000009100010101732123"</span><span class="token punctuation">,</span>
    <span class="token property">"originalTraceNo"</span><span class="token operator">:</span> <span class="token string">"99000009100010101732124"</span>
<span class="token punctuation">}</span>
```

</div></div></div>- BASE64编码后得到：

```
ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ==

```

- 赋值给biz\_content字段。
- 如果请求报文无法解析，或传过来的app\_id无效，则异常提示返回的报文中sign字段为空。

**报文举例**

<div id="bkmrk-json-%7B-%22action%22-%3A-%22e"><div><div data-codetab="0">[JSON](https://book.e-buy.com/books/e-buy-40/page/7f100 "网络通信时的一种数据交互格式")</div></div><div><div data-codetab="0">```
<span class="token punctuation">{</span>
     <span class="token property">"action"</span> <span class="token operator">:</span> <span class="token string">"efuli.cashvoucher.send"</span><span class="token punctuation">,</span>
     <span class="token property">"app_id"</span> <span class="token operator">:</span> <span class="token string">"2014072300007148"</span><span class="token punctuation">,</span>
     <span class="token property">"biz_content"</span> <span class="token operator">:</span> <span class="token string">"ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ=="</span><span class="token punctuation">,</span>
     <span class="token property">"timestamp"</span> <span class="token operator">:</span> <span class="token string">"1483372334"</span><span class="token punctuation">,</span>
     <span class="token property">"version"</span> <span class="token operator">:</span> <span class="token string">"20171212"</span><span class="token punctuation">,</span>
     <span class="token property">"sign"</span> <span class="token operator">:</span> <span class="token string">"7E65B60DCFA42B04"</span>
 <span class="token punctuation">}</span>
```

</div></div></div>##### 3.签名算法

#### a.筛选并排序

获取所有请求参数，不包括字节类型参数，如文件、字节流，剔除sign字段，剔除值为空的参数，并按照第一个字符的键值ASCII码递增排序（字母升序排序），如果遇到相同字符则按照第二个字符的键值ASCII码递增排序，以此类推。

- 注意：biz\_content字段需要先Base64编码，再进行拼接

#### b.拼接

将排序后的参数与其对应值，组合成“参数=参数值”的格式，并且把这些参数用&amp;字符连接起来，此时生成的字符串为待签名字符串。

#### c.签名值计算

使用各自语言对应的SHA256WithRSA签名函数利用应用私钥（APP\_PRIVATE\_KEY）对待签名字符串进行签名，并进行Base64编码。

**示例报文**

```
 {
     "action" : "efuli.cashvoucher.send",
     "app_id" : "102410000",
     "biz_content" : "ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ==",
     "timestamp" : "1483372334",
     "version" : "20171212",
     "sign" : "7E65B60DCFA42B04"
 }

```

**应用私钥（APP\_PRIVATE\_KEY）**

```
-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCdR0+PdnzkvvaNbSEp5Q8RpaelnrHu4msHAPiw1/DJXFPucoEPqPmDAq4IoaW02/mbvHQGr8d/g/g+cbCqUVctl8ygigTvlOAsoWJWrd76gk9lK+SsQBx3BN1pMbPADAljtFS3oJw10MjCg/wIgmwWaqdCRB1QGwJzw3HnripbHr59BKMv/VYPvgDJx+ohQrfLd9fysbJRcsQKqCs72jxD8U9KHO87upvpZtJT2QYdVrntsWL1UUxfyEIKmZy2Lf3UZvqKC4sahgH6pQhCMIhwBWm06FyktRji1ewNfF6zIpkCla/HvJzfqXaqhouXJm2qgRjJ/crfTjONdd/9iuNlAgMBAAECggEAS4GbwY0p4ouHRFha7okIVfmIZautUrkilscxnXzeHV2U8cnJCiKePvY/ZOdt7UkaKVks/rTO+vn5aMkd/nZ0evAAjiYUvoxjnymPU3u/q9Z5lWGgM83HnKAaR9FTsWRV8ab2cP3LYM6uQywoCFHM4GotiFO5GucMo1T2Tzq/HOUAjMzQASQ0ywaANZvNoZDw6ScMPUgGnYnHWbs34l7F2abyKyDiNo7sPtMtRpFYi+go+S7dygMX0G1IFoCIr4X2HNu/4e3XIFvJjzoUhCF/byDcM992LvcWVgM3Ke/F1oBm+bCFit67hN6mxoi2SEARdQGnBysvVo1FLPHKZ60FVQKBgQDidFk8hq8YKEvcjqPSJSd8Oo30zeyWf0R/QNLQOAIqYKCJAcAiHDcYMx5clQQxjFTYXriY+B1J3he6w3+5NStZqL1o1lcy5w7dhcVFXT1yn2KwUiO6YSJ25KeJHvXtDH66WGIQJMmbg90J2u4HRJxYNODmeVdS1seK5qaL0uxs6wKBgQCxzHbdbkoiJgFd/c7BdTKnZh2h6x7SsX44IcbTqKsx7zA61ogoegHaKB4yq3xaR8Gm9uazo5SCtbjS0bO5iQLrv8oLUDaNm5Ckm2ENk/M+TB0Hq24eFytiwUAS6FmdCncjq4xb2x8mqOQQiGvlyD91Na4HRBwxP16Wqwhz3Nac7wKBgAY1lIDRXJm3+SSKELnhZOzGGkBdKSCTSsiGeYFWF9Ebpys6jg8hYO1b8XguadgF9gmcx0kCfKMa4OGxHJ5yc8bYlqD6R5fQuBqg4WDehqHO9wDIr8wbf7ts158t5yZh0lO/uqigqZqHCheMFjzCx9qvUH9hUmCmHQCVBHoPBYaTAoGBAJcixAPURaYjglQAdOlUE3vivNuvvqLBCBb090tifCvVM71AMbuegsaMBadyyCECECY6iL85FPvLN1HVuh3DzrzRahEV3VmgXGLgRa7CDintj1u+qLthXJr0xN+NrOdmRwIGSCio6iD1vfAj1vwbrX2X5Nf+WKywPlp7BpNerPv3AoGALv4iJpOJVAW3Pmuvmc1a3cAsAvv0DGjiGOXn+IyBdX9tJtKppVPEwElibNAltvvgWX++5ctYD2SXNQLV56rkZCmauXP2gTPG3tCutH4jNiNIBUCfDXlt9DDyQAe0KfRFemzIa5rTWA7wRNsVTCm3n4ZqPlKfMC4HmOGU2hgN3LY=
-----END RSA PRIVATE KEY-----

```

**拼接报文参数**

<div id="bkmrk-string-list-action%3De"><div><div data-codetab="0">String</div><div data-codetab="1">List</div></div><div><div data-codetab="0">```
action=efuli.cashvoucher.send&app_id=<span class="token number">2014072300007148</span>&biz_content=ewogICAgICAgICAidHJhY<span class="token number">2</span>VObyI<span class="token number">6</span>ICI<span class="token number">5</span>OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW<span class="token number">5</span>hbFRyYWNlTm<span class="token number">8</span>iOiAiOTkwMDAwMDkxMDAwMTAxMDE<span class="token number">3</span>MzIxMjQiCiAgICAgfQ==&timestamp=<span class="token number">1483372334</span>&version=<span class="token number">20171212</span>
```

</div></div></div>**签名值计算**

```
gUTdEB0lAS/ECkP98weSHf6k31Fmd4hcw0zPG8ewbMTfDFSubKlel/1C16upb2AHzN873HMwUlkcTg7ZuN92KDIkfsbINd2IwVY2tWMvKt5O8gqC2a8XbS25ZObUlLK5zZmU7mQ/DLbyY+EAhkYdGnwskloJkydi2zmLv99xT5G01yXBLSNiTrPBTsc2OhBkA44kknnok0x+hS4HfcgQwGPMG4y+V5aT1bhPDypwdbfAg+EN/5XoSECsIcsvBirdk+BGPjBIuwHHF+Hir/3E3i20ImtlowBc6jwh5qFOVqGN/w2UEPfg6xJxHyW04FBipt6mw7huD4PA4pA4qZRnsg==

```

**签名Demo Java版**

[点击下载 signdemo.zip](https://gitbook.e-fuli.com/ebuy-whale-api/assets/signdemo.zip)