去微信支付申请key等配置项
接口请求值和返回值可参考微信官方文档
微信支付订单的流程
支付订单流程
支付类型分为
- JSAPI -JSAPI支付(小程序支付)
- NATIVE -Native支付(网页扫码支付)
- APP -APP支付(APP支付)
- MWEB--H5支付
本案例为NATIVE支付,其他支付需要修改WxPayUtil中的getWxQrcode方法中的值修改
packageParams.put("trade_type", "NATIVE");
key不用修改,key修改为对应的类型,同时也需要开通对应的服务
注意:在小程序支付的时候,需要传入openid
例如
packageParams.put("openid","openid");
项目架构
本文案例仅限参考,所以没有连接数据库,具体业务逻辑自行添加
添加maven
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6</version>
</dependency>
<!-- 微信支付-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>3.9.7.B</version>
</dependency>
<!-- jackson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-common</artifactId>
<version>2.6.3</version>
</dependency>
yml配置
wxpay:
app_id: 公众号Id
mch_id: 商户号
api_key: api key
certPath: 退款证书路径
unifiedorder_url: 统一下单
orderquery_url: 查询订单状态
closeorder_url: 关闭订单
refund_url: 申请退款
refundquery_url: 退款查询
shorturl_url: 转换短连接
notifyUrl: 微信异步回调
异步通知在本地测试环境,应使用内网穿透工具(例如natapp)
微信参数配置
package com.wxpay.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* 微信配置参数
* @author 许雪恒
*/
@Data
@Configuration
public class WxPayConfig {
/**
* 公众号Id
*/
@Value("${wxpay.app_id}")
private String appId;
/**
* 商户号
*/
@Value("${wxpay.mch_id}")
private String mchId;
/**
* api key
*/
@Value("${wxpay.api_key}")
private String apiKey;
/**
* 微信异步回调
*/
@Value("${wxpay.notifyUrl}")
private String notifyUrl;
/**
* 退款证书路径
*/
@Value("${wxpay.certPath}")
private String certPath;
/**
* 统一下单
*/
@Value("${wxpay.unifiedorder_url}")
private String unifiedOrderUrl;
/**
* 查询订单状态
*/
@Value("${wxpay.orderquery_url}")
private String orderQueryUrl;
/**
* 关闭订单
*/
@Value("${wxpay.closeorder_url}")
private String closeorderUrl;
/**
* 申请退款
*/
@Value("${wxpay.refund_url}")
private String refundUrl;
/**
* 退款查询
*/
@Value("${wxpay.refundquery_url}")
private String refundqueryUrl;
/**
* 转换短连接
*/
@Value("${wxpay.shorturl_url}")
private String shorturlUrl;
}
消息返回类
package com.wxpay.result;
import lombok.Data;
/**
* 消息返回类
* @Author: 许雪恒
*/
@Data
public class Result {
//操作成功
public static int SUCCESS=200;
//系统内部错误
public static int ERROR=500;
private int code;
private String msg;
private Object data;
public static Result success(Object data){
Result result = new Result();
result.code= SUCCESS;
result.msg="操作成功";
result.data=data;
return result;
}
public static Result error(String msg){
Result result = new Result();
result.code= ERROR;
result.msg=msg;
result.data=null;
return result;
}
public static Result custom(int code, String msg, Object data){
Result result = new Result();
result.code=code;
result.msg=msg;
result.data=data;
return result;
}
}
常量类Constant
package com.wxpay.constants;
/**
* 常量类
* @Author 许雪恒
* @Date 2021/9/1 10:01
*/
public class Constant {
/**
* 操作成功返回状态码
*/
public static final Integer RESULT_SUCCESS_CODE = 200;
/**查询状态信息展示**/
public static final String PAY_STATUS_MSG_NOT_PAY = "交易创建";
public static final String PAY_STATUS_MSG_SUCCESS = "支付成功";
public static final String PAY_STATUS_MSG_FINISHED = "交易完成";
public static final String PAY_STATUS_MSG_CLOSED = "交易关闭";
public static final String PAY_STATUS_MSG_NOT_EXIST = "交易不存在";
public static final String PAY_STATUS_MSG_FAIL = "请求失败,请刷新重试";
/**
* 成功
*/
public static final String SUCCESS = "SUCCESS";
/**
* 失败
*/
public static final String FAIL = "FAIL";
/**
* 成功提示信息
*/
public static final String SUCCESS_MSG = "操作成功";
/**
* 失败提示信息
*/
public static final String FAIL_MSG = "操作失败";
/**
* 业务正常状态
*/
public static final String CHARACTER_ENCODING_UTF8 = "UTF-8";
}
工具类
HttpUtil工具类
package com.wxpay.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
/**
* 工具类
* 处理post请求
*/
public class HttpUtil
{
//超时时间
private final static int CONNECT_TIMEOUT = 3000;
//默认编码
private final static String DEFAULT_ENCODING = "UTF-8";
/**
* 处理post请求
* @param urlStr 跳转地址
* @param data 传入数据(xml)
* @return
*/
public static String postData(String urlStr, String data){
return postData(urlStr, data, null);
}
/**
* 处理post请求
* @param urlStr 跳转地址
* @param data 传入数据(xml)
* @param contentType
* @return
*/
public static String postData(String urlStr, String data, String contentType){
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(contentType != null) {
conn.setRequestProperty("content-type", contentType);
}
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null) {
data = "";
}
writer.write(data);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
Sy