第三方发票报销查询
变更历史
日期 | 变更描述 | 变更人 | 版本 | 批注 |
---|---|---|---|---|
2020/11/12 | 添加接口“根据流水号查询发票信息附加税号名称不一致标识” | 陈焕威 | V1.1 | |
2020/07/08 | 编写第三方接入规范初稿 | 李创 | V1.0 |
对接约定
发票云API采用RESTfull的设计方式,客户端通过HTTP协议的GET、POST(目前主要是这两种)方法请求进行调用。
Restful:参考资料
http://www.infoq.com/cn/articles/designing-restful-http-apps-roth
API的调用地址基本上遵循如下约定的方式:
API地址前缀+ 服务 + 资源+ 参数
测试环境: https://api-dev.piaozone.com/test
正式环境: https://api.piaozone.com
对接过程中需要:发票云授权标识(client_id)、授权密钥(client_secret)、加密密钥(encrypt_key)进行授权,每个环境的授权不同,获取方式可以找实施人员协助提供
接口返回约定: 若无特别说明,接口返回如下
{
"errcode": "0000", ///成功时为0000, 失败时为非0000
"description": "操作成功", //描述,失败时可以根据这个字段进行提示
"data": "" //请求的返回实际数据
}
根据报销单信息查询当前对应的封面/影像/发票
请求方式: POST
数据格式: application/json
请求地址: /m6/bill/expense/message/query/expenseId/thirdparty?reqid=${reqid}&access_token={access_token}
access_token参考:获取AccessToken(下同)
Query参数:
参数名 | 类型 | 是否必填 | 说明 | 示例 |
---|---|---|---|---|
reqid | String | 是 | 当前13位毫秒级时间戳加3位随机数字(总共16位) | 1661306277676 |
请求数据:请求的json数据。需采用AES128加密再传输,加密方式参考:JAVA方式、C++方式、C#方式
{
"expenseId": "", // 报销单ID
}
参数 | 类型 | 说明 |
---|---|---|
expenseId | string | 报销单id |
返回结果:
发票数据格式请参考:进项发票数据格式
{
"data": {
"attachment": [
"serialNo":"附件流水号",
"attachmentName":"附件名称",
"attachmentType":"附件类型,1:pdf2:图片",
"gatherTime":"采集时间",
"localUrl":"原件预览url",
"remark":"备注",
"rotationAngle":"文件旋转角度",
"snapshotUrl":"快照url"
],//影像列表
"cover": [
"coverNo":"封面影像编号",
"fileType":"文件类型,1:pdf2:图片",
"localUrl":"原件预览url",
"snapshotUrl":"快照url",
"rotationAngle":"文件旋转角度"
],//封面列表
"invoice": []//发票列表
},
"description": "成功",
"errcode": "0000",
"invoiceCount": 16,//发票总数
"totalAmount": 5368.67,//发票总金额
"totalTaxAmount": 197.95//发票总税额
}
请求示例:
package com.kingdee.apitest;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.apitest.AES.AES128;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
public class ThirdPartyDemo {
private static final String HOST = "https://api-dev.piaozone.com/test";
private static final String THIRED_PARTY_API_PATH = "/m6/bill/expense/message/query/expenseId/thirdparty?access_token={access_token}";
private static final String CONTENT_TYPE = "application/json";
private static final CloseableHttpClient httpClient = HttpClients.createDefault();
public static void main(String[] args) throws Exception {
String thiredresult = "";
String client_id = "client_id";
String secret = "secret";
long currentTimeMillis = System.currentTimeMillis();
String sign = client_id + secret + currentTimeMillis;
String md5Hex = DigestUtils.md5Hex(sign);
//获取access_token
String accessToken = AccessTokenDemo.getAccessToken(client_id, md5Hex, currentTimeMillis);
System.out.println(accessToken);
//调用报销单信息查询当前对应的封面/影像/发票
if(StringUtils.hasLength(accessToken)){
String expenseId = "YPxIxrbfQC6ZKtiCPoi6wUpE9J8=";
thiredresult = queryThirdPartyByExpenseId(expenseId, accessToken);
}
System.out.println("返回结果:" + thiredresult);
}
/**
* 根据报销单ID查询对应的封面/影像/发票
* @param expenseId 报销单ID
* @param accessToken
* @return
*/
private static String queryThirdPartyByExpenseId(String expenseId, String accessToken) throws Exception {
if(!StringUtils.hasLength(expenseId)){
return null;
}
String thirdparty_path = THIRED_PARTY_API_PATH.replace("{access_token}", accessToken);
HttpPost httpPost = new HttpPost(HOST + thirdparty_path);
httpPost.setHeader("Content-Type", CONTENT_TYPE);
//组装参数
JSONObject params = new JSONObject();
params.put("expenseId", expenseId);
//将请求的JSON数据用AES128加密,加密方法请下载对应接口文档中的JAVA方式
String paramsStr = AES128.encrypt1(params.toJSONString());
StringEntity stringEntity = new StringEntity(paramsStr);
httpPost.setEntity(stringEntity);
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
String result = EntityUtils.toString(httpEntity);
return result;
}
}
根据流水号查询发票信息附加税号名称不一致标识
请求方式: POST
数据格式: application/json
请求地址: m4/bill/fpzs/invoice/verificate/query?reqid=${reqid}&access_token={access_token}
Query参数:
参数名 | 类型 | 是否必填 | 说明 | 示例 |
---|---|---|---|---|
reqid | String | 是 | 当前13位毫秒级时间戳加3位随机数字(总共16位) | 1661306277676 |
请求数据:请求的json数据。需采用AES128加密再传输,加密方式参考:JAVA方式、C++方式、C#方式
{
"serialNo": "", // 发票流水号
"taxNo": "", // 企业税号
"companyName": "", // 企业名称
"bxd_key": "", // 报销单ID
"ticketParam": "", // 报销拦截参数
}
参数 | 类型 | 说明 |
---|---|---|
serialNo | string | 发票流水号 |
taxNo | string | 企业税号 |
companyName | string | 企业名称 |
bxd_key | string | 报销单ID |
ticketParam | string | 报销拦截参数:四位数,例1010, 参数规则顺序: 0 不允许 1 允许 第1位:已报销过的发票是否允许导入 第2位:发票抬头与企业名称不一致的发票是否允许导入 第3位:发票抬头与税号不一致发票是否允许导入 第4位:发票查验不通过的发票是否允许导入 |
返回结果:
发票数据格式请参考:发票数据规范
{
"data": [
[
{
"salerName": "",//销方名称
"downloadUrl": "https://api.kingdee.com/kdrive/user/file/public?client_id=200242&file_id=159998368&scode=bUpHNjlFTU5hSWdjR3hXWkM9K0Rz&sign=4232a935176dc6849db9fc320beaa1374796dae4",//pdf下载地址
"authenticateFlag": 1,//认证标志:0未任何认证及勾选,1勾选,2勾选认证,3扫描认证
"checkStatus": 3,//查验状态1:通过,2,不通过,3:未查验
"trip": "无",//行程 起终点
"price": "0",//单价
"salerTaxNo": "",//销方税号
"invoiceType": "8",//发票类型 1.普通电子发票2.电子发票专票3.普通纸质发票4.专用纸质发票5.普通纸质卷票7.通用机打8.的士票9.火车票10.飞机票11.其他12.机动车.13.二手车14.定额发票15.通行费16.客运发票17.过路过桥费18.车船税发票(专票)19.完税证明20.轮船票21.海关缴款书22.被占位中23.通用机打电子发票
"licenseNumber": "",//车牌号
"place": "深圳市",//乘车地地名
"invoiceNo": "02425273",//发票号码
"timeGetOff": "09:53",//下车时间
"pixel": "1080,1440",//原图像素大小,宽、高
"buyerAddressPhone": "",//买方地址电话
"timeGetOn": "09:41",//上车时间
"mileage": "7.96",// 里程
"salerAccount": "",//销方账号
"originalGraphUrl": "https://api.kingdee.com/kdrive/user/file/public?client_id=200242&file_id=159998368&scode=bUpHNjlFTU5hSWdjR3hXWkM9K0Rz&sign=4232a935176dc6849db9fc320beaa1374796dae4",//原图地址
"amount": "27.00",//总金额
"buyerTaxNo": "",//购货方方识别号
"validateMessage": "发票已在报销中",//校验信息
"verifyResult": [//检验结果
{
"key": "repeat",
"name": "错误原因:被其他单据在用或已用,禁止导入",
"config": "3",//发票校验 0严格管控 1不控制 2红框警示 3黄框警示
"result": "1",
"msg": "已被FYBX-2020-11-04-00007,FYBX-2020-11-05-00016,HQBXD20201106174,FYBX-2020-11-12-00010单据报销",
"extFields": [
"FYBX-2020-11-04-00007,FYBX-2020-11-05-00016,HQBXD20201106174,FYBX-2020-11-12-00010"
]
}
],
"buyerName": "",//购货方名称
"invoiceDate": "2020-10-25",//开票日期
"invoiceCode": "144031970219",//发票代码
"serialNo": "3c656ea846064b18ae597d32be42a9d00",//发票流水号
"errorLevel": "0",//0校验通过
"checkFlag": 1,
"totalAmount": "27.00",//票价
"salerAddressPhone": "",//销方地址电话
"checkTime": "",//
"buyerAccount": "",// 买方账号
"authenticateTime": "",//认证时间
"rotationAngle": "0",//发票旋转角度
"snapshotUrl": "https://api.kingdee.com/kdrive/user/file/thumbnail?client_id=200242&file_id=159998368&quality=100&scode=N1plRGRXTHF4WHdkdTNSZFVncWl4&sign=48f0e604a37f3863657039ce5d28b9e73e077f27&width=800",//发票快照地址
"isRevise": "1",//发票是否被修改:1-未修改;2-已修改
"taxAmount": "0",//税额
"totalAmountCn": "",//价税合计金额繁体
"region": "[19,263,510,1389]",//区域编码
"expenseStatus": "60"//报销状态,1、未用;30、在用,60-已使用
},
{
"passengerName": "陈智雍",//乘客姓名
"stationGetOn": "广州南",// 上车站点
"salerName": "",//销方名称
"downloadUrl": "https://api.kingdee.com/kdrive/user/file/public?client_id=200242&file_id=159998368&scode=bUpHNjlFTU5hSWdjR3hXWkM9K0Rz&sign=4232a935176dc6849db9fc320beaa1374796dae4",
"authenticateFlag": 1,
"departurePosition": {//起航点
"area": "番禺区",
"province": "广东省",
"city": "广州市"
},
"trainNum": "G6345",//车次
"checkStatus": 3,//查验状态1:通过,2,不通过,3:未查验
"trainTime": "20:41",//火车乘车时间
"trip": "广州南 - 深圳北",//行程
"stationGetOff": "深圳北",//下车站点
"salerTaxNo": "",//销方税号
"invoiceType": "9",//发票类型 1.普通电子发票2.电子发票专票3.普通纸质发票4.专用纸质发票5.普通纸质卷票7.通用机打8.的士票9.火车票10.飞机票11.其他12.机动车.13.二手车14.定额发票15.通行费16.客运发票17.过路过桥费18.车船税发票(专票)19.完税证明20.轮船票21.海关缴款书22.被占位中23.通用机打电子发票
"invoiceNo": "B023810",//发票号码
"pixel": "1080,1440",//原图像素大小,宽、高
"buyerAddressPhone": "",
"salerAccount": "",
"originalGraphUrl": "https://api.kingdee.com/kdrive/user/file/public?client_id=200242&file_id=159998368&scode=bUpHNjlFTU5hSWdjR3hXWkM9K0Rz&sign=4232a935176dc6849db9fc320beaa1374796dae4",
"amount": "68.35",
"buyerTaxNo": "",
"validateMessage": "发票已在报销中",
"verifyResult": [
{
"key": "repeat",
"name": "错误原因:被其他单据在用或已用,禁止导入",
"config": "3",
"result": "1",
"msg": "已被FYBX-2020-11-04-00007,FYBX-2020-11-05-00016,HQBXD20201106174,FYBX-2020-11-12-00010单据报销",
"extFields": [
"FYBX-2020-11-04-00007,FYBX-2020-11-05-00016,HQBXD20201106174,FYBX-2020-11-12-00010"
]
}
],
"buyerName": "",
"invoiceDate": "2020-10-03",
"invoiceCode": "20201003",
"serialNo": "853efae6839e49f0a5da29956aeabdac0",
"errorLevel": "0",
"checkFlag": 1,
"totalAmount": "74.50",
"taxRate": "0.090000",
"seatGrade": "二等座",
"salerAddressPhone": "",
"checkTime": "",
"buyerAccount": "",
"authenticateTime": "",
"rotationAngle": "90",
"snapshotUrl": "https://api.kingdee.com/kdrive/user/file/thumbnail?client_id=200242&file_id=159998368&quality=100&scode=N1plRGRXTHF4WHdkdTNSZFVncWl4&sign=48f0e604a37f3863657039ce5d28b9e73e077f27&width=800",
"isRevise": "1",
"destinationPosition": {
"area": "龙华区",
"province": "广东省",
"city": "深圳市"
},
"printingSequenceNo": "B023810",
"taxAmount": "6.15",
"totalAmountCn": "",
"region": "[381,455,968,1308]",
"expenseStatus": "60"
}
]
],
"description": "成功",
"errcode": "0000"
}
接口示例:
参照-根据报销单信息查询当前对应的封面/影像/发票接口示例
根据影像编号查询报销单ID和报销单编号
请求方式: POST
数据格式: application/json
请求地址: /m6/bill/expense/expenseInfo/query/thirdparty?reqid=${reqid}&access_token={access_token}
Query参数:
参数名 | 类型 | 是否必填 | 说明 | 示例 |
---|---|---|---|---|
reqid | String | 是 | 当前13位毫秒级时间戳加3位随机数字(总共16位) | 1661306277676 |
请求数据:请求的json数据。需采用AES128加密再传输,加密方式参考:JAVA方式、C++方式、C#方式
{
"scanBillNo": "BXD_a000001", // 影像编号
}
参数 | 类型 | 说明 |
---|---|---|
scanBillNo | string | 影像编号 |
返回结果:
{
"data": {
"expenseNum": "BXD-20200622-003334", // 报销单编号
"expenseId": "Ik2TrOC5RSCOND0pE9J8=" //报销单ID
},
"description": "成功",
"errcode": "0000"
}
clientId错误返回结果:
{
"data": ["ab00001","ab0002"],// 正确的clientId列表
"description": "授权信息关系错误",
"errcode": "0411"
}
接口示例:
参照:根据报销单信息查询当前对应的封面/影像/发票接口示例