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

179 lines
6.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}