Skip to content

fapiaoapi/invoice-sdk-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 

Repository files navigation

电子发票/数电发票 Java SDK | 开票、验真、红冲一站式集成

Maven Central License Java 17+

发票 Java SDK 专为电子发票、数电发票(全电发票)场景设计,支持开票、红冲、版式文件下载等核心功能,快速对接税务平台API。

关键词: 电子发票SDK,数电票Java,开票接口,发票api,发票开具,发票红冲,全电发票集成


📖 核心功能

基础认证

  • 获取授权 - 快速接入税务平台身份认证
  • 人脸二维码登录 - 支持数电发票平台扫码登录
  • 认证状态查询 - 实时获取纳税人身份状态

发票开具

  • 🎫 数电蓝票开具 - 支持增值税普通/专用电子发票
  • 📄 版式文件下载 - 自动获取销项发票PDF/OFD/XML文件

发票红冲

  • 🔍 红冲前蓝票查询 - 精确检索待红冲的电子发票
  • 🛑 红字信息表申请 - 生成红冲凭证
  • 🔄 负数发票开具 - 自动化红冲流程

🚀 快速安装

Maven

<dependency>
    <groupId>io.github.fapiaoapi</groupId>
    <artifactId>invoice</artifactId>
    <version>1.0.15</version>
</dependency>

Gradle

implementation 'io.github.fapiaoapi:invoice:1.0.15'

📦 查看Maven Central最新版本

本sdk仅支持Java 17+,其他版本请用旧版本

java8-java16开发票demo

java8-java16红冲发票demo

java8-java16发票税额demo


📚 查看完整中文文档 | 💡 更多示例代码


🔍 为什么选择此SDK?

  • 精准覆盖中国数电发票标准 - 严格遵循国家最新接口规范
  • 开箱即用 - 无需处理XML/签名等底层细节,专注业务逻辑
  • 企业级验证 - 已在生产环境处理超100万张电子发票

📊 支持的开票类型

发票类型 状态
数电发票(普通发票) ✅ 支持
数电发票(增值税专用发票) ✅ 支持
数电发票(铁路电子客票) ✅ 支持
数电发票(航空运输电子客票行程单) ✅ 支持
数电票(二手车销售统一发票) ✅ 支持
数电纸质发票(增值税专用发票) ✅ 支持
数电纸质发票(普通发票) ✅ 支持
数电纸质发票(机动车发票) ✅ 支持
数电纸质发票(二手车发票) ✅ 支持

🤝 贡献与支持

🎯 快速开始:5分钟开出一张数电发票

package tax.invoice.example;

import java.io.PrintStream;
import tax.invoice.InvoiceClient;
import tax.invoice.model.ApiResponse;
import tax.invoice.model.AuthorizationResponse;

import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import java.io.ByteArrayOutputStream;
import java.util.Base64;


public class BasicExample {
    public static void main(String[] args) {
        try {
            // 显式设置 System.out 的编码为 UTF-8
            System.setOut(new PrintStream(System.out, true, "UTF-8"));

            // 配置信息
            String appKey = "";
            String appSecret = "";

            String nsrsbh = "91500112MADFAXXXX";//统一社会信用代码
            String title = "XXXX科技有限公司";//名称(营业执照)
            String username = "1325580XXXX";//手机号码(电子税务局)
            String password = "123456XXXX";//个人用户密码(电子税务局)
            String sf = "01";//身份(电子税务局)
            String fphm = "";
            String kprq = "";
            String token = "";

            String type = "6";//6 基础 7标准
            // Redis配置

            /*
              <dependency>
                  <groupId>redis.clients</groupId>
                  <artifactId>jedis</artifactId>
                  <version>3.9.0</version>
              </dependency>
             */
            Jedis redis = new Jedis("127.0.0.1", 6379);
            redis.auth("test123456");


            // 创建客户端
            InvoiceClient client = new InvoiceClient(appKey, appSecret);

            // 从Redis获取Token
            String redisKey = nsrsbh +"@"+username+ "@TOKEN";
            token = redis.get(redisKey);
            if (token != null && !token.isEmpty()) {
                client.setAuthorization(token);
                System.out.println("Token From Redis: ");
            } else {
                //一 获取授权
                /*
                 * 获取授权Token文档
                 * @see https://fa-piao.com/doc.html#api1?source=github
                 */
                ApiResponse<AuthorizationResponse> authResponse = client.getAuthorization(nsrsbh,type);
                if (authResponse.isSuccess()) {
                    token = authResponse.getData().getToken();
                    client.setAuthorization(token);
                    redis.setex(redisKey, 3600 * 24 * 30, token); // 设置30天过期
                    System.out.println("授权成功,Token: " + token);
                } else {
                    System.out.println("授权失败: " + authResponse.getMsg());
                    return;
                }
            }

            try {
                /*
                 * 前端模拟数电发票/电子发票开具 (蓝字发票)
                 * @see https://fa-piao.com/fapiao.html?source=github
                 *
                 */

                /*
                 *
                 * 开票参数说明demo
                 * @see https://github.com/fapiaoapi/invoice-sdk-java/blob/master/examples/TaxExample.java
                 */
                //开具蓝票参数
                Map<String, Object> invoiceParams = new LinkedHashMap<>();
                invoiceParams.put("fplxdm", "82");
                invoiceParams.put("fpqqlsh", appKey + System.currentTimeMillis());
                invoiceParams.put("ghdwmc", "个人");
//                    invoiceParams.put("ghdwsbh", "914208XXXXXXX");
                invoiceParams.put("hjje", 396.04);
                invoiceParams.put("hjse", 3.96);
                invoiceParams.put("jshj", 400);
                invoiceParams.put("kplx", 0);
                invoiceParams.put("username", username);
                invoiceParams.put("xhdwdzdh", "重庆市渝北区龙溪街道丽园路2号XXXX 1325580XXXX");
                invoiceParams.put("xhdwmc", title);
                invoiceParams.put("xhdwsbh", nsrsbh);
                invoiceParams.put("xhdwyhzh", "工商银行XXXX 15451211XXXX");
                invoiceParams.put("zsfs", 0);
                invoiceParams.put("fyxm[0][fphxz]", 0);
                invoiceParams.put("fyxm[0][spmc]", "*软件维护服务*接口服务费");
                invoiceParams.put("fyxm[0][ggxh]", "");
                invoiceParams.put("fyxm[0][dw]", "次");
                invoiceParams.put("fyxm[0][spsl]", 100);
                invoiceParams.put("fyxm[0][dj]", 1);
                invoiceParams.put("fyxm[0][je]", 100);
                invoiceParams.put("fyxm[0][sl]", 0.01);
                invoiceParams.put("fyxm[0][se]", 0.99);
                invoiceParams.put("fyxm[0][hsbz]", 1);
                invoiceParams.put("fyxm[0][spbm]", "3040201030000000000");
                invoiceParams.put("fyxm[1][fphxz]", 0);
                invoiceParams.put("fyxm[1][spmc]", "*软件维护服务*接口服务费");
                invoiceParams.put("fyxm[1][ggxh]", "");
                invoiceParams.put("fyxm[1][spsl]", 150);
                invoiceParams.put("fyxm[1][dj]", 2);
                invoiceParams.put("fyxm[1][je]", 300);
                invoiceParams.put("fyxm[1][sl]", 0.01);
                invoiceParams.put("fyxm[1][se]", 2.97);
                invoiceParams.put("fyxm[1][hsbz]", 1);
                invoiceParams.put("fyxm[1][spbm]", "3040201030000000000");

                //二 开具蓝票
                /*
                 * 开具数电发票文档
                 * @see https://fa-piao.com/doc.html#api6?source=github
                 *
                 */
                ApiResponse<Map<String, Object>> invoiceResponse = client.blueTicket(invoiceParams);
                switch (invoiceResponse.getCode()){
                    case 200:
                        Map<String, Object> invoiceData = invoiceResponse.getData();
                        if (invoiceData == null || invoiceData.get("Fphm") == null || invoiceData.get("Kprq") == null) {
                            System.out.println("开票成功但返回字段缺失: " + invoiceResponse.getData());
                            break;
                        }
                        fphm = invoiceData.get("Fphm").toString();
                        kprq = invoiceData.get("Kprq").toString();
                        System.out.println("发票号码: " + fphm);
                        System.out.println("开票日期: " + kprq);

                        //三 下载发票
                        Map<String, Object> pdfParams = new HashMap<>();
                        pdfParams.put("downflag", "4");
                        pdfParams.put("nsrsbh", nsrsbh);
                        pdfParams.put("username", username);
                        pdfParams.put("fphm", fphm);
                        pdfParams.put("Kprq", kprq);

                        ApiResponse<Map<String, Object>> pdfResponse = client.getPdfOfdXml(pdfParams);
                        if (pdfResponse.isSuccess()) {
                            System.out.println("发票下载成功");
                            System.out.println(pdfResponse.getData());
                        }
                        break;

                    case 420:
                        System.out.println("登录(短信认证)");
                        /*
                         * 前端模拟短信认证弹窗
                         * @see https://fa-piao.com/fapiao.html?action=sms&source=github
                         */
                        // 1. 发短信验证码
                        /*
                         * @see https://fa-piao.com/doc.html#api2?source=github
                         */
                        // ApiResponse<Map<String, Object>> loginResponse = client.loginDppt(nsrsbh, username, password, "");
                        // if (loginResponse.getCode() == 200) {
                        //     System.out.println(loginResponse.getMsg());
                        //     System.out.println("请" + username + "接收验证码");
                        //     try {
                        //         sleep(60000); // 等待60秒
                        //     } catch (InterruptedException ex) {
                        //         Thread.currentThread().interrupt();
                        //     }
                        // }
                        // 2. 输入验证码
                        /*
                         * @see https://fa-piao.com/doc.html#api2?source=github
                         */
                        // System.out.println("请输入验证码");
                        // String smsCode = ""; // 这里应该获取用户输入的验证码
                        // ApiResponse<Map<String, Object>> loginResponse2 = client.loginDppt(nsrsbh, username, password, smsCode);
                        // if (loginResponse2.getCode() == 200) {
                        //     System.out.println(loginResponse2.getData());
                        //     System.out.println("验证成功");
                        // }
                        break;

                    case 430:
                        System.out.println("人脸认证");
                        /*
                         * 前端模拟人脸认证弹窗
                         * @see https://fa-piao.com/fapiao.html?action=face&source=github
                         */
                        // 1. 获取人脸二维码
                        /*
                         * @see https://fa-piao.com/doc.html#api3?source=github
                         */
//                             ApiResponse<Map<String, Object>> qrCodeResponse = client.getFaceImg(nsrsbh, username, "1");
//                             Map<String, Object> qrData = qrCodeResponse.getData();
//                             if (qrData == null) {
//                                 System.out.println("人脸二维码返回为空: " + qrCodeResponse.getMsg());
//                                 break;
//                             }
//                             Object ewmlyObj = qrData.get("ewmly");
//                             String ewmly = ewmlyObj == null ? "" : ewmlyObj.toString();
//                             System.out.println("swj".equals(ewmly) ? "请使用税务局app扫码" : "个人所得税app扫码");
//                             Object ewmObj = qrData.get("ewm");
//                             if (ewmObj != null && ewmObj.toString().length() < 500) {
//                                 // 需要引入二维码生成库来构建二维码
//                                 /*
//                                    <dependency>
//                                        <groupId>com.google.zxing</groupId>
//                                        <artifactId>core</artifactId>
//                                        <version>3.5.3</version>
//                                    </dependency>
//                                    <dependency>
//                                        <groupId>com.google.zxing</groupId>
//                                        <artifactId>javase</artifactId>
//                                        <version>3.5.3</version>
//                                    </dependency>
//                                  */
//                                String base64 = toBase64((String) ewmObj,300);
//                                qrData.put("ewm", base64);
//                                 System.out.println("data:image/png;base64," + base64);
//                                 // String base64Uri = "data:image/png;base64," + base64;
//                                 // 前端使用示例: <img src="base64Uri" />
//                             }

                        // 2. 认证完成后获取人脸二维码认证状态
                        /*
                         * @see https://fa-piao.com/doc.html#api4?source=github
                         */
                        // String rzid = qrCodeResponse.getData().get("rzid").toString();
                        // ApiResponse<Map<String, Object>> faceStatusResponse = client.getFaceState(nsrsbh, rzid, username, "1");
                        // System.out.println("code: " + faceStatusResponse.getCode());
                        // System.out.println("data: " + faceStatusResponse.getData());
                        //
                        // if (faceStatusResponse.getData() != null) {
                        //     String slzt = faceStatusResponse.getData().get("slzt").toString();
                        //     String status = "1".equals(slzt) ? "未认证" : ("2".equals(slzt) ? "成功" : "二维码过期");
                        //     System.out.println("认证状态: " + status);
                        // }
                        break;
                    case 401:
                        // token过期 重新获取并缓存token
                        System.out.println("授权失败:" + invoiceResponse.getMsg());
                        // 重新获取token的逻辑
                        break;
                    default:
//                            System.out.println("参数:" + invoiceParams);
                        System.out.println(invoiceResponse.getCode() + " " + invoiceResponse.getMsg());
                        break;
                }

            } catch (Exception e) {
                // 处理开票异常
                String errorMsg = e.getMessage();
                System.out.println("错误: " + errorMsg);
            }

        } catch (Exception e) {
            System.out.println("系统错误: " + e.getMessage());
            e.printStackTrace();
        }
    }


    public static String toBase64(String text, int size) {
        try {
            BitMatrix matrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, size, size);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(matrix, "PNG", out);
            return Base64.getEncoder().encodeToString(out.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("生成二维码失败", e);
        }
    }

}

发票红冲demo 发票税额计算demo

About

发票sdk java 电子发票/数电发票/全电发票/数电票/开票

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages