**目录**

1. 开发准备

2. 时序图

3. 拉起发票列表（微信内）

3.1 接口说明

3.2 请求方式

3.3 返回结果

3.4 示例代码

4. 拉起发票列表（外部App）

4.1 接口说明

4.2 请求方式

4.3 返回结果

5 查询发票信息并获取PDF文档

6 获取api_ticket

7 发票签名方法

## 1. 开发准备

在开始开发前，请确认已提前做好以下准备工作：

（1）拥有微信服务号，并且已完成认证；

（2）拥有可以联网的打印机；

（3）拥有云端后台，可以对打印机发出指令。

## 2. 时序图

![](https://mmbiz.qpic.cn/mmbiz_png/PiajxSqBRaEJsqKkSJGg4THBibpJuQOS6W8SFibkUuT3ib9xxBSrZ6wDvA7ZOVSngWYyl13gmFt9vq0lQReHialYzkw/0?wx_fmt=png)

## 3. 拉起发票列表（微信内）

### 3.1 接口说明

该接口功能为在微信内拉起发票卡券列表（如下图所示），用户勾选需要提交打印的发票后，开发者获得所选发票的标识信息。

![](https://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEJsqKkSJGg4THBibpJuQOS6WKRRxvJRSBzhcjVQ7GbjZ750CxE5xIazWolvzhEWbheUr03d8LZL3aQ/0?wx_fmt=jpeg)

本接口的调用须遵循JS-SDK的调用方法，请在开发前阅读[JS-SDK说明文档](/doc/service/guide/h5/jssdk)以熟悉开发术语和基本接口的调用。

### 3.2 请求方式

参考示例代码，传入下表中的参数即可成功拉起发票列表页。

| 参数      | 类型       | 是否必填 | 描述                                                  |
| --------- | ---------- | -------- | ----------------------------------------------------- |
| timestamp | string(32) | 是       | 签名生成的时间戳，采用unix十位时间戳                  |
| nonceStr  | string(32) | 是       | 用于生成签名的随机字符串，签名生成方法， 参见 6.3     |
| signType  | string(32) | 是       | 签名类型，签名生成方法见 参见6.3                      |
| cardSign  | string(64) | 是       | 发票签名，按照文档 生成完签名后作为参数传入， 参见6.3 |

### 3.3 返回结果

用户点击确认或取消后，将按下表所列字段格式及含义返回结果。

| 返回字段               | 类型         | 值       | 含义               |
| ---------------------- | ------------ | -------- | ------------------ |
| err_msg choose_invoice | string       | ok       | 选取发票成功       |
| fail                   | 选取发票失败 |
| cancel                 | 选取发票取消 |
| choose_invoice_info    | object       | 对象列表 | 用户选中的发票列表 |

choose_invoice_info的对象结构如下

{ card_id = @"", encrypt_code = @"" app_id=@"" }

各字段含义如下：

| 字段         | 类型   | 描述                                                                                               |
| ------------ | ------ | -------------------------------------------------------------------------------------------------- |
| card_id      | string | 所选发票卡券的card_id                                                                              |
| encrypt_code | string | 所选发票卡券的加密code，打印服务商可以通过card_id和encrypt_code获得用户申请打印的发票信息及PDF文档 |
| app_id       | string | 开票方的appid                                                                                      |

获得card_id和encrypt_code后，开发者可以按照 查询发票信息并获取PDF文档 一节的方法，获取每张发票的结构化信息及PDF文件。

### 3.4 示例代码

```
wx.config({
            beta: true,
            debug: false,
            appId: "wx00000000000000",
            timestamp: 1489030247,
            nonceStr: "(9J4YRV[#@",
            signature: "f027317f8910000000000000000000",
            jsApiList: ['chooseInvoice']
 });
   wx.ready(function () {
            wx.invoke('chooseInvoice', {
                        'timestamp': 1489030247, // 卡券签名时间戳
                              'nonceStr':   "p(6N&7WOAF", // 卡券签名随机串
                          'signType': 'SHA1', // 签名方式，默认'SHA1'
                         'cardSign':   "a72043eed36c74300000000000000000" // 卡券签名
                      },  function(res) {
                               alert(JSON.stringify(res));
                      }
            });
 });
```

## 4. 拉起发票列表（外部App）

### 4.1 接口说明

微信也支持外部App拉起发票列表的接口。与微信内拉起发票列表接口相似，在用户勾选并点击确认后，可以获得发票的标识数据。

该接口须遵循JS-SDK的调用方法，并且必须满足一定条件才能调用。**请在开发前检查自己是否已满足以下条件**：

1 ）获得一个已认证的[微信开放平台](https://open.weixin.qq.com/)账号；

2 ）在微信开放平台上创建一个应用并提交应用通过审核。未注册应用的开发者可在开发者应用登记页面进行登记；

3 ）已下载微信电子发票报销SDK，iOS及Android下载地址见电子发票文档资源下载部分；

4 ）通读 [微信开放平台资源中心](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN)中关于SDK使用的基本方法，并正确导入到自身的应用中。

### 4.2 请求方式

**iOS 应用**

参考压缩包内的OpenSDK1.7.7文件，使用时调用WXChooseInvoice类。其中需要签名的部分，参考JS-SDK的调用方式。

**Android 应用**

参考压缩包内，进入jar文件，使用时调用WXChooseCard类，并传入CardType为“INVOICE”。其中需要签名的部分，参考JS-SDK的调用方式。

### 4.3 返回结果

返回结果请与微信内拉起发票列表的返回结果相同，参见3.3。

## 5 查询发票信息并获取PDF文档

## 6 获取api_ticket

## 7 发票签名方法

在应用JS-SDK和App SDK时需要进行签名，以便校验数据传输过程未被篡改，签名实现方法如下：

**参与签名参数**

| 参数       | 描述                                               |
| ---------- | -------------------------------------------------- |
| cardType   | 填入INVOICE                                        |
| timestamp  | 拉起发票列表时使用的时间戳（utc+8）                |
| appid      | 调用该接口的appid                                  |
| nonceStr   | 随机字符串                                         |
| api_ticket | 通过acess_token换取的临时票据，详情 参见6.3 |

**签名方法**

将 api_ticket、appid、timestamp、nonceStr、cardType的value值进行字符串的字典序排序。再将所有参数字符串拼接成一个字符串进行sha1加密，得到cardSign。

例如：api_ticket=aaa、appid=aab、timestamp=abc、nonceStr=bbc、cardType=cde，那么先拼成字符串aaaaababcbbccde，再将此字符串进行sha1加密，得到cardSign。
