|
|
@@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
|
|
import cn.hutool.core.io.IoUtil;
|
|
|
import cn.hutool.core.util.RandomUtil;
|
|
|
+import cn.hutool.core.util.URLUtil;
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
import com.kym.common.config.WxFapiaoConfig;
|
|
|
@@ -54,6 +55,7 @@ import java.nio.charset.StandardCharsets;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
|
|
|
@@ -526,6 +528,85 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //================================================================发票=====================================================================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户抬头信息填写URL
|
|
|
+ *
|
|
|
+ * @param invoice
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public TitleUrl titleUrl(Invoice invoice) {
|
|
|
+ var headers = new HttpHeaders();
|
|
|
+ var params = Map.of(
|
|
|
+ "fapiao_apply_id", invoice.getApplyId(),
|
|
|
+ "appid", conf.getAppid(),
|
|
|
+ "openid", invoice.getOpenid(),
|
|
|
+ "total_amount", invoice.getTotalMoney(),
|
|
|
+ "source", "MINIPROGRAM"
|
|
|
+ );
|
|
|
+ headers.addHeader("Accept", "application/json");
|
|
|
+ var res = wxHttpClient.get(headers, fapiaoConfig.getTitleUrl().concat(URLUtil.buildQuery(params, StandardCharsets.UTF_8)), TitleUrl.class);
|
|
|
+ return res.getServiceResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理发票抬头填写完成通知
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void titleWriteNotice(HttpServletRequest request) {
|
|
|
+ var notifyRes = handleWxNotify(request);
|
|
|
+ try {
|
|
|
+ // TODO: 2023-10-12 步骤 用户选择开票的订单,确定(数据库插入invoice数据)进入抬头填写页面,输入抬头确定开票,收到抬头填写完成通知后
|
|
|
+ // 再获取用户抬头更新invoice抬头数据。后台审核人员进行开票操作
|
|
|
+ TitleWriteNotification titleWriteNotification = ((NotificationParser) notifyRes[1]).parse((RequestParam) notifyRes[0], TitleWriteNotification.class);
|
|
|
+ // 查询用户填写的抬头信息
|
|
|
+ var applyId = titleWriteNotification.getFapiaoApplyId();
|
|
|
+ var buyerInformation = userTitle(applyId);
|
|
|
+ // 更新invoice表数据
|
|
|
+ invoiceService.lambdaUpdate()
|
|
|
+ .eq(Invoice::getApplyId, applyId)
|
|
|
+ .set(Invoice::getInvoiceType, buyerInformation.getType())
|
|
|
+ .set(Invoice::getInvoiceTitle, buyerInformation.getName())
|
|
|
+ .set(Invoice::getTaxId, buyerInformation.getTaxpayer_id())
|
|
|
+ .set(Invoice::getAddress, buyerInformation.getAddress())
|
|
|
+ .set(Invoice::getBankName, buyerInformation.getBank_name())
|
|
|
+ .set(Invoice::getBankAccount, buyerInformation.getBank_account())
|
|
|
+ .set(Invoice::getPhone, buyerInformation.getPhone())
|
|
|
+ .set(Invoice::getEmail, buyerInformation.getEmail())
|
|
|
+ .update();
|
|
|
+ // 运营后台财务操作开具发票
|
|
|
+ } catch (ValidationException e) {
|
|
|
+ // 签名验证失败,返回 401 UNAUTHORIZED 状态码
|
|
|
+ LOGGER.error("微信处理发票抬头填写完成通知验签失败", e);
|
|
|
+ throw new BusinessException("验签失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户填写的抬头信息
|
|
|
+ *
|
|
|
+ * @param applyId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public FaPiao.BuyerInformation userTitle(String applyId) {
|
|
|
+ var headers = new HttpHeaders();
|
|
|
+ headers.addHeader("Accept", "application/json");
|
|
|
+ var params = """
|
|
|
+ {
|
|
|
+ "fapiao_apply_id" : %s,
|
|
|
+ "scene" : %s
|
|
|
+ }
|
|
|
+ """.stripIndent().formatted(applyId, "WITHOUT_WECHATPAY"); // 非微信支付场景
|
|
|
+ var requestBody = new JsonRequestBody.Builder().body(params).build();
|
|
|
+ var res = wxHttpClient.patch(headers, fapiaoConfig.getDevConfig(), requestBody, FaPiao.BuyerInformation.class);
|
|
|
+ LOGGER.info("用户发票申请applyId:{},抬头信息:{}", applyId, res);
|
|
|
+ return res.getServiceResponse();
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 获取商户开票基础信息
|
|
|
@@ -614,10 +695,9 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
InvoiceNotification invoiceNotification = ((NotificationParser) notifyRes[1]).parse((RequestParam) notifyRes[0], InvoiceNotification.class);
|
|
|
LOGGER.info("微信开具发票结果通知回调{}:验签解密完毕,数据:\n{}", notifyRes[2], invoiceNotification);
|
|
|
// 业务逻辑
|
|
|
- if (invoiceNotification.getFapiaoInformation().get(0).getFapiaoStatus().equals(InvoiceNotification.FapiaoStatus.ISSUED)) {
|
|
|
+ if (invoiceNotification.getFapiaoInformation().get(0).getFapiaoStatus().equals(InvoiceNotification.FapiaoStatus.ISSUED.name())) {
|
|
|
// 更新发票状态
|
|
|
invoiceService.lambdaUpdate().set(Invoice::getStatus, Invoice.STATUS_已开票).eq(Invoice::getApplyId, invoiceNotification.getFapiaoApplyId()).update();
|
|
|
-
|
|
|
} else {
|
|
|
LOGGER.error("微信开具发票失败:{}", invoiceNotification);
|
|
|
}
|
|
|
@@ -628,6 +708,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 微信电子发票配置开发选项,例如回调地址、全部账单展示开发票入口开关
|
|
|
*/
|