在Spring Boot中对接微信支付的详细步骤如下:
一、前期准备
-
注册微信支付商户账号
-
前往微信支付商户平台注册并完成实名认证。
-
获取以下关键信息:
appid
:公众号或小程序的AppID。mch_id
:微信支付商户号。api_key
:商户平台设置的API密钥(用于签名)。notify_url
:支付结果回调地址(需公网可访问)。
-
-
配置开发环境
- 确保项目使用Java 8+和Spring Boot 2.x。
- 配置域名和HTTPS(微信支付要求回调地址必须为HTTPS)。
二、添加依赖
在pom.xml
中添加必要依赖:
xml
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- XML处理 -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- 其他Spring Boot基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
三、配置参数
在application.yml
中配置微信支付参数:
vbnet
wxpay:
appid: your_appid
mch-id: your_mch_id
api-key: your_api_key
notify-url: https://your-domain.com/pay/notify
通过@ConfigurationProperties
读取配置:
less
@Configuration
@ConfigurationProperties(prefix = "wxpay")
@Data
public class WxPayConfig {
private String appid;
private String mchId;
private String apiKey;
private String notifyUrl;
}
四、实现工具类
- 签名工具
vbnet
public class WxPayUtil {
public static String generateSign(Map<String, String> data, String apiKey) {
// 按参数名ASCII字典序排序
List<String> keyList = new ArrayList<>(data.keySet());
Collections.sort(keyList);
StringBuilder sb = new StringBuilder();
for (String key : keyList) {
if (!key.equals("sign") && data.get(key) != null && !data.get(key).isEmpty()) {
sb.append(key).append("=").append(data.get(key)).append("&");
}
}
sb.append("key=").append(apiKey);
// MD5签名(或使用HMAC-SHA256)
return DigestUtils.md5Hex(sb.toString()).toUpperCase();
}
}
- HTTP请求工具
java
public class WxPayHttpClient {
public static String post(String url, String xmlData) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(xmlData, "UTF-8"));
post.setHeader("Content-Type", "application/xml");
CloseableHttpResponse response = client.execute(post);
return EntityUtils.toString(response.getEntity(), "UTF-8");
}
}
五、统一下单接口
- Controller入口
less
@RestController
@RequestMapping("/pay")
public class WxPayController {
@Autowired
private WxPayConfig wxPayConfig;
@PostMapping("/create")
public String createOrder(@RequestBody OrderRequest orderRequest) throws Exception {
Map<String, String> data = new HashMap<>();
data.put("appid", wxPayConfig.getAppid());
data.put("mch_id", wxPayConfig.getMchId());
data.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
data.put("body", orderRequest.getBody());
data.put("out_trade_no", orderRequest.getOrderNo());
data.put("total_fee", String.valueOf(orderRequest.getTotalFee())); // 单位:分
data.put("spbill_create_ip", "123.12.12.123");
data.put("notify_url", wxPayConfig.getNotifyUrl());
data.put("trade_type", "NATIVE"); // JSAPI、APP等
// 生成签名
String sign = WxPayUtil.generateSign(data, wxPayConfig.getApiKey());
data.put("sign", sign);
// 转换为XML
String xmlData = mapToXml(data);
// 调用微信统一下单接口
String response = WxPayHttpClient.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlData);
// 解析返回的XML,获取code_url或prepay_id
Map<String, String> respData = parseXml(response);
return respData.get("code_url");
}
}
六、处理支付回调
- 回调接口实现
xml
@PostMapping("/notify")
public String payNotify(HttpServletRequest request) throws Exception {
// 读取回调数据
String xmlData = IOUtils.toString(request.getInputStream(), "UTF-8");
Map<String, String> notifyData = parseXml(xmlData);
// 验证签名
String sign = notifyData.get("sign");
String localSign = WxPayUtil.generateSign(notifyData, wxPayConfig.getApiKey());
if (!sign.equals(localSign)) {
return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
}
// 处理业务逻辑(如更新订单状态)
String orderNo = notifyData.get("out_trade_no");
orderService.updateOrderPaid(orderNo);
// 返回成功响应
return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
}
七、其他功能
-
订单查询
- 调用
https://api.mch.weixin.qq.com/pay/orderquery
接口,传递订单号查询状态。
- 调用
-
退款
- 调用
https://api.mch.weixin.qq.com/secapi/pay/refund
接口,需使用商户证书(.p12
文件)。
- 调用
八、注意事项
- 金额单位:微信支付以分为单位(如100表示1元)。
- 超时处理:设置合理的超时时间和重试机制。
- 幂等性:处理回调时确保重复通知不会导致重复业务操作。
- 日志记录:记录关键步骤日志,便于排查问题。
- 沙箱测试 :使用微信支付沙箱环境进行测试。
通过以上步骤,即可在Spring Boot项目中完成微信支付的对接。具体实现需参考微信支付官方文档调整参数和接口调用方式。