# 开票申请

# 对接必读

开票相关接口关于字段为空不返回情况的说明,对接前务必查看对接必读

# 开蓝票

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/insertWithArray?appid=XXXXX

TIP

每次请求的数据不能超过20张单据

此接口只能用来开具蓝票

签名载荷(Payload)中必须包含属性requestdatas,它的值为表单参数requestdatas的MD5值,具体使用方式参考样例代码示例

表达提交前,需使用URLEncoder.encode(...)方法进行编码

# 请求体参数

# 表单说明

参数 描述 说明
requestdatas 开票申请发票信息,包含发票头发票明细
email 邮件推送配置(可选) 开具特殊票种-电子行程单该字段必传。
sms 短信推送配置(可选)
url 回调服务配置(可选)
delurl 退回业务系统回调服务配置(可选)
autoAudit 是否自动审核(可选) true:自动审核,即不需要人工在发票平台确认开票,直接进行开票 false:不自动审核,即需要人工确认如果不传,代表true
nc6x-ubl ncc友企联回调参数

# 发票头

参数 类型 长度 是否必填 默认值 描述 说明
FPQQLSH String 20 发票请求流水号
FPLX String 1 1 发票类型 1:增值税电子普通发票;
2:增值税电子专用发票;
3:增值税普通发票;
4:增值税专用发票 、增值税专用发票(机动车);
5:机动车销售统一发票;
8:增值税电子普通发票(成品油);
10:成品油普通发票;
11:成品油专用发票;
15:二手车销售统一发票;
31:数电专用发票;
32:数电普通发票;
33:数电纸质发票(增值税专用发票);
34:数电纸质发票(普通发票);
35:数电票(航空运输电子客票行程单);
36:数电纸质发票(机动车销售统一发票);
XSF_NSRSBH String 20 销售方纳税人识别号
XSF_MC String 100 销售方名称 如果为空,获取发票平台配置的销售方名称;开具特殊票种-电子行程单该字段必传。
XSF_DZDH String 100 销售方地址、电话 如果为空,获取发票平台配置的销售方地址及电话
XSF_DZ String 300 销售方地址 如果为空,获取发票平台配置的销售方地址 数电专用字段
XSF_DH String 60 销售方电话 如果为空,获取发票平台配置的销售方电话 数电专用字段
XSF_YHZH String 100 销售方银行、账号 如果为空,获取发票平台配置的销售方银行及账号
XSF_YH String 120 销售方银行 如果为空,获取发票平台配置的销售方银行 数电专用字段
XSF_ZH String 100 销售方账号 如果为空,获取发票平台配置的销售方账号 数电专用字段
GMF_NSRSBH String 20 购买方纳税人识别号 发票类型31 数电专用发票(必填)
GMF_MC String 100 购买方名称
GMF_DZDH String 100 购买方地址、电话 数电票此字段非必填
GMF_YHZH String 100 购买方银行、账号 数电票此字段非必填
GMF_DZ String 300 购买方地址 数电专用字段
GMF_DH String 60 购买方电话 数电专用字段
GMF_YH String 120 购买方银行 数电专用字段
GMF_ZH String 100 购买方账号 数电专用字段
ALLELCUSERNAME String 300 数电发票用户名 如果发票类型是数电发票用户名必填 ,并且是国密4密文
ALLELCPASSWORD String 300 数电发票密码 如果发票类型是数电发票密码必填 ,并且是国密4密文
KPR String 8 开票人 如果为空,获取发票平台配置的开票人
SKR String 8 收款人 如果为空,获取发票平台配置的收款人
FHR String 8 复核人 如果为空,获取发票平台配置的复核人
SLSM String 1 税率说明 1:当小规模纳税人开具3%税率时需要填写税率说明; 2:前期已开具发票,发生销售折让、中止或者退回等情形需要开具红字发票,或者开票有误需要重新开具; 3:因为实际经营业务需要,放弃享受减按1%征收率征收增值税政策。
JSHJ BigDecimal 15,2 价税合计 两位小数。明细价税合计之和必须与总的价税合计一致
HJJE BigDecimal 15,2 合计金额 两位小数。为空时,根据明细项目进行合计。
HJSE BigDecimal 15,2 合计税额 两位小数。为空时,根据明细项目进行合计。
BZ String 200 备注
LYID String 100 请求来源唯一标识
BMB_BBH String 20 编码版本号 增加商品编码功能后,税局下载的商品编码表版本
ORGCODE String 50 开票点编码 如果一个税号对应多个开票点,此字段必输,用于确定唯一开票点
WXORDERID String 微信订单号 商户开票完成后,传入订单号和商户id将自动插入用户微信卡包(参考微信卡包指引) (opens new window)
WXAPPID String 微信商户id 商户开票完成后,传入订单号和商户id将自动插入用户微信卡包(参考微信卡包指引) (opens new window)
WXAUTHID String 微信批量插入卡包的授权id 如果使用批量插入卡包的授权,需要传此参数,否则不需要
ZDYBZ String 200 自定义备注
SGBZ String 1 收购标志 2-农产品收购
TSPZ String 1 特殊票种 0-一般
2-燃油增值税专用发票
8-农产品销售
9-农产品收购
11-烟草发票
12-机动车发票
14-成品油发票
DK-代开发票
16-矿产品发票
E01-成品油发票
E02-稀土发票
E03-建筑服务发票
E04-货物运输
E05-不动产销售
E06-不动产租赁服务发票
E07-代收车船税
E09-旅客运输
E12-自产农产品销售
E14-机动车
E16-农产品收购
E17-光伏收购
E18-卷烟发票
E22-电子行程单
E32-电子烟
(数电票对应的特殊票种为E开头,其他的为税控发票的特殊票种)
ZSFS String 1 0 征税方式 0-普通征税 2-差额征税/差额开票 3-全额开票
PROJECTCODE String 50 项目编号
ACOUNTORGCODE String 50 会计主体编码
WBSCODE String 36 WBS编号
TDZZSXMBH String 土地增值税项目编号 数电特殊票种-建筑服务必传
BDCDZ String 不动产租赁地址 数电特殊票种-不动产租赁服务必传。格式:省市区详细地址
ZLQQ String 租赁日期起 数电特殊票种-不动产租赁服务必传。例:2023-03-22。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
ZLQZ String 租赁日期止 数电特殊票种-不动产租赁服务必传。例:2024-03-22。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
KDSBZ String 是否跨地址标志 数电特殊票种-不动产租赁服务及建筑服务必传。枚举Y:是;N:否
KQYSSSXBGGLBM String 跨区域涉税事项报验管理编号 数电特殊票种-建筑服务专属属性。对于非乐企通道,当“跨地市标志”为“是”时,“跨区域涉税事项报验管理编号”为必填;当“跨地市标志”为“否”时,“跨区域涉税事项报验管理编号”不可填写。
EINVOICESHOWGXFYHZH String 数电发票是否显示购销方银行、账号 数电发票是否显示购销方银行、账号: 0:不显示 1:仅显示销售方银行、账号 2:仅显示购买方银行、账号 3:购销方银行、账号都显示
EINVOICESHOWSKRSHR String 数电发票(非纸质发票)是否显示收款人、复核人 数电发票(非纸质发票)是否显示收款人、复核人。0:不显示 1:仅显示收款人 2:仅显示复核人 3:收款人复核人都显示
EINVOICESHOWGXFDZDH String 备注是否显示地址、电话 0:不显示 1:仅显示销地址、电话 2:仅显示购买方地址、电话 3:购销方地址、电话都显示
SDLC String 数电纸票联次Value 数电纸质发票联次信息。枚举为:
{"label":"2016版增值税普通发票(二联折叠票)","value":"04","type":"3"}
{"label":"2016版增值税普通发票(五联折叠票)","value":"05","type":"3"}
{"type":"3","label":"2008版增值税普通发票(五联无金额限制版)","value":"000008101500"}
{"label":"增值税专用发票(中文三联无金额限制版)","value":"1130","type":"1"}
{"label":"增值税专用发票(中文六联无金额限制版)","value":"1160","type":"1"}
{"label":"机动车销售统一发票(六联无金额限制版)","value":"000008102600","type":"4"}
注:传值为对应的value字段,枚举不完善,如不满足您的需求可联系我们补充
tspzs List 数电特殊票种其他要素属性集合 数电特殊票种-建筑服务及旅客运输等必传。
bdcxsTspzs List 数电特殊票种不动产属性集合 数电特殊票种-新版本不动产销售及不动产租赁必传。
LYDJH String 200 业务来源单据号
TICKETNUMBER String 13位电子票号 开具特殊票种-电子行程单该字段必传
BUYERTYPE String 购买机票方类型 0:企业 1:机关或事业单位 2:个人3:其他;开具特殊票种-电子行程单该字段必传
FAREAMOUNT String 加减价
ORDERNUMBER String 企业购票订单号
USERNAME String 用户名
GPCODE String GP单号
PASSENGERNAME String 乘客姓名
PASSENGERIDNUM String 乘客身份证号码/护照号码
ENDORSEMENTS String 签注
OFFICE String 出票Office号
ISSUEDBY String 出票单位
IATA String IATA号
PNR String PNR号
TICKETINFORMATION String 机票票面提示信息
INSURANCE String 保险信息
ELECTRONICTICKETTYPE String 机票类型 0:国内; 1:国际
VERIFYCODE String 验证码
OVERDUEFLAG String 超期标识 true: 超期;false: 未超期
DFGTGMBZ String 多方共同购买标志 Y:多方共同购买N:非多方共同购买
ZRRBS String 购买方自然人标志 仅在开具数电普票(电子)时使用,如受票方(发票抬头)为自然人,并要求能将发票归集在个人票夹中展示,需提供姓名及身份证号(自然人纳税人识别号),此参数传入Y;如受票方(发票抬头)为个体工商户,需提供社会统一信用代码或纳税人识别号,此参数传入N
ZJLX String 证件类型代码 适用于自然人标识为Y时的自然人补充信息,枚举参见出行人证件类型代码枚举。收购发票或者ZJHM、GUOJI两个字段有值时,必填
ZJHM String 证件号码 适用于自然人标识为Y时的自然人补充信息。收购发票或者ZJLX、GUOJI两个字段有值时,必填
GUOJI String 国籍代码 适用于自然人标识为Y时的自然人补充信息,枚举参见国家地区代码枚举。收购发票或者ZJLX、ZJHM两个字段有值时,必填
MQKFRL String 每千克煤炭发热量 数电票煤炭类字段。不含税金额超过一千万时,该字段必填。
GJQL String 干基全硫 数电票煤炭类字段。不含税金额超过一千万时,该字段必填。
GZWHJHFF String 干燥无灰基挥发分 数电票煤炭类字段。不含税金额超过一千万时,该字段必填。
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 发票明细

参数 类型 长度 是否必填 默认值 描述 说明
FPHXZ Integer 2 0 发票行性质 0-正常行1-折扣行2-被折扣行
XMMC String 300 项目名称 数电票:300字节/150中文;税控票:80字节/40中文
XMBM String 255 项目编码 如果项目名称为空,会根据项目编码匹配云平台的商品档案(物料创建)
GGXH String 150 规格型号 非数电发票规格型号最大长度为40个字符,数电发票长度为150个字符
DW String 300 单位 如果是成品油发票,必填且只能是"吨或升"<\br>如果是矿产品发票,必填且只能是"立方米、吨、千克、克或克拉"。数电票:长度300,税控票:长度20
XMSL BigDecimal 15,6 项目数量 如果是成品油发票,必填。
XMHSDJ BigDecimal 15,6 项目含税单价 项目单价为空时,根据项目金额反算。不为空时不进行计算
XMDJ BigDecimal 15,6 项目单价 为"不含税单价",项目单价为空时,根据项目金额反算。不为空时不进行计算
XMJE BigDecimal 15,2 项目金额 为"不含税金额",项目金额为空,根据项目价税合计反算。不为空时不进行计算
XMJSHJ BigDecimal 15,2 项目价税合计
SL BigDecimal 6,6 税率 6 位小数,例 17%为 0.17
SE BigDecimal 15,2 税额 税额为空,根据价税合计反算。不为空时不进行计算。
HH string 60 行号 有折扣时需要必输
ZKHHH string 60 折扣行行号 有折扣时需要必输
SPBM string 19 商品编码 税收分类编码
ZXBM string 20 10 商品自行编码
YHZCBS int 2 0 享受优惠标识 0:不使用,1:使用
LSLBS string 1 零税率标识 空:非零利率,0:出口退税,1:免税,2:不征收,3普通零税率
ZZSTSGL string 50 优惠政策说明 按3%简易征收,按5%简易征收 (此字段非空时,享受优惠标识YHZCBS字段值需为1)
KCE BigDecimal 15,2 扣除额 扣除额
detailMotor Object 明细特殊票种扩展属性 机动车及数电特殊票种-不动产租赁服务及建筑服务必传
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 明细特殊票种扩展属性 -> detailMotor

参数 类型 长度 是否必填 默认值 描述 说明
CQZSBH String 产权证书编号 数电特殊票种-不动产租赁服务必传。没有传 无
JZFWFSD String 建筑服务发生地 数电特殊票种-建筑服务必传
JZXMMC String 建筑项目名称 数电特殊票种-建筑服务必传
CD String 产地 机动车开具时-产地必传
CJHM String 车架号码 机动车开具-车架号码必传
CLLX String 车辆类型 机动车开具-车辆类型必传
CPXH String 厂牌型号 机动车开具-厂牌型号必传
SCQYMC String 生产企业名称 机动车开具-仅当发票类型为5:机动车销售统一发票时,生产企业名称必填
SFZHM String 身份证号码/组织机构代码 机动车开具-身份证号码/组织机构代码非必填
HGZH String 合格证号 机动车开具-合格证号非必填
JKZMSH String 进口证明书号 机动车开具-进口证明书号非必填
SJDH String 商检单号 机动车开具-商检单号非必填
FDJHM String 发动机号码 机动车开具-发动机号码非必填
DUNWEI String 吨位 机动车开具-吨位非必填
XCRS String 限乘人数 机动车开具-限乘人数非必填
DH String 电话 机动车开具-电话非必填
DZ String 地址 机动车开具-地址非必填
KHYH String 开户银行 机动车开具-开户银行非必填
ZH String 账户 机动车开具-账户非必填
SWJGDM String 主管税务机关代码 机动车开具-主管税务机关代码非必填
SWJGMC String 主管税务机关名称 机动车开具-主管税务机关名称非必填
WSPZH String 完税凭证号 机动车开具-完税凭证号非必填
GFDZ String 买方单位/个人住址 机动车开具-买方单位/个人住址非必填
GFDH String 买方电话 机动车开具-买方电话非必填
CPZH String 车牌照号 机动车开具-车牌照号非必填
DJZH String 登记证号 机动车开具-登记证号非必填
CGSMC String 转入地车辆车管所名称 机动车开具-转入地车辆车管所名称非必填
XFDW String 卖方单位/个人 机动车开具-卖方单位/个人非必填
XFHM String 卖方单位代码/身份证号 机动车开具-卖方单位代码/身份证号非必填
XFDZ String 卖方单位/个人住址 机动车开具-卖方单位/个人住址非必填
XFDH String 卖方电话 机动车开具-卖方电话非必填
JYDW String 经营、拍卖单位 机动车开具-经营、拍卖单位非必填
JYDZ String 经营、拍卖单位地址 机动车开具-经营、拍卖单位地址非必填
JYSBH String 经营、拍卖单位纳税人识别号 机动车开具-经营、拍卖单位纳税人识别号非必填
JYYHZH String 开户银行及账号 机动车开具-开户银行及账号非必填
JYDH String 经营、拍卖单位电话 机动车开具-经营、拍卖单位电话非必填
SCMC String 二手车市场 机动车开具-二手车市场非必填
SCSBH String 二手车市场纳税人识别号 机动车开具-二手车市场纳税人识别号非必填
SCDZ String 二手车市场地址 机动车开具-二手车市场地址非必填
SCYHZH String 二手车市场开户银行及账号 机动车开具-二手车市场开户银行及账号非必填
SCDH String 二手车市场电话 机动车开具-二手车市场电话非必填
VEHICLEVERSION String 机动车统一销售发票版本 机动车开具-机动车统一销售发票版本非必填
GMFSFZJLX String 机动车统一销售发票购买方身份证件类型 机动车开具-机动车统一销售发票购买方身份证件类型非必填
MTZLDM String 煤炭种类代码 如为0100:政府保供煤;0200:长协煤;0300:市场煤。传递对应的序号即可
MTZLDMXY String 煤炭种类代码协议 如为0200:长协煤,必填。则传递下级协议编号,0201:协议期不足半年;0202:协议期在半年至一年之间;0203:协议期在一年至两年之间;0204:协议期在两年以上

# 数电特殊票种其他要素属性 -> tspzs

参数 类型 长度 是否必填 默认值 描述 说明
JTGJLXDM String 交通工具类型 数电特殊票种-旅客运输必传
YSMXXH String 运输明细序号 数电特殊票种-建筑服务及旅客运输等必传
QYD String 起运地 数电特殊票种-建筑服务及旅客运输等必传
DDD String 到达地 数电特殊票种-建筑服务及旅客运输等必传
YSGJZL String 运输工具种类 数电特殊票种-货物运输必传
YSGJPH String 运输工具牌号/航班号 数电特殊票种-货物运输必传
YSHWMC String 运输货物名称 数电特殊票种-货物运输必传
CXRXH Object 出行人序号
CXR string 出行人/承运人名称
CARRIERCODE string 电子行程单,承运人二字码
CHUXRQ string 出行日期 格式yyyy-MM-dd HH:mm
CFD string 出发地
LKDDD string 到达地
ZWDJ string 座位等级
FAREBASIS string 电子行程单:客票级别/客票类别
NOTVALIDBEFORE string 电子行程单:客票生效日期 yyyy-MM-dd
NOTVALIDAFTER string 电子行程单:有效截至日期 yyyy-MM-dd
ALLOW string 电子行程单:免费行李
ITINERARYTYPE string 电子行程单:行程类型 0:普通运输段 1:地面运输
GTGMF string 共同购买方

# 数电特殊票种不动产属性 -> bdcxsTspzs

参数 类型 长度 是否必填 默认值 描述 说明
CXRXH Object 明细序号 注意该序号要与明细行中正数行行号一对一关联
BDCDZ string 不动产地址 格式:省市区详细地址
ZLQQ string 租赁日期起 例:2023-03-22。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
ZLQZ string 租赁日期止 例:2023-03-22。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
KDSBZ string 是否跨地址标志 枚举Y:是;N:否
CQZSBH string 产权证书编号 没有传 无
MJDW string 面积单位 平方千米、平方米、公顷、亩、hm²、km²、m²、米(铁路线与管道等使用)
CPH string 车牌号 仅在税收分类编码为“3040502020200000000”时选填
WQHTBABH string 网签合同备案编号
TDZZSXMBH string 土地增值税项目编号
HDJSJG string 核定计税价格 不属于核定计税不动产销售的可不填写
SJCJHSJE string 实际成交含税金额 若按核定计税价格征税的,为必填

# 邮件推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 200 接收地址 接收地址,多个地址使用","分隔开

# 短信推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 200 接收地址 接收地址,多个地址使用","分隔开

# 回调服务配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
url String 500 回调url 开票申请调用方配置回调url,当电子发票开具成功后,调用此服务,POST电子发票相关信息。信息包含:1、pdf版式文件2、发票数据、3、发票下载链接
ncc通过友企联方案回调可不传此参数
intf String 200 ncc回调接口名 ncc通过友企联方案回调时必传
method String 200 ncc回调方法名 ncc通过友企联方案回调时必传

# 退回回调推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
url String 500 回调url,使用业务系统退回功能时,退回将会调用此服务,post方式,相关信息1.fpqqlsh发票请求流水号 2.xsfNsrsbh销售方纳税人识别号 接收地址,多个地址使用","分隔开

# 请求样例

标准表单参数样例

requestdatas=[ {
	"FPQQLSH" : "12345678901234567890",
	"XSF_NSRSBH" : "销售方纳税人识别号",
	"XSF_MC" : "销售方名称",
	"XSF_DZDH" : "销售方地址、电话",
    "XSF_DZ" : "销售方地址", (数电专用)
    "XSF_DH" : "销售方电话", (数电专用)
	"XSF_YHZH" : "销售方银行、账号",
    "XSF_YH" : "销售方银行",  (数电专用)
    "XSF_ZH" : "销售方账号",   (数电专用)
	"GMF_NSRSBH" : "购买方纳税人识别号",(发票类型31 数电专用发票(必填))
	"GMF_MC" : "购买方名称",
	"GMF_DZDH" : "购买方地址、电话",
    "GMF_DZ" : "购买方地址",(数电专用)
    "GMF_DH" : "购买方电话",(数电专用)
	"GMF_YHZH" : "购买方银行、账号",
    "GMF_YH" : "购买方银行",(数电专用)
    "GMF_ZH" : "购买方账号",(数电专用)
    "ALLELCUSERNAME": "电子税务局用户名(发票类型为数电发票时必传并且是国密四密文)",(数电专用)
    "ALLELCPASSWORD": "电子税务局密码 (发票类型为数电发票时必传并且是国密四密文)",(数电专用)
	"KPR" : "开票人",
	"SKR" : "收款人",
	"FHR" : "复核人",
	"JSHJ" : "价税合计",
	"HJJE" : "合计金额",
	"HJSE" : "合计税额",
	"BZ" : "备注",
	"BMB_BBH" : "10.0",
    "define":{
      "特征key":"特征值示例 选填"
    },
	"items" : [{
            "FPHXZ" : "发票行性质",
            "XMMC" : "项目名称",
            "GGXH" : "规格型号",
            "DW" : "单位",
            "XMSL" : "项目数量",
            "XMDJ" : "项目单价",
            "XMJE" : "项目金额",
            "XMJSHJ" : "项目价税合计",
            "SL" : "税率",
            "SE" : "税额",
            "HH":"行号",
            "SPBM":"商品编码",
            "ZXBM":"自行编码",
            "define":{
              "特征key":"特征值示例 选填"
            }
            "KCE":300
		}
	]
}]
&email=[
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x1@yonyou.com,x2@yonyou.com"
    }, 
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x3@yonyou.com"
    }
]
&sms=[{
	"fpqqlsh":"12345678901234567890",
        "address": "13511111111,13511111112"
    }]
&url=[{
		"fpqqlsh":"12345678901234567890",
        "url": "http://url.com/msg"
    }]
&delurl=[{
		"fpqqlsh":"12345678901234567890",
        "url": "http://url.com/msg"
    }]
&nc6x-ubl=[{
        "fpqqlsh":"12345678901234567890",
        "method":"queryUserPermAppPksOrCodes",
        "intf":"nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService"   
}]
&autoAudit=true

最小请求参数样例

TIP

销售方地址及电话、银行及账号、销售方名称可以通过销售方纳税人识别号获取

requestdatas=[{
	"FPQQLSH" : "12345678901234567890",
    "XSF_NSRSBH" : "销售方纳税人识别号",
    "GMF_MC" : "购买方名称",
    "JSHJ" : 117,
    "items" : 
		    [
			    {
		            "XMMC" : "项目名称",
		            "XMJSHJ" : 117,
		            "SL" : 0.17,
		            "SPBM" : "1010101020000000000"
		        }
		    ]
}]

包含折扣行开票样例

TIP

包含折扣行的单据需要增加以下信息 FPHXZ:发票行性质 HH:行号 ZKHHH:折扣行行号 折扣行上规则型号、单位、数量、单价 不用设值。折扣行的项目名称必须与被折扣行一样。被折扣行记录对应折扣行行号 。

requestdatas=[{
	"FPQQLSH" : "12345678901234567890",
    "XSF_NSRSBH" : "销售方纳税人识别号",
    "GMF_MC" : "购买方名称",
    "JSHJ" : 799,
    "items" : 
		    [
			    {
				    "FPHXZ" : 2,
		            "XMMC" : "项目名称",
		            "XMSL" : 1,
		            "XMJSHJ" : 899,
		            "SL" : 0.17,
		            "HH":"1",
		            "ZKHHH":"2"
		        },
		        {
			        "FPHXZ" : 1,
		            "XMMC" : "项目名称",
		            "XMJSHJ" : -100,
		            "SL" : 0.17,
		            "HH":"2",
		        }
		    ]
}]

数电不动产接口报文样例

requestdatas=[{
	"FPQQLSH": "202302171613262049",
	"FPLX": "31",
	"XSF_NSRSBH": "441234567AAAAAA",
	"XSF_MC": "htt灰度01AAAA",
	"TSPZ": "E06",//特殊票种-不动产租赁代码
    "BDCDZ": "北京市北京市辖区东城区滨河公园5-4-1803",//不动产租赁地址:省市区详细地址
    "ZLQQ": "2023-03-22",//租赁日期起 。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
    "ZLQZ": "2023-04-30",//租赁日期止 。“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16。目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
    "KDSBZ": "N",//是否跨地址标志 Y:是;N:否
	"ORGCODE": "htt001",
	"GMF_NSRSBH": "913418025914242188",
	"GMF_MC": "labo1",
	"GMF_DZDH": "",
	"GMF_YHZH": "",
	"KPR": "hett",
	"SKR": "hett",
	"FHR": "hett",
	"JSHJ": 14837.170000000000000,
	"HJJE": 13130.240000000000000,
	"HJSE": 1706.930000000000000,
	"BZ": "",
	"BMB_BBH": "28.0",
	"XSF_DZ": "北京",
	"XSF_DH": "13141422555",
	"XSF_YH": "北京",
	"XSF_ZH": "65456787889",
	"GMF_DZ": "",
	"GMF_DH": null,
	"GMF_YH": "",
	"GMF_ZH": "",
    "define":{
      "特征key":"特征值示例 选填"
    },
	"items": [{
		"FPHXZ": 0,
		"XMMC": "*经营租赁*小熊",
		"XMBM": "3040502020101000000",
		"GGXH": "",
		"XMJE": 13130.240000000000000,
		"XMJSHJ": 14837.17,
		"SL": 0.13,
		"SE": 1706.930000000000000,
		"HH": 1,
		"SPBM": "3040502020101000000",
		"DW": "公顷",//面积单位,取值为:平方千米、平方米、公顷、亩
		"XMSL": 870.000000000000000,
		"detailMotor": {
			"CQZSBH": "2324423231231231" //产权证书编号
		}
	}]
}]

数电不动产租赁新版本报文样例,兼容多个租赁明细

[{
	"FPQQLSH": "202302171613262049",
	"FPLX": "31",
	"XSF_NSRSBH": "441234567AAAAAA",
	"XSF_MC": "htt灰度01AAAA",
	"TSPZ": "E06",//特殊票种-不动产租赁代码
	"ORGCODE": "htt001",
	"GMF_NSRSBH": "913418025914242188",
	"GMF_MC": "labo1",
	"GMF_DZDH": "",
	"GMF_YHZH": "",
	"KPR": "hett",
	"SKR": "hett",
	"FHR": "hett",
	"JSHJ": 14837.170000000000000,
	"HJJE": 13130.240000000000000,
	"HJSE": 1706.930000000000000,
	"BZ": "",
	"BMB_BBH": "28.0",
	"XSF_DZ": "北京",
	"XSF_DH": "13141422555",
	"XSF_YH": "北京",
	"XSF_ZH": "65456787889",
	"GMF_DZ": "",
	"GMF_DH": null,
	"GMF_YH": "",
	"GMF_ZH": "",
	"items": [{
		"FPHXZ": 0,
		"XMMC": "*经营租赁*小熊",
		"XMBM": "3040502020101000000",
		"GGXH": "",
		"XMJE": 13130.240000000000000,
		"XMJSHJ": 14837.17,
		"SL": 0.13,
		"SE": 1706.930000000000000,
		"HH": 1,
		"SPBM": "3040502020101000000",
		"DW": "公顷",//面积单位,取值为:平方千米、平方米、公顷、亩
		"XMSL": 870.000000000000000
	}],
    "bdcxsTspzs": [{ 
		"CXRXH": "1",//明细序号,注意该序号要与明细行中正数行行号一对一关联
	    "BDCDZ": "北京市北京市辖区东城区滨河公园5-4-1803",//不动产租赁地址:省市区详细地址
        "ZLQQ": "2023-03-22",//租赁日期起 
        //“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16
        "ZLQZ": "2023-04-30",//租赁日期止 
        //“3040502020200000000 车辆停放服务” 目前只该税编需使用新格式,基础通道要求后边补充时分,新格式:2024-10-25 10:16
        ***不动产租赁日期格式补充说明,目前兼容传入日期后的格式兼容,自动匹配税编做日期截取,但不会自动补充详细日期
        "KDSBZ": "N",//是否跨地址标志 Y:是;N:否
        "CQZSBH": "2324423231231231," //产权证书编号
        "MJDW": "公顷",//面积单位,取值为:平方千米、平方米、公顷、亩
        "CPH": "车牌号",//仅在税收分类编码为“3040502020200000000”时选填
	}]
}]

数电建筑服务接口报文样例

requestdatas=[{
    "FPQQLSH": "202302171613262049",
    "FPLX": "31",
    "XSF_NSRSBH": "441234567AAAAAA",
    "XSF_MC": "htt灰度01AAAA",
    "TSPZ": "E03",//特殊票种-建筑服务代码
    "TDZZSXMBH": "232342131",//土地增值税项目编号
    "KDSBZ": "N",//是否跨地址标志 Y:是;N:否
    "KQYSSSXBGGLBM": "XXXXXXXXX",//跨区域涉税事项报验管理编号,对于非乐企通道,当“跨地市标志”为“是”时,“跨区域涉税事项报验管理编号”为必填;当“跨地市标志”为“否”时,“跨区域涉税事项报验管理编号”不可填写。
    "ORGCODE": "htt001",
    "GMF_NSRSBH": "913418025914242188",
    "GMF_MC": "labo1",
    "GMF_DZDH": "",
    "GMF_YHZH": "",
    "KPR": "hett",
    "SKR": "hett",
    "FHR": "hett",
    "JSHJ": 14837.170000000000000,
    "HJJE": 13130.240000000000000,
    "HJSE": 1706.930000000000000,
    "BZ": "",
    "BMB_BBH": "28.0",
    "XSF_DZ": "北京",
    "XSF_DH": "13141422555",
    "XSF_YH": "北京",
    "XSF_ZH": "65456787889",
    "GMF_DZ": "",
    "GMF_DH": null,
    "GMF_YH": "",
    "GMF_ZH": "",
    "define":{
      "特征key":"特征值示例 选填"
    },
    "items": [{
        "FPHXZ": 0,
        "XMMC": "*经营租赁*小熊",
        "XMBM": "3040502020101000000",
        "GGXH": "",
        "XMJE": 13130.240000000000000,
        "XMJSHJ": 14837.17,
        "SL": 0.13,
        "SE": 1706.930000000000000,
        "HH": 1,
        "SPBM": "3040502020101000000",
        "DW": "公顷",
        "XMSL": 870.000000000000000,
        "detailMotor": {
            "JZFWFSD": "北京市北京市辖区东城区",//建筑服务发生地
            "JZXMMC": "地砖"//建筑项目名称
        }
    }]
 }]

数电货物运输服务接口报文样例

requestdatas=[{
    "FPQQLSH": "202302171613262050",
    "FPLX": "31",
    "XSF_NSRSBH": "44123456789012AAAAAA",
    "XSF_MC": "AAAA广东全电",
    "TSPZ": "E04",
    "ORGCODE": "AAAA03",
    "GMF_NSRSBH": "913418025914242188",
    "GMF_MC": "labo1",
    "GMF_DZDH": "",
    "GMF_YHZH": "",
    "KPR": "hett",
    "SKR": "hett",
    "FHR": "hett",
    "JSHJ": 14837.170000000000000,
    "HJJE": 13130.240000000000000,
    "HJSE": 1706.930000000000000,
    "BZ": "",
    "BMB_BBH": "28.0",
    "XSF_DZ": "北京",
    "XSF_DH": "13141422555",
    "XSF_YH": "北京",
    "XSF_ZH": "65456787889",
    "GMF_DZ": "",
    "GMF_DH": null,
    "GMF_YH": "",
    "GMF_ZH": "",
    "define":{
       "特征key":"特征值示例 选填"
    },
    "items": [{
        "FPHXZ": 0,
        "XMMC": "*运输服务*国内道路货物运输服务",
        "XMBM": "3010102020100000000",
        "GGXH": "",
        "XMJE": 13130.240000000000000,
        "XMJSHJ": 14837.17,
        "SL": 0.13,
        "SE": 1706.930000000000000,
        "HH": 1,
        "SPBM": "3040502020101000000",
        "DW": "吨",
        "XMSL": 870.000000000000000
    }],
    "tspzs": [{
        "YSMXXH": "1",
        "YSGJZL": "铁路运输",
        "YSGJPH": "G443",
        "QYD": "北京市北京市辖区东城区",
        "DDD": "河北省石家庄市长安区",
        "YSHWMC": "煤矿"
    }, {
        "YSMXXH": "2",
        "YSGJZL": "铁路运输",
        "YSGJPH": "Z3232",
        "QYD": "河北省石家庄市桥西区",
        "DDD": "天津市天津市辖区和平区",
        "YSHWMC": "瓷器"
    }]
 }]

数电不动产销售接口报文样例

requestdatas=[{
  "FPQQLSH": "202302171613262049",
  "FPLX": "31",
  "XSF_NSRSBH": "441234567AAAAAA",
  "XSF_MC": "htt灰度01AAAA",
  "TSPZ": "E05", //特殊票种-不动产销售代码
  "BDCDZ": "北京市北京市辖区东城区滨河公园5-4-1803", //不动产地址:省市区详细地址
  "WQHTBABH": "312312312123", //网签合同备案编号
  "TDZZSXMBH": "312312312123", //土地增值税项目编号
  "BDCDWDM": "312312312123", //不动产单元代码
  "HDJSJG": "312312312123", //核定计税价格。不属于核定计税不动产销售的可不填写
  "SJCJHSJE": "312312312123", //实际成交含税金额。若按核定计税价格征税的,为必填
  "KDSBZ": "N", //是否跨地址标志 Y:是;N:否
  "ORGCODE": "htt001",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 14837.170000000000000,
  "HJJE": 13130.240000000000000,
  "HJSE": 1706.930000000000000,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "define":{
    "特征key":"特征值示例 选填"
  },
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*经营租赁*小熊",
    "XMBM": "3040502020101000000",
    "GGXH": "",
    "XMJE": 13130.240000000000000,
    "XMJSHJ": 14837.17,
    "SL": 0.13,
    "SE": 1706.930000000000000,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "公顷", //面积单位,取值为:平方千米、平方米、公顷、亩
    "XMSL": 870.000000000000000,
    "detailMotor": {
      "CQZSBH": "2324423231231231" //产权证书编号
    }
  }],
  "DFGTGMBZ": "Y",//多方共同购买标志 Y:多方共同购买N:非多方共同购买
   "tspzs": [{ 
       "CXRXH": "1",//明细序号 
       "GTGMF": "刘亦菲", //共同购买方
       "CXRZJLXDM": "101", //证件类型
       "SFZJHM": "120110202401142323" //证件号码
   }]
}]

数电不动产销售新版本报文样例,兼容多套房产

[{
	"FPQQLSH": "202302171613262049",
	"FPLX": "31",
	"XSF_NSRSBH": "441234567AAAAAA",
	"XSF_MC": "htt灰度01AAAA",
	"TSPZ": "E05",//特殊票种-不动产销售代码
	"ORGCODE": "htt001",
	"GMF_NSRSBH": "913418025914242188",
	"GMF_MC": "labo1",
	"GMF_DZDH": "",
	"GMF_YHZH": "",
	"KPR": "hett",
	"SKR": "hett",
	"FHR": "hett",
	"JSHJ": 14837.170000000000000,
	"HJJE": 13130.240000000000000,
	"HJSE": 1706.930000000000000,
	"BZ": "",
	"BMB_BBH": "28.0",
	"XSF_DZ": "北京",
	"XSF_DH": "13141422555",
	"XSF_YH": "北京",
	"XSF_ZH": "65456787889",
	"GMF_DZ": "",
	"GMF_DH": null,
	"GMF_YH": "",
	"GMF_ZH": "",
	"items": [{
		"FPHXZ": 0,
		"XMMC": "*经营租赁*小熊",
		"XMBM": "3040502020101000000",
		"GGXH": "",
		"XMJE": 13130.240000000000000,
		"XMJSHJ": 14837.17,
		"SL": 0.13,
		"SE": 1706.930000000000000,
		"HH": 1,
		"SPBM": "3040502020101000000",
		"DW": "公顷",//面积单位,取值为:平方千米、平方米、公顷、亩
		"XMSL": 870.000000000000000,
		"detailMotor": {
			"CQZSBH": "2324423231231231" //产权证书编号
		}
	}],
    "DFGTGMBZ": "Y",//多方共同购买标志 Y:多方共同购买N:非多方共同购买
    "tspzs": [{ 
		"CXRXH": "1",//明细序号 
		"GTGMF": "刘亦菲", //共同购买方
		"CXRZJLXDM": "101", //证件类型
		"SFZJHM": "120110202401142323" //证件号码
	}],
    "bdcxsTspzs": [{ 
		"CXRXH": "1",//明细序号,注意该序号要与明细行正数行行号一对一关联
	    "BDCDZ": "北京市北京市辖区东城区滨河公园5-4-1803",//不动产地址:省市区详细地址
        "WQHTBABH": "312312312123",//网签合同备案编号
        "TDZZSXMBH": "312312312123",//土地增值税项目编号
        "BDCDWDM": "312312312123",//不动产单元代码
        "HDJSJG": "312312312123",//核定计税价格。不属于核定计税不动产销售的可不填写
        "SJCJHSJE": "312312312123",//实际成交含税金额。若按核定计税价格征税的,为必填
        "KDSBZ": "N",//是否跨地址标志 Y:是;N:否
		"CQZSBH": "2324423231231231," //产权证书编号
		"MJDW": "公顷",//面积单位,取值为:平方千米、平方米、公顷、亩
	}]
}]

数电旅客运输接口报文样例

requestdatas=[{
  "FPQQLSH": "202302171613262049",
  "FPLX": "31",
  "XSF_NSRSBH": "441234567AAAAAA",
  "XSF_MC": "htt灰度01AAAA",
  "TSPZ": "E09",//特殊票种-旅客运输服务
  "ORGCODE": "htt001",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 14837.170000000000000,
  "HJJE": 13130.240000000000000,
  "HJSE": 1706.930000000000000,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "define":{
    "特征key":"特征值示例 选填"
  },
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*运输服务*国际旅客运输",
    "XMBM": "3040502020101000000",
    "GGXH": "",
    "XMJE": 13130.240000000000000,
    "XMJSHJ": 14837.17,
    "SL": 0.13,
    "SE": 1706.930000000000000,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "",
    "XMSL": 870.000000000000000
  }],
  "tspzs": [{
    "CXRXH": "1",//出行人序号
    "CXR": "张三",//出行人
    "CHUXRQ": "2022-11-01",//出行日期,格式yyyy-MM-dd
    "CXRZJLXDM": "101",//出行人证件类型代码
    "SFZJHM": "1233445",//身份证件号码
    "CFD": "北京市怀柔区",//出发地
    "LKDDD北京市平谷区",//到达地
    "ZWDJ": "二等座",//座位等级若交通工具为火车、飞机、船舶,则该要素为必填,其他选项选填;
    ---交通工具为火车:一等座、二等座、软席(软座、软卧)、硬席(硬座、硬卧)
    ---交通工作为飞机: 经济舱、头等舱、公务舱
    ---交通工具为船舶: 一等舱、二等舱 、三等舱
    "JTGJLXDM": "2"//交通工具类型代码(1:飞机 2:火车 3:长途汽车 4:公共交通 5:出租车 6:汽车 7:船舶 9:其他)
  }]
}]

# 出行人证件类型代码枚举

证件类型代码 证件名称
101 组织机构代码证
102 营业执照
103 税务登记证
199 其他单位证件
201 居民身份证
202 军官证
203 武警警官证
204 士兵证
205 军队离退休干部证
206 残疾人证
207 残疾军人证(1-8级)
208 外国护照
210 港澳居民来往内地通行证
212 中华人民共和国往来港澳通行证
213 台湾居民来往大陆通行证
214 大陆居民往来台湾通行证
215 外国人居留证
216 外交官证
217 使(领事)馆证
218 海员证
219 香港永久性居民身份证
220 台湾身份证
221 澳门特别行政区永久性居民身份证
222 外国人身份证件
224 就业失业登记证
225 退休证
226 离休证
227 中国护照
228 城镇退役士兵自谋职业证
229 随军家属身份证明
230 中国人民解放军军官转业证书
231 中国人民解放军义务兵退出现役证
232 中国人民解放军士官退出现役证
233 外国人永久居留身份证(外国人永久居留证)
234 就业创业证
235 香港特别行政区护照
236 澳门特别行政区护照
237 中华人民共和国港澳居民居住证
238 中华人民共和国台湾居民居住证
239 《中华人民共和国外国人工作许可证》(A类)
240 《中华人民共和国外国人工作许可证》(B类)
241 《中华人民共和国外国人工作许可证》(C类)
291 出生医学证明
299 其他个人证件

# 国家地区代码枚举

国家(地区)代码 (地区)名称
004 阿富汗
008 阿尔巴尼亚共和国
010 南极洲
012 阿尔及利亚民主人民共和国
016 美属萨摩亚
020 安道尔公国
024 安哥拉共和国
028 安提瓜和巴布达
031 阿塞拜疆共和国
032 阿根廷共和国
036 澳大利亚联邦
040 奥地利共和国
044 巴哈马联邦
048 巴林国
050 孟加拉人民共和国
051 亚美尼亚共和国
052 巴巴多斯
056 比利时王国
060 百慕大
064 不丹王国
068 玻利维亚共和国
070 波斯尼亚和黑塞哥维那
072 博茨瓦纳共和国
074 布维岛
076 巴西联邦共和国
084 伯利兹
086 英属印度洋领地
090 所罗门群岛
092 英属维尔京群岛
096 文莱达鲁萨兰国
100 保加利亚共和国
104 缅甸联邦
108 布隆迪共和国
112 白俄罗斯共和国
116 柬埔寨王国
120 喀麦隆共和国
124 加拿大
132 佛得角共和国
136 开曼群岛
140 中非共和国
144 斯里兰卡民主社会主义共和国
148 乍得共和国
152 智利共和国
156 中华人民共和国
158 中国台湾
162 圣诞岛
166 科科斯(基林)群岛
170 哥伦比亚共和国
174 科摩罗伊斯兰联邦共和国
175 马约特
178 刚果共和国
180 刚果民主共和国
184 库克群岛
188 哥斯达黎加共和国
191 克罗地亚共和国
192 古巴共和国
196 塞浦路斯共和国
203 捷克共和国
204 贝宁共和国
208 丹麦王国
212 多米尼克国
214 多米尼加共和国
218 厄瓜多尔共和国
222 萨尔瓦多共和国
226 赤道几内亚共和国
231 埃塞俄比亚联邦民主共和国
232 厄立特里亚国
233 爱沙尼亚共和国
234 法罗群岛
238 福克兰群岛(马尔维纳斯)
239 南乔治亚岛和南桑德韦奇岛
242 斐济群岛共和国
246 芬兰共和国
250 法兰西共和国
254 法属圭亚那
258 法属波利尼西亚
260 法属南部领地
262 吉布提共和国
266 加蓬共和国
268 格鲁吉亚
270 冈比亚共和国
275 巴勒斯坦国
276 德意志联邦共和国
288 加纳共和国
292 直布罗陀
296 基里巴斯共和国
300 希腊共和国
304 格陵兰
308 格林纳达
312 瓜德罗普
316 关岛
320 危地马拉共和国
324 几内亚共和国
328 圭亚那合作共和国
332 海地共和国
334 赫德岛和麦克唐纳岛
336 梵蒂冈城国
340 洪都拉斯共和国
344 中国香港特别行政区
348 匈牙利共和国
352 冰岛共和国
356 印度共和国
360 印度尼西亚共和国
364 伊朗伊斯兰共和国
368 伊拉克共和国
372 爱尔兰
376 以色列国
380 意大利共和国
384 科特迪瓦共和国
388 牙买加
392 日本国
398 哈萨克斯坦共和国
400 约旦哈希姆王国
404 肯尼亚共和国
408 朝鲜民主主义人民共和国
410 大韩民国
414 科威特国
417 吉尔吉斯共和国
418 老挝人民民主共和国
422 黎巴嫩共和国
426 莱索托王国
428 拉脱维亚共和国
430 利比里亚共和国
434 大阿拉伯利比亚人民社会主义民众国
438 列支敦士登公国
440 立陶宛共和国
442 卢森堡大公国
446 中国澳门特别行政区
450 马达加斯加共和国
454 马拉维共和国
458 马来西亚
462 马尔代夫共和国
466 马里共和国
470 马耳他共和国
474 马提尼克
478 毛里塔尼亚伊斯兰共和国
480 毛里求斯共和国
484 墨西哥合众国
492 摩纳哥公国
496 蒙古国
498 摩尔多瓦共和国
499 黑山
500 蒙特塞拉特
504 摩洛哥王国
508 莫桑比克共和国
512 阿曼苏丹国
516 纳米比亚共和国
520 瑙鲁共和国
524 尼泊尔王国
528 荷兰王国
530 荷属安的列斯
533 阿鲁巴
540 新喀里多尼亚
548 瓦努阿图共和国
554 新西兰
558 尼加拉瓜共和国
562 尼日尔共和国
566 尼日利亚联邦共和国
570 纽埃
574 诺福克岛
578 挪威王国
580 北马里亚纳自由联邦
581 美国本土外小岛屿
583 密克罗尼西亚联邦
584 马绍尔群岛共和国
585 帕劳共和国
586 巴基斯坦伊斯兰共和国
591 巴拿马共和国
598 巴布亚新几内亚独立国
600 巴拉圭共和国
604 秘鲁共和国
608 菲律宾共和国
612 皮特凯恩
616 波兰共和国
620 葡萄牙共和国
624 几内亚比绍共和国
626 东帝汶
630 波多黎各
634 卡塔尔国
638 留尼汪
642 罗马尼亚
643 俄罗斯联邦
646 卢旺达共和国
654 圣赫勒拿
659 圣基茨和尼维斯联邦
660 安圭拉
662 圣卢西亚
666 圣皮埃尔和密克隆
670 圣文森特和格林纳丁斯
674 圣马力诺共和国
678 圣多美和普林西比民主共和国
682 沙特阿拉伯王国
686 塞内加尔共和国
688 塞尔维亚
690 塞舌尔共和国
694 塞拉利昂共和国
702 新加坡共和国
703 斯洛伐克共和国
704 越南社会主义共和国
705 斯洛文尼亚共和国
706 索马里共和国
710 南非共和国
716 津巴布韦共和国
724 西班牙王国
728 南苏丹
732 西撒哈拉
736 苏丹共和国
740 苏里南共和国
744 斯瓦尔巴岛和扬马延岛
748 斯威士兰王国
752 瑞典王国
756 瑞士联邦
760 阿拉伯叙利亚共和国
762 塔吉克斯坦共和国
764 泰王国
768 多哥共和国
772 托克劳
776 汤加王国
780 特立尼达和多巴哥共和国
784 阿拉伯联合酋长国
788 突尼斯共和国
792 土耳其共和国
795 土库曼斯坦
796 特克斯和凯科斯群岛
798 图瓦卢
800 乌干达共和国
804 乌克兰
807 前南斯拉夫马其顿共和国
818 阿拉伯埃及共和国
826 大不列颠及北爱尔兰联合王国
831 根西岛
832 泽西岛
833 马恩岛
834 坦桑尼亚联合共和国
840 美利坚合众国
850 美属维尔京群岛
854 布基纳法索
858 乌拉圭东岸共和国
860 乌兹别克斯坦共和国
862 委内瑞拉共和国
876 瓦利斯和富图纳
882 萨摩亚独立国
887 也门共和国
891 南斯拉夫联盟共和国
894 赞比亚共和国
A00 科索沃

数电代收车船税发票报文样例

requestdatas=[{
  "FPQQLSH": "202302171613262049",
  "FPLX": "31",
  "XSF_NSRSBH": "441234567AAAAAA",
  "XSF_MC": "htt灰度01AAAA",
  "TSPZ": "E07",//特殊票种-代收车船税代码
  "BXDH": "89293943482432",//保险单号
  "CPHCBDJH": "豫MUX555",//车牌号/船舶登记号
  "SKSSQ": "2023-01 2023-03",//税款所属期yyyy-MM+空格+yyyy-MM
  "DSCCSJE": "350000",//代收车船税金额
  "ZNJ": "100",//滞纳金
  "JEHJ": "350100",//金额合计
  "CJH": "233134133384938",//车辆识别代码/车架号码
  "ORGCODE": "htt001",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 14837.170000000000000,
  "HJJE": 13130.240000000000000,
  "HJSE": 1706.930000000000000,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "define":{
    "特征key":"特征值示例 选填"
  },
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*代收车船*宝马X6",
    "XMBM": "3040502020101000000",
    "GGXH": "",
    "XMJE": 13130.240000000000000,
    "XMJSHJ": 14837.17,
    "SL": 0.13,
    "SE": 1706.930000000000000,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "辆",
    "XMSL": 870.000000000000000
  }]
}]

数电差额征收-差额开票报文样例

requestdatas=[{
  "FPQQLSH": "202302171613262050",
  "FPLX": "31",
  "XSF_NSRSBH": "44123456789012AAAAAA",
  "XSF_MC": "AAAA广东全电",
  "ZSFS": "2",//征收方式:差额征收-差额开票
  "ORGCODE": "AAAA03",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 14837.170000000000000,
  "HJJE": 13130.240000000000000,
  "HJSE": 1706.930000000000000,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "define":{
    "特征key":"特征值示例 选填"
  },
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*运输服务*国内道路货物运输服务",
    "XMBM": "3010102020100000000",
    "GGXH": "",
    "XMJE": 13130.240000000000000,
    "XMJSHJ": 14837.17,
    "SL": 0.13,
    "SE": 1706.930000000000000,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "吨",
    "XMSL": 870.000000000000000,
    "KCE": 100.00//扣除总额
  }],
  "cepzs": [{
    "XH": 1,//序号
    "PZLX": "01",//凭证类型,01 数电票、02 增值税专用发票、03 增值税普通发票、04 营业税发票、05 财政票据、06 法院裁决书、07 契税完税凭证、08 其他发票类、09 其他扣除凭证
    "FPHM": "23442000000000000293",//全电发票号码
    "FPDM": "",//非全电发票代码
    "ZZFPHM": "",//非全电发票号码
    "PZHM": "",//凭证号码
    "KJRQ": "2023-01-04",//开票日期,格式形如:yyyy-MM-dd
    "HJJE": 1000.00,//合计金额
    "KCE": 100.00,//扣除额
    "BZ": "",//备注
    "LY": "手工录入",//录入方式,取值范围如下:手工录入 勾选录入 模板录入
    "BCKCJE": 100.00,//本次扣除金额
    "PZHJJE": 1000.00//凭证合计金额
  }]
}]

数电差额征收-全额开票报文样例

requestdatas=[{
  "FPQQLSH": "202302171613262050",
  "FPLX": "31",
  "XSF_NSRSBH": "44123456789012AAAAAA",
  "XSF_MC": "AAAA广东全电",
  "ZSFS": "3", //征收方式:差额征收-全额开票
  "ORGCODE": "AAAA03",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 14837.170000000000000,
  "HJJE": 13130.240000000000000,
  "HJSE": 1706.930000000000000,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "define":{
    "特征key":"特征值示例 选填"
  },
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*运输服务*国内道路货物运输服务",
    "XMBM": "3010102020100000000",
    "GGXH": "",
    "XMJE": 13130.240000000000000,
    "XMJSHJ": 14837.17,
    "SL": 0.13,
    "SE": 1706.930000000000000,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "吨",
    "XMSL": 870.000000000000000,
    "KCE": 100.00 //扣除总额,与差额征收差额开票一样
  }],
  "cepzs": [{
    "XH": 1, //序号
    "PZLX": "01", //凭证类型,01 数电票、02 增值税专用发票、03 增值税普通发票、04 营业税发票、05 财政票据、06 法院裁决书、07 契税完税凭证、08 其他发票类、09 其他扣除凭证
    "FPHM": "23442000000000000293", //全电发票号码
    "FPDM": "", //非全电发票代码
    "ZZFPHM": "", //非全电发票号码
    "PZHM": "", //凭证号码
    "KJRQ": "2023-01-04", //开票日期,格式形如:yyyy-MM-dd
    "HJJE": 1000.00, //合计金额
    "KCE": 100.00, //扣除额
    "BZ": "", //备注
    "LY": "手工录入", //录入方式,取值范围如下:手工录入 勾选录入 模板录入
    "BCKCJE": 100.00, //本次扣除金额
    "PZHJJE": 1000.00 //凭证合计金额
  }]

}]

数电电子行程单-精简

requestdatas=[{
             	"FPQQLSH": "YONYOUTEST590002",
             	"FPLX": "35",
             	"XSF_NSRSBH": "91510000742262413G",
             	"XSF_MC": "",
             	"ORGCODE": "41800001",
             	"GMF_NSRSBH": "9151000072538219XQ",
             	"GMF_MC": "用友网络科技股份有限公司四川分公司",
             	"TICKETNUMBER": "8762426443744",
             	"BUYERTYPE": "0",
             	"XSF_DZ": "北京",
             	"XSF_DH": "13141422555",
             	"XSF_YH": "北京",
             	"XSF_ZH": "65456787889",
             	"GMF_DZ": "",
             	"GMF_DH": "",
             	"GMF_YH": "",
             	"GMF_ZH": ""
             }]
&email=[
    {
	    "fpqqlsh":"YONYOUTEST590002",
        "address": "x1@yonyou.com,x2@yonyou.com"
    }
]
&sms=[{
	    "fpqqlsh":"YONYOUTEST590002",
        "address": "13511111111,13511111112"
    }]

数电电子行程单-全量完整开票报文

requestdatas=[{
  "FPQQLSH": "202302171613262049",
  "FPLX": "35",
  "LYDJH": "00023123123123", //业务来源单据号
  "XSF_NSRSBH": "441234567AAAAAA",
  "XSF_MC": "htt灰度01AAAA",
  "TSPZ": "E22", //特殊票种-电子行程单
  "ORGCODE": "htt001",
  "GMF_NSRSBH": "913418025914242188",
  "GMF_MC": "labo1",
  "TICKETNUMBER": "9992181190174", //13位电子票号
  "BUYERTYPE": "2", //购买机票方类型:0:企业 1:机关或事业单位 2:个人3:其他
  "FAREAMOUNT": "20", //加减价
  "ORDERNUMBER": "23234234dg2323dsdf", //企业购票订单号
  "USERNAME": "zhangwuji", //用户名
  "GPCODE": "1312314132131", //GP单号
  "PASSENGERNAME": "boge", //乘客姓名
  "PASSENGERIDNUM": "212312312321423123123", //乘客身份证号码/护照号码
  "ENDORSEMENTS": "Q/改退收费", //签注
  "OFFICE": "PEK112", //出票Office号
  "ISSUEDBY": "中国国际航空股份有限公司( 电话销售服务中心 )", //出票单位
  "IATA": "XXXXXX", //IATA号
  "PNR": "XXXXXX", //PNR号
  "TICKETINFORMATION": "CA1501T3 乘机", //机票票面提示信息
  "INSURANCE": "XXX", //保险信息
  "ELECTRONICTICKETTYPE": "0", //机票类型 0:国内 1:国际
  "VERIFYCODE": "ielldje", //验证码
  "OVERDUEFLAG": "false", //超期标识true: 超期 false: 未超期
  "GMF_DZDH": "",
  "GMF_YHZH": "",
  "KPR": "hett",
  "SKR": "hett",
  "FHR": "hett",
  "JSHJ": 1420.00,
  "HJJE": 1306.88,
  "HJSE": 113.12,
  "BZ": "",
  "BMB_BBH": "28.0",
  "XSF_DZ": "北京",
  "XSF_DH": "13141422555",
  "XSF_YH": "北京",
  "XSF_ZH": "65456787889",
  "GMF_DZ": "",
  "GMF_DH": null,
  "GMF_YH": "",
  "GMF_ZH": "",
  "items": [{
    "FPHXZ": 0,
    "XMMC": "*运输服务*票价",
    "XMBM": "3040502020101000000",
    "GGXH": "",
    "XMJE": 1238.53,
    "XMJSHJ": ,
    "SL": 0.09,
    "SE": 111.47,
    "HH": 1,
    "SPBM": "3040502020101000000",
    "DW": "",
    "XMSL": "",
  },
    {
      "FPHXZ": 0,
      "XMMC": "*运输服务*燃油附加费",
      "XMBM": "3040502020101000000",
      "GGXH": "",
      "XMJE": 18.35,
      "XMJSHJ": ,
      "SL": 0.09,
      "SE": 0,
      "HH": 2,
      "SPBM": "3040502020101000000",
      "DW": "",
      "XMSL": "",
    },
    {
      "FPHXZ": 0,
      "XMMC": "*运输服务*代收民航发展基金",
      "XMBM": "3040502020101000000",
      "GGXH": "",
      "XMJE": 50,
      "XMJSHJ": ,
      "SL": 0.00,
      "LSLBS": "3",
      "SE": 0,
      "HH": 3,
      "SPBM": "3040502020101000000",
      "DW": "",
      "XMSL": "",
    },
    {
      "FPHXZ": 0,
      "XMMC": "*运输服务*其他",
      "XMBM": "3040502020101000000",
      "GGXH": "",
      "XMJE": 0,
      "XMJSHJ": ,
      "SL": 0.00,
      "LSLBS": "3",
      "SE": 0,
      "HH": 4,
      "SPBM": "3040502020101000000",
      "DW": "",
      "XMSL": "",
    }

  ],
  "tspzs": [{
    "CXRXH": "1", //出行人序号
    "CXR": "张三", //承运人名称
    "CARRIERCODE": "CA", //承运人二字码
    "CHUXRQ": "2022-11-01 08:30 ", //出行日期,格式yyyy-MM-dd HH:mm
    "CFD": "北京-首都###T3###PEK", //出发地
    "LKDDD": "上海-虹桥###T2###SHA", //到达地
    "ZWDJ": "Y", //座位等级
    "YSGJPH": "2" //航班号
    "FAREBASIS": "Y" //客票级别/客票类别
    "NOTVALIDBEFORE": "2024-05-17" //客票生效日期
    "NOTVALIDAFTER": "2024-05-17" //有效截至日期
    "ALLOW": "20K" //免费行李
    "ITINERARYTYPE": "0" //行程类型 0:普通运输段 1:地面运输
  }]
}]

# 返回结果说明

参数 类型 描述 说明
code String 状态码 详见状态码说明
msg String 信息说明

# 返回样例

{
	"code": "0000", 
	"msg": "success"
}

# 开蓝票-自动拆分

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/insertWithSplit?appid=XXXXX

TIP

每次请求的数据不能超过10张单据

此接口只能用来开具蓝票(数电特殊票种开具样例见开蓝票接口)

签名载荷(Payload)中必须包含属性requestdatas,它的值为表单参数requestdatas的MD5值,具体使用方式参考样例代码示例

# 请求体参数

# 表单说明

参数 描述 说明
requestdatas 开票申请发票信息,包含发票头发票明细
email 邮件推送配置(可选)
sms 短信推送配置(可选)
url 回调服务配置(可选)
delurl 退回业务系统回调服务配置(可选)
autoAudit 是否自动审核(可选) true:自动审核,即不需要人工在发票平台确认开票,直接进行开票 false:不自动审核,即需要人工确认
如果不传,代表true
nc6x-ubl ncc友企联回调参数

# 发票头

参数 类型 长度 是否必填 默认值 描述 说明
FPQQLSH String 20 发票请求流水号
FPLX String 1 1 发票类型 1:增值税电子普通发票;
2:增值税电子专用发票;
3:增值税普通发票;
4:增值税专用发票 、增值税专用发票(机动车);
5:机动车销售统一发票;
8:增值税电子普通发票(成品油);
10:成品油普通发票;
11:成品油专用发票;
15:二手车销售统一发票;
31:数电专用发票;
32:数电普通发票;
33:数电纸质发票(增值税专用发票);
34:数电纸质发票(普通发票);
35:数电票(航空运输电子客票行程单)
36:数电纸质发票(机动车销售统一发票)
XSF_NSRSBH String 20 销售方纳税人识别号
XSF_MC String 100 销售方名称 如果为空,获取发票平台配置的销售方名称
XSF_DZDH String 100 销售方地址、电话 如果为空,获取发票平台配置的销售方地址及电话
XSF_DZ String 300 销售方地址 如果为空,获取发票平台配置的销售方地址 (数电专用字段)
XSF_DH String 60 销售方电话 如果为空,获取发票平台配置的销售方电话 (数电专用字段)
XSF_YHZH String 100 销售方银行、账号 如果为空,获取发票平台配置的销售方银行及账号
XSF_YH String 120 销售方银行 如果为空,获取发票平台配置的销售方银行 (数电专用字段)
XSF_ZH String 100 销售方账号 如果为空,获取发票平台配置的销售方账号 (数电专用字段)
GMF_NSRSBH String 20 购买方纳税人识别号 发票类型31 数电专用发票(必填)
GMF_MC String 100 购买方名称
GMF_DZDH String 100 购买方地址、电话 数电票此字段非必填
GMF_YHZH String 100 购买方银行、账号 数电票此字段非必填
GMF_DZ String 300 购买方地址 (数电专用字段)
GMF_DH String 60 购买方电话 如果为空,获取发票平台配置的购买方地址 (数电专用字段)
GMF_YH String 120 购买方银行 如果为空,获取发票平台配置的购买方电话(数电专用字段)
GMF_ZH String 100 购买方账号 如果为空,获取发票平台配置的购买方账号(数电专用字段)
ALLELCUSERNAME String 300 数电发票用户名 使用基础通道开具数电票且需要指定税局账号时,该字段必填。
ALLELCPASSWORD String 300 数电发票密码 使用基础通道开具数电票且需要指定税局账号时,该字段必填。
KPR String 8 开票人 如果为空,获取发票平台配置的开票人
SKR String 8 收款人 如果为空,获取发票平台配置的收款人
FHR String 8 复核人 如果为空,获取发票平台配置的复核人
SLSM String 1 税率说明 1:当小规模纳税人开具3%税率时需要填写税率说明 2:前期已开具发票,发生销售折让、中止或者退回等情形需要开具红字发票,或者开票有误需要重新开具; 3:因为实际经营业务需要,放弃享受减按1%征收率征收增值税政策。
JSHJ BigDecimal 15,2 价税合计 两位小数。明细价税合计之和必须与总的价税合计一致
HJJE BigDecimal 15,2 合计金额 两位小数。为空时,根据明细项目进行合计。
HJSE BigDecimal 15,2 合计税额 两位小数。为空时,根据明细项目进行合计。
BZ String 230 备注 长度不能大于230
LYID String 100 请求来源唯一标识
BMB_BBH String 20 13.0 编码版本号 增加商品编码功能后,税局下载的商品编码表版本
ORGCODE String 50 开票点编码 支持一个公司多个开票点场景。如果为空,获取默认的开票点
PROJECTCODE String 50 项目编号 https://developers.weixin.qq.com/doc/offiaccount/WeChat_Invoice/E_Invoice/Instruction.html
ACOUNTORGCODE String 50 会计主体编码
WBSCODE String 36 WBS编码
WXORDERID String 微信订单号 商户开票完成后,传入订单号和商户id将自动插入用户微信卡包(参考微信卡包指引) (opens new window)
WXAPPID String 微信商户id 商户开票完成后,传入订单号和商户id将自动插入用户微信卡包(参考微信卡包指引) (opens new window)
TSPZ String 1 特殊票种 0-一般
2-燃油增值税专用发票
8-农产品销售
9-农产品收购
11-烟草发票
12-机动车发票
14-成品油发票
DK-代开发票
16-矿产品发票
E01-成品油发票
E02-稀土发票
E03-建筑服务发票
E04-货物运输
E05-不动产销售
E06-不动产租赁服务发票
E07-代收车船税
E09-旅客运输
E12-自产农产品销售
E14-机动车
E16-农产品收购
E17-光伏收购
E18-卷烟发票
E32-电子烟
(数电票对应的特殊票种为E开头,其他的为税控发票的特殊票种)
LYDJH String 200 业务来源单据号
DFGTGMBZ String 多方共同购买标志 Y:多方共同购买N:非多方共同购买
ZRRBS String 购买方自然人标志 仅在开具数电普票(电子)时使用,如受票方(发票抬头)为自然人,并要求能将发票归集在个人票夹中展示,需提供姓名及身份证号(自然人纳税人识别号),此参数传入Y;如受票方(发票抬头)为个体工商户,需提供社会统一信用代码或纳税人识别号,此参数传入N
ZJLX String 证件类型代码 适用于自然人标识为Y时的自然人补充信息,枚举参见出行人证件类型代码枚举。收购发票或者ZJHM、GUOJI两个字段有值时,必填
ZJHM String 证件号码 适用于自然人标识为Y时的自然人补充信息。收购发票或者ZJLX、GUOJI两个字段有值时,必填
GUOJI String 国籍代码 适用于自然人标识为Y时的自然人补充信息,枚举参见国家地区代码枚举。收购发票或者ZJLX、ZJHM两个字段有值时,必填
EINVOICESHOWGXFYHZH String 数电发票是否显示购销方银行、账号 数电发票是否显示购销方银行、账号: 0:不显示 1:仅显示销售方银行、账号 2:仅显示购买方银行、账号 3:购销方银行、账号都显示
EINVOICESHOWSKRSHR String 数电发票(非纸质发票)是否显示收款人、复核人 数电发票(非纸质发票)是否显示收款人、复核人。0:不显示 1:仅显示收款人 2:仅显示复核人 3:收款人复核人都显示
EINVOICESHOWGXFDZDH String 备注是否显示地址、电话 0:不显示 1:仅显示销地址、电话 2:仅显示购买方地址、电话 3:购销方地址、电话都显示
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 发票明细

参数 类型 长度 是否必填 默认值 描述 说明
FPHXZ Integer 2 0 发票行性质 0-正常行1-折扣行2-被折扣行
XMMC String 600 项目名称
GGXH String 150 规格型号 非数电发票规格型号最大长度为40个字符,数电发票长度为150个字符
DW String 300 单位 如果是成品油发票,必填且只能是"吨或升"<\br>如果是矿产品发票,必填且只能是"立方米、吨、千克、克或克拉"
XMSL BigDecimal 15,6 项目数量 如果是成品油发票,必填。
XMDJ BigDecimal 15,6 项目单价 为"不含税单价,项目单价为空时,根据项目金额反算。不为空时不进行计算
XMJE BigDecimal 15,2 项目金额 为"不含税金额",项目金额为空,根据项目价税合计反算。不为空时不进行计算
XMJSHJ BigDecimal 15,2 项目价税合计
SL BigDecimal 6,6 税率 6 位小数,例 17%为 0.17
SE BigDecimal 15,2 税额 税额为空,根据价税合计反算。不为空时不进行计算。
HH string 60 行号 有折扣时需要必输
ZKHHH string 60 折扣行行号 有折扣时需要必输
SPBM string 19 商品编码 税收分类编码
ZXBM string 20 10 商品自行编码
YHZCBS int 2 0 享受优惠标识 0:不使用,1:使用
LSLBS string 1 零税率标识 空:非零利率,0:出口退税,1:免税,2:不征收,3普通零税率
ZZSTSGL string 50 优惠政策说明 按3%简易征收,按5%简易征收 (此字段非空时,享受优惠标识YHZCBS字段值需为1)
KCE BigDecimal 15,2 扣除额 扣除额
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 邮件推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 短信推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 回调服务配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
url String 500 回调url 开票申请调用方配置回调url,当电子发票开具成功后,调用此服务,POST电子发票相关信息。信息包含:1、pdf版式文件2、发票数据、3、发票下载链接ncc通过友企联方案回调可不传此参数
intf String 200 ncc回调接口名 ncc通过友企联方案回调时必传
method String 200 ncc回调方法名 ncc通过友企联方案回调时必传

# 请求样例

标准表单参数样例

requestdatas=[ {
	"FPQQLSH" : "12345678901234567890",
	"XSF_NSRSBH" : "销售方纳税人识别号",
	"XSF_MC" : "销售方名称",
	"XSF_DZDH" : "销售方地址、电话",
    "XSF_DZ" : "销售方地址",  (数电专用字段)
    "XSF_DH" : "销售方电话",(数电专用字段)
	"XSF_YHZH" : "销售方银行、账号",
    "XSF_YH" : "销售方银行",(数电专用字段)
    "XSF_ZH" : "销售方账号",(数电专用字段)
	"GMF_NSRSBH" : "购买方纳税人识别号", (发票类型31 数电专用发票(必填))(数电专用字段)
	"GMF_MC" : "购买方名称",
	"GMF_DZDH" : "购买方地址、电话",
    "GMF_DZ" : "购买方地址",(数电专用字段)
    "GMF_DH" : "购买方电话",(数电专用字段)
	"GMF_YHZH" : "购买方银行、账号",
    "GMF_YH" : "购买方银行",(数电专用字段)
    "GMF_ZH" : "购买方账号",(数电专用字段)
    "ALLELCUSERNAME": "电子税务局用户名(发票类型为数电发票时必传并且是国密四密文)",(数电专用字段)
    "ALLELCPASSWORD": "电子税务局密码 (发票类型为数电发票时必传并且是国密四密文)",  (数电专用字段)
	"KPR" : "开票人",
	"SKR" : "收款人",
	"FHR" : "复核人",
	"JSHJ" : "价税合计",
	"HJJE" : "合计金额",
	"HJSE" : "合计税额",
	"BZ" : "备注",
	"BMB_BBH" : "10.0",
    "define":{
       "特征key":"特征值示例 选填"
    },
	"items" : [{
            "FPHXZ" : "发票行性质",
            "XMMC" : "项目名称",
            "GGXH" : "规格型号",
            "DW" : "单位",
            "XMSL" : "项目数量",
            "XMDJ" : "项目单价",
            "XMJE" : "项目金额",
            "XMJSHJ" : "项目价税合计",
            "SL" : "税率",
            "SE" : "税额",
            "HH":"行号",
            "SPBM":"商品编码",
            "ZXBM":"自行编码",
            "define":{
              "特征key":"特征值示例 选填"
            }
            "KCE":300
		}
	]
}]
&email=[
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x1@yonyou.com,x2@yonyou.com", 
    }, 
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x3@yonyou.com", 
    }
]
&sms=[{
	"fpqqlsh":"12345678901234567890",
        "address": "13511111111,13511111112", 
    }]
&url=[{
		"fpqqlsh":"12345678901234567890",
        "url": "http://url.com/msg"
    }]
&nc6x-ubl=[{
        "fpqqlsh":"12345678901234567890",
        "method":"queryUserPermAppPksOrCodes",
        "intf":"nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService"   
}]
&autoAudit=true

最小请求参数样例

TIP

销售方地址及电话、银行及账号、销售方名称可以通过销售方纳税人识别号获取

requestdatas=[{
	"FPQQLSH" : "12345678901234567890",
    "XSF_NSRSBH" : "销售方纳税人识别号",
    "GMF_MC" : "购买方名称",
    "JSHJ" : 117,
    "items" : 
		    [
			    {
		            "XMMC" : "项目名称",
		            "XMSL" : 1,
		            "XMJSHJ" : 117,
		            "SL" : 0.17
		        }
		    ]
}]

包含折扣行开票样例

TIP

包含折扣行的单据需要增加以下信息 FPHXZ:发票行性质 HH:行号 ZKHHH:折扣行行号 折扣行上规则型号、单位、数量、单价 不用设值。折扣行的项目名称必须与被折扣行一样。被折扣行记录对应折扣行行号 。

requestdatas=[{
	"FPQQLSH" : "12345678901234567890",
    "XSF_NSRSBH" : "销售方纳税人识别号",
    "GMF_MC" : "购买方名称",
    "JSHJ" : 799,
    "items" : 
		    [
			    {
				    "FPHXZ" : 2,
		            "XMMC" : "项目名称",
		            "XMSL" : 1,
		            "XMJSHJ" : 899,
		            "SL" : 0.17,
		            "HH":"1",
		            "ZKHHH":"2"
		        },
		        {
			        "FPHXZ" : 1,
		            "XMMC" : "项目名称",
		            "XMJSHJ" : -100,
		            "SL" : 0.17,
		            "HH":"2",
		        }
		    ]
}]

# 返回结果说明

参数 类型 描述 说明
code String 状态码 详见状态码说明
msg String 信息说明
datas JSONArray 拆分结果数据 拆分结果数据

# 拆分结果数据

  • 发票头数据
参数 类型 必填 描述 说明
bmbBbh String 商品编码表版本
fpjz String 发票介质 0.电票 2.纸票
fplx String 发票类型 详见发票类型
fpzt String 发票状态 1-待开票(需要开票员确认开票);2-开票中;3-开票失败;4-开票成功。详见销项发票状态
kplx String 开票类型 0.蓝票 1.红票
lylx String 来源类型 详见开票来源类型
lyid String 存储ID 存储拆分前发票的发票请求流水号
zdrq String 制单日期
zsfs String 征税方式:0.征税 2.差额 3.全额开票
fpqqlsh String 发票请求流水号 拆分后的发票请求流水号
jqbh String 机器编号
fpHm String 发票号码
fpDm String 发票代码
fpMw String 发票密文
jym String 校验码
kprq String 开票日期 格式YYYYMMDDHHMMSS
gmfDzdh String 购买方地址、电话
gmfMc String 购买方名称
gmfNsrsbh String 购买方纳税人识别号
gmfYhzh String 购买方银行、账户
xsfDzdh String 销售方地址、电话
xsfMc String 销售方名称
xsfNsrsbh String 销售纳税人识别号
xsfYhzh String 销售方银行、账户
yfpDm String 原发票代码
yfpHm String 原发票号码
hjje BigDecimal 合计金额
hjse BigDecimal 合计税额
jshj BigDecimal 价税合计
kpr String 开票人
fhr String 复核人
skr String 收款人
bz String 备注
zfbz String 作废标志 Y:是;N否
bred String 是否红冲 Y:是;N否
zdybz String 自定义备注
items Object 发票明细 发票明细数据
  • 发票明细数据
参数 类型 必填 描述 说明
xmmc String 项目名称
ggxh String 规格型号
spbm String 商品编码
xmhsdj String 项目含税单价
yhzcbs String 销售优惠标识;0:不使用,1:使用
zxbm String 商品自行编码
dw String 单位
xmsl doube 项目数量
xmdj doube 项目单价
xmje doube 项目金额
xmjshj String 项目价税合计
sl String 税率
se String 税额
hh string 行号

# 返回样例

{
    "code": "0000",
    "msg": "success",
    "datas": [
        {
            "bmbBbh": "13.0",
            "bz": "BZSHY",
            "fhr": "FHR",
            "fpjz": "0",
            "fplx": "1",
            "fpqqlsh": "shy100000000000006",
            "fpzt": "2",
            "gmfDzdh": "address",
            "gmfMc": "shy00004",
            "gmfNsrsbh": "214356654322666",
            "gmfYhzh": "213456543233523",
            "hjje": 30000,
            "hjse": 5100,
            "jshj": 35100,
            "kplx": 0,
            "kpr": "KPR",
            "lyid":"<对于确实已发生拆分行为的发票,这里是:拆分前发票的发票请求流水号FPQQLSH>",
            "lylx": "1",
            "skr": "SKR",
            "xsfDzdh": "XSFDZDH",
            "xsfMc": "测试3",
            "xsfNsrsbh": "111222333456333",
            "xsfYhzh": "6217000010005805406",
            "zdrq": 1505400195352,
            "zsfs": "0",
            "items": [
                {
                    "dw": "DW",
                    "fphxz": 0,
                    "ggxh": "GGXH",
                    "hh": "1",
                    "kce": 0,
                    "se": 5100,
                    "sl": 0.17,
                    "spbm": "1060301010100000000",
                    "xmdj": 15000,
                    "xmhsdj": 17550,
                    "xmje": 30000,
                    "xmjshj": 35100,
                    "xmmc": "JYZBSS",
                    "xmsl": 2,
                    "yhzcbs": 0,
                    "zkhhh": "",
                    "zxbm": "10"
                }
            ]
        }
    ]
}

# 开票状态查询

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/V3/queryInvoiceStatus?appid=XXXXX

# 请求体参数

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号

# 请求样例

表单参数如下

fpqqlsh=12345678901234567890

# 返回结果说明

参数 类型 必填 描述 说明
fpqqlsh String 发票请求流水号
code String 状态码 0000-查询成功;1002-数据不存在;详见状态码说明
msg String 信息说明
statuscode String 开票状态码 1-待开票(需要开票员确认开票);2-开票中;3-开票失败;4-开票成功
status String 开票状态 待开票;开票中;开票失败;开票成功
errmsg String 开票失败明细 开票状态为失败时,此处为明细信息
bstatus String 版式状态 0-重画版式成功;1-版式失败 (版式失败,data数据中没有pdf)
data String 开票内容 开票状态为开票成功时,返回开票信息,为JSONObject,信息格式与回调服务相同。

# 返回样例

    样例1(开票中)
    {
	    "fpqqlsh": "12345678901234567890",
		"code": "0000",
	    "msg": "查询成功",
	    "statuscode": "1",
		"status": "待开票"
	}

    样例2(开票失败)
    {
	    "fpqqlsh": "12345678901234567890",
		"code": "0000",
	    "msg": "查询成功",
	    "statuscode": "3",
		"status": "开票失败",
		"errmsg":"税控设备错误"
    }
   样例3(开票成功版式失败)
   {
       "fpqqlsh": "12345678901234567890",
       "bsstatus": "1",
       "code": "0000",
       "msg": "查询成功",
       "statuscode": "4",
       "status": "开票成功",
       "data": "{\"data\":\"{\\\"bmbBbh\\\":\\\"32.0\\\",\\\"bz\\\":\\\"差额征税:70.00。\\\",\\\"ewm\\\":\\\"01,10,011002680026,03198042,99.13,20220830,12530225777282455095,BCC0\\\",\\\"fhr\\\":\\\"KPR1234567890123\\\",\\\"fpDm\\\":\\\"011002680026\\\",\\\"fpHm\\\":\\\"03198042\\\",\\\"fpMw\\\":\\\"0395323/<+46230+83<0<053+502>67*48-<829/<6>/181288983/397*->/29134075+>-39+9225/-*>1/5/3>5+4750156>019<759/57102\\\",\\\"fpjz\\\":\\\"0\\\",\\\"fplx\\\":\\\"1\\\",\\\"fpqqlsh\\\":\\\"83010000004\\\",\\\"gmfDzdh\\\":\\\"测试地址电话 34432222\\\",\\\"gmfMc\\\":\\\"\\\",\\\"gmfNsrsbh\\\":\\\"111222333444555\\\",\\\"gmfYhzh\\\":\\\"111112222233333\\\",\\\"hjje\\\":99.13,\\\"hjse\\\":0.87,\\\"items\\\":[{\\\"dw\\\":\\\"\\\",\\\"fphxz\\\":0,\\\"ggxh\\\":\\\"\\\",\\\"hh\\\":\\\"2\\\",\\\"kce\\\":70.00,\\\"se\\\":0.87,\\\"sl\\\":0.030000,\\\"spbm\\\":\\\"1010101010000000000\\\",\\\"xmdj\\\":9.0114739629,\\\"xmje\\\":99.13,\\\"xmjshj\\\":100.00,\\\"xmmc\\\":\\\"*谷物*测试商品1\\\",\\\"xmsl\\\":11.0000000000,\\\"yhzcbs\\\":0,\\\"zkhhh\\\":\\\"\\\",\\\"zxbm\\\":\\\"10\\\"}],\\\"jqbh\\\":\\\"499000144000\\\",\\\"jshj\\\":100.00,\\\"jym\\\":\\\"12530225777282455095\\\",\\\"kplx\\\":0,\\\"kpr\\\":\\\"KPR1234567890123\\\",\\\"kprq\\\":\\\"20220830165147\\\",\\\"lyid\\\":\\\"\\\",\\\"lylx\\\":\\\"2\\\",\\\"skr\\\":\\\"KPR1234567890123\\\",\\\"xsfDzdh\\\":\\\"北京市海淀区北清路68号 62437728\\\",\\\"xsfMc\\\":\\\"11134444\\\",\\\"xsfNsrsbh\\\":\\\"111222333456333\\\",\\\"xsfYhzh\\\":\\\"建设银行 3333322222111111\\\",\\\"zdrq\\\":1661788800000,\\\"zsfs\\\":\\\"2\\\"}\",\"code\":\"0000\",\"msg\":\"开票成功\",\"fpqqlsh\":\"83010000004\"}",
       
}

# 版式重画

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/bsRestartCreate?appid=XXXXX

# 请求体参数

参数 类型 长度 是否必填 默认值 描述 说明
fpDm String 12 发票代码
fpHm String 8 发票号码

# 请求样例

表单参数如下

fpDm=200009975509
fpHm=26112814

# 返回结果说明

参数 类型 必填 描述 说明
code String 状态码 0000-查询成功;1002-数据不存在;详见状态码说明
msg String 信息说明
data String 默认是null

# 返回样例

    样例1(版式生成成功)
    {
		"code": "0000",
        "datas"  null,
	    "msg": "操作成功"
	}

    样例2(版式生成失败)
    {
		"code": "1002",
        "datas"  null,
	    "msg": "发票代码:200009975509,发票号码:26112813该张发票不存在!"
    }
    样例3(版式生成失败)
   {
        "code": "9999",
        "datas"  null,
        "msg": "发票代码:200009975509,发票号码:26112813重新生成版式失败!原因是:[购买方名称为空。]"
}
   

# 发票红冲请求

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/red?appid=XXXXX``

TIP

每次请求的数据不能超过10张单据

# 请求体参数

# 表单说明

参数 描述 说明
requestdatas 发票红冲参数
email 邮件推送配置(可选)
sms 短信推送配置(可选)
url 回调服务配置(可选)
delurl 退回业务系统回调服务配置(可选)
autoAudit 是否自动审核(可选) true:自动审核,false:不自动审核。
如果不传,代表true
nc6x-ubl ncc友企联回调参数

# 发票红冲参数

参数 类型 长度 是否必填 默认值 描述 说明
FPQQLSH String 20 发票请求流水号 注意不是蓝字的发票请求流水号,是本次发票红冲的请求流水号
FPLX String 4 发票类型 只有数电发票红冲税控发票才必填,必须指定发票类型为数电发票类型;详见发票类型
fpDm String 12 蓝字发票代码 被红冲的发票代码
fpHm String 20 蓝字发票号码 被红冲的发票号码
GMF_MC String 100 购买方名称
GMF_DZDH String 100 购买方地址电话
GMF_YHZH String 100 购买方银行账号
GMF_NSRSBH String 100 购买方纳税人识别号
ORGCODE String 50 开票点编码 如果一个税号对应多个开票点,此字段必输,用于确定唯一开票点
XSF_NSRSBH String 50 销售方纳税人识别号 如果一个税号只有一个开票点,可以只传销方税号;销方税号和开票点编码必传其中之一
KPR String 8 开票人 如果为空,获取发票平台配置的开票人
SKR String 8 收款人 如果为空,获取发票平台配置的收款人
FHR String 8 复核人 如果为空,获取发票平台配置的复核人
SLSM String 1 税率说明 1:当小规模纳税人开具3%税率时需要填写税率说明 2:前期已开具发票,发生销售折让、中止或者退回等情形需要开具红字发票,或者开票有误需要重新开具;3:因为实际经营业务需要,放弃享受减按1%征收率征收增值税政策。
HCYY String 1 红冲原因说明 :1 销货退回 2 开票有误 3 开票中止 4 销售折让 数电发票红冲原因必填
hzxxbbh String 20 红字信息表编号 专票红冲时必传
ALLELCUSERNAME String 300 数电发票用户名 如果发票类型是数电发票用户名必填 ,并且是国密四密文 (数电专用字段)
ALLELCPASSWORD String 300 数电发票密码 如果发票类型是数电发票密码必填 , 并且是国密四密文 (数电专用字段)
LYDJH String 200 业务来源单据号
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 邮件推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 短信推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 回调服务配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
url String 500 回调url 开票申请调用方配置回调url,当电子发票开具成功后,调用此服务,POST电子发票相关信息。信息包含:1、pdf版式文件2、发票数据、3、发票下载链接ncc通过友企联方案回调可不传此参数
intf String 200 ncc回调接口名 ncc通过友企联方案回调时必传
method String 200 ncc回调方法名 ncc通过友企联方案回调时必传

# 请求样例

表单参数如下

requestdatas=[
    {
        "fpHm": "03091804", 
        "fpDm": "000000000000", 
        "FPQQLSH": "test1101",
        "hzxxbbh":"1101081902045091",(数电专票红冲暂不需要红字信息表)
        "HCYY" :"1",  (数电发票红冲原因必填)
        "define":{
          "特征key":"特征值示例 选填"
        },
      "ALLELCUSERNAME": "电子税务局用户名(发票类型为数电发票时必传并且是国密四密文)", (数电专用字段)
      "ALLELCPASSWORD": "电子税务局密码 (发票类型为数电发票时必传并且是国密四密文)"   (数电专用字段)
    }
] 
&email=[
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x1@yonyou.com,x2@yonyou.com"
    }, 
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x3@yonyou.com"
    }
]
&sms=[{
	"fpqqlsh":"12345678901234567890",
        "address": "13511111111,13511111112"
    }]
&url=[{
		"fpqqlsh":"12345678901234567890",
        "url": "http://url.com/msg"
    }]
&nc6x-ubl=[{
        "fpqqlsh":"12345678901234567890",
        "method":"queryUserPermAppPksOrCodes",
        "intf":"nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService"   
}]
&autoAudit=true

# 返回结果说明

参数 类型 描述 说明
code String 状态码 详见状态码说明
msg String 信息说明

# 返回样例

{
    "code": "0000", 
    "msg": "success"
}

# 开票申请审核通过

此服务与开票蓝票请求服务、发票红冲请求服务配合使用。对于autoAudit=false的开票请求,通过调用此服务驱动开票。autoAudit=true时,不用调用此服务。

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/issue?appid=XXXXX

TIP

此接口只能用来开具蓝票

签名载荷(Payload)中必须包含属性requestdatas,它的值为表单参数requestdatas的MD5值,具体使用方式参考样例代码示例

# 请求体参数

# 表单说明

参数 描述 说明
requestdatas 发票开具动作参数

# 发票开具动作参数

参数 类型 长度 是否必填 默认值 描述 说明
FPQQLSH String 20 发票请求流水号
XSF_NSRSBH String 20 销售方纳税人识别号
JSHJ BigDecimal 价税合计

# 请求样例

requestdatas=[{
	"FPQQLSH" : "12345678901234567890",
	"XSF_NSRSBH" : "销售方纳税人识别号",
	"JSHJ":1234
}]

# 返回结果说明

参数 类型 描述 说明
code String 状态码 详见状态码说明
msg String 信息说明

# 返回样例

{
	"code": "0000", 
	"msg": "success"
}

# 发票部分红冲

# URL

POST

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/part-red?appid=XXXXX

TIP

每次请求的数据不能超过10张单据

签名载荷(Payload)中必须包含属性requestdatas,它的值为表单参数requestdatas的MD5值,具体使用方式参考样例代码示例

# 请求体参数

# 表单说明

参数 描述 说明
requestdatas 开票申请发票信息,包含发票头发票明细
email 邮件推送配置(可选)
sms 短信推送配置(可选)
url 回调服务配置(可选)
delurl 退回业务系统回调服务配置(可选)
autoAudit 是否自动审核(可选) true:自动审核,即不需要人工在发票平台确认开票,直接进行开票 false:不自动审核,即需要人工确认
如果不传,代表true
nc6x-ubl ncc友企联回调参数

# 发票头

参数 类型 长度 是否必填 默认值 描述 说明
FPQQLSH String 20 发票请求流水号 注意不是蓝字的发票请求流水号,是本次发票红冲的请求流水号
FPLX String 4 发票类型 只有数电发票红冲税控发票才必填,必须指定发票类型为数电发票类型;详见发票类型
fpDm String 12 蓝字发票代码 被红冲的发票代码
fpHm String 8 蓝字发票号码 被红冲的发票号码
GMF_MC String 100 购买方名称
GMF_DZDH String 100 购买方地址电话
GMF_YHZH String 100 购买方银行账号
GMF_NSRSBH String 100 购买方纳税人识别号
KPR String 8 开票人 如果为空,获取发票平台配置的开票人
SKR String 8 收款人 如果为空,获取发票平台配置的收款人
FHR String 8 复核人 如果为空,获取发票平台配置的复核人
SLSM String 1 税率说明 1:当小规模纳税人开具3%税率时需要填写税率说明 2:前期已开具发票,发生销售折让、中止或者退回等情形需要开具红字发票,或者开票有误需要重新开具; 3:因为实际经营业务需要,放弃享受减按1%征收率征收增值税政策。
HCYY String 1 红冲原因说明 :1 销货退回 2 开票有误 3 服务中止 4 销售折让 数电发票红冲原因必填
JSHJ BigDecimal 15,2 价税合计 两位小数。明细价税合计之和必须与总的价税合计一致;价税合计小于0,并且绝对值不能大于蓝票
HJJE BigDecimal 15,2 合计金额 两位小数。为空时,根据明细项目进行合计。合计金额小于0,并且绝对值不能大于蓝票
HJSE BigDecimal 15,2 合计税额 两位小数。为空时,根据明细项目进行合计。
LYID String 100 请求来源唯一标识
BMB_BBH String 20 13.0 编码版本号 增加商品编码功能后,税局下载的商品编码表版本
ORGCODE String 50 开票点编码 如果一个税号对应多个开票点,此字段必输,用于确定唯一开票点
hzxxbbh String 20 红字信息表编号 专票红冲时必传
ALLELCUSERNAME String 300 数电发票用户名 如果发票类型是数电发票用户名必填 ,并且是国密四密文 (数电专用字段)
ALLELCPASSWORD String 300 数电发票密码 如果发票类型是数电发票密码必填 , 并且是国密四密文 (数电专用字段)
LYDJH String 200 业务来源单据号
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 发票明细

参数 类型 长度 是否必填 默认值 描述 说明
XMMC String 90 项目名称
XMBM String 90 项目编码 如果项目名称为空,会根据项目编码匹配云平台的商品档案
GGXH String 40 规格型号 非数电发票规格型号最大长度为40个字符,数电发票长度为150个字符
DW String 20 单位
XMSL BigDecimal 15,6 项目数量 项目数量必须小于0
XMDJ BigDecimal 15,6 项目单价 项目单价为空时,根据项目金额反算。不为空时不进行计算;
XMJE BigDecimal 15,2 项目金额 项目金额为空,根据项目价税合计反算。不为空时不进行计算;金额必须小于0
XMJSHJ BigDecimal 15,2 项目价税合计 价税合计必须小于0
SL BigDecimal 6,6 税率 6 位小数,例 17%为 0.17
SE BigDecimal 15,2 税额 税额为空,根据价税合计反算。不为空时不进行计算。
HH string 60 行号 有折扣时需要必输
SPBM string 19 商品编码 税收分类编码
define Object 特征值数组 传参样例:{"pan_1": "这是个字符串"}

# 邮件推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 短信推送配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
address String 500 接收地址 接收地址,多个地址使用","分隔开

# 回调服务配置

参数 类型 长度 是否必填 默认值 描述 说明
fpqqlsh String 20 发票请求流水号 必须和上面的开票请求对应
url String 500 回调url 开票申请调用方配置回调url,当电子发票开具成功后,调用此服务,POST电子发票相关信息。信息包含:1、pdf版式文件2、发票数据、3、发票下载链接ncc通过友企联方案回调可不传此参数
intf String 200 ncc回调接口名 ncc通过友企联方案回调时必传
method String 200 ncc回调方法名 ncc通过友企联方案回调时必传

# 返回结果说明

参数 类型 描述 说明
code String 状态码 详见状态码说明
msg String 信息说明

# 返回样例

{
	"code": "0000", 
	"msg": "success"
}

# 请求样例

标准表单参数样例

requestdatas=[ {
	"FPQQLSH" : "12345678901234567890",
	"fpHm": "03091804", 
	"fpDm": "000000000000", 
	"KPR" : "开票人",
	"SKR" : "收款人",
	"FHR" : "复核人",
	"JSHJ" : "价税合计",
	"HJJE" : "合计金额",
	"HJSE" : "合计税额",
    "hzxxbbh":"1101081902045091",
    "define":{
       "特征key":"特征值示例 选填"
    },
	"items" : [{
            "XMMC" : "项目名称",
            "GGXH" : "规格型号",
            "DW" : "单位",
            "XMSL" : "项目数量",
            "XMDJ" : "项目单价",
            "XMJE" : "项目金额",
            "XMJSHJ" : "项目价税合计",
            "SL" : "税率",
            "SE" : "税额",
            "HH":"行号",
            "SPBM":"商品编码",
            "define":{
              "特征key":"特征值示例 选填"
            }
		}
	]
}]
&email=[
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x1@yonyou.com,x2@yonyou.com"
    }, 
    {
	    "fpqqlsh":"12345678901234567890",
        "address": "x3@yonyou.com"
    }
]
&sms=[{
	"fpqqlsh":"12345678901234567890",
        "address": "13511111111,13511111112"
    }]
&url=[{
		"fpqqlsh":"12345678901234567890",
        "url": "http://url.com/msg"
    }]
&nc6x-ubl=[{
        "fpqqlsh":"12345678901234567890",
        "method":"queryUserPermAppPksOrCodes",
        "intf":"nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService"   
}]
&autoAudit=true

最小请求参数样例

TIP

销售方地址及电话、银行及账号、销售方名称可以通过销售方纳税人识别号获取

requestdatas=[{
    "FPQQLSH" : "12345678901234567890",
    "fpHm": "03091804", 
    "fpDm": "000000000000", 
    "JSHJ" : -117,
    "items" : 
		    [
			    {
		            "XMMC" : "项目名称",
		            "SPBM" : "1010101020000000000",
		            "XMJSHJ" : -117,
		            "SL" : 0.17
		        }
		    ]
}]

# 删除开票失败申请

对于开票失败数据进行删除调用接口删除,以下场景无法删除:

  1. 状态不是开票失败状态;
  2. 税盘已经开票成功但是生成pdf文件失败(可以联系平台人员进行修复)

# URL

POST application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/deleteInvoiceFailData

# 请求头参数

参数 类型 是否必填 描述 备注
sign String 请求签名信息 使用JWT生成token

签名参考开票签名功能

# 请求体

fpqqlsh=22902929292

# 请求体说明

参数 说明 类型 长度 必输
fpqqlsh 发票请求流水号 String 20

# 返回值

{
    "code" : "0000",
    "msg" : "操作成功"
}

# 返回值说明

参数 类型 描述 说明
code String 状态编码
msg String 提示信息

# 重发邮件

# URL

POST application/x-www-form-urlencoded; charset=UTF-8

http://{HOST}:{PORT}/output-tax/api/invoiceApply/callBackByEmail

# 请求头参数

参数 类型 是否必填 描述 备注
sign String 请求签名信息 使用JWT生成token

签名参考开票签名功能

# 请求体

fpqqlsh=22902929292&email=17090028043@163.com

# 请求体说明

参数 说明 类型 长度 必输
fpqqlsh 发票请求流水号 String 20
email 邮件地址 String 100 否,为空发送到开票申请地址

# 返回值

{
    "code" : "0000",
    "msg" : "邮件发送成功"
}

# 返回值说明

参数 类型 描述 说明
code String 状态编码
msg String 提示信息

# 返回状态码说明

状态码 状态说明
0000 yfpdm:%syfphm:%s的蓝票已申请上传红字申请表。如状态长时间显示未上传,请检查开票助手及税盘是否连接正常
1001 yfpdm:%syfphm:%s的蓝票不存在于税务云系统中,请检查
1002 yfpdm:%syfphm:%s的蓝票不可整体红冲,请检查该蓝票是否已作废,或已开具过红票
1003 yfpdm:%syfphm:%s的蓝票已通过该接口进行红冲,且红冲成功,请检查
1008 yfpdm:%syfphm:%s的蓝票已通过其他途径红冲或部分红冲,不能调用专票整体红冲接口,请检查
1011 yfpdm:%syfphm:%s的红冲专票正在开票中,请稍后查看。如长时间未响应,请检查开票助手及税盘是否连接正常
1013 yfpdm:%syfphm:%s的红字申请表已上传成功,且开票成功
2001 未找到相应的税控组织
2003 销售方纳税人识别号与税控组织对应的纳税人识别号不匹配
2007 缺少发票明细数据,请检查
2010 发票金额超过最大限额
3011 电子签名被篡改
3013 购买方纳税人识别号为空
3019 发票已经作废
5001 税盘不在线
8001 签名失败
8002 非法的api调用
8004 appid为空
8005 无法获取appid对应的key
8008 验签失败,签名数据缺少requestdatas
8009 验签失败,签名数据被窜改
9999 未知错误,按照msg提示处理

# 附录

# NCC友企联回调数据样例

{
	"method": "queryUserPermAppPksOrCodes",
	"interface": "nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService",
	"serviceMethodArgInfo": [
		{
			"agg": false,
			"argType": "java.lang.String",
			"isArray": false,
			"isPrimitive": false,
			"argValue": "{\"data\":\"{\"ewm\":\"01,10,68974368,010011652011,20160906,,12345678901234567890,\",\"fhr\":\"ljm111\",\"fpDm\":\"010011652011\",\"fpHm\":\"68974368\",\"fpMw\":\"<-<>48938<4+<14>735+<2554*8-1-<+15<*026+848686/2/3//0>+*>>>356*<757/47>90+<25<<3575**934<+15<*026+848686--57\",\"fplx\":\"1\",\"fpjz\":\"0\",\"fpqqlsh\":\"12345677901234567897\",\"bmbBbh\":\"10.0\",\"gmfMc\":\"测试开票用户\",\"hjje\":100.00,\"hjse\":17.00,\"jqbh\":\"111111111111\",\"jshj\":117,\"jym\":\"12345678901234567890\",\"kplx\":0,\"kpr\":\"2\",\"kprq\":\"20160906202718\",\"skr\":\"ljm111\",\"corpId\":\"5bdfc3b7-fd88-4947-8a50-2474b97d7eef\",\"orgId\":\"12010101\",\"xsfDzdh\":\"北京市海淀区 110\",\"xsfMc\":\"北京\",\"xsfNsrsbh\":\"111112222233333\",\"xsfYhzh\":\"1 1\",\"yfpDm\":\"\",\"yfpHm\":\"\",\"items\":[{\"fphxz\":0,\"se\":17.00,\"sl\":0.17,\"xmdj\":100.000000,\"xmje\":100.00,\"xmjshj\":117,\"xmmc\":\"项目名称\",\"spbm\":\"3070101000000000000\",\"zxbm\":\"10\",\"yhzcbs\":0,\"xmsl\":1}]}\",  \"code\":\"0000\",   \"msg\": \"开票成功\", \"fpqqlsh\": \"12345677901234567897\", \"pdf\": \"pdf文件流\",\"shareurl\": \"http://192.168.52.101/invoiceent-web/s/ab799b5413221cc19088a465d62f8c4f\",\"sharecode\": \"E3N2\" }"
		}
	]
}

# 常规回调数据样例


{
    "data": "{\"ewm\":\"01,10,68974368,010011652011,20160906,,12345678901234567890,\",\"zdybz\":\"自定义备注\",\"fhr\":\"ljm111\",\"fpDm\":\"010011652011\",\"fpHm\":\"68974368\",\"fpMw\":\"<-<>48938<4+<14>735+<2554*8-1-<+15<*026+848686/2/3//0>+*>>>356*<757/47>90+<25<<3575**934<+15<*026+848686--57\",\"fplx\":\"1\",\"fpjz\":\"0\",\"fpqqlsh\":\"12345677901234567897\",\"bmbBbh\":\"10.0\",\"gmfMc\":\"测试开票用户\",\"hjje\":100.00,\"hjse\":17.00,\"jqbh\":\"111111111111\",\"jshj\":117,\"jym\":\"12345678901234567890\",\"kplx\":0,\"kpr\":\"2\",\"kprq\":\"20160906202718\",\"skr\":\"ljm111\",\"corpId\":\"5bdfc3b7-fd88-4947-8a50-2474b97d7eef\",\"orgId\":\"12010101\",\"xsfDzdh\":\"北京市海淀区 110\",\"xsfMc\":\"北京\",\"xsfNsrsbh\":\"111112222233333\",\"xsfYhzh\":\"1 1\",\"yfpDm\":\"\",\"yfpHm\":\"\",\"items\":[{\"fphxz\":0,\"se\":17.00,\"sl\":0.17,\"xmdj\":100.000000,\"xmje\":100.00,\"xmjshj\":117,\"xmmc\":\"项目名称\",\"spbm\":\"3070101000000000000\",\"zxbm\":\"10\",\"yhzcbs\":0,\"xmsl\":1}]}",
    "code": "0000",
    "msg": "开票成功",
    "fpqqlsh": "12345677901234567897",
    "pdf": "pdf/ofd文件流base64",
    "shareurl": "http://192.168.52.101/invoiceent-web/s/ab799b5413221cc19088a465d62f8c4f?tenantId=ab2c",
    "sharecode": "E3N2",
	"fileType": "ofd"
}

# 回调服务参数

参数 类型 描述 说明
code String 开票信息码 0000代表开票成功
msg String 开票失败信息
fpqqlsh String 发票请求流水号
fileType String 文件类型 增值税电子专用发票、电子发票(增值税专用发票)为ofd格式;其他为pdf格式;
pdf String pdf文件 使用Base64解码为二进制流,可以保存为pdf或ofd文件
shareurl String 发票提取url
sharecode String 发票提取码 与提取url配合使用
data String 发票详细信息 回调服务发票详细信息
ewmdata String 交付二维码 Base64数据
pdfurl String pdf版式文件下载链接
ofdurl String ofd版式文件下载链接
xmlurl String xml版式文件下载链接

# 回调服务发票详细信息

  • 发票头数据
参数 类型 描述 说明
bmbBbh String 商品编码表版本
fpjz String 发票介质 0.电票 2.纸票
fplx String 发票类型
fpzt String 发票状态 1-待开票(需要开票员确认开票);2-开票中;3-开票失败;4-开票成功。详见销项发票状态
kplx String 开票类型 0.蓝票 1.红票
lylx String 来源类型
lyid String 存储ID 存储拆分前发票的发票请求流水号
zdrq String 制单日期
zsfs String 征税方式:0.征税 2.差额 3.全额开票
fpqqlsh String 发票请求流水号
jqbh String 机器编号
fpHm String 发票号码
fpDm String 发票代码
fpMw String 发票密文
jym String 校验码
kprq String 开票日期 格式YYYYMMDDHHMMSS
gmfDzdh String 购买方地址、电话
gmfMc String 购买方名称
gmfNsrsbh String 购买方纳税人识别号
gmfYhzh String 购买方银行、账户
xsfDzdh String 销售方地址、电话
xsfMc String 销售方名称
xsfNsrsbh String 销售纳税人识别号
xsfYhzh String 销售方银行、账户
yfpDm String 原发票代码
yfpHm String 原发票号码
hjje BigDecimal 合计金额
hjse BigDecimal 合计税额
jshj BigDecimal 价税合计
kpr String 开票人
fhr String 复核人
skr String 收款人
bz String 备注
zfbz String 作废标志 Y:是;N否
bred String 是否红冲 Y:是;N否
zdybz String 自定义备注
items Object 发票明细 发票明细数据
  • 发票明细数据
参数 类型 描述 说明
xmmc String 项目名称
ggxh String 规格型号
spbm String 商品编码
xmhsdj String 项目含税单价
yhzcbs String 销售优惠标识;0:不使用,1:使用
zxbm String 商品自行编码
dw String 单位
xmsl doube 项目数量
xmdj doube 项目单价
xmje doube 项目金额
xmjshj String 项目价税合计
sl String 税率
se String 税额
hh string 行号

# 回调服务返回结果

回调服务对回调信息处理后,需要返回处理结果信息。 返回参数约定如下:

参数 类型 描述 说明
code String 处理结果编码 0000:表示回调服务处理成功
msg String 处理结果明细信息 回调处理的明细信息。如果存在错误,此处为错误信息

# 样例代码

样例代码演示的是开票服务的调用,请根据实际应用场景参考使用 样例代码获取可以发邮件至wangweir@yonyou.com,注意标明具体编程语言

# Java(适用于JDK1.6及其更高版本)

# Maven配置文件依赖

依赖配置如下

		<!-- httpclient,发送HTTP请求 -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5</version>
		</dependency>
		<!-- gson,json转换工具 -->
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.7</version>
		</dependency>
		<!-- jjwt,Java Web Token签名工具包 -->
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.6.0</version>
		</dependency>
# API调用代码
/**
 * 
 */
import com.google.gson.GsonBuilder;
import com.yonyou.einvoice.einvoiceApply.JwtParamBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.compression.CompressionCodecs;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.interfaces.RSAPrivateKey;
import java.util.*;
import java.util.Map.Entry;

/**
 * @date 2018/5/25
 * 该样例代码为调用开蓝票接口代码,适用于JDK1.6及更高版本,jdk1.6版本需要对签名方法稍做修改,修改方法在签名方法内已经写明
 * 请求参数的注意事项也在参数构建的过程中写明,请详细阅读样例代码。
 */

public class InsertWithArray {

    //测试环境有测试appid和证书,正式环境有正式appid和证书,请务必对应使用
    //测试环境appid就用这个,正式环境需要替换成正式的
    private static String APPID = "commontesterCA";
    //这个是测试环境的域名,正式环境为https://fapiao.yonyoucloud.com
    private static String DOMAIN = "https://yesfp.yonyoucloud.com";
    private static String URL = DOMAIN + "/output-tax/api/invoiceApply/insertWithArray?appid=" + APPID;
    //pro22.pfx为测试环境通讯证书,正式环境需要替换成正式的
    private static String KEYPATH = "src/main/resources/certificate/pro22.pfx";
    //证书密码
    private static String PASSWORD = "password";

    public static void main(String[] args) {
        try {
            new InsertWithArray().callInvoiceApply();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }


    public void callInvoiceApply() throws Exception {
//        提供两种构建HttpClient实例的方法,如果使用被注释掉的方法构建实例报证书不被信任的错误,那么请使用未被注释的构建方法
//        HttpClient httpClient = HttpClients.custom().build();
        HttpClient httpClient = createSSLClientDefault();    //信任所有https证书
        HttpPost httpPost = new HttpPost(URL);
        // 构造POST表单Map
        Map<String, String> paramsMap = buildPostParam();
        // 签名
        String sign = this.sign(paramsMap);
        httpPost.addHeader("sign", sign);
        // 转换POST表单参数
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        Iterator<Entry<String, String>> iterator = paramsMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, String> elem = iterator.next();
            list.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
        }
        if (list.size() > 0) {
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
            httpPost.setEntity(entity);
        }
        // 发送http post请求,并得到响应结果
        HttpResponse response = httpClient.execute(httpPost);
        String result;
        if (response != null) {
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                result = EntityUtils.toString(resEntity, "UTF-8");
                System.out.println(result);
            }
        }
    }

    /**
     * 签名
     *
     * @param paramsMap 表单参数
     * @return 签名值
     * @throws Exception
     */
    private String sign(Map<String, String> paramsMap) throws Exception {

        PrivateKey privateKey = loadPrivateKeyOfCA();
        Map<String, Object> claims =
                JwtParamBuilder.build().setSubject("tester").setIssuer("einvoice").setAudience("einvoice")
                        .addJwtId().addIssuedAt().setExpirySeconds(3600).setNotBeforeSeconds(3600).getClaims();
        // 需要将表单参数requestdatas的数据进行md5加密,然后放到签名数据的requestdatas中。
        // 此签名数据必须存在,否则在验证签名时会不通过。
        String value = paramsMap.get("requestdatas");
        claims.put("requestdatas", getMD5(value));
        // 使用jdk1.6版本时,删除下面代码的中.compressWith(CompressionCodecs.DEFLATE)
        String compactJws = Jwts.builder().signWith(SignatureAlgorithm.RS512, privateKey)
                .setClaims(claims).compressWith(CompressionCodecs.DEFLATE).compact();
        return compactJws;
    }

//    /**
//     * 当在linux环境下运行代码,签名方法报空指针异常的时候,采用该签名方法可以避免这个问题
//     * 使用该方法需要添加新的maven依赖,如下:
//     * <dependency>
//     *     <groupId>com.auth0</groupId>
//     *     <artifactId>java-jwt</artifactId>
//     *     <version>3.3.0</version>
//     * </dependency>
//     * @param paramsMap
//     * @return
//     * @throws Exception
//     */
//    private String sign(Map<String, String> paramsMap) throws Exception {
//
//        RSAPrivateKey privateKey = loadPrivateKeyOfCA();
//        Map<String, Object> claims =
//                JwtParamBuilder.build().setSubject("tester").setIssuer("einvoice").setAudience("einvoice")
//                        .addJwtId().addIssuedAt().setExpirySeconds(300).setNotBeforeSeconds(300).getClaims();
//        String token;
//        try {
//            Algorithm algorithm = Algorithm.RSA512(null, privateKey);
//            token = JWT.create()
//                    .withClaim("requestdatas",getMD5(paramsMap.get("requestdatas")))
//                    .withHeader(claims)
//                    .sign(algorithm);
//        } catch (JWTCreationException exception){
//            //Invalid Signing configuration / Couldn't convert Claims.
//            return null;
//        }
//
//        return token;
//    }
    /**
     * 计算参数MD5
     *
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    private static String getMD5(String str) throws UnsupportedEncodingException,
            NoSuchAlgorithmException {
        byte[] buf = null;
        buf = str.getBytes("utf-8");
        MessageDigest md5 = null;
        md5 = MessageDigest.getInstance("MD5");
        md5.update(buf);
        byte[] tmp = md5.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : tmp) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }


    /**
     * 读取证书私钥
     *
     * @return
     * @throws UnrecoverableKeyException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    protected RSAPrivateKey loadPrivateKeyOfCA() throws UnrecoverableKeyException, KeyStoreException,
            NoSuchAlgorithmException, CertificateException, IOException {
        FileInputStream in = new FileInputStream(KEYPATH);
        KeyStore ks = KeyStore.getInstance("pkcs12");
        ks.load(in, PASSWORD.toCharArray());
        String alias = ks.aliases().nextElement();
        RSAPrivateKey caprk = (RSAPrivateKey) ks.getKey(alias, PASSWORD.toCharArray());
        return caprk;
    }


    /**
     * post表单数据
     *
     * @return
     */
    private Map<String, String> buildPostParam() {
        Map<String, String> paramsMap = new HashMap<String, String>();
        paramsMap.put("requestdatas", this.buildRequestDatas());
        paramsMap.put("email", this.buildEmailConfigs());
        paramsMap.put("sms", this.buildSmsConfigs());
        paramsMap.put("url", this.buildUrlConfigs());
        paramsMap.put("autoAudit", "false");
        return paramsMap;
    }

    /**
     * url回掉配置
     *
     * @return
     */
    private String buildUrlConfigs() {
        List<Object> datas = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("url", "http://117.12.12.3:7787/EinvoiceRESTService/CallBackEInvoices/");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造短信发送信息
     *
     * @return
     */
    private String buildSmsConfigs() {
        List<Object> datas = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("address", "123123123123");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造email发送信息
     *
     * @return
     */
    private String buildEmailConfigs() {
        List<Object> datas = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("address", "123@163.com");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造requestdatas
     *
     * @return
     */
    private String buildRequestDatas() {
        List<Object> datas = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        data.put("FPQQLSH", buildFpqqlsh());
        //测试环境请一定要使用测试纳税人识别号
        data.put("XSF_NSRSBH", "201609140000001");
        data.put("GMF_MC", "购买方名称");
        data.put("GMF_DZDH", "购买方地址电话");
        //组织编码,测试环境请一定使用测试环境的组织编码
        data.put("ORGCODE", "20160914001");
        data.put("JSHJ", 1395.00);
        data.put("items", buildItems());
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造request发票明细
     *
     * @return
     */
    private List<Object> buildItems() {
        List<Object> items = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        data.put("XMJSHJ", "1395.00");
        data.put("XMMC", "住宅物业管理费1");
        //税率16%需要写成0.16的格式
        data.put("SL", 0.16);
        //SPBM字段为商品税收分类编码,不同的商品会有不同的编码,不对应的话会影响报税,需要咨询下公司财务
        data.put("SPBM", "3040502029902000000");
        items.add(data);
        return items;
    }


    /**
     * 获取发票请求流水号
     * 长度不超过20位,长度在1到20位的字母和数字组合,不可以重复的,不要包含window系统文件名限制的特殊字符
     *
     * @return 发票请求流水号
     */
    private String buildFpqqlsh() {
        return "164291i05h2080000sKs";
    }
}

# API相关工具类
package com.yonyou.einvoice.test;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * @author wangweir
 *
 */
public class JwtParamBuilder {

  /** JWT {@code Issuer} claims parameter name: <code>"iss"</code> */
  public static final String ISSUER = "iss";

  /** JWT {@code Subject} claims parameter name: <code>"sub"</code> */
  public static final String SUBJECT = "sub";

  /** JWT {@code Audience} claims parameter name: <code>"aud"</code> */
  public static final String AUDIENCE = "aud";

  /** JWT {@code Expiration} claims parameter name: <code>"exp"</code> */
  public static final String EXPIRATION = "exp";

  /** JWT {@code Not Before} claims parameter name: <code>"nbf"</code> */
  public static final String NOT_BEFORE = "nbf";

  /** JWT {@code Issued At} claims parameter name: <code>"iat"</code> */
  public static final String ISSUED_AT = "iat";

  /** JWT {@code JWT ID} claims parameter name: <code>"jti"</code> */
  public static final String ID = "jti";

  private Map<String, Object> claims;

  private final long now;

  private JwtParamBuilder() {
    claims = new HashMap<>();
    now = System.currentTimeMillis() / 1000l;
  }

  public static JwtParamBuilder build() {
    return new JwtParamBuilder();
  }

  public JwtParamBuilder addIssuedAt() {
    claims.put(ISSUED_AT, now);
    return this;
  }

  public JwtParamBuilder setExpirySeconds(final Integer expirySeconds) {
    claims.put(EXPIRATION, now + expirySeconds);
    return this;
  }

  public JwtParamBuilder setNotBeforeSeconds(final Integer beforeSeconds) {
    claims.put(NOT_BEFORE, now - beforeSeconds);
    return this;
  }

  public JwtParamBuilder setSubject(String sub) {
    addOneClaim(SUBJECT, sub);
    return this;
  }

  public JwtParamBuilder setIssuer(String iss) {
    addOneClaim(ISSUER, iss);
    return this;
  }

  public JwtParamBuilder setAudience(String aud) {
    addOneClaim(AUDIENCE, aud);
    return this;
  }

  public JwtParamBuilder addJwtId() {
    return setJwtId(UUID.randomUUID().toString());
  }

  public JwtParamBuilder setJwtId(String jwtid) {
    addOneClaim(ID, UUID.randomUUID().toString());
    return this;
  }

  public JwtParamBuilder claim(String name, Object value) {
    if (value == null) {
      this.claims.remove(name);
    } else {
      this.claims.put(name, value);
    }
    return this;
  }

  private void addOneClaim(String key, String value) {
    if (value != null && value.length() > 0) {
      claims.put(key, value);
    }
  }


  /**
   * @return the claims
   */
  public Map<String, Object> getClaims() {
    return claims;
  }


}

# Java(适用于JDK1.5)

# Maven配置文件依赖

依赖配置如下,除此之外还需要单独引入JWT的java-jwt-2.2.1-SNAPSHOT.jar包,请联系接口调试人员获取jar包。

		<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.52</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.0.1</version>
        </dependency>
# API调用代码
import com.auth0.jwt.Algorithm;
import com.auth0.jwt.JWTSigner;
import com.google.gson.GsonBuilder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.*;


/**
 * @author xingguoqing
 * 开具蓝票接口,本样例适合JDK1.5,除了需要按照pom文件引入相关jar外,还需要单独引入jwt包(联系接口调试人员)
 * @date 2018/5/9 下午1:37
 */
public class InsertWithArray {

    //测试环境有测试appid和证书,正式环境有正式appid和证书,请务必对应使用
    //测试环境appid就用这个,正式环境需要替换成正式的
    private static String APPID = "commontesterCA";
    //这个是测试环境的域名,正式环境为https://fapiao.yonyoucloud.com
    private static String DOMAIN = "https://yesfp.yonyoucloud.com";
    private static String URL = DOMAIN + "/output-tax/api/invoiceApply/insertWithArray?appid=" + APPID;
    //pro22.pfx为测试环境通讯证书,正式环境需要替换成正式的
    private static String KEYPATH = "src/main/resources/certificate/pro22.pfx";
    //证书密码
    private static String PASSWORD = "password";

    private static class TrustAnyTrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }


    private static class TrustAnyHostnameVerifier implements X509HostnameVerifier {
        public boolean verify(String hostname, SSLSession session){
            return true;
        }
        public void verify(String s, SSLSocket sslSocket) throws IOException { }
        public void verify(String s, X509Certificate x509Certificate) throws SSLException {}
        public void verify(String s, String[] strings, String[] strings1) throws SSLException {}
    }

    private static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{new InsertWithArray.TrustAnyTrustManager()}, new java.security.SecureRandom());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,new InsertWithArray.TrustAnyHostnameVerifier());
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    public static void main(String[] args) {
        try {
            new InsertWithArray().callInvoiceApply();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 调用接口开票
     * @throws Exception
     */
    public void callInvoiceApply() throws Exception {

        HttpClient httpClient = createSSLClientDefault();    //忽略https证书
        HttpPost httpPost = new HttpPost(URL);
        // 构造POST表单Map
        Map<String, String> paramsMap = buildPostParam();
        System.out.println(paramsMap);
        // 签名
        String sign = this.sign(paramsMap);
        System.out.println(sign);
        httpPost.addHeader("sign", sign);
        // 转换POST表单参数
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        Iterator<Map.Entry<String, String>> iterator = paramsMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> elem = iterator.next();
            list.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
        }
        if (list.size() > 0) {
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
            httpPost.setEntity(entity);
        }
        // 发送http post请求,并得到响应结果
        HttpResponse response = httpClient.execute(httpPost);
        String result = "";
        if (response != null) {
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                result = EntityUtils.toString(resEntity, "UTF-8");
                System.out.println(result);
            }
        }
    }


    /**
     * 签名
     *
     * @param paramsMap 表单参数
     * @return 签名值
     * @throws Exception
     */
    private String sign(Map<String, String> paramsMap) throws Exception {

        // 读取CA证书
        PrivateKey privateKey = loadPrivateKeyOfCA();
        Map<String, Object> claims =
                JwtParamBuilder.build().setSubject("tester").setIssuer("einvoice").setAudience("einvoice")
                        .addJwtId().addIssuedAt().setExpirySeconds(3600).setNotBeforeSeconds(3600).getClaims();

        // 需要将表单参数requestdatas的数据进行md5加密,然后放到签名数据的requestdatas中。
        // 此签名数据必须存在,否则在验证签名时会不通过。
        String value = paramsMap.get("requestdatas").toString();
        claims.put("requestdatas", getMD5(value));
        JWTSigner signer = new JWTSigner(privateKey);
        String compactJws = signer.sign(claims, new JWTSigner.Options().setExpirySeconds(300)
                .setNotValidBeforeLeeway(5).setIssuedAt(true).setJwtId(true).setAlgorithm(Algorithm.RS256));
        return compactJws;
    }

    /**
     * 计算MD5
     *
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    private static String getMD5(String str) throws UnsupportedEncodingException,
            NoSuchAlgorithmException {
        byte[] buf = null;
        buf = str.getBytes("utf-8");
        MessageDigest md5 = null;
        md5 = MessageDigest.getInstance("MD5");
        md5.update(buf);
        byte[] tmp = md5.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : tmp) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }


    /**
     * 读取证书私钥
     *
     * @return
     * @throws UnrecoverableKeyException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    protected RSAPrivateKey loadPrivateKeyOfCA() throws UnrecoverableKeyException, KeyStoreException,
            NoSuchAlgorithmException, CertificateException, IOException {
        FileInputStream in = new FileInputStream(KEYPATH);
        KeyStore ks = KeyStore.getInstance("pkcs12");
        ks.load(in, PASSWORD.toCharArray());
        String alias = ks.aliases().nextElement();
        RSAPrivateKey caprk = (RSAPrivateKey) ks.getKey(alias, PASSWORD.toCharArray());
        return caprk;
    }


    /**
     * post表单数据
     *
     * @return
     */
    private Map<String, String> buildPostParam() {
        Map<String, String> paramsMap = new HashMap<String, String>();
        paramsMap.put("requestdatas", this.buildRequestDatas());
//        paramsMap.put("email", this.buildEmailConfigs());
//        paramsMap.put("sms", this.buildSmsConfigs());
//        paramsMap.put("url", this.buildUrlConfigs());
//        paramsMap.put("autoAudit", "false");
        return paramsMap;
    }

    /**
     * url回掉配置
     *
     * @return
     */
    private String buildUrlConfigs() {
        List<Object> datas = new ArrayList();
        Map<String, Object> data = new HashMap();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("url", "http://117.12.12.3:7787/EinvoiceRESTService/CallBackEInvoices/");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造短信发送信息
     *
     * @return
     */
    private String buildSmsConfigs() {
        List<Object> datas = new ArrayList();
        Map<String, Object> data = new HashMap();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("address", "15611500957");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造email发送信息
     *
     * @return
     */
    private String buildEmailConfigs() {
        List<Object> datas = new ArrayList();
        Map<String, Object> data = new HashMap();
        data.put("fpqqlsh", buildFpqqlsh());
        data.put("address", "xinggq7@yonyou.com");
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造requestdatas
     *
     * @return
     */
    private String buildRequestDatas() {
        List<Object> datas = new ArrayList();
        Map<String, Object> data = new HashMap();
        data.put("FPQQLSH", buildFpqqlsh());
        //测试环境请一定要使用测试纳税人识别号
        data.put("XSF_NSRSBH", "201609140000001");
        //组织编码,测试环境请一定使用测试环境的组织编码
        data.put("ORGCODE", "20160914001");
        data.put("GMF_MC", "123");
        data.put("JSHJ", 0);
        data.put("items", buildItems());
        datas.add(data);
        GsonBuilder builder = new GsonBuilder();
        return builder.create().toJson(datas);
    }

    /**
     * 构造request发票明细
     *
     * @return
     */
    private List<Object> buildItems() {
        List<Object> items = new ArrayList();
        Map<String, Object> data = new HashMap();
        data.put("XMJSHJ", 10951200);
        data.put("XMMC", "住宅物业管理费");
        //税率17%需要写成0.17的格式
        data.put("SL", 0.17);
        data.put("XMSL", 146016);
        //SPBM字段为商品税收分类编码,不同的商品会有不同的编码,不对应的话会影响报税,需要咨询下公司财务
        data.put("SPBM", "3040502029902000000");
        items.add(data);
        return items;
    }

    /**
     * 获取发票请求流水号
     *长度不超过20位,长度在1到20位的字母和数字组合,不可以重复的,不要包含window系统文件名限制的特殊字符
     * @return 发票请求流水号
     */
    private String buildFpqqlsh() {
        return "1k4f91i05h2080000sKs";
    }
}


# API相关工具类
package com.yonyou.einvoice.test;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * @author wangweir
 *
 */
public class JwtParamBuilder {

  /** JWT {@code Issuer} claims parameter name: <code>"iss"</code> */
  public static final String ISSUER = "iss";

  /** JWT {@code Subject} claims parameter name: <code>"sub"</code> */
  public static final String SUBJECT = "sub";

  /** JWT {@code Audience} claims parameter name: <code>"aud"</code> */
  public static final String AUDIENCE = "aud";

  /** JWT {@code Expiration} claims parameter name: <code>"exp"</code> */
  public static final String EXPIRATION = "exp";

  /** JWT {@code Not Before} claims parameter name: <code>"nbf"</code> */
  public static final String NOT_BEFORE = "nbf";

  /** JWT {@code Issued At} claims parameter name: <code>"iat"</code> */
  public static final String ISSUED_AT = "iat";

  /** JWT {@code JWT ID} claims parameter name: <code>"jti"</code> */
  public static final String ID = "jti";

  private Map<String, Object> claims;

  private final long now;

  private JwtParamBuilder() {
    claims = new HashMap<>();
    now = System.currentTimeMillis() / 1000l;
  }

  public static JwtParamBuilder build() {
    return new JwtParamBuilder();
  }

  public JwtParamBuilder addIssuedAt() {
    claims.put(ISSUED_AT, now);
    return this;
  }

  public JwtParamBuilder setExpirySeconds(final Integer expirySeconds) {
    claims.put(EXPIRATION, now + expirySeconds);
    return this;
  }

  public JwtParamBuilder setNotBeforeSeconds(final Integer beforeSeconds) {
    claims.put(NOT_BEFORE, now - beforeSeconds);
    return this;
  }

  public JwtParamBuilder setSubject(String sub) {
    addOneClaim(SUBJECT, sub);
    return this;
  }

  public JwtParamBuilder setIssuer(String iss) {
    addOneClaim(ISSUER, iss);
    return this;
  }

  public JwtParamBuilder setAudience(String aud) {
    addOneClaim(AUDIENCE, aud);
    return this;
  }

  public JwtParamBuilder addJwtId() {
    return setJwtId(UUID.randomUUID().toString());
  }

  public JwtParamBuilder setJwtId(String jwtid) {
    addOneClaim(ID, UUID.randomUUID().toString());
    return this;
  }

  public JwtParamBuilder claim(String name, Object value) {
    if (value == null) {
      this.claims.remove(name);
    } else {
      this.claims.put(name, value);
    }
    return this;
  }

  private void addOneClaim(String key, String value) {
    if (value != null && value.length() > 0) {
      claims.put(key, value);
    }
  }


  /**
   * @return the claims
   */
  public Map<String, Object> getClaims() {
    return claims;
  }


}

# C#

# 添加引用

使用包管理开发工具NuGet添加依赖。NuGet具体使用方法请自行Google。 在程序包管理器控制台输入下列命令安装依赖 1、Install-Package Newtonsoft.Json 2、Install-Package jose-jwt Newtonsoft.Json用来进行json转换 jose-jwt用来进行jwt签名

# API调用代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using Jose;
using Newtonsoft.Json;

namespace Invoicing
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //构造url
            var baseUrl = "https://127.0.0.1:8080";
            var url = baseUrl + "/output-tax/api/invoiceApply/insertWithArray?appid=123213";
            var req = (HttpWebRequest) WebRequest.Create(url);


            //请求体参数_requestdatas(发票头+发票明细)
            var requestdatas = BuildRequestDatas();

            var paraEnvoice = "requestdatas=" + Uri.EscapeDataString(requestdatas);
            //json数组格式,可以多张发票,流水号关联
            //请求体参数_email(邮件推送配置)
            var paraEmail = "email=" + Uri.EscapeDataString(BuildEmailData());
            //请求体参数_sms(短信推送配置)
            var paraSms = "sms=" + BuildMobileData();
            //json数组格式,可以多手机号,以流水号关联
            //请求体参数_url(回调服务配置)
            var paraUrl = "url=" + HttpUtility.UrlEncode(BuildUrlData()); //json数组格式,可以多url,以流水号关联 
            //拼接参数字符串
            var param = paraEnvoice + '&' + paraEmail + '&' + paraSms + '&' + paraUrl + "&autoAudit=false";


            //设置消息头
            // var bs = Encoding.ASCII.GetBytes(param);
            var bs = Encoding.UTF8.GetBytes(param);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded;charset=" + Encoding.UTF8.WebName;
            req.Headers.Add("sign", Sign(requestdatas)); //放入签名信息在消息头
            req.ContentLength = bs.Length;
            Console.WriteLine("请求头信息:");
            Console.WriteLine(req.Headers.ToString());
            Console.WriteLine("---------------------------");
            Console.WriteLine("请求体信息:");
            Console.WriteLine(param);
            Console.WriteLine("---------------------------");

            //发送请求
            using (var reqStream = req.GetRequestStream())
            {
                reqStream.Write(bs, 0, bs.Length);
                reqStream.Close();
            }

            //获取请求
            using (var response = (HttpWebResponse) req.GetResponse())
            {
                var responseStream = response.GetResponseStream();

                if (responseStream == null)
                {
                    return;
                }
                using (var reader = new StreamReader(responseStream, Encoding.UTF8))
                {
                    var responseData = reader.ReadToEnd();
                    Console.WriteLine("返回信息:");
                    Console.WriteLine(responseData);
                    Console.WriteLine("---------------------------");
                }
            }
        }

        /// <summary>
        ///     数据签名
        /// </summary>
        /// <param name="requestdatas"></param>
        /// <returns></returns>
        private static string Sign(string requestdatas)
        {
            var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //5分钟内有效
            var exp = ts.TotalMilliseconds + 360000;

            var payload = new Dictionary<string, object>
            {
                {"sub", "tester"},
                {"exp", exp},
                {"requestdatas", GetMd5(requestdatas)}
            };

            var privateKey =
                new X509Certificate2("D:/CA/keystore/pro22.pfx", "password",
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as
                    RSACryptoServiceProvider;

            var token = JWT.Encode(payload, privateKey, JwsAlgorithm.PS256);

            return token;
        }

        /// <summary>
        ///     获取md5值
        /// </summary>
        /// <param name="requestdatas"></param>
        /// <returns></returns>
        private static string GetMd5(string requestdatas)
        {
            using (var md5Hash = MD5.Create())
            {
                var hash = GetMd5Hash(md5Hash, requestdatas);
                return hash;
            }
        }

        private static string GetMd5Hash(MD5 md5Hash, string input)
        {
            // Convert the input string to a byte array and compute the hash.
            var data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            var sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data 
            // and format each one as a hexadecimal string.
            for (var i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        /// <summary>
        ///     构造邮件交付配置信息
        /// </summary>
        /// <returns></returns>
        private static string BuildEmailData()
        {
            var emailDatas = new List<Dictionary<string, object>>();
            var oneEmail = new Dictionary<string, object>
            {
                {"fpqqlsh", "1234567890"},
                {"address", "xxx@yonyou.com"}
            };
            emailDatas.Add(oneEmail);

            return JsonConvert.SerializeObject(emailDatas);
        }

        /// <summary>
        ///     构建短信交付配置
        /// </summary>
        /// <returns></returns>
        private static string BuildMobileData()
        {
            var mobileDatas = new List<Dictionary<string, object>>();
            var oneMobile = new Dictionary<string, object>
            {
                {"fpqqlsh", "1234567890"},
                {"address", "13111111111"}
            };
            mobileDatas.Add(oneMobile);

            return JsonConvert.SerializeObject(mobileDatas);
        }

        /// <summary>
        ///     构建url回调配置
        /// </summary>
        /// <returns></returns>
        private static string BuildUrlData()
        {
            var urlDatas = new List<Dictionary<string, object>>();
            var oneUrl = new Dictionary<string, object>
            {
                {"fpqqlsh", "1234567890"},
                {"url", "http://127.0.0.1:8080/callback"}
            };
            urlDatas.Add(oneUrl);

            return JsonConvert.SerializeObject(urlDatas);
        }

        /// <summary>
        ///     开票请求数据
        /// </summary>
        /// <returns></returns>
        private static string BuildRequestDatas()
        {
            var requestDatas = new List<Dictionary<string, object>>();
            //构造发票头
            var oneInvoice = new Dictionary<string, object>
            {
                {"FPQQLSH", "12345678902222"},
                {"XSF_NSRSBH", "5001020100060171"},
                {"ORGCODE", "20160914001"},
                {"GMF_MC", "购买方名称"},
                {"JSHJ", 117}
            };
            requestDatas.Add(oneInvoice);

            var items = new List<Dictionary<string, object>>();
            oneInvoice.Add("items", items);

            //构造一个发票明细
            var oneItem = new Dictionary<string, object>
            {
                {"XMMC", "项目名称"},
                {"SPBM", "1070102039900000000"},
                {"XMJSHJ", 117},
                {"SL", 0.17}
            };

            items.Add(oneItem);


            return JsonConvert.SerializeObject(requestDatas);
        }
    }
}

# PHP

# 添加引用

引入JWT.php

<?php

namespace Firebase\JWT;
use \DomainException;
use \InvalidArgumentException;
use \UnexpectedValueException;
use \DateTime;

/**
 * JSON Web Token implementation, based on this spec:
 * https://tools.ietf.org/html/rfc7519
 *
 * PHP version 5
 *
 * @category Authentication
 * @package  Authentication_JWT
 * @author   Neuman Vong <neuman@twilio.com>
 * @author   Anant Narayanan <anant@php.net>
 * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
 * @link     https://github.com/firebase/php-jwt
 */
class JWT
{

    /**
     * When checking nbf, iat or expiration times,
     * we want to provide some extra leeway time to
     * account for clock skew.
     */
    public static $leeway = 0;

    /**
     * Allow the current timestamp to be specified.
     * Useful for fixing a value within unit testing.
     *
     * Will default to PHP time() value if null.
     */
    public static $timestamp = null;

    public static $supported_algs = array(
        'HS256' => array('hash_hmac', 'SHA256'),
        'HS512' => array('hash_hmac', 'SHA512'),
        'HS384' => array('hash_hmac', 'SHA384'),
        'RS256' => array('openssl', 'SHA256'),
        'RS384' => array('openssl', 'SHA384'),
        'RS512' => array('openssl', 'SHA512'),
    );

    /**
     * Decodes a JWT string into a PHP object.
     *
     * @param string        $jwt            The JWT
     * @param string|array  $key            The key, or map of keys.
     *                                      If the algorithm used is asymmetric, this is the public key
     * @param array         $allowed_algs   List of supported verification algorithms
     *                                      Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
     *
     * @return object The JWT's payload as a PHP object
     *
     * @throws UnexpectedValueException     Provided JWT was invalid
     * @throws SignatureInvalidException    Provided JWT was invalid because the signature verification failed
     * @throws BeforeValidException         Provided JWT is trying to be used before it's eligible as defined by 'nbf'
     * @throws BeforeValidException         Provided JWT is trying to be used before it's been created as defined by 'iat'
     * @throws ExpiredException             Provided JWT has since expired, as defined by the 'exp' claim
     *
     * @uses jsonDecode
     * @uses urlsafeB64Decode
     */
    public static function decode($jwt, $key, array $allowed_algs = array())
    {
        $timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;

        if (empty($key)) {
            throw new InvalidArgumentException('Key may not be empty');
        }
        $tks = explode('.', $jwt);
        if (count($tks) != 3) {
            throw new UnexpectedValueException('Wrong number of segments');
        }
        list($headb64, $bodyb64, $cryptob64) = $tks;
        if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
            throw new UnexpectedValueException('Invalid header encoding');
        }
        if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
            throw new UnexpectedValueException('Invalid claims encoding');
        }
        if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
            throw new UnexpectedValueException('Invalid signature encoding');
        }
        if (empty($header->alg)) {
            throw new UnexpectedValueException('Empty algorithm');
        }
        if (empty(static::$supported_algs[$header->alg])) {
            throw new UnexpectedValueException('Algorithm not supported');
        }
        if (!in_array($header->alg, $allowed_algs)) {
            throw new UnexpectedValueException('Algorithm not allowed');
        }
        if (is_array($key) || $key instanceof \ArrayAccess) {
            if (isset($header->kid)) {
                if (!isset($key[$header->kid])) {
                    throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
                }
                $key = $key[$header->kid];
            } else {
                throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
            }
        }

        // Check the signature
        if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
            throw new SignatureInvalidException('Signature verification failed');
        }

        // Check if the nbf if it is defined. This is the time that the
        // token can actually be used. If it's not yet that time, abort.
        if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
            );
        }

        // Check that this token has been created before 'now'. This prevents
        // using tokens that have been created for later use (and haven't
        // correctly used the nbf claim).
        if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
            );
        }

        // Check if this token has expired.
        if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
            throw new ExpiredException('Expired token');
        }

        return $payload;
    }

    /**
     * Converts and signs a PHP object or array into a JWT string.
     *
     * @param object|array  $payload    PHP object or array
     * @param string        $key        The secret key.
     *                                  If the algorithm used is asymmetric, this is the private key
     * @param string        $alg        The signing algorithm.
     *                                  Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
     * @param mixed         $keyId
     * @param array         $head       An array with header elements to attach
     *
     * @return string A signed JWT
     *
     * @uses jsonEncode
     * @uses urlsafeB64Encode
     */
    public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
    {
        $header = array('typ' => 'JWT', 'alg' => $alg);
        if ($keyId !== null) {
            $header['kid'] = $keyId;
        }
        if ( isset($head) && is_array($head) ) {
            $header = array_merge($head, $header);
        }
        $segments = array();
        $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
        $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
        $signing_input = implode('.', $segments);

        $signature = static::sign($signing_input, $key, $alg);
        $segments[] = static::urlsafeB64Encode($signature);

        return implode('.', $segments);
    }

    /**
     * Sign a string with a given key and algorithm.
     *
     * @param string            $msg    The message to sign
     * @param string|resource   $key    The secret key
     * @param string            $alg    The signing algorithm.
     *                                  Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
     *
     * @return string An encrypted message
     *
     * @throws DomainException Unsupported algorithm was specified
     */
    public static function sign($msg, $key, $alg = 'HS256')
    {
        if (empty(static::$supported_algs[$alg])) {
            throw new DomainException('Algorithm not supported');
        }
        list($function, $algorithm) = static::$supported_algs[$alg];
        switch($function) {
            case 'hash_hmac':
                return hash_hmac($algorithm, $msg, $key, true);
            case 'openssl':
                $signature = '';
                $success = openssl_sign($msg, $signature, $key, $algorithm);
                if (!$success) {
                    throw new DomainException("OpenSSL unable to sign data");
                } else {
                    return $signature;
                }
        }
    }

    /**
     * Verify a signature with the message, key and method. Not all methods
     * are symmetric, so we must have a separate verify and sign method.
     *
     * @param string            $msg        The original message (header and body)
     * @param string            $signature  The original signature
     * @param string|resource   $key        For HS*, a string key works. for RS*, must be a resource of an openssl public key
     * @param string            $alg        The algorithm
     *
     * @return bool
     *
     * @throws DomainException Invalid Algorithm or OpenSSL failure
     */
    private static function verify($msg, $signature, $key, $alg)
    {
        if (empty(static::$supported_algs[$alg])) {
            throw new DomainException('Algorithm not supported');
        }

        list($function, $algorithm) = static::$supported_algs[$alg];
        switch($function) {
            case 'openssl':
                $success = openssl_verify($msg, $signature, $key, $algorithm);
                if ($success === 1) {
                    return true;
                } elseif ($success === 0) {
                    return false;
                }
                // returns 1 on success, 0 on failure, -1 on error.
                throw new DomainException(
                    'OpenSSL error: ' . openssl_error_string()
                );
            case 'hash_hmac':
            default:
                $hash = hash_hmac($algorithm, $msg, $key, true);
                if (function_exists('hash_equals')) {
                    return hash_equals($signature, $hash);
                }
                $len = min(static::safeStrlen($signature), static::safeStrlen($hash));

                $status = 0;
                for ($i = 0; $i < $len; $i++) {
                    $status |= (ord($signature[$i]) ^ ord($hash[$i]));
                }
                $status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash));

                return ($status === 0);
        }
    }

    /**
     * Decode a JSON string into a PHP object.
     *
     * @param string $input JSON string
     *
     * @return object Object representation of JSON string
     *
     * @throws DomainException Provided string was invalid JSON
     */
    public static function jsonDecode($input)
    {
        if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
            /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
             * to specify that large ints (like Steam Transaction IDs) should be treated as
             * strings, rather than the PHP default behaviour of converting them to floats.
             */
            $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
        } else {
            /** Not all servers will support that, however, so for older versions we must
             * manually detect large ints in the JSON string and quote them (thus converting
             *them to strings) before decoding, hence the preg_replace() call.
             */
            $max_int_length = strlen((string) PHP_INT_MAX) - 1;
            $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
            $obj = json_decode($json_without_bigints);
        }

        if (function_exists('json_last_error') && $errno = json_last_error()) {
            static::handleJsonError($errno);
        } elseif ($obj === null && $input !== 'null') {
            throw new DomainException('Null result with non-null input');
        }
        return $obj;
    }

    /**
     * Encode a PHP object into a JSON string.
     *
     * @param object|array $input A PHP object or array
     *
     * @return string JSON representation of the PHP object or array
     *
     * @throws DomainException Provided object could not be encoded to valid JSON
     */
    public static function jsonEncode($input)
    {
        $json = json_encode($input);
        if (function_exists('json_last_error') && $errno = json_last_error()) {
            static::handleJsonError($errno);
        } elseif ($json === 'null' && $input !== null) {
            throw new DomainException('Null result with non-null input');
        }
        return $json;
    }

    /**
     * Decode a string with URL-safe Base64.
     *
     * @param string $input A Base64 encoded string
     *
     * @return string A decoded string
     */
    public static function urlsafeB64Decode($input)
    {
        $remainder = strlen($input) % 4;
        if ($remainder) {
            $padlen = 4 - $remainder;
            $input .= str_repeat('=', $padlen);
        }
        return base64_decode(strtr($input, '-_', '+/'));
    }

    /**
     * Encode a string with URL-safe Base64.
     *
     * @param string $input The string you want encoded
     *
     * @return string The base64 encode of what you passed in
     */
    public static function urlsafeB64Encode($input)
    {
        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
    }

    /**
     * Helper method to create a JSON error.
     *
     * @param int $errno An error number from json_last_error()
     *
     * @return void
     */
    private static function handleJsonError($errno)
    {
        $messages = array(
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
        );
        throw new DomainException(
            isset($messages[$errno])
            ? $messages[$errno]
            : 'Unknown JSON error: ' . $errno
        );
    }

    /**
     * Get the number of bytes in cryptographic strings.
     *
     * @param string
     *
     * @return int
     */
    private static function safeStrlen($str)
    {
        if (function_exists('mb_strlen')) {
            return mb_strlen($str, '8bit');
        }
        return strlen($str);
    }
}

# API调用代码
<?php
require 'vendor/autoload.php';
use \Firebase\JWT\JWT;
include('JWT.php');
class InvoiceDemo {
    private static $appid = 'commontesterCA';
    private static $baseUrl = 'https://yesfp.yonyoucloud.com/output-tax/api/invoiceApply/';
	
    private static $keyfile='D:/web/irm-cams.web/cn/pro22.pfx';

    private static $blueApi = 'insertWithArray';

    //开蓝票接口
     public function blueInvoice() {
        $fpqqlsh = $this->buildFpqqlsh();
        $requestdatas = array(
            array(
                "FPQQLSH" => $fpqqlsh,
                "XSF_NSRSBH" => "201609140000001",
                "ORGCODE" => "20160914001",
                "GMF_MC" => "天津国联鸿泰科技有限公司",
                "GMF_DZDH" => "天津市河北区王串场街王串场四号路4号增19号 86-022-84847456",
                "GMF_YHZH" => "中国建设银行股份有限公司天津河北支行 12050166080000000517",
                "ZDYBZ" => "这是放射所报名费xx单号的开票",
                "JSHJ" => 780.00,
                "items" => array(
                    array(
                        "XMMC" => "技术服务费",
                        "SPBM" => "3040101",
                        "XMJSHJ" => 117,
                        "SL" => 0.06,
                    )
                )
            )
        );
        $url = array(
            array(
                "fpqqlsh"=>$fpqqlsh,
                "url" => "http://bjxr246.cname.zaojiaojia.net/callback.php?callbackUrl"
            )
        );
        $email=array(
             array(
              "fpqqlsh"=>$fpqqlsh,
              "address"=>"315389520@qq.com"
             ) 
        );
        $params = array(
            'requestdatas'=>json_encode($requestdatas),
            'email'=>json_encode($email),          
            'url'=>json_encode($url),
            "autoAudit" => 'true'
        );

       return  $this->exec(self::$blueApi, $params);
    }
      //获取发票请求流水号(唯一)
    private function    buildFpqqlsh(){
          return "2018052615510000004";
      }

    protected function exec($api, array $params) {
        $api = self::$baseUrl . $api . "?appid=" . self::$appid;

        $options = array(
            'header'=>array(
                'sign'=>$this->sign($params),
            )
        );
        return self::post($api, $params, $options);
    }
    //jwt签名
    private function sign(array $params){
        $ts = time();
        $signParams = array(
            'sub'=>'tester',
            'iss'=>'einvoice',
            'aud'=>'einvoice',
            'jti'=>$ts,
            'iat'=>$ts,
            'exp'=>$ts+300,
            'nbf'=>$ts-300
        );
        // 需要将表单参数requestdatas的数据进行md5加密,然后放到签名数据的requestdatas中。
        // 此签名数据必须存在,否则在验证签名时会不通过。
        $requestdatas=$params['requestdatas'];
        if(!empty($requestdatas)) {
            $signParams['requestdatas'] = md5($requestdatas);
        }
        //读取CA证书与PEM格式证书需要根据实际证书使用情况而定,目前这两种都支持 
        $privateKey = $this->loadPrivateKeyOfCA(self::$keyfile);
        // $privateKey = $this->loadPrivateKeyOfPem(self::$keyfile);     
        $sign = JWT::encode($signParams, $privateKey, 'RS256');
        return $sign;
    }

    //读取PEM编码格式
    private function loadPrivateKeyOfPem($file) {
        if(!file_exists($file)) {
            throw new \Exception("Error: Key file $file is not exists.");
        }
        if(!$key = file_get_contents($file)) {
            throw new \Exception("Error: Key file $file is empty.");
        }
        return $key;
    }
    //读取证书私钥
     private function loadPrivateKeyOfCA($file) {
        if(!file_exists($file)) {
            throw new \Exception("Error: Cert file $file is not exists.");
        }
        if (!$cert_store = file_get_contents($file)) {
            throw new \Exception("Error: Unable to read the cert file $file .");
        }
        if (openssl_pkcs12_read($cert_store, $cert_info, "password")) {
            return $cert_info['pkey'];
        } else {
            throw new \Exception("Error: Unable to read the cert store from $file .");
        }
    }

    private static function post($url, $params, array $options=null) {
        $ch = curl_init();
        self::setOption($ch, $options);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_POST, count($params));
        $params = http_build_query($params);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        $content = curl_exec($ch);
        $errorCode = curl_errno($ch);
        curl_close($ch);
        return array($errorCode, $content);
    }

    private static function setOption($ch, array $options=null) {
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        if($options === null) {
            $options = array();
        }
        if(isset($options["cookie"]) && is_array($options["cookie"])) {
            $cookieArr = array();
            foreach($options["cookie"] as $key=>$value) {
                $cookieArr[] = "$key=$value";
            }
            $cookie = implode("; ", $cookieArr);
            curl_setopt($ch, CURLOPT_COOKIE, $cookie);
        }
        $timeout = 30;
        if(isset($options["timeout"])) {
            $timeout = $options["timeout"];
        }
        if(isset($options["ua"])) {
            curl_setopt($ch, CURLOPT_USERAGENT, $options["ua"]);
        }
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        if(isset($options['header'])) {
            curl_setopt($ch, CURLOPT_HEADER, true);
            $header = array();
            foreach($options['header'] as $k=>$v) {
                $header[] = $k.": ".$v;
            }
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
    }
}
$invoiceDemo=new InvoiceDemo();
$result=$invoiceDemo->blueInvoice();
var_dump($result);
?>

Last Updated: 3/6/2025, 12:09:00 PM