# 航信电子发票 SDK (huapiaoer-sdk)
基于航信(票慧通)乐企版 v5.1 的电子发票 Java SDK,封装了发票开具、红冲、查询、发送邮件等全部接口。
## 引入依赖
```xml
com.kym
huapiaoer-sdk
5.1.0
```
## 快速开始
```java
// 1. 创建配置
HuapiaoerConfig config = HuapiaoerConfig.builder()
.appSecret("你的票慧通 appsecret")
.build();
// 2. 创建客户端
HuapiaoerClient client = new HuapiaoerClient(config);
// 3. 调用接口
List drawers = client.getDrawerIdList("915001*******460R");
```
## 配置参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `appSecret` | String | 是 | — | 票慧通提供的密钥 |
| `baseUrl` | String | 否 | `https://erp.huapiaoer.com` | API 正式环境地址 |
> `appSecret` 由 SDK 自动注入到所有请求中,无需手动设置。
---
## API 参考
### 1. 查询开票人列表
查询当前企业下所有开票人。
```java
List getDrawerIdList(String nsrsbh)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| `nsrsbh` | String | 开票方税号(商家税号) |
---
### 2. 授权订单号
微信支付商户授权,在发起开票前调用。
```java
AuthorizeOrderResponse getAuthorizeOrderId(AuthorizeOrderRequest request)
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `omsoutputorderid` | String | 是 | 订单号(企业号 + 流水号) |
| `appid` | String | 是 | 商户 AppID |
| `openid` | String | 是 | 微信 OpenID |
| `source` | String | 否 | `WEB` / `MINIPROGRAM` |
---
### 3. 发票开具
开具蓝字发票。
```java
OpenInvoiceResponse openBlueInvoice(OpenBlueInvoiceRequest request)
```
请求核心字段:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `issuerid` | String | 否 | 开票人 ID |
| `tradeinfo.payType` | String | 是 | 支付渠道编码,见 `PayType` 枚举 |
| `tradeinfo.outTradeNo` | String | 是 | 支付流水号 |
| `head.kpje` | String | 是 | 开票总金额 |
| `head.orderId` | String | 是 | 开票订单号 |
| `head.b2cshopid` | String | 是 | 商家税号 |
| `head.invoicetitle` | String | 是 | 购方抬头 |
| `head.invoiceTypeCode` | String | 是 | 发票类型,见 `InvoiceType` 枚举 |
| `head.registrationnumber` | String | 否 | 购方税号 |
| `head.companyaddress` | String | 否 | 购方地址 |
| `head.mobilenumber` | String | 否 | 购方手机号 |
| `head.openaccountbank` | String | 否 | 银行名称 |
| `head.bankaccount` | String | 否 | 银行账号 |
| `head.remark` | String | 否 | 发票备注 |
| `head.recmail` | String | 否 | 接收邮箱 |
| `details` | List | 是 | 商品明细 |
商品明细 (`DetailInfo`):
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `goodsname` | String | 是 | 商品名称 |
| `price` | Double | 是 | 商品单价(元) |
| `sl` | Double | 是 | 数量 |
| `goodscategory` | String | 否 | 商品大类(与 taxcode/tax 二选一) |
| `taxcode` | String | 否 | 税目编码(与 goodscategory 二选一) |
| `tax` | String | 否 | 税率(与 goodscategory 二选一) |
| `attributes` | String | 否 | 规格型号 |
| `unitname` | String | 否 | 单位 |
| `discount` | Double | 否 | 折扣金额(元) |
使用示例:
```java
OpenInvoiceResponse resp = client.openBlueInvoice(
new OpenBlueInvoiceRequest()
.setIssuerid("1868914789939154946")
.setTradeinfo(new TradeInfo()
.setPayType(PayType.WECHAT_PAY.getCode())
.setOutTradeNo("WX20240410000001"))
.setHead(new HeadInfo()
.setOrderId("1019000000000001")
.setB2cshopid("914403008888888888")
.setKpje("1.00")
.setInvoicetitle("深圳柯适科技有限公司")
.setRegistrationnumber("91440300MA5FB8A214")
.setInvoiceTypeCode(InvoiceType.DIGITAL_NORMAL.getCode())
.setRecmail("test@qq.com"))
.setDetails(List.of(
new DetailInfo()
.setGoodsname("充电服务费")
.setPrice(1.0)
.setSl(1.0)
.setTaxcode("1030302000000000xxx")
.setTax("0.13")
))
);
// resp.getCode() → "200"
// resp.getData() → "订单生成成功!请让用户授权。"
// resp.getOrderId() → "1019000000000001"
// resp.getAuthorizeQRCode() → "https://image.huapiaoer.com/xxx.png"
```
---
### 4. 发票红冲
冲红已开具的发票。
```java
HuapiaoerResponse openRedInvoice(String orderId)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| `orderId` | String | 发票订单号 |
---
### 5. 发票查询
查询发票开票结果。
```java
InvoiceInfo getInvoice(String orderId, int invoicetype)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| `orderId` | String | 航信订单号 |
| `invoicetype` | int | `1` 蓝票,`2` 红票,见 `InvoiceQueryType` |
返回 `InvoiceInfo` 包含:`invoicenumber`(发票号码)、`invoicecode`(发票代码)、`invoiceurl`(PDF 地址)、`ofdurl`(OFD 地址)、`xmlurl`(XML 地址)、`ticketTotalAmountHasTax`(金额)等。
---
### 6. 发送邮件
将发票发送到指定邮箱。
```java
HuapiaoerResponse sendMail(String orderId, int invoiceType, String email)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| `orderId` | String | 订单号 |
| `invoiceType` | int | `1` 蓝票,`2` 红票 |
| `email` | String | 目标邮箱 |
---
### 7. 生成开票二维码
生成自助开票二维码,用户扫码填写抬头开票。
```java
HuapiaoerResponse getInvoiceQrcode(InvoiceQrcodeRequest request)
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `head.orderId` | String | 是 | 开票订单号 |
| `head.b2cshopid` | String | 是 | 商家税号 |
| `head.invoiceTypeCode` | String | 是 | 发票类型 |
| `head.remark` | String | 否 | 发票备注 |
| `details` | List | 是 | 商品明细(不含 discount) |
---
### 8. 企业搜索
根据企业简称查询企业基本信息。
```java
List searchEnterprise(String enterpriseName)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| `enterpriseName` | String | 公司简称(4 个字符起生效) |
---
## 枚举常量
### InvoiceType 发票类型
| 枚举 | 编码 | 说明 |
|------|------|------|
| `DIGITAL_SPECIAL` | `"081"` | 数电专票 |
| `DIGITAL_NORMAL` | `"082"` | 数电普票 |
### InvoiceQueryType 查询类型
| 枚举 | 值 | 说明 |
|------|-----|------|
| `BLUE` | `1` | 蓝票 |
| `RED` | `2` | 红票 |
### PayType 支付渠道
| 枚举 | 编码 | 说明 |
|------|------|------|
| `CASH` | `"01"` | 现金 |
| `BANK_TRANSFER` | `"02"` | 银行转账 |
| `ALIPAY` | `"09"` | 支付宝 |
| `WECHAT_PAY` | `"10"` | 微信支付 |
| `UNIONPAY_QUICK` | `"11"` | 云闪付 |
| ... | ... | 共 14 种支付渠道 |
---
## 异常处理
所有接口在 `code != "200"` 或网络异常时抛出 `HuapiaoerException`:
```java
try {
List drawers = client.getDrawerIdList("...");
} catch (HuapiaoerException e) {
// e.getCode() — 状态码
// e.getMessage() — 错误描述
}
```