目录
1. 开发准备
2. 用户获取电子发票流程
2.1 交互流程
2.2 时序图
3. 获取授权页链接
3.1 获取授权页ticket
3.1.1 接口说明
3.1.2 请求方式
3.1.3 返回结果
3.1.4 示例代码
3.2 获取授权页链接
3.2.1 接口说明
3.2.2 请求方式
3.2.3 返回结果
3.2.4 示例代码
3.3 不同场景下获取授权页链接
3.3.1 微信内H5跳转授权页
3.3.2 App跳转授权页
3.3.3 PC网页拉起授权页
4. 设置授权页字段信息
4.1 接口说明
4.2 请求方式
4.3 返回结果
4.4 示例代码
5. 查询授权页字段信息
5.1 接口说明
5.2 请求方式
5.3 返回结果
5.4 示例代码
6. 获取授权完成状态
6.1 收取授权完成事件推送
6.1.1 接口说明
6.1.2 返回结果
6.1.3 示例代码
6.2 查询授权完成状态
6.2.1 接口说明
6.2.2 请求方式
6.2.3 返回结果
6.2.4 示例代码
7. 拒绝开票
7.1 接口说明
7.2 请求方式
7.3 返回结果
7.4 示例代码
8. 将电子发票卡券插入用户卡包
8.1 接口说明
8.2 请求方式
8.3 返回结果
8.4 示例代码
9. 向用户提供发票或其它消费凭证PDF
9.1 上传PDF
9.1.1 接口说明
9.1.2 请求方式
9.1.3 返回结果
9.1.4 示例代码
9.2 查询已上传的PDF文件
9.2.1 接口说明
9.2.2 请求方式
9.2.3 返回结果
9.2.4 示例代码
10. 更新发票卡券状态
10.1 接口说明
10.2 请求方式
10.3 返回结果
10.4 示例代码
11. 状态更新事件推送
11.1 接口说明
11.2 返回结果
11.3 示例代码
12. 备注
12.1 错误码清单
12.2 发票报销状态一览表
12.3 发票跳转链接协议
12.4 解码code接口
12.4.1 接口说明
12.4.2 请求方式
12.4.3 返回结果
12.4.4 示例代码
1. 开发准备
开票平台或自建平台商户通过用户的授权,可以在开票完成后将发票以卡券形式插入用户卡包。在调用本章节相关接口前请确认已完成了如下准备:
1)已完成公众号的开通和认证;
2)公众号已启用卡券能力;
在此基础上,若商户希望在开票流程中唤起授权页、调用用户微信中已保存的发票抬头信息,需申请微信电子发票商户权限。
若开票平台或自建平台商户需要通过微信递送发票,需申请微信电子发票开票平台权限。
2. 用户获取电子发票流程
2.1 交互流程
2.2 时序图
- 获取授权页链接
3.1 获取授权页ticket
3.1.1 接口说明
商户在调用授权页前需要先获取一个7200s过期的授权页ticket,在获取授权页接口中,该ticket作为参数传入,加强安全性。
3.1.2 请求方式
请求URL:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card
请求方法:GET
3.1.3 返回结果
数据格式:JSON
参数
类型
是否必填
描述
errcode
Int
是
错误码,含义见本节备注
errmsg
String
是
错误信息,含义见本节备注
ticket
String
是
临时票据,用于在获取授权链接时作为参数传入
expires_in
Int
是
ticket的有效期,一般为7200秒
3.1.4 示例代码
返回:
{
“errcode”: 0,
“errmsg”:”ok”,
“ticket”:”m7RQzjA_ljjEkt-JCoklRM5zrzYr-6PI09QydZmNXXz-opTqMv53aFj1ykRt_AOtvqidqZZsLhCDgwGC6nBDiA”,
“expires_in”: 7200
}
3.2 获取授权页链接
3.2.1 接口说明
本接口供商户调用。商户通过本接口传入订单号、开票平台标识等参数,获取授权页的链接。在微信中向用户展示授权页,当用户点击了授权页上的“领取发票”/“申请开票”按钮后,即完成了订单号与该用户的授权关系绑定,后续开票平台可凭此订单号发起将发票卡券插入用户卡包的请求,微信也将据此授权关系校验是否放行插卡请求。
授权页包括三种样式,商户可以通过传入不同type的值进行调用。各样式授权页如下图所示:
不同样式授权页作用如下:
type=0(申请开票类型):用于商户已从其它渠道获得用户抬头,拉起授权页发起开票,开票成功后保存到用户卡包;
type=1(填写抬头申请开票类型):调用该类型时,页面会显示微信存储的用户常用抬头。用于商户未收集用户抬头,希望为用户减少填写步骤。需要留意的是,当使用支付后开票业务时,只能调用type=1类型。
type=2(领取发票类型):用于商户发票已开具成功,拉起授权页后让用户将发票归集保存到卡包。
请注意:本接口尚未支持代理调用模式,需使用商户自身的公众平台appid及appsecret进行调用。代理调用模式后续会开放,请留意本文档更新。
3.2.2 请求方式
请求URL:https://api.weixin.qq.com/card/invoice/getauthurl?access_token={access_token}
请求方法:POST
请求参数:
请求参数使用JSON格式,参数清单如下:
参数
类型
是否必填
描述
s_pappid
String
是
开票平台在微信的标识号,商户需要找开票平台提供
order_id
String
是
订单id,在商户内单笔开票请求的唯一识别号,
money
Int
是
订单金额,以分为单位
timestamp
Int
是
时间戳
source
String
是
开票来源,app:app开票,web:微信h5开票
redirect_url
String
否
授权成功后跳转页面。本字段只有在source为H5的时候需要填写,引导用户在微信中进行下一步流程。app开票因为从外部app拉起微信授权页,授权完成后自动回到原来的app,故无需填写。
ticket
String
是
从上一环节中获取
type
Int
是
授权类型,0:开票授权,1:填写字段开票授权,2:领票授权
3.2.3 返回结果
数据格式:JSON
参数
类型
是否必填
描述
errcode
Int
是
错误码
errmsg
String
是
错误信息
当错误码为0时,有以下信息:
参数
类型
是否必填
描述
auth_url
String
是
授权链接
3.2.4 示例代码
请求:
{
“s_pappid”: “wxabcd”,
“order_id”: “1234”,
“money”: 11,
“timestamp”: 1474875876,
“source”: “web”,
“redirect_url”: “https://mp.weixin.qq.com“,
“ticket”: “tttt”,
“type”: 1
}
返回:
{
“errcode”: 0,
“errmsg”: “ok”,
“auth_url”: “http://auth_url”
}
注:当在微信以外调试环境中调用本接口时,返回接口会型如:weixin://xxxx,此时需要将链接放到微信中打开,即可拉起授权页,完成后续流程。
3.3 不同场景下获取授权页链接
微信内H5跳转形式见上文。
3.3.1 微信内H5跳转授权页
商户可以通过该方法从自身的App上拉起微信并打开从上节接口中获取的开票授权页。
3.3.2 App跳转授权页
代码调用示例:
Android:
OpenWebview.Req req = new OpenWebview.Req();
req.url = “http://xxxx“; //此处url传入上一节获取的授权页
api.sendReq(req);
iOS:
OpenWebviewReq *req = [[OpenWebviewReq alloc] init];
req.url = @”http://xxx“; //此处url传入上一节中获取的授权页
[WXApi sendReq:req];
注意事项:
1.商户在调用时须申请该方法权限;
2.开发者须检查自己的app是否已经支持微信SDK,并须先熟悉微信SDK接口的调用方法,
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417674108&token=&lang=zh_CN
3.该方法仅支持微信6.2以上版本的微信,低版本微信用户打开无效
3.3.3 PC网页拉起授权页
网页内跳转开票授权页,商户须使用上节中获取到的授权页链接生成二维码供用户扫描以拉起授权页。
4. 设置授权页字段信息
4.1 接口说明
当用户使用type=1的类型的授权页时,可以使用本接口设置授权页上需要用户填写的信息。若使用type=0或type=2类型的授权页,无需调用本接口。本接口为一次性设置,后续除非在需要调整页面字段时才需要再次调用。
请注意,设置为显示状态的字段均为必填字段,用户若不填写将无法进入后续流程
4.2 请求方式
请求URL:https://api.weixin.qq.com/card/invoice/setbizattr?action=set_auth_field&access_token={access_token}
请求方法:POST
请求参数:
请求参数使用JSON格式,参数清单如下:
参数
类型
是否必填
描述
auth_field
Object
是
授权页字段
auth_field为Object,包含以下字段:
参数
类型
是否必填
描述
user_field
Object
是
授权页个人发票字段
biz_field
Object
是
授权页单位发票字段
user_field为Object,包含以下字段:
参数
类型
是否必填
描述
show_title
Int
否
是否填写抬头,0为否,1为是
show_phone
Int
否
是否填写电话号码,0为否,1为是
show_email
Int
否
是否填写邮箱,0为否,1为是
require_phone
Int
否
电话号码是否必填,0为否,1为是
require_email
Int
否
邮箱是否必填,0位否,1为是
custom_field
Object
否
自定义字段
biz_field为Object,包含以下字段:
参数
类型
是否必填
描述
show_title
Int
否
是否填写抬头,0为否,1为是
show_tax_no
Int
否
是否填写税号,0为否,1为是
show_addr
Int
否
是否填写单位地址,0为否,1为是
show_phone
Int
否
是否填写电话号码,0为否,1为是
show_bank_type
Int
否
是否填写开户银行,0为否,1为是
show_bank_no
Int
否
是否填写银行帐号,0为否,1为是
require_tax_no
Int
否
税号是否必填,0为否,1为是
require_addr
Int
否
单位地址是否必填,0为否,1为是
require_phone
Int
否
电话号码是否必填,0为否,1为是
require_bank_type
Int
否
开户类型是否必填,0为否,1为是
require_bank_no
Int
否
税号是否必填,0为否,1为是
custom_field
Object
否
自定义字段
custom_field为List,每个对象包含以下字段:
参数
类型
是否必填
描述
errcode
Int
是
错误码
errmsg
String
是
错误信息
4.3 返回结果
数据格式:JSON
参数
类型
是否必填
描述
errcode
Int
是
错误码
errmsg
String
是
错误信息
4.4 示例代码
请求:
{
“auth_field” : {
“user_field” : {
“require_phone” : 1,
“custom_field” : [
{
“is_require” : 1,
“key” : “field1”
}
],
“show_email” : 1,
“show_title” : 1,
“show_phone” : 1,
“require_email” : 1
},
“biz_field” : {
“require_phone” : 0,
“custom_field” : [
{
“is_require” : 0,
“key” : “field2”
}
],
“require_bank_type” : 0,
“require_tax_no” : 0,
“show_addr” : 1,
“require_addr” : 0,
“show_title” : 1,
“show_tax_no” : 1,
“show_phone” : 1,
“show_bank_type” : 1,
“show_bank_no” : 1,
“require_bank_no” : 0
}
}
}
返回:
{
“errcode”: 0,
“errmsg”: “ok”
}
5. 查询授权页字段信息
5.1 接口说明
本接口与上一个接口配套使用,商户可以通过本接口查询到授权页的字段设置情况。
5.2 请求方式
请求URL:https://api.weixin.qq.com/card/invoice/setbizattr?action=get_auth_field&access_token={access_token}
请求方法:POST
请求参数:
请求参数使用JSON格式,传入空值,即{}
5.3 返回结果
数据格式:JSON
参数
类型
是否必填
描述
errcode
Int
是
错误码
errmsg
String
是
错误信息
auth_field
Object
否
当错误码为0时非空,为查询所得的授权页字段设置情况
auth_field为Object,包含以下字段:
参数
类型
是否必填
描述
user_field
Object
否
授权页个人发票字段
biz_field
Object
否
授权页单位发票字段
user_filed为Object,包含以下字段:
参数
类型
是否必填
描述
show_title
Int
否
是否填写抬头,0为否,1为是
show_phone
Int
否
是否填写电话号码,0为否,1为是
show_email
Int
否
是否填写邮箱,0为否,1为是
require_phone
Int
否
电话是否必填,0为否,1为是
require_email
Int
否
邮箱是否必填,0为
custom_field
Object
否
自定义字段
biz_field为Object,包含以下字段:
参数
类型
是否必填
描述
show_title
Int
否
是否填写抬头,0为否,1为是
show_tax_no
Int
否
是否填写税号,0为否,1为是
show_addr
Int
否
是否填写单位地址,0为否,1为是
show_phone
Int
否
是否填写电话号码,0为否,1为是
show_bank_type
Int
否
是否填写开户银行,0为否,1为是
show_bank_no
Int
否
是否填写银行帐号,0为否,1为是
require_tax_no
Int
否
税号是否必填,0为否,1为是
require_addr
Int
否
单位地址是否必填,0为否,1为是
require_phone
Int
否
电话号码是否必填,0为否,1为是
require_bank_type
Int
否
开户类型是否必填,0为否,1为是
require_bank_no
Int
否
税号是否必填,0为否,1为是
require_tax_no
Int
否
税号是否必填,0为否,1为是
custom_field
Object
否
自定义字段
custom_field为list每个对象包括以下字段:
参数
类型
是否必填
描述
key
String
是
自定义字段名称,最长5个字
Is_require
Int
否
自定义字段是否必填,0位否,1为是
5.4 示例代码
请求:
{}
返回:
{
“errcode”: 0,
“errmsg”: “ok”,
“auth_field”: {
“user_field”: {
“show_title”: 1,
“show_phone”: 1,
“show_email”: 1,
“custom_field”: [{“key”: “field1”}]
},
“biz_field”: {
“show_title”: 1,
“show_tax_no”: 1,
“show_addr”: 1,
“show_phone”: 1,
“show_bank_type”: 1,
“show_bank_no”: 1,
“custom_field”: [{“key”: “field2”}]
}
}
}
6. 获取授权完成状态
6.1 收取授权完成事件推送
6.1.1 接口说明
在用户授权同意发票存入自己微信账户后,商户可以收到授权完成的状态推送。收到推送后,可以将order_id连同开票信息一并发送给开票平台,以便开票平台在开票成功后将电子发票插入用户卡包。电子发票授权完成状态推送使用公众平台统一的事件推送机制。关于推送机制以及推送URL的配置参见:
http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025274&token=&lang=zh_CN=&lang=zh_CN
6.1.2 返回结果
返回结果使用XML格式回传,结果字段清单如下:
参数
类型
是否必填
描述
ToUserName
String
是
公众号标识
FromUserName
String
是
用户openid
CreateTime
Int
是
事件时间
MsgType
String
是
固定为event
Event
String
是
固定为user_authorize_invoice
SuccOrderId
String
否
授权成功的订单号,与失败订单号两者必显示其一
FailOrderId
String
否
授权失败的订单号,与成功订单号两者必显示其一
AppId
String
是
用于接收事件推送的公众号的AppId
Source
String
是
授权来源,web表示来自微信内H5,app标识来自app
6.1.3 示例代码