wisdomPark/gather-app/src/main/java/com/ruoyi/database/service/WechatMiniProgramPayService...

179 lines
6.5 KiB
Java
Raw Normal View History

2025-11-26 11:16:51 +08:00
package com.ruoyi.database.service;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.service.WxPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.util.*;
@Service
public class WechatMiniProgramPayService {
@Autowired
private WxPayService wxPayService;
@Value("${wx.pay.notifyUrl}")
private String notifyUrl;
/**
* 创建小程序支付订单
*/
public Map<String, Object> createJsapiOrder(String openid, String orderId, Integer amount,
String description, String clientIp) {
try {
System.out.println("开始创建支付订单: " + orderId + ", openid: " + openid + ", 金额: " + amount + "");
// 构建支付请求
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.outTradeNo(orderId) // 商户订单号
.totalFee(amount) // 金额(分)
.body(description) // 商品描述
.tradeType("JSAPI") // 交易类型:小程序支付
.openid(openid) // 用户openid
.spbillCreateIp(clientIp) // 终端IP
.notifyUrl(notifyUrl) // 支付结果通知地址
.build();
System.out.println("调用微信支付统一下单API...");
// 调用微信支付API
WxPayUnifiedOrderResult result = wxPayService.unifiedOrder(request);
// 生成小程序支付参数
Map<String, String> paymentParams = createPaymentParams(result);
System.out.println("支付订单创建成功: " + orderId + ", prepay_id: " + result.getPrepayId());
// 返回结果
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("paymentParams", paymentParams);
response.put("prepayId", result.getPrepayId());
return response;
} catch (Exception e) {
System.err.println("创建支付订单失败: " + orderId + ", 错误: " + e.getMessage());
e.printStackTrace();
Map<String, Object> response = new HashMap<>();
response.put("success", false);
response.put("message", "创建支付订单失败: " + e.getMessage());
return response;
}
}
/**
* 生成小程序支付参数
*/
private Map<String, String> createPaymentParams(WxPayUnifiedOrderResult result) {
Map<String, String> paymentParams = new HashMap<>();
// 小程序支付必需的参数
paymentParams.put("appId", result.getAppid());
paymentParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
paymentParams.put("nonceStr", result.getNonceStr());
paymentParams.put("package", "prepay_id=" + result.getPrepayId());
paymentParams.put("signType", "MD5");
// 生成签名
String sign = generateSign(paymentParams);
paymentParams.put("paySign", sign);
System.out.println("生成支付参数: " + paymentParams);
return paymentParams;
}
/**
* 生成支付签名
*/
private String generateSign(Map<String, String> params) {
try {
// 按照参数名ASCII字典序排序
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
// 拼接字符串
StringBuilder sb = new StringBuilder();
for (String key : keys) {
if ("sign".equals(key) || key.isEmpty() || params.get(key) == null) {
continue;
}
sb.append(key).append("=").append(params.get(key)).append("&");
}
// 加上API密钥
sb.append("key=").append(wxPayService.getConfig().getMchKey());
String signStr = sb.toString();
System.out.println("签名原串: " + signStr);
// MD5加密并转大写
String sign = md5(signStr).toUpperCase();
System.out.println("生成签名: " + sign);
return sign;
} catch (Exception e) {
throw new RuntimeException("生成签名失败", e);
}
}
/**
* MD5加密
*/
private String md5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
}
/**
* 获取客户端IP地址
*/
public String getClientIpAddress(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 如果是多级代理取第一个IP
if (ip != null && ip.contains(",")) {
ip = ip.substring(0, ip.indexOf(",")).trim();
}
// 本地开发环境处理
if ("0:0:0:0:0:0:0:1".equals(ip) || "127.0.0.1".equals(ip)) {
ip = "123.123.123.123"; // 替换为你的服务器公网IP
}
System.out.println("获取到客户端IP: " + ip);
return ip;
}
/**
* 获取WxPayService实例
*/
public WxPayService getWxPayService() {
return wxPayService;
}
}