1.打包SDK到本地仓库
首先,下载SDK打包并安装到本地的maven仓库,方便在项目中使用。
进入下载的SDK的项目目录,然后打开黑窗口,输入命令:
mvn source:jar install -Dmaven.test.skip=true
2.引入依赖
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>3.0.9</version>
</dependency>
3.加入配置
pay:
wx:
appID: #公众账号ID
mchID: #商户号
key: #商户密钥
payType: #交易类型
notifyUrl: #回调地址
4.定义配置类
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfigImpl;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PayConfiguration {
@Bean
@ConfigurationProperties(prefix = "pay.wx")
public WXPayConfigImpl payConfig(){
return new WXPayConfigImpl();
}
/**
* 注册WXPay对象
* @param payConfig 支付相关配置
* @return WXPay对象
* @throws Exception 连结WX失败时用到
*/
@Bean
public WXPay wxPay(WXPayConfigImpl payConfig) throws Exception {
return new WXPay(payConfig);
}
}
5.微信工具类
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfigImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class PayUtils {
@Autowired
private WXPay wxPay;
@Autowired
private WXPayConfigImpl payConfig;
//构造二维码--订单号,总金额,商品名称
public String createOrder(String orderNo, Long totalPay, String desc){
Map<String, String> data = new HashMap<>();
// 商品描述
data.put("body", desc);
// 订单号
data.put("out_trade_no", orderNo);
//金额,单位是分
data.put("total_fee", totalPay.toString());
//调用微信支付的终端IP
data.put("spbill_create_ip", "127.0.0.1");
//回调地址
data.put("notify_url", payConfig.getNotifyUrl());
// 交易类型为扫码支付
data.put("trade_type", payConfig.getPayType());
// 利用wxPay工具,完成下单
Map<String, String> result = null;
try {
result = wxPay.unifiedOrder(data);
} catch (Exception e) {
log.error("【微信下单】创建预交易订单异常失败", e);
throw new RuntimeException("微信下单失败", e);
}
// 校验业务状态
String resultCode = result.get("result_code");
if ("FAIL".equals(resultCode)) {
log.error("【微信支付】微信支付业务失败,错误码:{},原因:{}", result.get("err_code"), result.get("err_code_des"));
throw new RuntimeException("【微信支付】微信支付业务失败");
}
// 下单成功,获取支付链接
String url = result.get("code_url");
if (StringUtils.isBlank(url)) {
throw new RuntimeException("微信下单失败,支付链接为空");
}
return url;
}
//根据订单编号查询订单
public Boolean checkPayment(String orderNo) {
Map map = new HashMap();
map.put("out_trade_no",orderNo);
try {
Map result = wxPay.orderQuery(map);
//success表示交易成功
return "SUCCESS".equals(result.get("trade_state"));
} catch (Exception e) {
log.error("【微信查询】查询微信支付状态失败", e);
return false;
}
}
//关闭订单
public Boolean closeOrder(String orderNo) {
Map map = new HashMap();
map.put("out_trade_no",orderNo);
try {
Map result = wxPay.closeOrder(map);
//success表示交易成功
String state = (String)result.get("result_code");
return "SUCCESS".equals(state);
} catch (Exception e) {
log.error("【微信关闭】关闭微信支付状态失败", e);
return false;
}
}
}
6.在项目中调用
//调用微信工具类,生成支付二维码
String url = payUtils.createOrder(orderNo,
totalPay,
desc);
//查询微信的支付状态
Boolean payment = payUtils.checkPayment(orderNo);
//关闭订单,通知微信关闭
payUtils.closeOrder(orders.getOrderNo());
官方文档:微信支付开发文档
业务流程时序图
业务流程说明:
(1)商户后台系统根据用户选购的商品生成订单。
(2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;
(3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
(4)商户后台系统根据返回的code_url生成二维码。
(5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
(6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
(7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
(8)微信支付系统根据用户授权完成支付交易。
(9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
(10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
(11)未收到支付通知的情况,商户后台系统调用【查询订单API】(查单实现可参考:支付回调和查单实现指引)。
(12)商户确认订单已支付后给用户发货。