微信支付部分

This commit is contained in:
menxipeng
2025-11-24 23:42:09 +08:00
parent b29d2c696c
commit c7fd167167
17 changed files with 523 additions and 60 deletions

View File

@@ -41,4 +41,6 @@ public class CallBackController {
}
}
}

View File

@@ -0,0 +1,142 @@
package com.ruoyi.web.controller.back;
import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.system.service.IOrderInfoService;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/call/back")
public class WechatPayNotifyController {
@Autowired
private IOrderInfoService orderService;
/**
* 微信支付结果回调接口
* POST /api/wechat/pay/notify
*/
@PostMapping("/wechat")
public Map<String, String> handleWechatPayNotify(HttpServletRequest request,
HttpServletResponse response) {
Map<String, String> result = new HashMap<>();
try {
System.out.println("收到微信支付回调通知");
// 1. 构建回调参数
RequestParam requestParam = buildRequestParam(request);
NotificationParser parser = new NotificationParser();
// 2. 解析并验证通知
Transaction transaction = parser.parse(requestParam, Transaction.class);
System.out.println("解析支付通知成功:");
System.out.println("商户订单号: " + transaction.getOutTradeNo());
System.out.println("微信支付订单号: " + transaction.getTransactionId());
System.out.println("交易状态: " + transaction.getTradeState());
System.out.println("交易类型: " + transaction.getTradeType());
System.out.println("金额: " + transaction.getAmount().getTotal());
// 3. 处理业务逻辑
orderService.processPaymentResult(transaction);
// if (processResult) {
// // 4. 返回成功响应
// result.put("code", "SUCCESS");
// result.put("message", "成功");
// System.out.println("支付回调处理成功");
// } else {
// result.put("code", "FAIL");
// result.put("message", "处理失败");
// System.err.println("支付回调处理失败");
// }
} catch (Exception e) {
System.err.println("支付回调处理异常: " + e.getMessage());
e.printStackTrace();
// 返回失败响应
result.put("code", "FAIL");
result.put("message", "处理异常: " + e.getMessage());
}
return result;
}
/**
* 从HttpServletRequest构建RequestParam
*/
private RequestParam buildRequestParam(HttpServletRequest request) throws Exception {
// 获取微信回调的头部信息
String wechatpaySerial = request.getHeader("Wechatpay-Serial");
String wechatpaySignature = request.getHeader("Wechatpay-Signature");
String wechatpayTimestamp = request.getHeader("Wechatpay-Timestamp");
String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
String wechatpaySignatureType = request.getHeader("Wechatpay-Signature-Type");
System.out.println("回调头部信息:");
System.out.println("Wechatpay-Serial: " + wechatpaySerial);
System.out.println("Wechatpay-Timestamp: " + wechatpayTimestamp);
System.out.println("Wechatpay-Nonce: " + wechatpayNonce);
System.out.println("Wechatpay-Signature-Type: " + wechatpaySignatureType);
// 读取请求体
String body = getRequestBody(request);
System.out.println("回调请求体: " + body);
return new RequestParam.Builder()
.serialNumber(wechatpaySerial)
.nonce(wechatpayNonce)
.signature(wechatpaySignature)
.timestamp(wechatpayTimestamp)
.signType(wechatpaySignatureType)
.body(body)
.build();
}
/**
* 读取请求体内容
*/
private String getRequestBody(HttpServletRequest request) throws Exception {
StringBuilder stringBuilder = new StringBuilder();
try (java.io.BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
}
return stringBuilder.toString();
}
//
//
// /**
// * 处理退款逻辑
// */
// private boolean handleRefund(Order order, Transaction transaction) {
// // 实现退款逻辑
// System.out.println("处理退款: " + order.getOutTradeNo());
// return true;
// }
//
// /**
// * 处理订单关闭逻辑
// */
// private boolean handleClosedPayment(Order order, Transaction transaction) {
// // 实现订单关闭逻辑
// System.out.println("处理订单关闭: " + order.getOutTradeNo());
// return true;
// }
}

View File

@@ -3,14 +3,17 @@ package com.ruoyi.web.controller.client;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.ruoyi.common.core.domain.dto.OrderCreateRequest;
import com.ruoyi.common.core.domain.dto.PaymentRequest;
import com.ruoyi.common.core.domain.dto.RefundRequest;
import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.IOrderInfoService;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import org.aspectj.weaver.loadtime.Aj;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -46,6 +49,12 @@ public class ClientOrderInfoController extends BaseController
}
}
// 调起微信支付参数
@GetMapping("/wechatPay")
public AjaxResult wechatPay(@RequestParam("orderId") String orderId) {
return orderInfoService.wechatPay(orderId);
}
/**
* 支付订单
*/

View File

@@ -53,15 +53,17 @@ public class ClientShopUserController {
ShopUser shopUser = new ShopUser();
shopUser.setUserId(userId);
shopUser.setStatus(2L);
String code = redisCache.getCacheObject("sms_code:"+shopUser.getPhone());
String code = redisCache.getCacheObject("sms_code:"+param.getPhone());
if (param.getCode() != null) {
if (Objects.equals(code, param.getCode())) {
shopUserService.updateShopUserId(shopUser);
int delInt = shopUserService.removeById(userId);
if (delInt > 0){
return AjaxResult.success();
}
}else {
return AjaxResult.error("验证码错误");
}
}
return AjaxResult.error("注销账号失败");
}

View File

@@ -156,3 +156,11 @@ umApp:
# androidKey: 687b2df479267e0210b79b6f
IOSKey: 68ef6aa88560e34872ca7b41
#Q1w2e3r4
wechat:
appId: wx87084c0b6aa7aed6
merchantId: 1732990772
privateKeyPath: D:\musicpro\apiclient_key.pem
merchantCertPath: D:\musicpro\apiclient_cert.pem
wechatPayCertPath: D:\musicpro\pub_key.pem
publicKeyId: PUB_KEY_ID_0117329907722025112100111619002400
apiV3Key: ASSSUNTvttuiwqazuu12tnftANtfb004

View File

@@ -0,0 +1,60 @@
package com.ruoyi.common.constant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* 描述:
*
* @author MXP by 2025/11/24
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Configuration
@Component
public class WeChatConfig implements InitializingBean {
// merchantId: 1732990772
// privateKeyPath: D:\musicpro\apiclient_key.pem
// merchantCertPath: D:\musicpro\apiclient_cert.pem
// wechatPayCertPath: D:\musicpro\pub_key.pem
// publicKeyId: PUB_KEY_ID_0117329907722025112100111619002400
@Value("${wechat.appId}")
public String appId;
@Value("${wechat.merchantId}")
public String merchantId;
@Value("${wechat.privateKeyPath}")
public String privateKeyPath;
@Value("${wechat.merchantCertPath}")
public String merchantCertPath;
@Value("${wechat.wechatPayCertPath}")
public String wechatPayCertPath;
@Value("${wechat.apiV3Key}")
public String apiV3Key;
@Value("${wechat.publicKeyId}")
public String publicKeyId;
public static String APP_ID;
public static String MERCHANT_ID;
public static String PRIVATE_KEY_PATH;
public static String MERCHANT_CERT_PATH;
public static String WECHAT_PAY_CERT_PATH;
public static String API_V3_KEY;
public static String PUBLIC_KEY_ID;
@Override
public void afterPropertiesSet() {
APP_ID = this.appId;
MERCHANT_ID = this.merchantId;
PRIVATE_KEY_PATH = this.privateKeyPath;
MERCHANT_CERT_PATH = this.merchantCertPath;
WECHAT_PAY_CERT_PATH = this.wechatPayCertPath;
API_V3_KEY = this.apiV3Key;
PUBLIC_KEY_ID = this.publicKeyId;
}
}

View File

@@ -103,4 +103,7 @@ public class OrderInfo extends BaseEntity
/** 乐观锁版本号 */
@Excel(name = "乐观锁版本号")
private Long version;
private String description;
}

View File

@@ -137,7 +137,7 @@ public class SecurityConfig
// /client/index/re/music
requests.antMatchers("/login", "/register","/client/shopLogin","/file/download/**", "/captchaImage",
"/client/getCode","/client/file/**","/call/back/**","/client/index/getBanner",
"/client/index/getCategory","/client/index/re/bind/music","/client/index/re/music").permitAll()
"/client/index/getCategory","/client/index/re/bind/music","/client/index/re/music","/client/version/getLastVersion").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

View File

@@ -93,4 +93,6 @@ public interface ShopUserMapper {
int updateShopUserId(ShopUser shopUser);
int updateDeviceIdByPhone(ShopUserResq shopUser);
int deleteShopUserByUserId(Long userId);
}

View File

@@ -6,6 +6,8 @@ import com.ruoyi.common.core.domain.dto.OrderCreateRequest;
import com.ruoyi.common.core.domain.dto.PaymentRequest;
import com.ruoyi.common.core.domain.dto.RefundRequest;
import com.ruoyi.common.core.domain.vo.OrderInfoVO;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import java.util.List;
@@ -132,4 +134,8 @@ public interface IOrderInfoService
List<OrderInfoVO> selectOrderInfoVOList(OrderInfo orderInfo);
AjaxResult rePayOrder(PaymentRequest request);
AjaxResult wechatPay(String orderId);
AjaxResult processPaymentResult(Transaction transaction);
}

View File

@@ -26,4 +26,6 @@ public interface ShopUserService {
ShopUser selectUserById(Long userId);
int updateShopUserId(ShopUser shopUser);
int removeById(Long userId);
}

View File

@@ -308,6 +308,11 @@ public class CShopUserServiceImpl implements ShopUserService {
return shopUserMapper.updateShopUser(shopUser);
}
@Override
public int removeById(Long userId) {
return shopUserMapper.deleteShopUserByUserId(userId);
}
public ShopUser loginAndRegis(ShopUserResq shopUser) {
ShopUser member = shopUserMapper.selectShopUserByPhone(shopUser.getPhone());
if (shopUser.getPhone() != null && StringUtils.isNull(member)) {

View File

@@ -9,6 +9,7 @@ import com.ruoyi.common.core.domain.entity.PayStatusEnum;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.domain.vo.OrderInfoVO;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
@@ -16,6 +17,12 @@ import com.ruoyi.system.mapper.OrderInfoMapper;
import com.ruoyi.system.service.IOrderInfoService;
import com.ruoyi.system.util.AppleyPay;
import com.ruoyi.system.util.PaymentUtil;
import com.ruoyi.system.util.WeChatPayUtil;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -32,12 +39,19 @@ import java.util.*;
@Service
public class OrderInfoServiceImpl implements IOrderInfoService
{
private static final Logger log = LoggerFactory.getLogger(OrderInfoServiceImpl.class);
@Autowired
private OrderInfoMapper orderInfoMapper;
@Autowired
private PaymentUtil paymentUtil;
@Autowired
private WeChatPayUtil weChatPayUtil;
/**
* 查询【请填写功能名称】
*
@@ -347,6 +361,104 @@ public class OrderInfoServiceImpl implements IOrderInfoService
return null;
}
@Override
public AjaxResult wechatPay(String orderId) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return AjaxResult.error(401, "用户未登录");
}
// 参数校验
if (StringUtils.isEmpty(orderId)) {
return AjaxResult.error("订单ID不能为空");
}
// 查询订单
OrderInfo orderInfo = selectOrderByOrderId(orderId);
if (orderInfo == null) {
return AjaxResult.error("订单不存在");
}
// 检查订单状态
if (orderInfo.getPayStatus() != PayStatusEnum.CREATE.getStatus()) {
return AjaxResult.error("订单状态不正确");
}
// 检查用户权限
if (!loginUser.getUserId().equals(orderInfo.getUserId())) {
return AjaxResult.error("无权限操作此订单");
}
PrepayWithRequestPaymentResponse result = weChatPayUtil.prepayWithRequestPayment(orderInfo);
return AjaxResult.success("获取微信支付参数成功",result);
}
@Override
public AjaxResult processPaymentResult(Transaction transaction) {
try {
String outTradeNo = transaction.getOutTradeNo();
String tradeState = transaction.getTradeState().name();
String transactionId = transaction.getTransactionId();
int totalAmount = transaction.getAmount().getTotal();
String successTime = transaction.getSuccessTime();
log.info("订单号: {}交易状态: {}支付金额: {}", outTradeNo, tradeState, totalAmount);
// 1. 根据商户订单号查询本地订单
OrderInfo order = orderInfoMapper.selectOrderByOrderId(outTradeNo);
if (order == null) {
return AjaxResult.error("未找到对应订单");
}
// 2. 检查订单是否已经处理过(防止重复通知)
if ((OrderStatus.PAID.getCode()).equals(order.getPayStatus())) {
return AjaxResult.success("订单已支付,跳过处理");
}
//order.getAmount() 元转分
int amount = order.getAmount().multiply(new BigDecimal(100)).intValue();
// 3. 验证金额是否一致
if (amount != totalAmount) {
return AjaxResult.error("金额不一致");
}
// 4. 根据交易状态处理业务
if ("SUCCESS".equals(tradeState)) {
// 计算服务开始和结束时间
Date startTime = new Date();
// 支付成功
// 设置订单信息
order.setPayStatus(2L); // 2-已完成
order.setPayTime(DateUtils.getNowDate());
order.setStartTime(startTime);
order.setTradeNo(transactionId);
order.setCallbackContent(outTradeNo); // 保存交易ID
order.setCallTime(DateUtils.getNowDate());
order.setUpdateTime(DateUtils.getNowDate());
Date endTime = AppleyPay.calculateEndTime(startTime, order.getPackageType());
order.setEndTime(endTime);
return AjaxResult.success();
} else if ("REFUND".equals(tradeState)) {
// 转入退款
//return handleRefund(order, transaction);
} else if ("CLOSED".equals(tradeState)) {
// 已关闭
//return handleClosedPayment(order, transaction);
} else {
// 其他状态
log.info("未知状态: " + tradeState);
// 仍然返回成功,避免微信重复通知
}
} catch (Exception e) {
log.error("处理订单异常: {}", e.getMessage());
e.printStackTrace();
}
return AjaxResult.error("处理订单异常");
}
@Override
@Transactional
public AjaxResult confirmShipment(String orderId) {

View File

@@ -283,7 +283,7 @@ public class AppleyPay {
}
// 设置订单信息
orderInfo.setPayStatus(2L); // 2-待出货
orderInfo.setPayStatus(2L); // 2-已完成
orderInfo.setPayTime(DateUtils.getNowDate());
orderInfo.setStartTime(startTime);
orderInfo.setTradeNo(transactionId);
@@ -362,7 +362,7 @@ public class AppleyPay {
* @param packageType 套餐类型1-月付, 3-季付, 6-半年付, 12-年付
* @return 结束时间
*/
private Date calculateEndTime(Date startTime, String packageType) {
public static Date calculateEndTime(Date startTime, String packageType) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTime);

View File

@@ -1,58 +1,97 @@
package com.ruoyi.system.util;
import cn.hutool.core.util.IdUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.app.AppServiceExtension;
import com.wechat.pay.java.service.payments.app.model.CloseOrderRequest;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.app.model.QueryOrderByIdRequest;
import com.wechat.pay.java.service.payments.app.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.model.Transaction;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class WeChatAppServiceExtensionExample {
/**
* 商户号
*/
public static String merchantId = "190000****";
public static String merchantId = "1732990772";
/**
* 商户API私钥路径
*/
public static String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem";
public static String privateKeyPath = "D:\\musicpro\\apiclient_key.pem";
/**
* 商户证书序列号
*/
public static String merchantSerialNumber = "5157F09EFDC096DE15EBE81A47057A72********";
private static String merchantCertPath = "D:\\musicpro\\apiclient_cert.pem";
private static String wechatPayCertPath = "D:\\musicpro\\pub_key.pem";
/**
* 商户APIV3密钥
*/
public static String apiV3Key = "...";
public static String apiV3Key = "ASSSUNTvttuiwqazuu12tnftANtfb004";
public static AppServiceExtension service;
public static void main(String[] args) {
// 初始化商户配置
public static void main(String[] args) throws CertificateException, FileNotFoundException {
// 2. 加载商户证书并获取序列号
X509Certificate merchantCertificate = PemUtil.loadX509FromPath(merchantCertPath);
String merchantSerialNumber = merchantCertificate.getSerialNumber().toString(16).toUpperCase();
Config config =
new RSAAutoCertificateConfig.Builder()
new RSAPublicKeyConfig.Builder()
.merchantId(merchantId)
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
.privateKeyFromPath(privateKeyPath)
.publicKeyFromPath(wechatPayCertPath)
.publicKeyId("PUB_KEY_ID_0117329907722025112100111619002400")
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3Key)
.build();
// 初始化服务
service = new AppServiceExtension.Builder().config(config).build();
// // 初始化服务
// service = new AppServiceExtension.Builder().config(config).build();
AppServiceExtension service = new AppServiceExtension.Builder().config(config).build();
// 跟之前下单示例一样,填充预下单参数
PrepayRequest request = new PrepayRequest();
request.setAppid("wx87084c0b6aa7aed6");
request.setDescription("测试");
request.setMchid(merchantId);
request.setOutTradeNo("andhadwdbawqd2");
//request.setTimeExpire("2025-11-24T21:48:31+08:00");
request.setNotifyUrl("https://www.wechat.com");
Amount amount = new Amount();
amount.setTotal(1);
amount.setCurrency("CNY");
request.setAmount(amount);
// response包含了调起支付所需的所有参数可直接用于前端调起支付
PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
System.out.println(response);
try {
// ... 调用接口
PrepayWithRequestPaymentResponse response = prepayWithRequestPayment();
System.out.println(response);
} catch (HttpException e) { // 发送HTTP请求失败
// PrepayWithRequestPaymentResponse response = prepayWithRequestPayment();
// System.out.println(response);
} catch (HttpException e) {
e.printStackTrace();// 发送HTTP请求失败
// 调用e.getHttpRequest()获取请求打印日志或上报监控更多方法见HttpException定义
} catch (ServiceException e) { // 服务返回状态小于200或大于等于300例如500
// 调用e.getResponseBody()获取返回体打印日志或上报监控更多方法见ServiceException定义
@@ -66,41 +105,41 @@ public class WeChatAppServiceExtensionExample {
*/
public static void closeOrder() {
CloseOrderRequest request = new CloseOrderRequest();
// 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// 调用接口
service.closeOrder(request);
// CloseOrderRequest request = new CloseOrderRequest();
// // 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// // 调用接口
// service.closeOrder(request);
}
/**
* APP支付下单并返回APP调起支付数据
*/
public static PrepayWithRequestPaymentResponse prepayWithRequestPayment() {
PrepayRequest request = new PrepayRequest();
// 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// 调用接口
return service.prepayWithRequestPayment(request);
}
/**
* 微信支付订单号查询订单
*/
public static Transaction queryOrderById() {
QueryOrderByIdRequest request = new QueryOrderByIdRequest();
// 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// 调用接口
return service.queryOrderById(request);
}
/**
* 商户订单号查询订单
*/
public static Transaction queryOrderByOutTradeNo() {
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
// 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// 调用接口
return service.queryOrderByOutTradeNo(request);
}
// /**
// * APP支付下单并返回APP调起支付数据
// */
// public static PrepayWithRequestPaymentResponse prepayWithRequestPayment() {
// PrepayRequest request = new PrepayRequest();
// // 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// // 调用接口
// return service.prepayWithRequestPayment(request);
// }
//
// /**
// * 微信支付订单号查询订单
// */
// public static Transaction queryOrderById() {
//
// QueryOrderByIdRequest request = new QueryOrderByIdRequest();
// // 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// // 调用接口
// return service.queryOrderById(request);
// }
//
// /**
// * 商户订单号查询订单
// */
// public static Transaction queryOrderByOutTradeNo() {
//
// QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
// // 调用request.setXxx(val)设置所需参数具体参数可见Request定义
// // 调用接口
// return service.queryOrderByOutTradeNo(request);
// }
}

View File

@@ -0,0 +1,67 @@
package com.ruoyi.system.util;
import com.ruoyi.common.constant.WeChatConfig;
import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.app.AppServiceExtension;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.security.cert.X509Certificate;
/**
* 描述:
*
* @author MXP by 2025/11/24
*/
@Component
public class WeChatPayUtil {
public PrepayWithRequestPaymentResponse prepayWithRequestPayment(OrderInfo orderInfo){
// 2. 加载商户证书并获取序列号
X509Certificate merchantCertificate = PemUtil.loadX509FromPath(WeChatConfig.MERCHANT_CERT_PATH);
String merchantSerialNumber = merchantCertificate.getSerialNumber().toString(16).toUpperCase();
Config config =
new RSAPublicKeyConfig.Builder()
.merchantId(WeChatConfig.MERCHANT_ID)
.privateKeyFromPath(WeChatConfig.PRIVATE_KEY_PATH)
.publicKeyFromPath(WeChatConfig.WECHAT_PAY_CERT_PATH)
.publicKeyId(WeChatConfig.PUBLIC_KEY_ID)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(WeChatConfig.API_V3_KEY)
.build();
AppServiceExtension service = new AppServiceExtension.Builder().config(config).build();
// 跟之前下单示例一样,填充预下单参数
PrepayRequest request = new PrepayRequest();
request.setAppid(WeChatConfig.APP_ID);
request.setDescription(orderInfo.getPackageType());
request.setMchid(WeChatConfig.MERCHANT_ID);
request.setOutTradeNo(String.valueOf(orderInfo.getOrderId()));
//request.setTimeExpire("2025-11-24T21:48:31+08:00");
request.setNotifyUrl("https://lingxiapi.mingyuegn.top/prod-api/call/back/wechat");
Amount amount = new Amount();
// orderInfo.getAmount() 元转分
amount.setTotal(orderInfo.getAmount().multiply(new BigDecimal(100)).intValue());
amount.setCurrency("CNY");
request.setAmount(amount);
// response包含了调起支付所需的所有参数可直接用于前端调起支付
return service.prepayWithRequestPayment(request);
// "appid": "wxd678efh567hg6787",
// "partnerid": "190000XXXX",
// "prepayid": "wx26144052643535f4e6f9d125d829730000",
// "package": "Sign=WXPay",
// "noncestr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
// "timestamp": "1719123456",
// "sign": "A8422B7785FD739A8BC1E5A3F3626XXX"
}
}

View File

@@ -269,4 +269,8 @@
#{userId}
</foreach>
</select>
<delete id="deleteShopUserByUserId">
delete from shop_user where user_id = #{userId}
</delete>
</mapper>