Explorar o código

fix: 根据微信支付 v3 文档全面校正发票申请单请求体

- 移除不在文档中的字段:unit_price, amount, tax_amount, invoice_type
- 补上 Wechatpay-Serial 请求头
- 方法签名 cleanup,移除不再需要的参数

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
skyline hai 2 días
pai
achega
ad8b9a95be

+ 1 - 1
service/src/main/java/com/kym/service/miniapp/HuapiaoerInvoiceService.java

@@ -136,7 +136,7 @@ public class HuapiaoerInvoiceService {
             return;
         }
 
-        boolean success = wechatPayFapiaoService.insertToCard(invoice, result, properties.getNsrsbh());
+        boolean success = wechatPayFapiaoService.insertToCard(invoice);
 
         if (success) {
             try {

+ 15 - 24
service/src/main/java/com/kym/service/wechat/impl/WechatPayFapiaoService.java

@@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.kym.entity.miniapp.Invoice;
 import com.kym.entity.wechat.InvoiceOrderDetail;
-import com.kym.huapiaoer.model.response.InvoiceInfo;
 import com.wechat.pay.java.core.http.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -14,7 +13,10 @@ import java.util.HashMap;
 import java.util.List;
 
 /**
- * 通过微信支付 v3 电子发票 API 将航信发票插入用户微信卡包
+ * 通过微信支付 v3 电子发票 API 将航信发票插入用户微信卡包。
+ *
+ * @see <a href="https://pay.wechatpay.cn/doc/v3/merchant/4012538301">创建发票申请单</a>
+ * @see <a href="https://pay.wechatpay.cn/doc/v3/merchant/4012538365">插入卡包</a>
  */
 @Service
 @Slf4j
@@ -23,6 +25,8 @@ public class WechatPayFapiaoService {
     private static final String API_BASE = "https://api.mch.weixin.qq.com";
     private static final String CREATE_APPLICATION = "/v3/new-tax-control-fapiao/fapiao-applications";
     private static final String INSERT_CARD = "/v3/new-tax-control-fapiao/fapiao-applications/%s/card";
+    /** 商户证书序列号 */
+    private static final String MCH_SERIAL = "6A45EEB068369430B2FFD45EA29F641A8E18165F";
 
     private static final HttpHeaders JSON_HEADERS;
 
@@ -30,6 +34,7 @@ public class WechatPayFapiaoService {
         JSON_HEADERS = new HttpHeaders();
         JSON_HEADERS.addHeader("Accept", "application/json");
         JSON_HEADERS.addHeader("Content-Type", "application/json");
+        JSON_HEADERS.addHeader("Wechatpay-Serial", MCH_SERIAL);
     }
 
     /**
@@ -38,7 +43,7 @@ public class WechatPayFapiaoService {
      *
      * @return true 表示调用成功
      */
-    public boolean insertToCard(Invoice invoice, InvoiceInfo invoiceInfo, String sellerTaxId) {
+    public boolean insertToCard(Invoice invoice) {
         if (invoice.getOpenid() == null || invoice.getOpenid().isBlank()) {
             log.info("用户无 openid,跳过卡包插入, applyId:{}", invoice.getApplyId());
             return false;
@@ -46,7 +51,7 @@ public class WechatPayFapiaoService {
 
         try {
             // Step 1: 创建发票申请单
-            var appReq = buildApplicationRequest(invoice, invoiceInfo, sellerTaxId);
+            var appReq = buildApplicationRequest(invoice);
             log.info("创建微信发票申请单, applyId:{}, body:{}", invoice.getApplyId(), JSON.toJSONString(appReq));
 
             HttpResponse<JSONObject> appResp = WxPayServiceImpl.wxHttpClient.post(
@@ -80,7 +85,7 @@ public class WechatPayFapiaoService {
         }
     }
 
-    private HashMap<String, Object> buildApplicationRequest(Invoice invoice, InvoiceInfo result, String sellerTaxId) {
+    private HashMap<String, Object> buildApplicationRequest(Invoice invoice) {
         var orderDetails = invoice.getOrderDetails();
         int elecMoney = orderDetails.stream().mapToInt(InvoiceOrderDetail::getElecMoney).sum();
         int serviceMoney = orderDetails.stream().mapToInt(InvoiceOrderDetail::getServiceMoney).sum();
@@ -89,30 +94,20 @@ public class WechatPayFapiaoService {
 
         var items = new ArrayList<HashMap<String, Object>>();
         int totalAmount = 0;
-        int totalTax = 0;
 
         if (elecMoney > 0) {
-            int amt = elecMoney;
-            int tax = amt - (int) Math.round(amt / 1.13);
-            items.add(buildItem("充电电费", amt, tax, "1100101020200000000", 1300));
-            totalAmount += amt;
-            totalTax += tax;
+            items.add(buildItem("充电电费", elecMoney, "1100101020200000000", 1300));
+            totalAmount += elecMoney;
         }
         if (netServiceMoney > 0) {
-            int amt = netServiceMoney;
-            int tax = amt - (int) Math.round(amt / 1.13);
-            items.add(buildItem("充电服务费", amt, tax, "1100101020200000000", 1300));
-            totalAmount += amt;
-            totalTax += tax;
+            items.add(buildItem("充电服务费", netServiceMoney, "1100101020200000000", 1300));
+            totalAmount += netServiceMoney;
         }
 
         var fapiaoInfo = new HashMap<String, Object>();
         fapiaoInfo.put("fapiao_id", invoice.getApplyId());
         fapiaoInfo.put("total_amount", totalAmount);
-        fapiaoInfo.put("tax_amount", totalTax);
-        fapiaoInfo.put("amount", totalAmount - totalTax);
         fapiaoInfo.put("items", items);
-        fapiaoInfo.put("invoice_type", "082");
         if (invoice.getRemark() != null && !invoice.getRemark().isBlank()) {
             fapiaoInfo.put("remark", invoice.getRemark());
         }
@@ -133,15 +128,11 @@ public class WechatPayFapiaoService {
         return req;
     }
 
-    private HashMap<String, Object> buildItem(String name, int totalAmount, int taxAmount, String taxCode, int taxRate) {
-        int amount = totalAmount - taxAmount;
+    private HashMap<String, Object> buildItem(String name, int totalAmount, String taxCode, int taxRate) {
         var item = new HashMap<String, Object>();
         item.put("tax_code", taxCode);
         item.put("goods_name", name);
         item.put("quantity", 100000000);
-        item.put("unit_price", (long) totalAmount * 10000L);
-        item.put("amount", amount);
-        item.put("tax_amount", taxAmount);
         item.put("total_amount", totalAmount);
         item.put("tax_rate", taxRate);
         item.put("tax_prefer_mark", "NO_FAVORABLE");