小工具知识网

当前位置: 首页 > 行业知识 > 小程序自建平台开发票保存到微信卡包(java篇)

行业知识

小程序自建平台开发票保存到微信卡包(java篇)

2026-11-04 19:31:52 来源:互联网转载

目录

1 获取 Access token

2获取自身的开票平台识别码

3 获取授权页ticket

3.5 获取链接前需要先 设置商户联系方式

4 获取授权页链接

5 小程序打开授权页

6 收取授权完成事件推送

7 查询授权完成状态

8 创建发票卡券模板

 9 上传PDF

10 将电子发票卡券插入用户卡包


1 获取 Access token

这里的appid 和 secret  是公众号的 不要写小程序的哦

https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明

参数是否必须说明
grant_type是获取access_token填写client_credential
appid是第三方用户唯一凭证
secret是第三方用户唯一凭证密钥,即appsecret

这个获取代码我就不写了哈 应该都知道

2获取自身的开票平台识别码

这个地方代码我也不写  上面获取到的 Access token传入进来就行了   自己用postman调用一下 拿到invoice_url中的s_pappid存起来就行了

请求URL:https://api.weixin.qq.com/card/invoice/seturl?access_token={access_token}

请求方法:POST

请求参数

请求参数使用JSON格式,传入空值{}

返回结果

返回结果为JSON格式,字段如下:

参数类型是否必填描述
errcodestring是错误码
errmsgstring是错误信息
invoice_urlstring否该开票平台专用的授权链接。开票平台须将 invoice_url 内的 s_pappid 给到服务的商户,商户在请求授权链接时会向微信传入该参数,标识所使用的开票平台是哪家

这个获取到账号请截取下来 只需要获取一次 保存到配置文件即可

3 获取授权页ticket

ticket 的有效期,一般为 7200 秒

这个我也不写了 还是把上面获取的ACCESS_TOKEN传入 就能拿到ticket 记得写成一个方法 

请求方式

请求URL:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card

请求方法:GET

返回结果

返回结果使用JSON格式,字段如下:

参数类型是否必填描述
errcodeInt是错误码,含义见错误码
errmsgString是错误信息,含义见错误码
ticketString是临时票据,用于在获取授权链接时作为参数传入
expires_inInt是ticket 的有效期,一般为 7200 秒

示例代码

返回:{    "errcode": 0,    "errmsg":"ok",    "ticket":"m7RQzjA_ljjEkt-JCoklRM5zrzYr-6PI09QydZmNXXz-opTqMv53aFj1ykRt_AOtvqidqZZsLhCDgwGC6nBDiA",    "expires_in": 7200}

3.5 获取链接前需要先 设置商户联系方式

请求方式 请求URL:https://api.weixin.qq.com/card/invoice/setbizattr?action=set_contact&access_token={access_token}

请求方法:POST

请求参数使用JSON格式,字段如下:

参数类型是否必填描述
contactObject是联系方式信息

contact是Object,里面包括以下字段:

参数类型是否必填描述
time_outint是开票超时时间
phonestring是联系电话
public static JSONObject setContactInfo(String accessToken, int timeout, String phone) {        try {            String url = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_contact&access_token=" + accessToken;            URL obj = new URL(url);            HttpURLConnection conn = (HttpURLConnection) obj.openConnection();            // 设置请求方法为POST            conn.setRequestMethod("POST");            // 设置请求头            conn.setRequestProperty("Content-Type", "application/json");            // 构造请求参数            String requestBodyJson = "{\"contact\": {\"time_out\": " + timeout + ", \"phone\": \"" + phone + "\"}}";            // 发送POST请求            conn.setDoOutput(true);            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());            wr.writeBytes(requestBodyJson);            wr.flush();            wr.close();            // 读取响应            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));            String inputLine;            StringBuilder response = new StringBuilder();            while ((inputLine = in.readLine()) != null) {                response.append(inputLine);            }            in.close();            // 解析JSON响应            JSONObject result = new JSONObject(response.toString());                        conn.disconnect();            return result;        } catch (Exception e) {            e.printStackTrace();            JSONObject result = new JSONObject();             return result.put("errcode", 1);        }    }

4 获取授权页链接

获取授权页  让用户填写 抬头

根据自己需求选 类型

请求方式

请求URL:https://api.weixin.qq.com/card/invoice/getauthurl?access_token={access_token}

请求方法:POST

请求参数

请求参数使用JSON格式,字段如下:

参数类型是否必填描述
s_pappidString是开票平台在微信的标识号,商户需要找开票平台提供
order_idString是订单id,在商户内单笔开票请求的唯一识别号,
moneyInt是订单金额,以分为单位
timestampInt是时间戳
sourceString是开票来源,app:app开票,web:微信h5开票,wxa:小程序开发票,wap:普通网页开票
redirect_urlString否授权成功后跳转页面。本字段只有在source为H5的时候需要填写,引导用户在微信中进行下一步流程。app开票因为从外部app拉起微信授权页,授权完成后自动回到原来的app,故无需填写。
ticketString是从上一环节中获取
typeInt是授权类型,0:开票授权,1:填写字段开票授权,2:领票授权
/** * 获取授权url */public static JSONObject getAuthURLnew(String source,int money,String order_id,String ticket,String accessToken,String sPappid,int timestamp) throws Exception{if(money == 0 || order_id == null || ticket == null || sPappid==null){JSONObject  errParams = new JSONObject(); errParams.put("errcode",1);return errParams;}int code = sendPostRequest(accessToken);if(code == 1){JSONObject  errParams = new JSONObject(); errParams.put("errcode",1);return errParams;}String auth_url  = "";                  // 准备请求参数          JSONObject requestParams = new JSONObject();          requestParams.put("s_pappid", sPappid);          requestParams.put("order_id", order_id);          requestParams.put("money", money); // 假设订单金额为1元,单位为分          requestParams.put("timestamp", timestamp);          requestParams.put("source", source); // 根据你的需求选择开票来源           // requestParams.put("redirect_url", "YOUR_REDIRECT_URL"); // 如果需要的话          requestParams.put("ticket", ticket);          requestParams.put("type", 1); // 根据你的需求选择授权类型                                  // 发送POST请求到微信API          String apiUrl = "https://api.weixin.qq.com/card/invoice/getauthurl?access_token=" + accessToken;          URL url = new URL(apiUrl);          HttpURLConnection connection = (HttpURLConnection) url.openConnection();          connection.setRequestMethod("POST");          connection.setRequestProperty("Content-Type", "application/json; utf-8");          connection.setRequestProperty("Accept", "application/json");          connection.setDoOutput(true);            try (OutputStream os = connection.getOutputStream()) {              byte[] input = requestParams.toString().getBytes("utf-8");              os.write(input, 0, input.length);          }            try (BufferedReader br = new BufferedReader(                  new InputStreamReader(connection.getInputStream(), "utf-8"))) {              StringBuilder response = new StringBuilder();              String responseLine;              while ((responseLine = br.readLine()) != null) {                  response.append(responseLine.trim());              }         // 将JSON字符串转换为JSONObject              JSONObject data = new JSONObject(response.toString());          // 从JSONObject中获取auth_url的值              auth_url = data.getString("auth_url");              connection.disconnect();              return data;                      }  }

5 小程序打开授权页

小程序返回的数据是这样的

我们只需要 把返回的auth_url 和appid 换上去就行了代码下面

这是在微信开发者工具 你们逻辑哪个地方该打开这个授权页  就写在哪哦

wx.navigateToMiniProgram({    appId: '{appid}',    path: '{auth_url}',    success(res) {        console.log('navigateToMiniProgram success:', res)    },    fail(error){        console.log('navigateToMiniProgram fail:', error)    },    complete(res){        console.log('navigateToMiniProgram complete:', res)    }})

6 收取授权完成事件推送

在用户授权同意发票存入自己微信账户后,商户可以收到授权完成的状态推送。收到推送后,可以将order_id连同开票信息一并发送给开票平台,以便开票平台在开票成功后将电子发票插入用户卡包。

该事件将发送至开发者填写的URL(登录公众平台进入【开发者中心设置】,如果是open账号,也得用公众号账号来接,参考下图)。

这个你要去那里设置回调地址 接收那边的回调带给你个 订单id 然后可以通过这个id去查用户收钱填写的信息

我是这样处理的 回调地址是你们上面设置的 

           if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {

                // 事件类型

                String eventType = eventMessage.getEvent();    

                // 收取授权完成事件推送

                if (eventType.equals(MessageUtil.USER_AUTHORIZE_INVOICE)) {

                    //授权成功的ID

                    Invoice invoice = new Invoice();

                    String succOrderId = eventMessage.getSuccOrderId();    

                    if(succOrderId!=null || succOrderId != ""){

                        invoice.getAuthdata(succOrderId);

                    }

                }

7 查询授权完成状态

上面进入的你回调之后

请求方式

请求URL:https://api.weixin.qq.com/card/invoice/getauthdata?access_token={access_token}

请求方法:POST

请求参数

请求参数使用JSON格式,字段如下:

参数类型是否必填描述
order_idstring是发票order_id
s_pappidString是开票平台在微信的标识,由开票平台告知商户
// 查询授权完成状态    @SuppressWarnings("unused")public static JSONObject callGetAuthDataAPI(String accessToken, String orderId, String sPappid) throws Exception {      String API_URL = "https://api.weixin.qq.com/card/invoice/getauthdata?access_token=%s";    String apiUrl = String.format(API_URL, accessToken);          URL url = new URL(apiUrl);          HttpURLConnection connection = (HttpURLConnection) url.openConnection();          connection.setRequestMethod("POST");          connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");          connection.setRequestProperty("Accept", "application/json");          connection.setDoOutput(true);            JSONObject requestBody = new JSONObject();          requestBody.put("order_id", orderId);          requestBody.put("s_pappid", sPappid);            try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {              byte[] input = requestBody.toString().getBytes("utf-8");              os.write(input, 0, input.length);          }            try (BufferedReader br = new BufferedReader(                  new InputStreamReader(connection.getInputStream(), "utf-8"))) {              StringBuilder response = new StringBuilder();              String responseLine;              while ((responseLine = br.readLine()) != null) {                  response.append(responseLine.trim());              }              JSONObject result = new JSONObject(response.toString());             return result;          }      }

 查询出来的的数据 自己记得插入数据库对应开票订单的信息

8 创建发票卡券模板

只需创建一次 把卡劵id card_id 存起来哈

返回:{"errcode": 0,"errmsg": "ok","card_id": "pjZ8Yt9WoOePThU0NfUKz5-tBEWU"}

请求方式

请求URL:https://api.weixin.qq.com/card/invoice/platform/createcard?access_token={access_token}

请求方法:POST

请求参数

请求参数使用JSON格式,字段如下:

参数类型是否必填描述
invoice_infoObject是发票模板对象

invoice_info为Object,里面包括以下字段:

参数类型是否必填描述
base_infoobject是发票卡券模板基础信息
payeestring是收款方(开票方)全称,显示在发票详情内。故建议一个收款方对应一个发票卡券模板
typestring是发票类型

base_info为Object,里面包括以下字段:

参数类型是否必填描述
logo_urlstring是发票商家 LOGO ,请参考 新增永久素材
titlestring是收款方(显示在列表),上限为 9 个汉字,建议填入商户简称
custom_url_namestring否开票平台自定义入口名称,与 custom_url 字段共同使用,长度限制在 5 个汉字内
custom_urlstring否开票平台自定义入口跳转外链的地址链接 , 发票外跳的链接会带有发票参数,用于标识是从哪张发票跳出的链接
custom_url_sub_titlestring否显示在入口右侧的 tips ,长度限制在 6 个汉字内
promotion_url_namestring否营销场景的自定义入口
promotion_urlstring否入口跳转外链的地址链接,发票外跳的链接会带有发票参数,用于标识是从那张发票跳出的链接
promotion_url_sub_titlestring否显示在入口右侧的 tips ,长度限制在 6 个汉字内
 //创建发票卡劵模板    public static JSONObject createInvoiceCardTemplate(String accessToken, JSONObject invoiceInfo) throws Exception {          String url = "https://api.weixin.qq.com/card/invoice/platform/createcard?access_token="+accessToken;         URL obj = new URL(url);          HttpURLConnection con = (HttpURLConnection) obj.openConnection();                    // 设置请求方法          con.setRequestMethod("POST");                    // 设置请求头          con.setRequestProperty("Content-Type", "application/json; utf-8");          con.setRequestProperty("Accept", "application/json");          con.setDoOutput(true);                    // 构建请求体          String jsonInputString = invoiceInfo.toString();                    try (OutputStream os = con.getOutputStream()) {              byte[] input = jsonInputString.getBytes("utf-8");              os.write(input, 0, input.length);          }                   try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))) {              StringBuilder response = new StringBuilder();              String responseLine;              while ((responseLine = br.readLine()) != null) {                  response.append(responseLine.trim());              }              JSONObject result = new JSONObject(response.toString());            int errcode = (int) result.get("errcode");            if (errcode == 0) {                return result;            } else {            JSONObject result1 = new JSONObject();             return result1.put("errcode",1);            }        }      }  

 9 上传PDF

这里把财务开好的PDF发票文件  我这里写了一个pdf文件识别 拿到了对应的抬头信息

记得把返回的s_media_id在数据库对应订单存起来

返回:{"errcode":0,    "errmsg":"ok",    "s_media_id":"3015806758683707"}

请求方式

请求URL:https://api.weixin.qq.com/card/invoice/platform/setpdf?access_token={access_token}

请求方法:POST

请求参数

数据格式使用multipart/form-data,参数清单如下:

参数是否必填描述
pdf是

form-data中媒体文件标识,有filename、filelength、content-type等信息

//上传发票public static JSONObject uploadPDF(File file,String access_token,String invoiceName){JSONObject objectData = extractInvoiceNumber(file);int code = (int)objectData.get("errcode");JSONObject  errParams = new JSONObject(); if(code==1){errParams.put("errcode",1);errParams.put("errmsg","PDF文件解析失败");    return errParams;}if(!invoiceName.equals(objectData.get("companyName"))){errParams.put("errcode",1);errParams.put("errmsg","发票抬头与学生需开不一致");    return errParams;}String urlString = "https://api.weixin.qq.com/card/invoice/platform/setpdf?access_token="+access_token;  URL url;          try {              url = new URL(urlString);              HttpURLConnection conn = (HttpURLConnection) url.openConnection();              conn.setRequestMethod("POST");              conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");              conn.setDoOutput(true);              conn.setDoInput(true);              conn.setUseCaches(false);                // 获取输出流              OutputStream os = (OutputStream) conn.getOutputStream();                // 写入multipart/form-data的边界              String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";              os.write(("--" + boundary + "\r\n").getBytes());                // 写入文件表单字段              String formFieldName = "pdf";              String fileName = file.getName();              String contentType = Files.probeContentType(file.toPath());              String contentDisposition = "Content-Disposition: form-data; name=\"" + formFieldName + "\"; filename=\"" + fileName + "\"\r\n";              os.write(contentDisposition.getBytes());              os.write(("Content-Type: " + contentType + "\r\n\r\n").getBytes());                // 写入文件内容              Files.copy(file.toPath(), os);                // 写入multipart/form-data的结束边界              os.write(("\r\n--" + boundary + "--\r\n").getBytes());                // 刷新输出流              os.flush();              os.close();                // 获取响应              int responseCode = conn.getResponseCode();              if (responseCode == HttpURLConnection.HTTP_OK) {              BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));                  StringBuilder response = new StringBuilder();                  String line;                  while ((line = br.readLine()) != null) {                      response.append(line);                  }                  br.close();                  // 处理响应数据                  // 将JSON字符串转换为JSONObject                  JSONObject data = new JSONObject(response.toString());                 // 从JSONObject中获取auth_url的值                  int errcode = (int)data.get("errcode");                  if(errcode!=0){            errParams.put("errcode",1);            errParams.put("errmsg","PDF文件上传失败");            return errParams;                }                String sMediaId = data.getString("s_media_id");                if(sMediaId==null || sMediaId==""){            errParams.put("errcode",1);            errParams.put("errmsg","PDF文件上传失败");            return errParams;                }        errParams.put("errcode",0);        errParams.put("sMediaId",sMediaId);        return errParams;            } else {                  // 处理错误          errParams.put("errcode",1);        errParams.put("errmsg","PDF文件上传失败");        return errParams;            }          } catch (Exception e) {          // TODO Auto-generated catch block    errParams.put("errcode",1);    return errParams;        }  }

PDF发票文件识别信息工具方法   使用的正则表达式 

public static JSONObject extractInvoiceNumber(File file) { JSONObject ObjectData = new JSONObject();        try {//            File file = new File("D:\fp1.pdf");            PDDocument document = PDDocument.load(file);            PDFTextStripper pdfStripper = new PDFTextStripper();            pdfStripper.setSortByPosition(true);            String text = pdfStripper.getText(document);            System.out.println(text);            document.close();            int fee = 0; //发票的金额,以分为单位            String billingNo = ""; //发票号码            String billingCode = ""; //发票代码            int feeWithoutTax = 0;//不含税金额,以分为单位            int tax = 0; //税额,以分为单位            int billingTime = 0;  //发票的开票时间,为10位时间戳(utc+8)            String checkCode = ""; //校验码,发票pdf右上角,开票日期下的校验码;数电发票发票校验码为空            String companyName = ""; //发票抬头            Pattern pattern = Pattern.compile("发票号码:\s*(\d+)");            Matcher matcher = pattern.matcher(text);            List companyList = new ArrayList();            companyList.add("发票号码:\s*(\d+)");            companyList.add("发票号码:(\d+)");            // 查找匹配的发票号码            for (String patternName : companyList) {                // 使用正则表达式进行匹配                pattern = Pattern.compile(patternName);                matcher = pattern.matcher(text);                if (matcher.find()){                    billingNo = matcher.group(1);                    System.out.println("发票号码:"+billingNo);                    break;                }            }            if (billingNo.equals("")){                System.out.println("未找到发票抬头");            }            companyList.clear();            companyList.add("购 名称:(.*?) ");            companyList.add("名                   称: (.*?)\s");            companyList.add("        名        称: (.*?)\s");            companyList.add("买 名称:(.*?) ");            // 查找匹配的发票抬头            for (String patternName : companyList) {                // 使用正则表达式进行匹配                pattern = Pattern.compile(patternName);                matcher = pattern.matcher(text);                if (matcher.find()){                    companyName  = matcher.group(1);                    System.out.println("提取的发票抬头为:" + companyName);                    break;                }            }            if (companyName.equals("")){                System.out.println("未找到发票抬头");            }            companyList.clear();            companyList.add("(小写)¥(\d+\.\d{2})");            companyList.add(" \(小写\) ¥\s*(\d+\.\d{2})");            companyList.add("(小写)¥\s*(\d+(\.\d+)?)");            // 查找匹配的发票金额            for (String patternName : companyList) {                // 使用正则表达式进行匹配                pattern = Pattern.compile(patternName);                matcher = pattern.matcher(text);                if (matcher.find()){                    String invoiceNumber = matcher.group(1);                    Double  number = Double.parseDouble(invoiceNumber);                    number = number * 100;                    fee = (int) number.doubleValue();                    System.out.println("提取的发票金额为:" + fee);                    break;                }            }            if (fee==0){                System.out.println("未找到发票金额");            }            companyList.clear();            companyList.add("合 计 ¥(\d+\.\d{2})\s*¥(\d+\.\d{2})");            companyList.add("合        计 ¥(\d+\.\d{2})\s*¥(\d+\.\d{2})");            companyList.add("合       计 ¥(\d+\.\d{2})\s*¥(\d+\.\d{2})");            // 查找匹配的不含税金额            for (String patternName : companyList) {                // 使用正则表达式进行匹配                pattern = Pattern.compile(patternName);                matcher = pattern.matcher(text);                if (matcher.find()){                    String invoiceNumber = matcher.group(1);                    Double  number = Double.parseDouble(invoiceNumber);                    number = number * 100;                    feeWithoutTax = (int) number.doubleValue();                    System.out.println("提取的不含税金额为:" + feeWithoutTax);                    break;                }            }            if (feeWithoutTax==0){                System.out.println("未找到不含税金额");            }            companyList.clear();            companyList.add("合\s*计\s*¥\d+(\.\d+)?\s*¥(\d+(\.\d+)?)");            // 查找匹配的税金额            for (String patternName : companyList) {                // 使用正则表达式进行匹配                pattern = Pattern.compile(patternName);                matcher = pattern.matcher(text);                if (matcher.find()){                    String invoiceNumber = matcher.group(2);                    Double  number = Double.parseDouble(invoiceNumber);                    number = number * 100;                    tax = (int) number.doubleValue();                    System.out.println("提取的税金额为:" + tax);                    break;                }            }            if (tax==0){                System.out.println("未找到税金额");            }            if (text.contains("发票代码")) {                companyList.clear();                companyList.add("发票代码:\s*(\d+)");                companyList.add("发票代码:(\d+)");                // 查找匹配的发票代码                for (String patternName : companyList) {                    // 使用正则表达式进行匹配                    pattern = Pattern.compile(patternName);                    matcher = pattern.matcher(text);                    if (matcher.find()) {                        billingCode = matcher.group(1);                        System.out.println("提取的发票代码为:" + billingCode);                        break;                    }                }                if (billingCode.equals("")) {                    System.out.println("未找到发票代码");                }            }else{                System.out.println("未找到发票代码");            }                companyList.clear();                companyList.add("校  验   码:\s*(\d+(\s+\d+)*)");                companyList.add("校 验 码:\s*(\d+(?:\s+\d+)*)");                // 查找匹配的校  验   码                for (String patternName : companyList) {                    // 使用正则表达式进行匹配                    pattern = Pattern.compile(patternName);                    matcher = pattern.matcher(text);                    if (matcher.find()) {                        checkCode = matcher.group(1);                        System.out.println("提取的校  验   码为:" + checkCode);                        break;                    }                }                if (checkCode.equals("")) {                    System.out.println("未找到校  验   码");                }            if (text.contains("开票日期")) {                companyList.clear();                companyList.add("开票日期:\s*(\d{4})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*日");                companyList.add("开票日期:(\d{4})年(\d{1,2})月(\d{1,2})日");                // 查找匹配的校  验   码                for (String patternName : companyList) {                    // 使用正则表达式进行匹配                    pattern = Pattern.compile(patternName);                    matcher = pattern.matcher(text);                    if (matcher.find()) {                        // 提取年份、月份和日期                        String year = matcher.group(1);                        String month = matcher.group(2);                        String day = matcher.group(3);                        // 组合成完整的日期字符串(如果需要特定格式,可以在这里进行格式化)                        String invoiceDate = year + "年" + month + "月" + day+"日";                        billingTime = format(invoiceDate);                        System.out.println("提取的开票日期为:" + invoiceDate);                        break;                    }                }                if (billingTime==0) {                    System.out.println("未找到开票日期");                }            }else{                System.out.println("未找到开票日期");            }            ObjectData.put("errcode",0);            ObjectData.put("fee",fee);            ObjectData.put("billingNo",billingNo);            ObjectData.put("billingCode",billingCode);            ObjectData.put("feeWithoutTax",feeWithoutTax);            ObjectData.put("tax",tax);            ObjectData.put("billingTime",billingTime);            ObjectData.put("checkCode",checkCode);            ObjectData.put("companyName",companyName);            return ObjectData;        } catch (Exception e) {        ObjectData.put("errcode",1);        return ObjectData;        }    }//时间单位转换public static int format(String dateString) {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); // 设置时区为GMT+8        try {            Date date = sdf.parse(dateString);            return (int) (date.getTime() / 1000); // 转换为以秒为单位的时间戳        } catch (Exception e) {            return 1;        }    }

10 将电子发票卡券插入用户卡包

请求方式

请求URL:https://api.weixin.qq.com/card/invoice/insert?access_token={access_token}

请求方法:POST

请求参数

请求参数使用JSON格式,字段如下:

参数类型是否必填描述
order_idstring是发票order_id,既商户给用户授权开票的订单号
card_idString是发票card_id
appidString是该订单号授权时使用的appid,一般为商户appid
card_extObject是发票具体内容

card_ext为Object,包括以下内容:

参数类型是否必填描述
nonce_strString是随机字符串,防止重复
user_cardObject是用户信息结构体

user_card中包含一个invoice_user_data对象,invoice_user_data包含以下内容:

参数类型是否必填描述
feeInt是发票的金额,以分为单位
titleString是发票的抬头
billing_timeInt是发票的开票时间,为10位时间戳(utc+8)
billing_noString是发票的发票号码;数电发票传20位发票号码
billing_codeString是发票的发票代码;数电发票发票代码为空
infoList否商品详情结构,见下方
fee_without_taxInt是不含税金额,以分为单位
taxInt是税额,以分为单位
s_pdf_media_idString是发票pdf文件上传到微信发票平台后,会生成一个发票s_media_id,该s_media_id可以直接用于关联发票PDF和发票卡券。发票上传参考“ 3 上传PDF ”一节
s_trip_pdf_media_idString否其它消费附件的PDF,如行程单、水单等,PDF上传方式参考“ 3 上传PDF ”一节
check_codeString是校验码,发票pdf右上角,开票日期下的校验码;数电发票发票校验码为空
buyer_numberString否购买方纳税人识别号
buyer_address_and_phoneString否购买方地址、电话
buyer_bank_accountString否购买方开户行及账号
seller_numberString否销售方纳税人识别号
seller_address_and_phoneString否销售方地址、电话
seller_bank_accountString否销售方开户行及账号
remarksString否备注,发票右下角初
cashierString否收款人,发票左下角处
makerString否开票人,发票下方处

info为Object列表,列表中每个Object包含以下信息:

参数类型是否必填描述
nameString是项目的名称
numInt否项目的数量
unitString否项目的单位,如个
priceInt是项目的单价
//将电子发票卡券插入用户卡包public static JSONObject pushCoupons(String invoiceName,String sMediaId,String accessToken,String orderId,File file,String cardId) {  JSONObject  errParams = new JSONObject(); try{JSONObject objectData = extractInvoiceNumber(file);            //String sMediaId = element.getChildText("s_media_id");////String invoiceName=element.getChildText("invoice_name");String apiUrl = "https://api.weixin.qq.com/card/invoice/insert?access_token="+accessToken;JSONObject jsonParams = new JSONObject();JSONObject cardExt = new JSONObject();JSONObject userCard = new JSONObject();JSONObject invoiceUserData = new JSONObject();//List infoList = new ArrayList();//JSONObject info = new JSONObject();UUID uuid=UUID.randomUUID();invoiceUserData.put("fee", objectData.getInt("fee"));invoiceUserData.put("title", invoiceName);invoiceUserData.put("billing_time", objectData.getInt("billingTime"));invoiceUserData.put("billing_no", objectData.get("billingNo"));invoiceUserData.put("billing_code", objectData.get("billingCode"));invoiceUserData.put("fee_without_tax", objectData.getInt("feeWithoutTax"));invoiceUserData.put("tax", objectData.getInt("tax"));invoiceUserData.put("s_pdf_media_id", sMediaId);invoiceUserData.put("check_code", objectData.get("checkCode"));userCard.put("invoice_user_data", invoiceUserData);cardExt.put("nonce_str",uuid);cardExt.put("user_card", userCard);jsonParams.put("order_id", orderId);jsonParams.put("card_ext", cardExt);jsonParams.put("card_id", cardId);  //模板idjsonParams.put("appid", "wxb92aeb7a8c2089e5");          // 创建连接 URL url = new URL(apiUrl);       HttpURLConnection connection = (HttpURLConnection) url.openConnection();       connection.setRequestMethod("POST");       connection.setRequestProperty("Content-Type", "application/json; utf-8");       connection.setRequestProperty("Accept", "application/json");       connection.setDoOutput(true);          // 写入请求数据     try (OutputStream os = connection.getOutputStream()) {              byte[] input = jsonParams.toString().getBytes("utf-8");              os.write(input, 0, input.length);       }          // 读取响应     try (BufferedReader br = new BufferedReader(                  new InputStreamReader(connection.getInputStream(), "utf-8"))) {              StringBuilder response = new StringBuilder();              String responseLine;              while ((responseLine = br.readLine()) != null) {                  response.append(responseLine.trim());              }         // 将JSON字符串转换为JSONObject              JSONObject data = new JSONObject(response.toString());             connection.disconnect();              return data;                   }       }catch(Exception e){errParams.put("errcode",1);return errParams;}           } 

这样一套流程下来  就把发票插入到 对应的授权人的 微信卡包里啦

然后对应人公众号会收到一个收到发票的信息

创作不易 有问题可以留言 

上一篇:ExtJS 4源码深度探索,揭示前端框架的神秘面纱

下一篇:宝塔面板故障快速应对指南,轻松解决,保障运行无阻!