支付代码暂存
This commit is contained in:
parent
0a158ab1a3
commit
6f71c6abb6
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,5 +39,6 @@ nbdist/
|
|||||||
.nb-gradle/
|
.nb-gradle/
|
||||||
|
|
||||||
target/
|
target/
|
||||||
|
logs/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
<poi.version>3.9</poi.version>
|
<poi.version>3.9</poi.version>
|
||||||
<log4j2.version>2.17.2</log4j2.version>
|
<log4j2.version>2.17.2</log4j2.version>
|
||||||
<project.name>exam-admin</project.name>
|
<project.name>exam-admin</project.name>
|
||||||
|
<wechatpay-apiv3.version>0.4.4</wechatpay-apiv3.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
@ -170,6 +171,20 @@
|
|||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.11.0</version>
|
<version>2.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 微信支付SDK -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-apache-httpclient</artifactId>
|
||||||
|
<version>${wechatpay-apiv3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- httpclient 依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5.13</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -0,0 +1,62 @@
|
|||||||
|
package com.yf.exam.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 微信支付接口地址
|
||||||
|
* @Author 纪寒
|
||||||
|
* @Date 2022-10-17 17:56:25
|
||||||
|
* @Version 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "we-chat-payment-url-config")
|
||||||
|
public class WeChatPaymentUrlConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序JSAPI下单接口地址
|
||||||
|
*/
|
||||||
|
private String jsapiPalceOrderUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付订单号查询接口地址
|
||||||
|
*/
|
||||||
|
private String queryOrderNoUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户订单号接口查询
|
||||||
|
*/
|
||||||
|
private String queryMchIdUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭订单接口地址
|
||||||
|
*/
|
||||||
|
private String closeOrderUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请退款接口地址
|
||||||
|
*/
|
||||||
|
private String refundApplyUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询单笔退款接口地址
|
||||||
|
*/
|
||||||
|
private String refundQueryOrderUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请交易账单接口地址
|
||||||
|
*/
|
||||||
|
private String tradeApplyBillUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请资金账单接口地址
|
||||||
|
*/
|
||||||
|
private String capitalApplyBillUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App下单接口地址
|
||||||
|
*/
|
||||||
|
private String appPlaceOrderUrl;
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.yf.exam.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 新医路商户号微信支付参数配置类
|
||||||
|
* @Author 纪寒
|
||||||
|
* @Date 2022-10-17 16:55:04
|
||||||
|
* @Version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "xyl-we-chat-config")
|
||||||
|
public class XylWeChatPaymentConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新医路商户号
|
||||||
|
*/
|
||||||
|
private String xylMchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新医路API证书序号getXylVerifier
|
||||||
|
*/
|
||||||
|
private String xylMchSerialNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新医路私钥文件
|
||||||
|
*/
|
||||||
|
private String xylPrivateKeyPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新医路API V3版本密钥
|
||||||
|
*/
|
||||||
|
private String xylPaymentKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新医路支付回调地址
|
||||||
|
*/
|
||||||
|
private String xylWeChatNotifyUrl;
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package com.yf.exam.config.payment;
|
||||||
|
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
||||||
|
import com.yf.exam.config.XylWeChatPaymentConfig;
|
||||||
|
import com.yf.exam.core.exception.ServiceException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 新医路商户号微信支付核心配置类
|
||||||
|
* @Author 纪寒
|
||||||
|
* @Date 2022-10-17 18:56:22
|
||||||
|
* @Version 1.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
|
public class XylWeChatPaymentUtilConfig {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private XylWeChatPaymentConfig xylWeChatPaymentConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新医路签名信息
|
||||||
|
*
|
||||||
|
* @return 签名信息
|
||||||
|
* @throws Exception 异常信息
|
||||||
|
*/
|
||||||
|
@Bean(name = "xylVerifier")
|
||||||
|
public Verifier getXylVerifier() throws Exception {
|
||||||
|
//获取商户私钥
|
||||||
|
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
|
||||||
|
//私钥签名对象
|
||||||
|
PrivateKeySigner privateKeySigner = new PrivateKeySigner(xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey);
|
||||||
|
//身份认证对象
|
||||||
|
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(xylWeChatPaymentConfig.getXylMchId(), privateKeySigner);
|
||||||
|
// 获取证书管理器实例
|
||||||
|
CertificatesManager certificatesManager = CertificatesManager.getInstance();
|
||||||
|
// 向证书管理器增加需要自动更新平台证书的商户信息
|
||||||
|
certificatesManager.putMerchant(xylWeChatPaymentConfig.getXylMchId(), wechatPay2Credentials, xylWeChatPaymentConfig.getXylPaymentKey().getBytes(StandardCharsets.UTF_8));
|
||||||
|
// 从证书管理器中获取verifier
|
||||||
|
return certificatesManager.getVerifier(xylWeChatPaymentConfig.getXylMchId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新医路商户号带有签名的http请求对象
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient对象
|
||||||
|
*/
|
||||||
|
@Bean(name = "xinYiLuWeChatPayClient")
|
||||||
|
public CloseableHttpClient getXinYiLuWeChatPayClient(Verifier xylVerifier) {
|
||||||
|
log.info("开始获取新医路商户带有签名信息的http请求对象........");
|
||||||
|
//获取商户私钥
|
||||||
|
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
|
||||||
|
CloseableHttpClient closeableHttpClient = null;
|
||||||
|
try {
|
||||||
|
log.info("新医路签名验证证书,xinYiLuCertificatesVerifier:{}", xylVerifier);
|
||||||
|
//通过WeChatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
|
||||||
|
closeableHttpClient = WechatPayHttpClientBuilder.create()
|
||||||
|
.withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
|
||||||
|
.withValidator(new WechatPay2Validator(xylVerifier)).build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("新医路验证签名信息失败,失败信息:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
return closeableHttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新医路商户号无签名的http请求对象
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient对象
|
||||||
|
*/
|
||||||
|
@Bean(name = "xinYiLuWeChatPayNoSignClient")
|
||||||
|
public CloseableHttpClient getXinYiLuWeChatPayNoSignClient() {
|
||||||
|
log.info("获取新医路商户的无签名信息的http请求对象.........");
|
||||||
|
//获取商户私钥
|
||||||
|
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
|
||||||
|
//通过WeChatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
|
||||||
|
return WechatPayHttpClientBuilder.create()
|
||||||
|
.withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
|
||||||
|
.withValidator((response) -> true).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取商户的私钥文件
|
||||||
|
*
|
||||||
|
* @param filename 获取商户的私钥文件
|
||||||
|
* @return 商户私钥
|
||||||
|
*/
|
||||||
|
private PrivateKey getPrivateKey(String filename) {
|
||||||
|
try {
|
||||||
|
return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("新医路商户私钥文件不存在,错误原因:{}", e.getMessage());
|
||||||
|
throw new ServiceException("新医路商户私钥文件不存在,请联系管理员!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package com.yf.exam.modules.payment.service;
|
||||||
|
|
||||||
|
public interface PaymentService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
package com.yf.exam.modules.payment.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.yf.exam.config.WeChatPaymentUrlConfig;
|
||||||
|
import com.yf.exam.config.XylWeChatPaymentConfig;
|
||||||
|
import com.yf.exam.core.exception.ServiceException;
|
||||||
|
import com.yf.exam.modules.payment.service.PaymentService;
|
||||||
|
import com.yf.exam.modules.payment.vo.WeChatAppletSignVO;
|
||||||
|
import com.yf.exam.modules.utils.WeChatUtil;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
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;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.springframework.util.Base64Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2025-07-23 09:44
|
||||||
|
**/
|
||||||
|
public class PaymentServiceImpl implements PaymentService {
|
||||||
|
|
||||||
|
@Resource(name = "xinYiLuWeChatPayClient")
|
||||||
|
private CloseableHttpClient xinYiLuWeChatPayClient;
|
||||||
|
@Resource
|
||||||
|
private WeChatPaymentUrlConfig weChatPaymentUrlConfig;
|
||||||
|
@Resource
|
||||||
|
private WeChatUtil weChatUtil;
|
||||||
|
@Resource
|
||||||
|
private XylWeChatPaymentConfig xylWeChatPaymentConfig;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H5下单成功状态码
|
||||||
|
*/
|
||||||
|
private static final int HAVE_BODY_SUCCESS_CODE = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H5下单成功状态码
|
||||||
|
*/
|
||||||
|
private static final int NO_HAVE_BODY_SUCCESS_CODE = 204;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名算法
|
||||||
|
*/
|
||||||
|
private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名方式
|
||||||
|
*/
|
||||||
|
private static final String SIGN_TYPE = "RSA";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求h5下单接口方法
|
||||||
|
*
|
||||||
|
* @param jsApiParams 下单参数
|
||||||
|
* @param paymentDTO 输入参数
|
||||||
|
* @param prepayId JsAp下单接口返回值
|
||||||
|
* @return 结果
|
||||||
|
* @throws Exception 异常信息
|
||||||
|
*/
|
||||||
|
private String requestH5Interface(String jsApiParams, PaymentDTO paymentDTO, String prepayId) throws Exception {
|
||||||
|
//log.info("JsApi请求下单参数 ====> {}", jsApiParams);
|
||||||
|
StringEntity stringEntity = new StringEntity(jsApiParams, StandardCharsets.UTF_8);
|
||||||
|
stringEntity.setContentType("application/json");
|
||||||
|
HttpPost httpPost = new HttpPost(weChatPaymentUrlConfig.getJsapiPalceOrderUrl());
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
CloseableHttpResponse response = null;
|
||||||
|
String payAccount = "";
|
||||||
|
try {
|
||||||
|
response = xinYiLuWeChatPayClient.execute(httpPost);
|
||||||
|
payAccount = "山东柏杏新医健康服务有限公司";
|
||||||
|
//处理响应结果
|
||||||
|
if (Objects.isNull(response)) {
|
||||||
|
//log.error("JsApi下单接口执行错误, 执行账户为 ====> {}", payAccount);
|
||||||
|
throw new ServiceException("JsApi下单接口执行异常,请联系管理员!");
|
||||||
|
}
|
||||||
|
//响应状态码
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
//响应体
|
||||||
|
String result = EntityUtils.toString(response.getEntity());
|
||||||
|
if (statusCode == HAVE_BODY_SUCCESS_CODE) {
|
||||||
|
//请求成功,取出prepay_id的值并放入Redis缓存中,prepay_id的有效期为两小时,此处缓存一个半小时
|
||||||
|
Map<String, Object> resultMap = JSONObject.parseObject(result);
|
||||||
|
prepayId = resultMap.getOrDefault("prepay_id", "").toString();
|
||||||
|
redisTemplate.opsForValue().set(Constants.PREPAY_ID_KEY + paymentDTO.getOrderNo(), prepayId, 5400, TimeUnit.SECONDS);
|
||||||
|
} else if (statusCode == NO_HAVE_BODY_SUCCESS_CODE) {
|
||||||
|
//请求成功,无返回体
|
||||||
|
log.info("JsApi下单成功,无返回值信息!");
|
||||||
|
} else {
|
||||||
|
//请求失败
|
||||||
|
log.error("JsApi下单失败,失败原因为 ====> {}", result);
|
||||||
|
throw new ServiceException("JsApi下单失败,失败原因为:" + result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("JsApi下单失败,失败原因 =====> {}", e.getMessage());
|
||||||
|
throw new ServiceException("JsApi下单失败,请联系管理员!");
|
||||||
|
} finally {
|
||||||
|
if (response != null) {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prepayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建微信小程序调起支付参数设置
|
||||||
|
*
|
||||||
|
* @param prepayId jsapi下单返回参数信息
|
||||||
|
* @param buySource 购买来源
|
||||||
|
* @return 参数信息
|
||||||
|
* @throws Exception 异常信息
|
||||||
|
*/
|
||||||
|
private WeChatAppletSignVO getSignInfo(String prepayId, String buySource) throws Exception {
|
||||||
|
//根据购买来源判断使用泉医到家小程序id还是泉医助手小程序id
|
||||||
|
String appId = BuySourceEnum.TRAINING.getInfo().equals(buySource) ? nurseAppletChatConfig.getAppletId() : appletChatConfig.getAppletId();
|
||||||
|
//随机字符串
|
||||||
|
String nonceStr = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
//时间戳
|
||||||
|
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||||
|
//获取商户私钥
|
||||||
|
PrivateKey privateKey = null;
|
||||||
|
privateKey = weChatUtil.getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
|
||||||
|
if (privateKey == null) {
|
||||||
|
throw new ServiceException("获取商户私钥失败,请联系管理员!");
|
||||||
|
}
|
||||||
|
//计算签名信息
|
||||||
|
prepayId = "prepay_id=" + prepayId;
|
||||||
|
String signatureStr = Stream.of(appId, timestamp, nonceStr, prepayId)
|
||||||
|
.collect(Collectors.joining("\n", "", "\n"));
|
||||||
|
log.info("计算签名认证信息 =====> {}", signatureStr);
|
||||||
|
Signature sign = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||||
|
sign.initSign(privateKey);
|
||||||
|
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||||
|
String paySign = Base64Utils.encodeToString(sign.sign());
|
||||||
|
return WeChatAppletSignVO.builder().appId(appId).timeStamp(timestamp).nonceStr(nonceStr).prepayId(prepayId)
|
||||||
|
.signType(SIGN_TYPE).paySign(paySign).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.yf.exam.modules.payment.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 微信小程序调起支付参数信息
|
||||||
|
* @Author 纪寒
|
||||||
|
* @Date 2022-10-20 09:59:19
|
||||||
|
* @Version 1.0
|
||||||
|
*/
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
public class WeChatAppletSignVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = -2527792374746553807L;
|
||||||
|
/**
|
||||||
|
* 小程序id
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳
|
||||||
|
*/
|
||||||
|
private String timeStamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 随机字符串
|
||||||
|
*/
|
||||||
|
private String nonceStr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单详情扩展字符串,小程序为prepay_id的值
|
||||||
|
*/
|
||||||
|
private String prepayId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名方式
|
||||||
|
*/
|
||||||
|
private String signType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名
|
||||||
|
*/
|
||||||
|
private String paySign;
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.yf.exam.modules.utils;
|
||||||
|
|
||||||
|
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
||||||
|
import com.yf.exam.core.exception.ServiceException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 微信工具类
|
||||||
|
* @Author 纪寒
|
||||||
|
* @Date 2022-10-20 10:11:38
|
||||||
|
* @Version 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class WeChatUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取商户的私钥文件
|
||||||
|
*
|
||||||
|
* @param filename 获取商户的私钥文件
|
||||||
|
* @return 商户私钥
|
||||||
|
*/
|
||||||
|
public PrivateKey getPrivateKey(String filename) {
|
||||||
|
try {
|
||||||
|
return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("商户私钥文件不存在,错误原因:{}", e.getMessage());
|
||||||
|
throw new ServiceException("商户私钥文件不存在,请联系管理员!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,3 +29,19 @@ server:
|
|||||||
min-response-size: 10
|
min-response-size: 10
|
||||||
mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
|
mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
|
||||||
|
|
||||||
|
# 新医路微信商户号配置参数
|
||||||
|
xyl-we-chat-config:
|
||||||
|
# 新医路商户号 1633348407 山东新医路信息科技有限公司 山东柏杏新医健康服务有限公司
|
||||||
|
xyl-mch-id: 1690248007
|
||||||
|
# 新医路商户号API证书序号 7C6A18FC8E1F0445901B1BE1C4DD1ACE284C3D79
|
||||||
|
xyl-mch-serial-no: 760D3316C2F3DF8D1DB05B56A37BFCD3C34EEDA8
|
||||||
|
# 新医路商户私钥文件
|
||||||
|
xyl-private-key-path: baixing_apiclient_key.pem
|
||||||
|
# 新医路API V3版本密钥 Xyl699003981qazVFR4xsw23edcASDFG
|
||||||
|
xyl-payment-key: baixingXINYIHULIZHAN202400000000
|
||||||
|
# 新医路微信支付回调地址 https://quanyidaojia.xinelu.cn
|
||||||
|
xyl-wechat-notify-url: http://8.131.93.145:54097
|
||||||
|
# h5支付接口地址
|
||||||
|
we-chat-payment-url-config:
|
||||||
|
# h5下单接口地址
|
||||||
|
h5-palce-order-url: https://api.mch.weixin.qq.com/v3/pay/transactions/h5
|
||||||
|
|||||||
28
exam-admin/src/main/resources/baixing_apiclient_key.pem
Normal file
28
exam-admin/src/main/resources/baixing_apiclient_key.pem
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDUI5gWlq+q0K1k
|
||||||
|
+NZZe2qJhUH1qce00Dc6j7Rc6Ubnb7u7/UEqJMc/N2m/oIBdb5Lmb3OJZDhV8kHE
|
||||||
|
S1/U9aM/UZEW2fJWkcHxCyIreVJvETSCdFtgvk/lzwkkLZZiA8Hb0Irq4nJB+QFl
|
||||||
|
K4o7LLDMYhTI14WeH46jgOTdk5e1jKl2F9ShAt9TX3ZHVgnY4wp+iG3xAZytjyLJ
|
||||||
|
szbPLVrYAt3JTfzstsdfIIafKssBFExglzjnCeS6DCBDZkr9vEqG921nAKVVlC6j
|
||||||
|
CPDtxITddF25+uI7c0CAozCA0TAoXL7tyzgfnzfy3KkLz3wmMyb5IN/6vDg4A559
|
||||||
|
wNNmE1jdAgMBAAECggEAKKs6OPpiawjedQEPdtAmOH8HiiUmWA+ixuNN3JIMOco9
|
||||||
|
32hJ2d57JC9nYolOkpsVOoAbUjeYZUGwQgWBNb5xsW3dttfJkbcXyzIrNtJnb0uJ
|
||||||
|
GYldC0rw3km2ouzqa5f0zkNInocTCHrIPbD/KyECM+yJt4c54nqCSe4n8iKdbvxS
|
||||||
|
vNKcpQatfs2Egm1PcHsZ00bNSWlii/cz30CVUGCPYx0TZ0WhcjI5nFHINpRIM9rJ
|
||||||
|
A0K2R0rqE6/9MXNAJe4+h2TRvmWghBhx+QHCQRnc5ExIGoVsSiGvQkkMQmW8wmmw
|
||||||
|
SMxjAWjWNphFh4a+6Zv3UAfRyIjaS40RYyN7y3MeAQKBgQD+kjDOlNrsGoP35dbo
|
||||||
|
NuZieFWqm1gowA2cRwoAJ/qImllU7TTgVAyrMo9vu36ABw+rhDW6rSFB9r7hGGXj
|
||||||
|
NS5RfiezazwGj7ymQj3WtUoJlCmCuOGVIxCbQPUgSRc7+VBdvNf+6oUhIua7ncEG
|
||||||
|
WNAmcbU0gdAjG5S7j/LzOoStoQKBgQDVVG4gDeGktG+EQAsdcItm78Wzb+7P/5Bc
|
||||||
|
uyISCfENqbmzzfogRHqZEN5C+ZZP3S/On6q7jpDUWFP+WBBED6hezESo4kVA7Zh9
|
||||||
|
LsGU58nTGijxMoo05eUaXmZzvmjgNmpMHOMCKBCPnGZ67DeRwB/oFAfKwx4RRa++
|
||||||
|
VHrYnLSJvQKBgQCnjJRvAu3rw6/j8vQ1Nhz/5m+LsF6fw3exyde9LpLoYZ42FUFd
|
||||||
|
/DOyYb6iLWce4IbhvkyWpuhiwAH1qNc2aYQowr1ii0ugje3+B08oB33JPCjuDrz6
|
||||||
|
KW/+nww2yaRvJrJMX8RR1Qz2OEBgb33hrYaiJui6vE2/LaIAqMegan10wQKBgCVU
|
||||||
|
XODnDPERUeJGgqtoIjylAGdh0tw60Dwp0tBtRO0rIf/Ar2AuG3Xlab82hYL8JX12
|
||||||
|
mx2u2NEPk8MSDeabBs9v1yPmVFAEQ4bEQ8OWu85g6YErYtvWzrxKgIsIarmxS/B9
|
||||||
|
rYuXDy7SI2ynISI0CGFIAAUPF5fWJeacSdLVuRHRAoGBAO2cBz0bZJdKhoR+NMqN
|
||||||
|
CHpiTY+72hLhy4LB0XV7KsEumI0KI2i5EA4/cD+VCb+Qe6Hagoy78W/0s5MwBWzk
|
||||||
|
OwJ5JxBPZZROGwegxfb1P3NC1wazprKVTYbIUSomFbON4qQDjou13Y7gFeWsv2gE
|
||||||
|
Xq/BCiAbrbmltVKdxdqtRaQP
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
Loading…
Reference in New Issue
Block a user