|
|
@@ -13,11 +13,10 @@ import com.kym.common.config.WxPayConfig;
|
|
|
import com.kym.common.constant.ResponseEnum;
|
|
|
import com.kym.common.exception.BusinessException;
|
|
|
import com.kym.common.utils.CommUtil;
|
|
|
-import com.kym.common.utils.HttpUtil;
|
|
|
import com.kym.common.utils.LambadaTools;
|
|
|
import com.kym.common.utils.OrderUtils;
|
|
|
-import com.kym.entity.miniapp.*;
|
|
|
import com.kym.entity.miniapp.Account;
|
|
|
+import com.kym.entity.miniapp.*;
|
|
|
import com.kym.entity.wechat.*;
|
|
|
import com.kym.service.miniapp.*;
|
|
|
import com.kym.service.wechat.WxPayService;
|
|
|
@@ -54,10 +53,8 @@ import java.io.IOException;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
-import java.util.stream.Stream;
|
|
|
|
|
|
|
|
|
/**
|
|
|
@@ -557,9 +554,9 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
/**
|
|
|
* 申请发票
|
|
|
*/
|
|
|
-
|
|
|
+ @Override
|
|
|
public void applyInvoice(String invoiceId) {
|
|
|
- var invoice = invoiceService.lambdaQuery().eq(Invoice::getId,invoiceId).one();
|
|
|
+ var invoice = invoiceService.lambdaQuery().eq(Invoice::getId, invoiceId).one();
|
|
|
// 电费 税务商品编码:1100101020000000000
|
|
|
var elecMoney = invoice.getOrderDetails().stream().mapToInt(InvoiceOrderDetail::getElecMoney).sum();
|
|
|
var elecMoneyItem = new FaPiao.FaPiaoInfomation.IssueItem().setTotalAmount(elecMoney).setTaxCode("1100101020000000000");
|
|
|
@@ -574,6 +571,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
|
|
|
// 发票申请单号
|
|
|
var fapiaoApplyId = OrderUtils.getOrderNo();
|
|
|
+ invoiceService.lambdaUpdate().set(Invoice::getApplyId, fapiaoApplyId).eq(Invoice::getId, invoiceId).update();
|
|
|
|
|
|
// 客户开票信息
|
|
|
var buyerInformation = new FaPiao.BuyerInformation()
|
|
|
@@ -587,9 +585,10 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
|
|
|
// 发票信息
|
|
|
var fapiaoInformation = new FaPiao.FaPiaoInfomation();
|
|
|
+ // fapiao_id为invoice.id
|
|
|
fapiaoInformation.setFapiao_id(String.valueOf(invoice.getId()))
|
|
|
.setTotal_amount(invoice.getInvoiceAmount())
|
|
|
- .setItems(List.of(elecMoneyItem,serviceMoneyItem));
|
|
|
+ .setItems(List.of(elecMoneyItem, serviceMoneyItem));
|
|
|
|
|
|
// 请求参数
|
|
|
var fapiao = new FaPiao()
|
|
|
@@ -599,7 +598,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
.setFapiao_information(List.of(fapiaoInformation));
|
|
|
|
|
|
var requestBody = new JsonRequestBody.Builder().body(JSONObject.toJSONString(fapiao)).build();
|
|
|
- wxHttpClient.post(headers, fapiaoConfig.getFapiaoApplications(), requestBody,null);
|
|
|
+ wxHttpClient.post(headers, fapiaoConfig.getFapiaoApplications(), requestBody, null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -608,13 +607,20 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
* @param request
|
|
|
* @return
|
|
|
*/
|
|
|
- void wxInvoiceNotify(HttpServletRequest request) {
|
|
|
+ @Override
|
|
|
+ public void wxInvoiceNotify(HttpServletRequest request) {
|
|
|
var notifyRes = handleWxNotify(request);
|
|
|
try {
|
|
|
InvoiceNotification invoiceNotification = ((NotificationParser) notifyRes[1]).parse((RequestParam) notifyRes[0], InvoiceNotification.class);
|
|
|
LOGGER.info("微信开具发票结果通知回调{}:验签解密完毕,数据:\n{}", notifyRes[2], invoiceNotification);
|
|
|
- // TODO: 2023-09-17 业务逻辑
|
|
|
+ // 业务逻辑
|
|
|
+ if (invoiceNotification.getFapiaoInformation().get(0).getFapiaoStatus().equals(InvoiceNotification.FapiaoStatus.ISSUED)) {
|
|
|
+ // 更新发票状态
|
|
|
+ invoiceService.lambdaUpdate().set(Invoice::getStatus, Invoice.STATUS_已开票).eq(Invoice::getApplyId, invoiceNotification.getFapiaoApplyId()).update();
|
|
|
|
|
|
+ } else {
|
|
|
+ LOGGER.error("微信开具发票失败:{}", invoiceNotification);
|
|
|
+ }
|
|
|
} catch (ValidationException e) {
|
|
|
// 签名验证失败,返回 401 UNAUTHORIZED 状态码
|
|
|
LOGGER.error("微信开具发票结果通知验签失败", e);
|
|
|
@@ -622,5 +628,63 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 微信电子发票配置开发选项,例如回调地址、全部账单展示开发票入口开关
|
|
|
+ */
|
|
|
+ void devConfig() {
|
|
|
+ var headers = new HttpHeaders();
|
|
|
+ headers.addHeader("Accept", "application/json");
|
|
|
+ headers.addHeader("Content-Type", "application/json");
|
|
|
+
|
|
|
+ var params = """
|
|
|
+ {
|
|
|
+ "callback_url" : %s,
|
|
|
+ "show_fapiao_cell" : false
|
|
|
+ }
|
|
|
+ """.stripIndent().formatted(fapiaoConfig.getNotifyUrl());
|
|
|
+ var requestBody = new JsonRequestBody.Builder().body(params).build();
|
|
|
+ var res = wxHttpClient.patch(headers, fapiaoConfig.getDevConfig(), requestBody, JSONObject.class);
|
|
|
+ LOGGER.info("微信电子发票开发设置:{}", res.toString());
|
|
|
+ // TODO: 2023-10-07 业务逻辑
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: 2023-10-07 下载发票
|
|
|
+ void downloadInvoice(String invoiceId) {
|
|
|
+ var invoice = invoiceService.getById(invoiceId);
|
|
|
+ // TODO: 2023-10-07 查询发票下载信息,下载链接30s有效
|
|
|
+ var download = getFapiaoDownloadInfo(invoice.getApplyId());
|
|
|
+ var downloadInfo = download.getFapiao_download_info_list().get(0);
|
|
|
+ var params = "?token=%s&mchid=%s&openid=%s&invoice_code=%s&invoice_no=%s&fapiao_id=%s";
|
|
|
+ var inputStream = wxHttpClient.download(downloadInfo.getDownload_url().concat(params.formatted("", conf.getMchid(), "", "", "", invoice.getId())));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取发票下载信息
|
|
|
+ *
|
|
|
+ * @param applyId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private FapiaoDownload getFapiaoDownloadInfo(String applyId) {
|
|
|
+ var downloadUrl = fapiaoConfig.getFapiaoFiles().formatted(applyId);
|
|
|
+ var headers = new HttpHeaders();
|
|
|
+ headers.addHeader("Accept", "application/json");
|
|
|
+ var res = wxHttpClient.get(headers, downloadUrl, FapiaoDownload.class);
|
|
|
+ return res.getServiceResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询电子发票
|
|
|
+ *
|
|
|
+ * @param applyId
|
|
|
+ */
|
|
|
+ private FapiaoApplications queryFapiao(String applyId) {
|
|
|
+ var headers = new HttpHeaders();
|
|
|
+ headers.addHeader("Accept", "application/json");
|
|
|
+ headers.addHeader("Content-Type", "application/json");
|
|
|
+ var res = wxHttpClient.get(headers, fapiaoConfig.getQueryFapiao().formatted(applyId), FapiaoApplications.class);
|
|
|
+ return res.getServiceResponse();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
}
|