# 营收系统缴费接口
**版本:** 1.5
**作者:** 曹红强
## 修订记录
| 版本号 | 修改日期 | 修改人 | 修改内容 |
|---|---|---|---|
| v1.0 | 2021/03/24 | 曹红强 | 初始版本 |
| v1.1 | 2021/04/04 | 曹红强 | 新增代扣相关接口 |
| v1.2 | 2021/12/21 | 曹红强 | 完善文档结构及说明 |
| v1.3 | 2022/01/25 | 晋腾飞 | 完善文档结构及说明 |
| v1.4 | 2022/05/02 | 晋腾飞 | 添加托收相关接口 |
| v1.5 | 2023/03/10 | 晋腾飞 | 添加加密方式说明 |
## 概述
本文档主要是针对营收系统和银行(或代收机构)间的实时收费、银行代扣、银行托收(小额支付)协议。
## 术语
1. 文档中提到的商户、第三方支付平台、支付平台、第三方、支付公司指的就是第三方支付公司(比如支付宝,微信等)或者银行(比如招商银行,平安银行等)。
2. 公用事业单位:是指从接入的缴费事业单位,例如:自来水公司,电力公司等,第三方支付发的实时交易经总行和分行转发最终到公用事业单位进行处理。
## 通讯模式
公用事业单位和银行系统之间采用 Http 进行通讯,提交方式为 POST,加密方式在请求头 Header 填写,接口参数在 Http 包体中采用 XML 或 JSON 格式,默认 XML 格式。服务端口和服务地址,由公用事业单位提供。银行方接收接口返回超时时间建议设置为 30 秒。
## 报文说明
### 报文格式
#### XML
```xml
1.0.1
缴费渠道
交易码
交易日期
交易流水号
VALUE1
VALUE2
```
如上所示为 XML 报文示例:
1. 编码方式在报文中固定写“GBK”,但是实际的编码采用 GBK;
2. `in`:根节点;
3. `Version`:固定写“1.0.1”。
4. `InstId`:缴费渠道,长度最大长度 5 个字节,区别不同缴费渠道
5. `TranCode`:交易码,账单查询时交易码为 Query,查询应答给银行为 QueryRes;账单缴费时交易码为 Pay,缴费应答给银行时为 PayRes。
6. `TranDate`:交易日期,YYYYMMDD,如 20210101,当前交易时间。
7. `TranSeq`:交易流水号,由银行系统产生,用作标识每笔交易的请求,最大长度 40 个字节,并且同一天内该值不可重复。
8. `TAG1`:节点标签名;
9. `VALUE1`:节点值。
### 报文模版
#### 请求
```xml
1.0.1
00001
Query
20180101
123456789012
客户编号
……
```
#### 应答
```xml
1.0.1
00001
QueryRes
请求的日期原样返回
请求的日期原样返回
AAAAAAA
成功
客户编号
……
1
合同号
```
### 报文样例
#### 查询请求
```xml
1.0.1
00001
Query
20180101
123456789012
123456
654321
1
1
```
#### 查询应答
```xml
1.0.1
00001
QueryRes
20180101
123456789012
AAAAAAA
查询成功
RespMessage >
123456
654321
1
123456
张三
2314
```
### 销账请求
```xml
1.0.1
00001
Pay
20180101
123456789012
123456
654321
20110513081540
张三
5555
123456
```
### 销账应答
```xml
1.0.1
00001
PayRes
20180101
123456789012
AAAAAA
缴费成功
123456
654321
20110513081540
5555
```
## 报文编码
报文中可能有汉字,需要对报文进行 GBK 编码才能正常显示。
1. 编码方式在报文中固定写“GBK”
## 报文加密
### 加密方式说明
加密方式填写在 http 请求头 Header 里面,加密方式有:3DES,SM2,SM4,加密方式对 body 数据整体进行加密
| 中文域名 | 字段 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 加密类型 | EncryptType | char(20) | 必填 | 3DES,SM2,SM4 (默认 3DES) |
| 加密模式 | EncryptMode | char(20) | 必填 | 3DES(ECB), SM2(C1C2C3,C1C3C2), SM4(ECB,CBC) |
| 数据格式 | DataType | char(20) | 必填 | XML 或 JOSN (默认 XML) |
### 默认加密方式
如果 http 请求头 Header(EncryptType)不填写加密方式,默认为 XML 报文整体采用 3DES 函数加密,ECB 模式 PKCS7P 填充。
加密之后的报文,用 base64 编码。
### SM2 加密方式
http 请求头 Header 字段 EncryptType 填写 SM2,默认加密模式为 C1C3C2,默认报文 body 数据格式为 XML
### SM4 加密方式
http 请求头 Header 字段 EncryptType 填写 SM4,默认加密模式为 ECB,默认报文 body 数据格式为 XML
### 加密请求示例
加密方式请求头填写示例:
```
[Image Placeholder for Encrypt Header Example]
```
加密 body 请求示例:
```
[Image Placeholder for Encrypt Body Example]
```
## 报文头
### 报文头固定域
所有接口报文开始,都有这 5 个域,这里统一说明。查询和缴费的章节,不再说明报文头这 5 个域。
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 版本号 | Version | char(20) | | 必填 | 固定为 1.0.1 |
| 缴费渠道 | InstId | char(5) | | 必填 | 由水司软件方提供 |
| 交易码 | TranCode | char(20) | | 必填 | 见说明 |
| 交易日期 | TranDate | char(8) | | 必填 | YYYYMMDD |
| 流水号 | TranSeq | char(40) | Input2 | 必填 | 见说明 |
说明:
* **交易码:**
* 账单查询时交易码为 Query,查询应答给予银行为 QueryRes;
* 账单缴费时交易码为 Pay,缴费应答时为 PayRes;
* 代扣签约请求时交易码为 Signing,签约应答时为 SigningRes;
* 代扣解约请求时交易码为 Termination,解约应答时为 TerminationRes;
* 代扣送盘请求时交易码为 SendDisc,送盘应答时交易码为 SendDiscRes;
* 代扣回盘请求时交易码为 BackDisc,回盘应答时交易码为 BackDiscRes;
* 取消代扣交易请求时交易码为 CancelDisc,应答码为 CancelDiscRes;
* 代扣送盘状态查询交易码为 SendDiscCheck,应答交易码为 SendDiscCheckRes;
* 代扣回盘状态查询交易码为 BackDiscCheck,应答交易码为 BackDiscCheckRes;
* 客户基本信息查询交易码为 CustomerCheck, 应答交易码为 CustomerCheckRes;
* 实时收费红冲查询交易码为 PayInvalid,应答交易码为 PayInvalidRes;
* 代理收费向公用事业单位发起缴费单对账请求交易码为 PayCheck,应答交易码为 PayCheckRes。
* **交易流水号:** 由银行系统产生,用作标识每笔交易的请求,最大长度 40 个字节,并且值不可重复。
## 请求图例
### PostMan
```
[Image Placeholder for PostMan Example]
```
### Swagger
```
[Image Placeholder for Swagger Example]
```
说明:
* 请求返回 415 或 400 Body 加密内容请前后添加双引号
* 请求返回 500 请联系运维人员参与对接
## 1.1 实时收费
### 欠费查询
Query 是从银行向公用事业单位发起的查询缴费单信息的请求报文。
**请求地址:** `/api/app/payCeb/getChargeSearch`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 查询类型 | billType | char(10) | | 必填 | 见说明 |
| 起始笔数 | beginNum | Num(3) | | | 查询起始笔数,从 1 开始 |
| 查询笔数 | queryNum | Num(3) | | | 查询笔数 |
| 备用字段 | filed1 | char(100) | Input2 | | 二级渠道,默认 6,见说明 |
| 备用字段 | filed2 | char(100) | Input3 | | 预留字段 |
| 备用字段 | filed3 | char(100) | Input4 | | 预留字段 |
| 备用字段 | filed4 | char(100) | Input5 | | 预留字段 |
说明:
* **查询类型:** 默认 0,客户编号查询,1 条形码查询,客户编号为条形码;
* **二级渠道:**
* 1:支付宝;
* 2:微信;
* 6:实时收费
### 应答报文
QueryRes 是公用事业单位返回给银行的查询应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 查询返回代码 |
| 返回说明 | RespMessage | 60 | | 查询返回说明 |
| 客户编号 | billKey | char(35) | Output1 | 原样返回 |
| 机构编码 | companyId | Num(30) | | 原样返回 |
| 备用字段 | item1 | Num(100) | Output2 | 预留数据域 |
| 备用字段 | item2 | char(100) | Output3 | 预留数据域 |
| 备用字段 | item3 | char(100) | Item1 | 预留数据域 |
| 备用字段 | item4 | char(100) | Item2 | 预留数据域 |
| 备用字段 | item5 | char(100) | Item3 | 预留数据域 |
| 备用字段 | item6 | char(100) | Item4 | 预留数据域 |
| 备用字段 | item7 | char(100) | Item5 | 预留数据域 |
| 总笔数 | totalNum | char(3) | TotalNum | 返回总查询笔数 |
| 合同号 | contractNo | char(30) | ContractNo | 账单唯一标识 |
| 客户姓名 | customerName | char(100) | CustomerName | 循环域 |
| 余额 | balance | Number | Balance | 循环域(单位:分) |
| 应缴金额 | payAmount | Number | Amount | 循环域(单位:分) |
| 起始日期 | beginDate | char(10) | BeginDate | 循环域,停用字段 |
| 截至日期 | endDate | char(10) | EndDate | 循环域,停用字段 |
| 备用字段 | filed1 | char(100) | FormItem1 | 循环域 账期 |
| 备用字段 | filed2 | char(100) | FormItem2 | 循环域 滞纳金 |
| 备用字段 | filed3 | char(100) | FormItem3 | 循环域 |
| 备用字段 | filed4 | char(100) | FormItem4 | 循环域 |
| 备用字段 | filed5 | char(100) | FormItem5 | 循环域 客户地址 |
### 欠费缴纳
Pay 是银行向公用事业单位发起的欠费缴纳的请求报文。
**请求地址:** `/api/app/payCeb/getChargeOffs`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 查询类型 | billType | char(10) | | 必填 | 见说明 |
| 交易日期 | payDate | Num(3) | | 必填 | 见说明 |
| 备用字段 | filed1 | char(100) | Input2 | | 帐期 |
| 备用字段 | filed2 | char(100) | Input3 | | 滞纳金(单位:分) |
| 备用字段 | filed3 | char(100) | Item1 | 必填 | 二级渠道,见说明 |
| 备用字段 | filed4 | char(100) | Item2 | | 预留数据域 |
| 客户姓名 | customerName | char(100) | CustomerName | | 查询应答报文取 |
| 缴费金额 | payAmount | Number | Amount | 必填 | (单位:分) |
| 合同号 | contractNo | char(30) | ContractNo | 必填 | 查询接口应答报文取 |
说明:
* **查询类型:** 默认 0,客户编号查询,1 条形码查询,客户编号为条形码;
* **交易日期:** YYYYMMDDHHMMSS,(支付缴费单时系统当前时间)
* **二级渠道:**
* 1:支付宝
* 2:微信
* 6:其它
### 应答报文
PayRes 公用事业单位返回银行的缴费应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 缴费返回代码 |
| 返回说明 | RespMessage | 60 | | 缴费返回说明 |
| 客户编号 | billKey | char(35) | | 原样返回 |
| 机构编码 | companyId | Num(30) | | 原样返回 |
| 交易日期 | payDate | Num(14) | | 原样返回 |
| 缴费金额 | payAmount | Number(16,2) | | 原样返回 |
## 账单红冲
### 请求报文
PayInvalid 是从银行向公用事业单位发起的红冲缴费单信息的请求报文,只可红冲当天收费且未对账交易,红冲成功后银行需发起自动退款。
**请求接口:** `/api/app/payInvalid/payInvalid`
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 交易日期 | payDate | char(30) | | 交易日期 |
| 红冲流水号 | agencyBillNo | char(30) | | 缴费时的账单流水号 |
| 缴费金额 | payMoney | char(30) | | 缴费金额 |
说明:
* **交易日期:** YYYYMMDDHHMMSS,(支付缴费单时系统时间)
### 应答报文
PayInvalidRes 是公用事业单位返回给银行的红冲缴费单信息的应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 返回代码 | RespCode | char(30) | | 必填 | 返回代码 |
| 返回说明 | RespMessage | char(30) | | 必填 | 返回说明 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 交易日期 | payDate | char(30) | | | 交易日期 |
| 红冲流水号 | agencyBillNo | char(30) | | | 缴费时的账单流水号 |
| 缴费金额 | payMoney | char(30) | | | 缴费金额 |
## 对账文件上传
### 账单说明
银行每天日结后,进行批处理,自动生成和传送(通过 FTP 或 SFTP)对账文件给公用事业单位。
### 对账文件格式
对账文件为文本文件 txt 格式,编码格式为 UTF-8,包括明细行和汇总行。行内每个分项之间以“|”为分隔符。无交易数据时,对账文件有且只有一条汇总行。汇总行放在文件前面,定义如下:
`交易笔数|总金额`
明细行的定义如下:
`交易日期|交易流水号|客户编号|缴费金额|二级渠道|交易类型`
注释:对账文件内的交易流水号要与缴费时的流水号保持一致。
说明:
1. **关于文件命名:**
T 日所有交易按收费单位生成 n 个对账文件,文件名:机构编码(companyId)_对账日期.txt,其中对账日期为交易当天日期非当前时间。
例如:某水司机构编码(companyId)为 yhcs_yh,则 2021 年 1 月 1 日对账文件:yhcs_yh_20210101.txt;
2. 文件中只含缴费成功的交易;
3. 缴费金额单位是分;
4. 交易类型:默认 0,客户编号查询,1 条形码查询;
5. 文件编码格式采用 UTF-8。
### 对账接口
#### 对账说明
由代理收费公司每天日切后,进行批处理,自动生成和传送对账文件给公用事业单位。
#### 请求报文
PayCheck 代理收费向公用事业单位发起的缴费单对账的请求报文。
**请求接口:** `/api/app/payCeb/paymentCheck`
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 对账日期 | payDate | char(8) | 必填 | 需要对账的日期,非实时日期 |
| 交易笔数 | payCount | char(8) | 必填 | 交易总笔数 |
| 交易总金额 | payMoney | char(10) | 必填 | 交易总金额到分 |
| 对账文件名 | fileName | Char(100) | 必填 | 见说明 |
说明:
* **对账文件名:** 机构编码(companyId)_对账日期.txt,其中对账日期为交易当天日期非当前时间。
* **交易日期:** YYYYMMDDHHMMSS,(支付缴费单时系统时间)
#### 应答报文
PayCheckRes 公用事业单位返回的缴费对账应答报文。
| 中文域名 | 标签名 | 长度 | 约束条件 |
|---|---|---|---|
| 返回代码 | RespCode | 7 | 缴费返回代码 |
| 返回说明 | RespMessage | 60 | 缴费返回说明 |
| 机构编码 | companyId | char(30) | 原样返回 |
| 交易日期 | payDate | char(14) | 原样返回 |
| 缴费金额 | payAmount | Number(16,2) | 原样返回 |
## 1.2 银行代扣
### 代扣签约
Signing 是从银行向公用事业单位发起的代扣签约信息的请求报文。
**请求接口:** `/api/app/bankWithholding/signing`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 开户名称 | accountName | char(100) | | 必输 | 开户名称 |
| 开户账号 | accountNo | char(30) | | 必填 | 开户账号 |
| 开户行 | branchName | char(150) | | 必填 | 开户行 |
| 合同号 | contractNo | char(50) | | | 合同号 |
| 备用字段 | filed1 | char(100) | | | 预留字段 |
| 备用字段 | filed2 | char(100) | | | 预留字段 |
| 备用字段 | filed3 | char(100) | | | 预留字段 |
### 应答报文
SigningRes 是公用事业单位返回给银行的查询应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 查询返回代码 |
| 返回说明 | RespMessage | 60 | | 查询返回说明 |
| 客户编号 | billKey | char(35) | | 原样返回 |
| 备用字段 | filed1 | char(100) | | 循环域 |
| 备用字段 | filed2 | char(100) | | 循环域 |
| 备用字段 | filed3 | char(100) | | 循环域 |
### 代扣解约
Termination 是从银行向公用事业单位发起的代扣解约信息的请求报文。
**请求地址:** `/api/app/bankWithholding/termination`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 开户名称 | accountName | char(100) | | 必输 | 开户名称 |
| 开户账号 | accountNo | char(30) | | 必填 | 开户账号 |
| 开户行 | branchName | char(150) | | 必填 | 开户行 |
| 合同号 | contractNo | char(50) | | | |
| 备用字段 | filed1 | char(100) | | | 预留字段 |
| 备用字段 | filed2 | char(100) | | | 预留字段 |