From 15d223c549e0d94316db344f2f6337b605fffbae Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Tue, 16 Jan 2024 10:56:38 +0800
Subject: [PATCH] fapiao
---
src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java | 2
src/main/java/cc/mrbird/febs/pay/service/WxFaPiaoService.java | 11 +
src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java | 15 ++
src/test/java/cc/mrbird/febs/ProfitTest.java | 96 ++++++++++++-
src/main/resources/application-prod.yml | 1
src/main/resources/application-test.yml | 1
pom.xml | 5
src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java | 57 +++++++
src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java | 23 +-
src/main/resources/templates/febs/views/modules/system/faPiao.html | 75 ++++++++++
src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java | 3
src/main/java/cc/mrbird/febs/mall/dto/FaPiaoDto.java | 10 +
src/main/java/cc/mrbird/febs/pay/model/HeaderDto.java | 12 +
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java | 1
src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java | 108 +++++++++++++++
src/main/resources/wxP12/apiclient_cert.p12 | 0
16 files changed, 396 insertions(+), 24 deletions(-)
diff --git a/pom.xml b/pom.xml
index d38c03a..3f7a5b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,11 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>com.github.wechatpay-apiv3</groupId>
+ <artifactId>wechatpay-java</artifactId>
+ <version>0.2.12</version>
+ </dependency>
<!-- 图片压缩-->
<dependency>
<groupId>net.coobird</groupId>
diff --git a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
index f640c22..4d0b4b3 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -31,5 +31,6 @@
registration.excludePathPatterns("/api/leader/noLoginLeaderTitle");
registration.excludePathPatterns("/api/xcxPay/wxpayCallback");
registration.excludePathPatterns("/api/xcxPay/rechargeCallBack");
+ registration.excludePathPatterns("/api/xcxPay/fapiaoCallBack");
}
}
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
index f8125d8..31e3827 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
@@ -5,6 +5,9 @@
@Getter
public enum DataDictionaryEnum {
+
+ // 发票的通知回调路径
+ FP_CALLBACK_URL("FP_CALLBACK_URL", "FP_CALLBACK_URL"),
//微信订阅模板ID,
// 微信订单通知
// WX_TEMPLATE_ID_ONE("WX_TEMPLATE", "WX_TEMPLATE_ID_ONE"),
diff --git a/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java b/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
index 6393808..ca1b5e0 100644
--- a/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
+++ b/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
@@ -26,6 +26,8 @@
private String wecharpayMchid;
//支付秘钥
private String wecharpaySecret;
+ //支付秘钥V3
+ private String wecharpaySecretV3;
//高德KEY
private String gaodeKey;
//高德serviceName
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java b/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
index f6444ee..bef7b04 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
@@ -3,18 +3,22 @@
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
-import cc.mrbird.febs.mall.dto.AdminAgentAmountDto;
-import cc.mrbird.febs.mall.dto.AdminAgentDetailDto;
-import cc.mrbird.febs.mall.dto.AdminIndexVideoDto;
-import cc.mrbird.febs.mall.dto.CashOutSettingDto;
+import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.entity.DataDictionaryCustom;
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.mall.service.ICommonService;
import cc.mrbird.febs.mall.service.ISystemService;
+import cc.mrbird.febs.pay.model.HeaderDto;
+import cc.mrbird.febs.pay.service.WxFaPiaoService;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@@ -22,7 +26,9 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.io.IOException;
import java.math.BigDecimal;
+import java.security.KeyPair;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -39,6 +45,7 @@
private final ICommonService commonService;
private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
+ private final WxFaPiaoService wxFaPiaoService;
@PostMapping(value = "/bonusSystemSetting")
public FebsResponse bonusSystemSetting(@RequestBody Map<String, Object> map) {
@@ -122,6 +129,48 @@
return new FebsResponse().success().message("操作成功");
}
+ @PostMapping(value = "/faPiaoSet")
+ public FebsResponse faPiaoSet(FaPiaoDto faPiaoDto) {
+ dataDictionaryCustomMapper.updateDicValueByTypeAndCode(
+ DataDictionaryEnum.FP_CALLBACK_URL.getType(),
+ DataDictionaryEnum.FP_CALLBACK_URL.getCode(),
+ faPiaoDto.getCallbackUrl()
+ );
+ KeyPair privateKey = wxFaPiaoService.getPrivateKey();
+ HeaderDto headerDto = new HeaderDto();
+ headerDto.setCallback_url(faPiaoDto.getCallbackUrl());
+ headerDto.setShow_fapiao_cell(false);
+ String parseObj = JSONUtil.parseObj(headerDto).toString();
+ String baseUrl = "https://api.mch.weixin.qq.com";
+ String canonicalUrl = "/v3/new-tax-control-fapiao/merchant/development-config";
+ String postStr = wxFaPiaoService.createAuthorization(
+ "POST",
+ canonicalUrl,
+ parseObj,
+ privateKey
+ );
+ // 创建httppost
+ try {
+ HttpClient httpClient = new HttpClient();
+ PostMethod post = new PostMethod(baseUrl+canonicalUrl);
+ post.setRequestHeader("Accept", "application/json");
+ post.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+ post.setRequestHeader("Content-Type", "application/json");
+ post.setRequestHeader("Connection", "keep-alive");
+ post.setRequestHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+postStr);
+ RequestEntity entity = new StringRequestEntity(parseObj, "text/html", "utf-8");
+ post.setRequestEntity(entity);
+ httpClient.executeMethod(post);
+ String responseBodyAsString = post.getResponseBodyAsString();
+ cn.hutool.json.JSONObject maps = JSONUtil.parseObj(responseBodyAsString);
+ System.out.println(maps);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return new FebsResponse().success().message("操作成功");
+ }
+
@PostMapping(value = "/agentDetail")
public FebsResponse agentDetail(AdminAgentDetailDto adminAgentDetailDto) {
DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java b/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
index ff3fdea..e678562 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
@@ -99,4 +99,19 @@
model.addAttribute("indexVideoSet", adminIndexVideoDto);
return FebsUtil.view("modules/system/indexVideo");
}
+
+
+
+ @GetMapping("faPiao")
+ @RequiresPermissions("faPiao:update")
+ public String faPiao(Model model) {
+ FaPiaoDto faPiaoDto = new FaPiaoDto();
+ DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.FP_CALLBACK_URL.getType(),
+ DataDictionaryEnum.FP_CALLBACK_URL.getCode());
+ if (dic != null) {
+ faPiaoDto.setCallbackUrl(dic.getValue());
+ }
+ model.addAttribute("faPiaoDto", faPiaoDto);
+ return FebsUtil.view("modules/system/faPiao");
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/FaPiaoDto.java b/src/main/java/cc/mrbird/febs/mall/dto/FaPiaoDto.java
new file mode 100644
index 0000000..e13c2b4
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/FaPiaoDto.java
@@ -0,0 +1,10 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "DeliverGoodsDto", description = "接收参数类")
+public class FaPiaoDto {
+ private String callbackUrl;
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java b/src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java
index 2dcefa6..6830a9f 100644
--- a/src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java
+++ b/src/main/java/cc/mrbird/febs/pay/controller/XcxPayController.java
@@ -12,12 +12,7 @@
import cc.mrbird.febs.mall.service.IApiMallMemberWalletService;
import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
import cc.mrbird.febs.pay.model.NotifyData;
-import cc.mrbird.febs.pay.model.OrderStateDto;
-import cc.mrbird.febs.pay.model.OrderStateMsgVo;
-import cc.mrbird.febs.pay.model.WxTemplateData;
-import cc.mrbird.febs.pay.service.IPayService;
import cc.mrbird.febs.pay.service.IXcxPayService;
-import cc.mrbird.febs.pay.util.PayThreadPool;
import cc.mrbird.febs.pay.util.Signature;
import cc.mrbird.febs.pay.util.Util;
import cc.mrbird.febs.pay.util.WechatConfigure;
@@ -26,17 +21,12 @@
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.RestTemplate;
-import org.thymeleaf.engine.TemplateData;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
@@ -247,6 +237,19 @@
// System.out.println(rechargeNo);
// }
/**
+ * 微信电子发票回调接口
+ * @return
+ */
+ @Transactional(rollbackFor = Exception.class)
+ @RequestMapping(value = "/fapiaoCallBack")
+ public Map<Object, Object> fapiaoCallBack(HttpServletResponse response, HttpServletRequest request) throws IOException {
+ log.info("微信电子发票回调接口....");
+ Map<Object, Object> objectObjectHashMap = new HashMap<>();
+ objectObjectHashMap.put("code","SUCCESS");
+ objectObjectHashMap.put("message","");
+ return objectObjectHashMap;
+ }
+ /**
* 微信支付回调接口
*/
@Transactional(rollbackFor = Exception.class)
diff --git a/src/main/java/cc/mrbird/febs/pay/model/HeaderDto.java b/src/main/java/cc/mrbird/febs/pay/model/HeaderDto.java
new file mode 100644
index 0000000..9a0712a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/model/HeaderDto.java
@@ -0,0 +1,12 @@
+package cc.mrbird.febs.pay.model;
+
+import com.sun.org.apache.xpath.internal.operations.Bool;
+import lombok.Data;
+
+@Data
+public class HeaderDto {
+
+ private String callback_url;
+
+ private boolean show_fapiao_cell;
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/service/WxFaPiaoService.java b/src/main/java/cc/mrbird/febs/pay/service/WxFaPiaoService.java
new file mode 100644
index 0000000..960e8e2
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/service/WxFaPiaoService.java
@@ -0,0 +1,11 @@
+package cc.mrbird.febs.pay.service;
+
+import java.security.KeyPair;
+
+public interface WxFaPiaoService {
+
+ String createAuthorization(String method, String canonicalUrl, String body, KeyPair keyPair);//生成Token
+
+ KeyPair getPrivateKey();//通过证书获取私钥公钥
+
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java b/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
new file mode 100644
index 0000000..a35aa8d
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
@@ -0,0 +1,108 @@
+package cc.mrbird.febs.pay.service.impl;
+
+import cc.mrbird.febs.common.properties.XcxProperties;
+import cc.mrbird.febs.common.utils.SpringContextHolder;
+import cc.mrbird.febs.pay.service.WxFaPiaoService;
+import cc.mrbird.febs.pay.util.RandomStringGenerator;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.HttpUrl;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Base64Utils;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class WxFaPiaoServiceImpl implements WxFaPiaoService {
+
+ private final XcxProperties xcxProperties = SpringContextHolder.getBean(XcxProperties.class);
+
+ @Override
+ public String createAuthorization(String method, String canonicalUrl, String body, KeyPair keyPair) {
+ String nonceStr = RandomStringGenerator.getRandomStringByLength(32);//随机字符串
+ long timestamp = System.currentTimeMillis() / 1000;//时间戳
+ String signature = sign(method, canonicalUrl, timestamp, nonceStr, body, keyPair);//签名加密
+ return "mchid=\"" + xcxProperties.getWecharpayMchid() + "\","
+ + "nonce_str=\"" + nonceStr + "\","
+ + "timestamp=\"" + timestamp + "\","
+ + "serial_no=\"" + "50F37206347BCC9E6AC9860DAACE52AC035F7C24" + "\","//证书序列号
+ + "signature=\"" + signature + "\"";
+ }
+
+ @Override
+ public KeyPair getPrivateKey() {
+ return createPKCS12("Tenpay Certificate", "1658958205");
+ }
+ /**
+ * V3 SHA256withRSA 签名.
+ *
+ * @param method 请求方法 GET POST PUT DELETE 等
+ * @param canonicalUrl 例如 https://api.mch.weixin.qq.com/v3/pay/transactions/app?version=1 ——> /v3/pay/transactions/app?version=1
+ * @param timestamp 当前时间戳 因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
+ * @param nonceStr 随机字符串 要和TOKEN中的保持一致
+ * @param body 请求体 GET 为 "" POST 为JSON
+ * @param keyPair 商户API 证书解析的密钥对 实际使用的是其中的私钥
+ * @return the string
+ */
+ @SneakyThrows
+ public String sign(String method, String canonicalUrl, long timestamp, String nonceStr, String body, KeyPair keyPair) {
+ String signatureStr = Stream.of(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body)
+ .collect(Collectors.joining("\n", "", "\n"));
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initSign(keyPair.getPrivate());
+ sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
+ return Base64Utils.encodeToString(sign.sign());
+ }
+
+ /**
+ * 获取公私钥.通过证书
+ */
+ private KeyStore store;
+ private final Object lock = new Object();
+ public KeyPair createPKCS12(String keyAlias, String keyPass) {
+ ClassPathResource resource = new ClassPathResource(xcxProperties.getCertLocalPath());
+// File file = new File("src/main/resources/wxP12/apiclient_cert.p12");
+ char[] pem = keyPass.toCharArray();
+ try {
+ synchronized (lock) {
+ if (store == null) {
+ synchronized (lock) {
+ store = KeyStore.getInstance("PKCS12");
+ store.load(resource.getInputStream(), pem);
+// store.load(new FileInputStream(file), pem);
+ }
+ }
+ }
+ X509Certificate certificate = (X509Certificate) store.getCertificate(keyAlias);
+ certificate.checkValidity();
+ // 证书的序列号 也有用 50F37206347BCC9E6AC9860DAACE52AC035F7C24
+ String serialNumber = certificate.getSerialNumber().toString(16).toUpperCase();
+ // 证书的 公钥
+ PublicKey publicKey = certificate.getPublicKey();
+ // 证书的私钥
+ PrivateKey storeKey = (PrivateKey) store.getKey(keyAlias, pem);
+ return new KeyPair(publicKey, storeKey);
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot load keys from store: " , e);
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ System.out.println(new ClassPathResource("wxP12/apiclient_cert.p12").getFile().exists());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index d5cbbf0..af5002d 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -69,6 +69,7 @@
certLocalPath: /home/blnkaCert/apiclient_cert.p12
wecharpayMchid: 1658958205
wecharpaySecret: daL341aN5orDt13puXadsAf2rpuXdq4r
+ wecharpaySecretV3: daL341aN5orDt13puXadsAf2rpuX12v3
gaodeKey: 95ede7157929f5f6b6c758971be924b1
serviceName: yiyuanshucai
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
index 3e54b1d..0b43a6e 100644
--- a/src/main/resources/application-test.yml
+++ b/src/main/resources/application-test.yml
@@ -78,6 +78,7 @@
certLocalPath: /home/blnkaCert/apiclient_cert.p12
wecharpayMchid: 1658958205
wecharpaySecret: daL341aN5orDt13puXadsAf2rpuXdq4r
+ wecharpaySecretV3: daL341aN5orDt13puXadsAf2rpuX12v3
gaodeKey: 95ede7157929f5f6b6c758971be924b1
serviceName: yiyuanshucai
diff --git a/src/main/resources/templates/febs/views/modules/system/faPiao.html b/src/main/resources/templates/febs/views/modules/system/faPiao.html
new file mode 100644
index 0000000..d12dcaf
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/system/faPiao.html
@@ -0,0 +1,75 @@
+<div class="layui-fluid layui-anim febs-anim" id="fa-piao-set" lay-title="发票回调地址设置">
+ <div class="layui-row layui-col-space8 febs-container">
+ <form class="layui-form" action="" lay-filter="fa-piao-set-form">
+ <div class="layui-card">
+ <div class="layui-card-body">
+<!-- <div class="layui-form-item">-->
+<!-- <blockquote class="layui-elem-quote blue-border">是否</blockquote>-->
+<!-- <label class="layui-form-label">充值送金额:</label>-->
+<!-- <div class="layui-input-block">-->
+<!-- <input type="radio" name="giveState" value="1" title="开启" lay-filter="giveStateOpen" />-->
+<!-- <input type="radio" name="giveState" value="2" title="关闭" lay-filter="giveStateOpen" checked/>-->
+<!-- </div>-->
+<!-- </div>-->
+ <div class="layui-form-item activityBulletin-input febs-hide">
+ <label class="layui-form-label">回调地址:</label>
+ <div class="layui-input-block">
+ <input id="callbackUrl" type="text" name="callbackUrl" placeholder="" autocomplete="off" class="layui-input">
+ <div class="layui-form-mid layui-word-aux">收取微信的授权通知、开票通知、插卡通知等相关通知。</div>
+ </div>
+ </div>
+ </div>
+ <div class="layui-card-footer">
+ <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="fa-piao-set-form-submit" id="submit">保存</button>
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
+<style>
+ .layui-form-label {
+ width: 120px;
+ }
+
+ .layui-form-item .layui-input-block {
+ margin-left: 150px;
+ }
+
+ .layui-table-form .layui-form-item {
+ margin-bottom: 20px !important;
+ }
+</style>
+<script data-th-inline="javascript" type="text/javascript">
+ layui.use(['dropdown', 'jquery', 'validate', 'febs', 'form', 'eleTree'], function () {
+ var $ = layui.jquery,
+ febs = layui.febs,
+ form = layui.form,
+ faPiaoDto = [[${faPiaoDto}]],
+ validate = layui.validate,
+ $view = $('#fa-piao-set');
+
+ form.verify(validate);
+
+ initFPValue();
+
+ form.render();
+
+ function initFPValue() {
+ form.val("fa-piao-set-form", {
+ "callbackUrl": faPiaoDto.callbackUrl,
+ });
+ }
+ form.on('submit(fa-piao-set-form-submit)', function (data) {
+ console.log(data);
+ febs.post(ctx + 'admin/system/faPiaoSet', data.field, function (res) {
+ if (res.code == 200) {
+ febs.alert.success(res.message);
+ } else {
+ febs.alert.warn(res.message);
+ }
+ });
+ // window.location.reload();
+ return false;
+ });
+ });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/wxP12/apiclient_cert.p12 b/src/main/resources/wxP12/apiclient_cert.p12
new file mode 100644
index 0000000..bf33845
--- /dev/null
+++ b/src/main/resources/wxP12/apiclient_cert.p12
Binary files differ
diff --git a/src/test/java/cc/mrbird/febs/ProfitTest.java b/src/test/java/cc/mrbird/febs/ProfitTest.java
index 93719a9..817e62a 100644
--- a/src/test/java/cc/mrbird/febs/ProfitTest.java
+++ b/src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -12,8 +12,11 @@
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.*;
import cc.mrbird.febs.mall.vo.MallMemberCouponVo;
+import cc.mrbird.febs.pay.configure.WxPayUtil;
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
+import cc.mrbird.febs.pay.model.HeaderDto;
import cc.mrbird.febs.pay.service.IXcxPayService;
+import cc.mrbird.febs.pay.service.WxFaPiaoService;
import cc.mrbird.febs.pay.util.WechatConfigure;
import cc.mrbird.febs.rabbit.consumer.AgentConsumer;
import cn.hutool.core.collection.CollUtil;
@@ -22,10 +25,17 @@
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import okhttp3.HttpUrl;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -33,6 +43,8 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.ResourceLoader;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@@ -40,6 +52,7 @@
import java.math.BigDecimal;
import java.net.URLConnection;
import java.nio.charset.Charset;
+import java.security.KeyPair;
import java.util.*;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@@ -89,18 +102,81 @@
private MallGoodsMapper mallGoodsMapper;
@Autowired
private CouponGoodsMapper couponGoodsMapper;
+ @Autowired
+ private WxFaPiaoService wxFaPiaoService;
+ @Autowired
+ ResourceLoader resourceLoader;
@Test
- public void rankProfit() {
-// memberProfitService.rankProfit();
- MallMemberCouponDto mallMemberCouponDto = new MallMemberCouponDto();
- mallMemberCouponDto.setMemberId(72L);
- mallMemberCouponDto.setExpireTime(DateUtil.date());
- List<Long> couponIds = couponGoodsMapper.selectByGoodId(10L);
- List<MallMemberCouponVo> mallMemberCouponVos = new ArrayList<>();
- if(CollUtil.isNotEmpty(couponIds)){
- mallMemberCouponVos = mallMemberCouponMapper.selectListCreateInPage(mallMemberCouponDto,couponIds);
- System.out.println(mallMemberCouponVos);
+ public void rankProfit() throws IOException {
+// System.out.println(new ClassPathResource("wxP12/apiclient_cert.p12").getFile().exists());
+// System.out.println(new File("src/main/resources/wxP12/apiclient_cert.p12").exists());
+//
+// InputStream inputStream = new FileInputStream(file);
+// System.out.println(resourceLoader.getResource("classpath:/wxP12/apiclient_cert.p12").exists());
+ KeyPair privateKey = wxFaPiaoService.getPrivateKey();
+ HeaderDto headerDto = new HeaderDto();
+ headerDto.setCallback_url("https://api.blnka.cn/api/xcxPay/fapiaoCallBack");
+ headerDto.setShow_fapiao_cell(true);
+ String parseObj = JSONUtil.parseObj(headerDto).toString();
+ String baseUrl = "https://api.mch.weixin.qq.com";
+ String canonicalUrl = "/v3/new-tax-control-fapiao/merchant/development-config";
+ String postStr = wxFaPiaoService.createAuthorization(
+ "POST",
+ canonicalUrl,
+ parseObj,
+ privateKey
+
+ );
+ // 创建httppost
+ try {
+ HttpClient httpClient = new HttpClient();
+ PostMethod post = new PostMethod("https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/merchant/development-config");
+ post.setRequestHeader("Accept", "application/json");
+ post.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+ post.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
+ post.setRequestHeader("Connection", "keep-alive");
+ post.setRequestHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+postStr);
+ RequestEntity entity = new StringRequestEntity(parseObj, "text/html", "utf-8");
+ post.setRequestEntity(entity);
+ httpClient.executeMethod(post);
+ String responseBodyAsString = post.getResponseBodyAsString();
+ cn.hutool.json.JSONObject maps = JSONUtil.parseObj(responseBodyAsString);
+ System.out.println(maps);
+ } catch (IOException e) {
+ e.printStackTrace();
}
+
+ }
+
+ @Test
+ public void rankProfit2() throws IOException {
+ KeyPair privateKey = wxFaPiaoService.getPrivateKey();
+ String baseUrl = "https://api.mch.weixin.qq.com";
+ String canonicalUrl = "/v3/new-tax-control-fapiao/merchant/development-config";
+ String postStr = wxFaPiaoService.createAuthorization(
+ "GET",
+ canonicalUrl,
+ "",
+ privateKey
+
+ );
+ try {
+ HttpClient httpClient = new HttpClient();
+ GetMethod method = new GetMethod(baseUrl+canonicalUrl);
+ method.setRequestHeader("Accept", "application/json");
+ method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+ method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+ method.setRequestHeader("Connection", "keep-alive");
+ method.setRequestHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+postStr);
+ httpClient.executeMethod(method);
+ System.out.println(method);
+ String responseBodyAsString = method.getResponseBodyAsString();
+ cn.hutool.json.JSONObject maps = JSONUtil.parseObj(responseBodyAsString);
+ System.out.println(maps);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
}
--
Gitblit v1.9.1