添加微信支付功能
This commit is contained in:
parent
83b0db735a
commit
9ec69e8875
|
@ -10,6 +10,17 @@
|
||||||
<artifactId>nu-admin-biz</artifactId>
|
<artifactId>nu-admin-biz</artifactId>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- 微信支付 SDK -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-apache-httpclient</artifactId>
|
||||||
|
<version>0.4.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wxpay</groupId>
|
||||||
|
<artifactId>wxpay-sdk</artifactId>
|
||||||
|
<version>0.0.3</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.nursingunit.boot</groupId>
|
<groupId>com.nursingunit.boot</groupId>
|
||||||
<artifactId>nu-admin-local-api</artifactId>
|
<artifactId>nu-admin-local-api</artifactId>
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.nu.modules.wechart.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.github.wxpay.sdk.WXPay;
|
||||||
|
import com.github.wxpay.sdk.WXPayConstants;
|
||||||
|
import com.github.wxpay.sdk.WXPayUtil;
|
||||||
|
import com.nu.modules.wechart.entity.WXConfig;
|
||||||
|
import com.nu.modules.wechart.entity.WechatpayConfig;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/weiXinPay2")
|
||||||
|
@Slf4j
|
||||||
|
public class WechatPay2Controller {
|
||||||
|
@Autowired
|
||||||
|
public WechatpayConfig wechatpayConfig;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native下单
|
||||||
|
* 调用统一下单API,生成支付二维码
|
||||||
|
*/
|
||||||
|
@PostMapping("/native")
|
||||||
|
public Map<String,String> nativePay() throws Exception {
|
||||||
|
log.info("生成订单");
|
||||||
|
//生成订单
|
||||||
|
log.info("存入数据库...");
|
||||||
|
|
||||||
|
log.info("调用统一下单API");
|
||||||
|
// 订单号
|
||||||
|
String orderNo = IdUtil.simpleUUID();
|
||||||
|
// 请求body参数 看官方文档
|
||||||
|
WXConfig config = new WXConfig();
|
||||||
|
config.setAppId(wechatpayConfig.getAppid());
|
||||||
|
config.setMchId(wechatpayConfig.getMchId());
|
||||||
|
config.setKey(wechatpayConfig.getApiV3Key());
|
||||||
|
|
||||||
|
Map<String, String> paramsMap = new HashMap<>();
|
||||||
|
paramsMap.put("appid", wechatpayConfig.getAppid());
|
||||||
|
paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||||
|
paramsMap.put("description", "iPhone 15 Pro Max 5G");
|
||||||
|
paramsMap.put("out_trade_no", orderNo);
|
||||||
|
// 回调的地址
|
||||||
|
paramsMap.put("notify_url",wechatpayConfig.getNotifyDomain()+"/native/notify");
|
||||||
|
|
||||||
|
Map amountMap = new HashMap();
|
||||||
|
//订单总金额,单位为分。
|
||||||
|
amountMap.put("total", 1);
|
||||||
|
//CNY:人民币,境内商户号仅支持人民币。
|
||||||
|
amountMap.put("currency", "CNY");
|
||||||
|
paramsMap.put("total_fee", 1+"");
|
||||||
|
paramsMap.put("trade_type", "JSAPI");
|
||||||
|
String generateNonceStr = WXPayUtil.generateNonceStr();
|
||||||
|
paramsMap.put("nonce_str", generateNonceStr);
|
||||||
|
String body = "body";
|
||||||
|
paramsMap.put("body", body);
|
||||||
|
paramsMap.put("sign", WXPayUtil.generateSignature(paramsMap, wechatpayConfig.getApiV3Key(), WXPayConstants.SignType.MD5));
|
||||||
|
|
||||||
|
log.info("请求参数:" + paramsMap);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WXPay wxpay = new WXPay(config);
|
||||||
|
Map<String, String> response = wxpay.unifiedOrder(paramsMap);
|
||||||
|
for (String key : response.keySet()) {
|
||||||
|
log.info("微信支付订单微信返回参数:keys:" + key + " value:" + response.get(key).toString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,345 @@
|
||||||
|
package com.nu.modules.wechart.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.github.wxpay.sdk.WXPayUtil;
|
||||||
|
import com.nu.modules.wechart.entity.WechatpayConfig;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/weiXinPay")
|
||||||
|
@Slf4j
|
||||||
|
public class WechatPayController {
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
public WechatpayConfig wechatpayConfig;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native下单
|
||||||
|
* 调用统一下单API,生成支付二维码
|
||||||
|
*/
|
||||||
|
@PostMapping("/native")
|
||||||
|
public Map<String,String> nativePay() throws Exception {
|
||||||
|
log.info("生成订单");
|
||||||
|
//生成订单
|
||||||
|
log.info("存入数据库...");
|
||||||
|
|
||||||
|
log.info("调用统一下单API");
|
||||||
|
//调用统一下单API
|
||||||
|
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
|
||||||
|
|
||||||
|
// 订单号
|
||||||
|
String orderNo = IdUtil.simpleUUID();
|
||||||
|
// 请求body参数 看官方文档
|
||||||
|
Map paramsMap = new HashMap();
|
||||||
|
paramsMap.put("appid", wechatpayConfig.getAppid());
|
||||||
|
paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||||
|
paramsMap.put("description", "iPhone 15 Pro Max 5G");
|
||||||
|
paramsMap.put("out_trade_no", orderNo);
|
||||||
|
// 回调的地址
|
||||||
|
paramsMap.put("notify_url",wechatpayConfig.getNotifyDomain()+"/native/notify");
|
||||||
|
Map amountMap = new HashMap();
|
||||||
|
//订单总金额,单位为分。
|
||||||
|
amountMap.put("total", 1);
|
||||||
|
//CNY:人民币,境内商户号仅支持人民币。
|
||||||
|
amountMap.put("currency", "CNY");
|
||||||
|
|
||||||
|
paramsMap.put("amount", amountMap);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//将参数转换成json字符串
|
||||||
|
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||||
|
log.info("请求参数:" + jsonParams);
|
||||||
|
|
||||||
|
StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
||||||
|
entity.setContentType("application/json");
|
||||||
|
httpPost.setEntity(entity);
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+ jsonParams);
|
||||||
|
//创建httpclient对象
|
||||||
|
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||||
|
//完成签名并执行请求
|
||||||
|
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||||
|
try {
|
||||||
|
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||||
|
if (statusCode == 200) { //处理成功
|
||||||
|
log.info("成功, 返回结果 = " + bodyAsString);
|
||||||
|
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||||
|
log.info("成功");
|
||||||
|
} else {
|
||||||
|
log.info("Native下单失败,响应码 = " + statusCode+ ",返回结果 = " +
|
||||||
|
bodyAsString);
|
||||||
|
throw new IOException("request failed");
|
||||||
|
}
|
||||||
|
//响应结果
|
||||||
|
Map<String, String> resultMap = JSONUtil.toBean(bodyAsString,HashMap.class);
|
||||||
|
//二维码
|
||||||
|
String codeUrl = resultMap.get("code_url");
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("codeUrl", codeUrl);
|
||||||
|
map.put("orderNo", orderNo.toString());
|
||||||
|
return map;
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 支付通知
|
||||||
|
* 微信支付通过支付通知接口将用户支付成功消息通知给商户
|
||||||
|
*/
|
||||||
|
@PostMapping("/native/notify")
|
||||||
|
public Map<String,String> nativeNotify(@RequestBody Map<String,Object> signalRes, HttpServletResponse response){
|
||||||
|
Map<String, String> map = new HashMap<>();//应答对象
|
||||||
|
log.info("支付通知的完整数据 ===> {}", signalRes);
|
||||||
|
try {
|
||||||
|
//用密文解密出明文
|
||||||
|
Map<String,String> resource=(Map<String,String>)signalRes.get("resource");
|
||||||
|
String ciphertext=resource.get("ciphertext");
|
||||||
|
String associatedData=resource.get("associated_data");
|
||||||
|
String nonce=resource.get("nonce");
|
||||||
|
// 拿到明文
|
||||||
|
String plainText=new AesUtil(wechatpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);
|
||||||
|
//转换
|
||||||
|
HashMap<String,Object> data= JSONUtil.toBean(plainText,HashMap.class);
|
||||||
|
log.info("解密后的完整数据:{}",data);
|
||||||
|
//处理订单
|
||||||
|
log.info("处理订单...");
|
||||||
|
//成功应答:成功应答必须为200或204,否则就是失败应答
|
||||||
|
response.setStatus(200);
|
||||||
|
map.put("code", "SUCCESS");
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
response.setStatus(500);
|
||||||
|
map.put("code", "FAIL");
|
||||||
|
map.put("message","失败");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 查询订单
|
||||||
|
* @param orderNo
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@GetMapping("/query/{orderNo}")
|
||||||
|
public String queryOrder(@PathVariable String orderNo) throws Exception {
|
||||||
|
log.info("查询订单");
|
||||||
|
String url = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s", orderNo);
|
||||||
|
url = url+"?mchid="+wechatpayConfig.getMchId();
|
||||||
|
HttpGet httpGet = new HttpGet(url);
|
||||||
|
httpGet.setHeader("Accept", "application/json");
|
||||||
|
|
||||||
|
//创建httpclient对象
|
||||||
|
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||||
|
//完成签名并执行请求
|
||||||
|
CloseableHttpResponse response = wxPayClient.execute(httpGet);
|
||||||
|
try {
|
||||||
|
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||||
|
if (statusCode == 200) { //处理成功
|
||||||
|
log.info("成功, 返回结果 = " + bodyAsString);
|
||||||
|
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||||
|
log.info("成功");
|
||||||
|
} else {
|
||||||
|
log.info("查单接口调用,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
|
||||||
|
throw new IOException("request failed");
|
||||||
|
}
|
||||||
|
return bodyAsString;
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 用户取消订单
|
||||||
|
* @param orderNo 订单id
|
||||||
|
*/
|
||||||
|
@PostMapping("/cancel/{orderNo}")
|
||||||
|
public String cancel(@PathVariable String orderNo) throws Exception {
|
||||||
|
log.info("用户取消订单");
|
||||||
|
//创建远程请求对象
|
||||||
|
String url = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s/close", orderNo);
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
|
||||||
|
//组装json请求体
|
||||||
|
Map<String, String> paramsMap = new HashMap<>();
|
||||||
|
paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||||
|
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||||
|
log.info("请求参数 ===> {}", jsonParams);
|
||||||
|
|
||||||
|
//将请求参数设置到请求对象中
|
||||||
|
StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
||||||
|
entity.setContentType("application/json");
|
||||||
|
httpPost.setEntity(entity);
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
|
||||||
|
//创建httpclient对象
|
||||||
|
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||||
|
//完成签名并执行请求
|
||||||
|
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||||
|
try {
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||||
|
if (statusCode == 200) { //处理成功
|
||||||
|
log.info("成功200");
|
||||||
|
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||||
|
log.info("成功204");
|
||||||
|
} else {
|
||||||
|
log.info("Native下单失败,响应码 = " + statusCode);
|
||||||
|
throw new IOException("request failed");
|
||||||
|
}
|
||||||
|
return "订单取消成功";
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 申请退款
|
||||||
|
* @param orderNo 订单编号
|
||||||
|
*/
|
||||||
|
@PostMapping("/refunds/{orderNo}")
|
||||||
|
public Map<String,Object> refunds(@PathVariable String orderNo) throws Exception {
|
||||||
|
|
||||||
|
log.info("创建退款单记录...");
|
||||||
|
//根据订单编号创建退款单
|
||||||
|
|
||||||
|
log.info("调用退款API");
|
||||||
|
|
||||||
|
//调用统一下单API
|
||||||
|
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");
|
||||||
|
|
||||||
|
// 请求body参数
|
||||||
|
Map paramsMap = new HashMap();
|
||||||
|
paramsMap.put("out_trade_no", orderNo);//订单编号
|
||||||
|
|
||||||
|
// 给它一个退款单号
|
||||||
|
paramsMap.put("out_refund_no", "tk202412120001");//退款单编号
|
||||||
|
paramsMap.put("reason", "买了不发货");//退款原因
|
||||||
|
paramsMap.put("notify_url", wechatpayConfig.getNotifyDomain()+"/refunds/notify");//退款通知地址
|
||||||
|
|
||||||
|
Map amountMap = new HashMap();
|
||||||
|
amountMap.put("refund", 1);//退款金额
|
||||||
|
amountMap.put("total", 1);//原订单金额
|
||||||
|
amountMap.put("currency", "CNY");//退款币种
|
||||||
|
paramsMap.put("amount", amountMap);
|
||||||
|
|
||||||
|
//将参数转换成json字符串
|
||||||
|
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||||
|
log.info("请求参数 ===> {}" + jsonParams);
|
||||||
|
|
||||||
|
StringEntity entity = new StringEntity(jsonParams, "utf-8");
|
||||||
|
entity.setContentType("application/json");//设置请求报文格式
|
||||||
|
httpPost.setEntity(entity);//将请求报文放入请求对象
|
||||||
|
httpPost.setHeader("Accept", "application/json");//设置响应报文格式
|
||||||
|
|
||||||
|
//创建httpclient对象
|
||||||
|
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||||
|
//完成签名并执行请求,并完成验签
|
||||||
|
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||||
|
|
||||||
|
try {
|
||||||
|
//解析响应结果
|
||||||
|
String bodyAsString = EntityUtils.toString(response.getEntity());
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if (statusCode == 200) {
|
||||||
|
log.info("成功, 退款返回结果 = " + bodyAsString);
|
||||||
|
} else if (statusCode == 204) {
|
||||||
|
log.info("成功");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("退款异常, 响应码 = " + statusCode + ", 退款返回结果 = " + bodyAsString);
|
||||||
|
}
|
||||||
|
log.info("更新订单状态......");
|
||||||
|
log.info("更新退款单......");
|
||||||
|
return JSONUtil.toBean(bodyAsString,Map.class);
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 退款结果通知
|
||||||
|
* 退款状态改变后,微信会把相关退款结果发送给商户。
|
||||||
|
*/
|
||||||
|
@PostMapping("/refunds/notify")
|
||||||
|
public String refundsNotify(@RequestBody Map<String,Object> signalRes, HttpServletResponse response){
|
||||||
|
log.info("退款通知执行");
|
||||||
|
Map<String, String> map = new HashMap<>();//应答对象
|
||||||
|
try {
|
||||||
|
Map<String,String> resource=(Map<String,String>)signalRes.get("resource");
|
||||||
|
String ciphertext=resource.get("ciphertext");
|
||||||
|
String associatedData=resource.get("associated_data");
|
||||||
|
String nonce=resource.get("nonce");
|
||||||
|
// 拿到明文
|
||||||
|
String plainText=new AesUtil(wechatpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);
|
||||||
|
|
||||||
|
//转换
|
||||||
|
HashMap<String,Object> data= JSONUtil.toBean(plainText,HashMap.class);
|
||||||
|
log.info("解密后的完整数据:{}",data);
|
||||||
|
log.info("处理退款单................................");
|
||||||
|
log.info("更新订单状态................................");
|
||||||
|
|
||||||
|
//成功应答
|
||||||
|
response.setStatus(200);
|
||||||
|
map.put("code", "SUCCESS");
|
||||||
|
map.put("message", "成功");
|
||||||
|
return JSONUtil.toJsonStr(map);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//失败应答
|
||||||
|
response.setStatus(500);
|
||||||
|
map.put("code", "ERROR");
|
||||||
|
map.put("message", "失败");
|
||||||
|
return JSONUtil.toJsonStr(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 查询退款
|
||||||
|
* @param refundNo 退款订单
|
||||||
|
*/
|
||||||
|
@GetMapping("/query-refund/{refundNo}")
|
||||||
|
public String queryRefund(@PathVariable String refundNo) throws Exception {
|
||||||
|
|
||||||
|
log.info("查询退款接口调用 ===> {}", refundNo);
|
||||||
|
String url = String.format("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s", refundNo);
|
||||||
|
//创建远程Get 请求对象
|
||||||
|
HttpGet httpGet = new HttpGet(url);
|
||||||
|
httpGet.setHeader("Accept", "application/json");
|
||||||
|
//创建httpclient对象
|
||||||
|
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||||
|
//完成签名并执行请求
|
||||||
|
CloseableHttpResponse response = wxPayClient.execute(httpGet);
|
||||||
|
try {
|
||||||
|
String bodyAsString = EntityUtils.toString(response.getEntity());
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if (statusCode == 200) {
|
||||||
|
log.info("成功, 查询退款返回结果 = " + bodyAsString);
|
||||||
|
} else if (statusCode == 204) {
|
||||||
|
log.info("成功");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("查询退款异常, 响应码 = " + statusCode+ ", 查询退款返回结果 = " + bodyAsString);
|
||||||
|
}
|
||||||
|
return bodyAsString;
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.nu.modules.wechart.entity;
|
||||||
|
|
||||||
|
import com.github.wxpay.sdk.WXPayConfig;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fang
|
||||||
|
* @date 2020/2/26
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WXConfig implements WXPayConfig {
|
||||||
|
private byte[] certData;
|
||||||
|
|
||||||
|
public String appId;
|
||||||
|
public String key;
|
||||||
|
public String mchId;
|
||||||
|
|
||||||
|
/*public WXConfigUtil() throws Exception {
|
||||||
|
String certPath = ClassUtils.getDefaultClassLoader().getResource("").getPath()+"/weixin/apiclient_cert.p12";//从微信商户平台下载的安全证书存放的路径
|
||||||
|
File file = new File(certPath);
|
||||||
|
InputStream certStream = new FileInputStream(file);
|
||||||
|
this.certData = new byte[(int) file.length()];
|
||||||
|
certStream.read(this.certData);
|
||||||
|
certStream.close();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public byte[] getCertData() {
|
||||||
|
return certData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCertData(byte[] certData) {
|
||||||
|
this.certData = certData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppId() {
|
||||||
|
return appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppId(String appId) {
|
||||||
|
this.appId = appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMchId() {
|
||||||
|
return mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMchId(String mchId) {
|
||||||
|
this.mchId = mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAppID() {
|
||||||
|
return this.appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//parnerid,商户号
|
||||||
|
@Override
|
||||||
|
public String getMchID() {
|
||||||
|
return this.mchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getCertStream() {
|
||||||
|
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
|
||||||
|
return certBis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHttpConnectTimeoutMs() {
|
||||||
|
return 8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHttpReadTimeoutMs() {
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.nu.modules.wechart.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
|
@Data
|
||||||
|
public class WechatpayConfig {
|
||||||
|
// 商户ID
|
||||||
|
@Value("${wxpay.mch-id}")
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
// 商户API证书序列号
|
||||||
|
@Value("${wxpay.mch-serial-no}")
|
||||||
|
private String mchSerialNo;
|
||||||
|
|
||||||
|
// 商户私钥文件
|
||||||
|
@Value("${wxpay.private-key-path}")
|
||||||
|
private String privateKeyPath;
|
||||||
|
|
||||||
|
// APIv3密钥
|
||||||
|
@Value("${wxpay.api-v3-key}")
|
||||||
|
private String apiV3Key;
|
||||||
|
|
||||||
|
// APPID
|
||||||
|
@Value("${wxpay.appid}")
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
// 接收结果通知地址
|
||||||
|
@Value("${wxpay.notify-domain}")
|
||||||
|
private String notifyDomain;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -113,6 +113,8 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
|
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
|
||||||
filterChainDefinitionMap.put("/h5Api/nuBizAdvisoryInfo/**", "anon"); //授权接口排除
|
filterChainDefinitionMap.put("/h5Api/nuBizAdvisoryInfo/**", "anon"); //授权接口排除
|
||||||
filterChainDefinitionMap.put("/h5Api/nuBaseInfo/**", "anon"); //授权接口排除
|
filterChainDefinitionMap.put("/h5Api/nuBaseInfo/**", "anon"); //授权接口排除
|
||||||
|
filterChainDefinitionMap.put("/weiXinPay/**", "anon"); //微信支付接口
|
||||||
|
filterChainDefinitionMap.put("/weiXinPay2/**", "anon"); //微信支付接口
|
||||||
|
|
||||||
//update-begin--Author:scott Date:20221116 for:排除静态资源后缀
|
//update-begin--Author:scott Date:20221116 for:排除静态资源后缀
|
||||||
filterChainDefinitionMap.put("/", "anon");
|
filterChainDefinitionMap.put("/", "anon");
|
||||||
|
|
|
@ -175,7 +175,6 @@ public class ConfigMaterialCategoryController extends JeecgController<ConfigMate
|
||||||
* @param request
|
* @param request
|
||||||
* @param configMaterialCategory
|
* @param configMaterialCategory
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("ConfigMaterial:config_material_category:exportXls")
|
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialCategory configMaterialCategory) {
|
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialCategory configMaterialCategory) {
|
||||||
return super.exportXls(request, configMaterialCategory, ConfigMaterialCategory.class, "物料类别");
|
return super.exportXls(request, configMaterialCategory, ConfigMaterialCategory.class, "物料类别");
|
||||||
|
|
|
@ -164,7 +164,6 @@ public class ConfigMaterialInfoController extends JeecgController<ConfigMaterial
|
||||||
* @param request
|
* @param request
|
||||||
* @param configMaterialInfo
|
* @param configMaterialInfo
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("configMaterialInfo:config_material_info:exportXls")
|
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialInfo configMaterialInfo) {
|
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialInfo configMaterialInfo) {
|
||||||
return super.exportXls(request, configMaterialInfo, ConfigMaterialInfo.class, "物料信息");
|
return super.exportXls(request, configMaterialInfo, ConfigMaterialInfo.class, "物料信息");
|
||||||
|
|
|
@ -164,7 +164,6 @@ public class ConfigMaterialMedicationController extends JeecgController<ConfigMa
|
||||||
* @param request
|
* @param request
|
||||||
* @param configMaterialMedication
|
* @param configMaterialMedication
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("ConfigMaterial:config_material_medication:exportXls")
|
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialMedication configMaterialMedication) {
|
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialMedication configMaterialMedication) {
|
||||||
return super.exportXls(request, configMaterialMedication, ConfigMaterialMedication.class, "物料用药类型");
|
return super.exportXls(request, configMaterialMedication, ConfigMaterialMedication.class, "物料用药类型");
|
||||||
|
|
|
@ -162,7 +162,6 @@ public class ConfigMaterialTypeController extends JeecgController<ConfigMaterial
|
||||||
* @param request
|
* @param request
|
||||||
* @param configMaterialType
|
* @param configMaterialType
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("ConfigMaterial:config_material_type:exportXls")
|
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialType configMaterialType) {
|
public ModelAndView exportXls(HttpServletRequest request, ConfigMaterialType configMaterialType) {
|
||||||
return super.exportXls(request, configMaterialType, ConfigMaterialType.class, "物料类型");
|
return super.exportXls(request, configMaterialType, ConfigMaterialType.class, "物料类型");
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQD9DP/vMUP0rTVZ
|
||||||
|
rvoOXgpTpyzptWTuMLUBHfY63kpZ7cYEekkznIuqt1XE3HezlwL4uOrzaMR59sGJ
|
||||||
|
MD2kvh0V7wxlWYtA1nTLkUi5jUW8DmoMR2wlVOm+jV9SpG2AH4w/coMDHCIuMbge
|
||||||
|
ZncsIN3wJrAwSRFCWM2La1Bjzrt7z9GR/LwhX60RN9UvKvhcnFvuJWYe2wd62NQa
|
||||||
|
NvdGlApt8MW/WBFNLBaPlCM1Tp5TLOapVna9a42cRhzWW/gJr5i02nGQX1kFC5h1
|
||||||
|
On+DvUJGpXdLl/gr+f6Otr4TrvxOTVY4IU20UO/TkI1+cH9VXwY4VlNN1WrzVVtd
|
||||||
|
fN96ZCwVAgMBAAECggEAdZW103rL/gUCVmMlVMnD+K0lBJBCjx/Y6+T1RtOGLxV6
|
||||||
|
vxfnrfDfQXuhgjGD+dKBEfwzSNn0+kt8EPh2nHeu4kNLOkkKmR1N9k3TQk1wCvuT
|
||||||
|
sZL6oLo9R0s/8RHww+lk7RKT6D0JcPeve4jXdYzsNCx2EGnTeEX1dQRvvYERw2yY
|
||||||
|
hbp6jgtE0XZztK4+54aPqBmVrQCzhJdXwNmfNhspjMCUGN9SQ+NPyKr6Q9mL78px
|
||||||
|
+WWnmCPktekPAiBV1P87uVCuc1BWG7n2J1dyiUicqQ4T2v5S7KFJPjOMwy+dB0Pd
|
||||||
|
WxWAv3V6f3bQHUGV2Vj5NjRm+2z2DXTYofvso5u53QKBgQD/bEayMuJhsSGqV56Q
|
||||||
|
W3sqKTwB+MgEISbeONXkfOppazUxuGmUi1Je9d+7IujMCf8eP26OudIdW2CLY/VP
|
||||||
|
7EzOpx4Y16B75GuSfdIfgCrmaVIePD1yiC9rzhsQ/UkgP/gAof8BiY6GbSQXkSg2
|
||||||
|
W9MkeWFretgkuygYymI/y+rqLwKBgQD9n1oFHmYizu5abfKdXsGWQPIvqaO93FLF
|
||||||
|
nh3QM/VXAGC7R/oNqjlAD8ZJmaIOGDMwrfeZ4wDwdgs/DeIBDTpuuNG+KWSgP28X
|
||||||
|
NryIUyuu/4q0a4uIMhwdykKpPVVJ7bnPjihRY0HE3LdDqhnY5JLuGhGE9T7zD1KT
|
||||||
|
RwejCiRw+wKBgF8nmELEwB+C3LbYA4NmAUFYsTlO1DztmMxKwixn+PAi92M5f2PO
|
||||||
|
b3ZfBOVzgOSaiMdc/DQBt+wl4ZasO3R15LtL+ONqWSgulYCyjPgdSF4kOGp5KK8l
|
||||||
|
Wv0/gEfZBEgWbK7XqueItmcP+9Unx6JQnR1GduuSjTlJ3As4QlfgAPkTAoGABKjM
|
||||||
|
ypNIZRNQJbEnZ+S5wbzntiBztaU6kA7blVufAj4riMVFvsKF0rt3dRqxc3jWV+qa
|
||||||
|
ReV5uvEwO7RRlptbm3UhxVCVXKxNqiuDQy3j+48OSUpAgfwJsDJrDxjlXDpV045V
|
||||||
|
B0m/h5JWe5PAbc+lM2KfN8YZpfV+Gt6PMVuaV8kCgYBw+uhCANG+FHnFmNXR7E8m
|
||||||
|
HID8xorhnz6d9hwJKo2cE+DHQzjX03fiV9suq2QiYz50YX06CN/xPyPy+XRQh3Rj
|
||||||
|
xhd8jNnNUKJygXjGzlLVbO394ePcq9hNONds31m1wJILFAq3+LIrtWq3XUAyJpBp
|
||||||
|
w+xnruEDdBI/mm2Y76V8zg==
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -374,3 +374,17 @@ tplink:
|
||||||
username: administrator
|
username: administrator
|
||||||
password: Root@123..
|
password: Root@123..
|
||||||
uploadpath: /
|
uploadpath: /
|
||||||
|
# 微信支付
|
||||||
|
wxpay:
|
||||||
|
# APIv3密钥
|
||||||
|
api-v3-key: asdfiuzwe3534565478WETDSAFRWEq1E
|
||||||
|
# APPID
|
||||||
|
appid: wx8fc3e4305d2fbf0b
|
||||||
|
# 商户ID
|
||||||
|
mch-id: 1717618860
|
||||||
|
# 商户API证书序列号
|
||||||
|
mch-serial-no: 3E51C9D24F64CE50E9273E544561D29684AB21C7
|
||||||
|
# 接收结果通知地址
|
||||||
|
notify-domain: http://r2agtr.natappfree.cc
|
||||||
|
# 商户私钥文件路径
|
||||||
|
private-key-path: apiclient_key.pem
|
|
@ -1,5 +1,5 @@
|
||||||
server:
|
server:
|
||||||
port: 8081
|
port: 8082
|
||||||
tomcat:
|
tomcat:
|
||||||
max-swallow-size: -1
|
max-swallow-size: -1
|
||||||
error:
|
error:
|
||||||
|
|
20
pom.xml
20
pom.xml
|
@ -153,17 +153,17 @@
|
||||||
<version>${commonmark.version}</version>
|
<version>${commonmark.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Nacos 服务发现 -->
|
<!-- Nacos 服务发现 -->
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<!-- <groupId>com.alibaba.cloud</groupId>-->
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
|
||||||
<version>2021.0.5.0</version>
|
<!-- <version>2021.0.5.0</version>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
<!-- Nacos 配置中心 -->
|
<!-- Nacos 配置中心 -->
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<!-- <groupId>com.alibaba.cloud</groupId>-->
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
|
||||||
<version>2021.0.5.0</version>
|
<!-- <version>2021.0.5.0</version>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
<!-- RabbitMQ -->
|
<!-- RabbitMQ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
Loading…
Reference in New Issue