目录

1. 开发准备

2. 时序图

3. 拉起发票列表(微信内)

3.1 接口说明

3.2 请求方式

3.3 返回结果

3.4 示例代码

4. 拉起发票列表(外部App)

4.1 接口说明

4.2 请求方式

4.3 返回结果

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

5.1 接口说明

5.2 请求方式

5.3 返回结果

6 备注

6.1 错误码

6.2 发票状态

6.3 获取api_ticket

6.3.1 请求方式

6.3.2 返回结果

6.3.3 示例代码

6.4 发票签名方法

# 1. 开发准备

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

(1)拥有微信服务号,并且已完成认证;

(2)拥有可以联网的打印机;

(3)拥有云端后台,可以对打印机发出指令。

# 2. 时序图

# 3. 拉起发票列表(微信内)

# 3.1 接口说明

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

本接口的调用须遵循JS-SDK的调用方法,请在开发前阅读JS-SDK说明文档以熟悉开发术语和基本接口的调用。

# 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 )获得一个已认证的微信开放平台账号;

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

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

4 )通读 微信开放平台资源中心中关于SDK使用的基本方法,并正确导入到自身的应用中。

# 4.2 请求方式

iOS 应用

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

Android 应用

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

# 4.3 返回结果

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

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

# 5.1 接口说明

报销方在上一步获得用户选择提交的电子发票标识参数后,可以通过该接口查询电子发票的结构化信息,并获取发票PDF文件。

# 5.2 请求方式

请求URL:https://api.weixin.qq.com/card/invoice/reimburse/getinvoiceinfo?access_token={access_token}

请求方法:POST

请求参数:

请求参数使用JSON格式,参数清单如下

参数 类型 是否必填 描述
card_id string 发票卡券的card_id
encrypt_code string 发票卡券的加密code,和card_id共同构成一张发票卡券的唯一标识

# 5.3 返回结果

数据格式:JSON

参数 类型 是否必填 描述
errcode Int 错误码
errmsg String 错误信息

当错误码为0时,有以下信息:

参数 类型 是否必填 描述
card_id String 发票id
begin_time Int 发票的有效期起始时间
end_time Int 发票的有效期截止时间
openid String 用户标识
type String 发票的类型,如广东增值税普通发票
payee String 发票的收款方
detail String 发票详情
user_info Object 用户可在发票票面看到的主要信息

user_info包含以下信息:

参数 类型 是否必填 描述
fee Int 发票加税合计金额,以分为单位
title String 发票的抬头
billing_time Int 开票时间,为十位时间戳(utc+8)
billing_no String 发票代码
billing_code String 发票号码
info List 商品信息结构,见下方说明
fee_without_tax Int 不含税金额,以分为单位
tax Int 税额,以分为单位
pdf_url String 这张发票对应的PDF_URL
trip_pdf_url String 其它消费凭证附件对应的URL,如行程单、水单等
reimburse_status String 发票报销状态,见 备注6.2
check_code String 校验码(必填)
buyer_number String 购买方纳税人识别号(选填)
buyer_address_and_phone String 购买方地址、电话(选填)
buyer_bank_account String 购买方开户行及账号(选填)
seller_number String 销售方纳税人识别号(选填)
seller_address_and_phone String 销售方地址、电话(选填)
seller_bank_account String 销售方开户行及账号(选填)
remarks String 备注
cashier String 收款人,发票左下角处(选填)
maker String 开票人,发票有下角处(选填)

info为发票项目明细信息。数据格式表现为Object列表,每个Object包含以下信息:

参数 类型 是否必填 描述
name String 项目(商品)名称
num Int 项目数量
unit String 项目单位
price Int 单价,以分为单位

# 6 备注

# 6.1 错误码

在微信电子发票报销方案中,涉及的错误码及错误码含义如下:

错误码 含义
0 成功
72015 没有操作发票的权限
72017 发票抬头不一致
72023 发票已被其他公众号锁定
72024 发票状态错误

# 6.2 发票状态

通过接口获取发票信息时,涉及的发票状态码及状态含义如下:

状态 含义
INVOICE_REIMBURSE_INIT 发票初始状态,未锁定,可提交报销
INVOICE_REIMBURSE_LOCK 发票已锁定,无法重复提交报销
INVOICE_REIMBURSE_CLOSURE 发票已核销,从用户卡包中移除

# 6.3 获取api_ticket

<span id = "21>

# 6.3.1 请求方式

请求URL:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card

请求方法:GET

# 6.3.2 返回结果

返回格式:JSON

参数 类型 是否必填 描述
errcode Int 错误码
errmsg String 错误信息
ticket String 发票签名临时票据,即为后续发票签名中需要使用的Api_ticket
expires_in Int 有效期,以秒为单位。在有效期内重复请求ticket不会被刷新

# 6.3.3 示例代码

返回:

{
 "errcode":0, 
 "errmsg":"ok", 
 "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKdvsdshFKA", 
 "expires_in":7200 
}

# 6.4 发票签名方法

在应用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。