|
|
@@ -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");
|