正文
经过了微信支付之创建订单准备操作的准备操作,接下来我们就能够非常快速的开发出各种支付类型的创建订单接口。
商户Native支付下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付,也就是说后端只需要返回code_url即可。
@Slf4j
public class WxPayCommon {
/**
* 创建微信支付订单-Native方式
*
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxNativePay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.NATIVE_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("code_url");
}
return null;
}
}
使用方式也很简单,通过注入的方式获取到wxPayConfig和wxPayClient对象后,创建支付请求参数对象,调用刚刚编写的wxNativePay方法即可。
@Slf4j
@RestController
@RequestMapping("/api/v1/pay/test")
public class PayTestController {
@Autowired
private WxPayConfig wxPayConfig;
@Autowired
private CloseableHttpClient wxPayClient;
@ApiOperation("1.支付测试接口")
@GetMapping("/pay/test")
public Map<String, String> getCheckNum() {
WeChatBasePayData payData = new WeChatBasePayData();
payData.setTitle("支付测试商品");
payData.setOrderId(IdWorker.getIdStr()); //测试时随机生成一个,代表订单号
payData.setPrice(new BigDecimal("0.01"));
payData.setNotify(WxNotifyType.REFUND_NOTIFY);
String path = WxPayCommon.wxNativePay(wxPayConfig, payData, wxPayClient);
Map<String, String> map = new HashMap();
map.put("path", path);
return map;
}
}
返回数据实例:weixin://wxpay/bizpayurl?pr=BcL4yGozz
如何测试是否可用?把返回的字符复制到微信中,发送给任意人,然后点击,如果能弹出支付框代表成功。
创建微信支付订单JSAPI方式
商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按Native、JSAPI、APP等不同场景生成交易串调起支付。
jsapi用在微信的环境,例如公众号、小程序等,jsapi与Native方式不同的地方就是,它需要认证用户信息,这个用户信息就是openid,这是需要通过用户登录你的小程序或者关注公众号来获取的。
@Slf4j
public class WxPayCommon {
/**
* 创建微信支付订单-jsapi方式
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param openId 通过微信小程序或者公众号获取到用户的openId
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxJsApiPay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, String openId,CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 1.1 添加支付者信息
Map<String,String> payerMap = new HashMap();
payerMap.put("openid",openId);
paramsMap.put("payer",payerMap);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.JSAPI_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("prepay_id");
}
return null;
}
}
使用方式如下,相较于Native,改动的地方下方代码都标明了。
@Slf4j
@RestController
@RequestMapping("/api/v1/pay/test")
public class PayTestController {
@Autowired
private WxPayConfig wxPayConfig;
@Autowired
private CloseableHttpClient wxPayClient;
@ApiOperation("1.支付测试接口")
@GetMapping("/pay/test")
public Map<String, String> getCheckNum() {
WeChatBasePayData payData = new WeChatBasePayData();
payData.setTitle("支付测试商品");
payData.setOrderId(IdWorker.getIdStr()); //测试时随机生成一个
payData.setPrice(new BigDecimal("0.01"));
payData.setNotify(WxNotifyType.REFUND_NOTIFY);
// String path = WxPayCommon.wxNativePay(wxPayConfig, payData, wxPayClient);
// 每个账户所关联的openId都是不一样的,你也别拿我的试,需要看你们项目的环境
String path = WxPayCommon.wxJsApiPay(wxPayConfig, payData, "oS3tA4zspa1DYMK5zBYkZv9XMIqw", wxPayClient);
Map<String, String> map = new HashMap();
map.put("path", path);
return map;
}
}
返回数据实例:wx041634439436321ff6c8e788ac69830000
客户端JSAPI调起支付,这个就不属于服务器端了,各位去官方文档自行查看吧
创建微信支付订单APP支付方式
App支付,单从文档来看,请求参数和Native一样,返回的数据类似于JSAPI,但是我的权限没有开通,所以这里只是理论可行,等我未来开通了APP支付再来测试。
@Slf4j
public class WxPayCommon {
/**
* 创建微信支付订单-APP方式
*
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxAppPay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.APP_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("prepay_id");
}
return null;
}
}
使用方式和Native一样,这里就不展示了,返回数据实例:wx261153585405162d4d02642eabe7000000
H5支付同理,把Native方法拷贝,改个地址即可,H5的返回参数是h5_url而不是code_url
创建微信支付订单工具类
最后附上整体的微信支付工具类。
import com.card.config.WxPayConfig;
import com.card.enums.wxpay.WxApiType;
import com.card.exception.DefaultException;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* @author cv大魔王
* @version 1.0
* @date 2022/3/1 16:43
*/
@Slf4j
public class WxPayCommon {
/**
* 创建微信支付订单-Native方式
*
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxNativePay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.NATIVE_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("code_url");
}
return null;
}
/**
* 创建微信支付订单-jsapi方式
*
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param openId 通过微信小程序或者公众号获取到用户的openId
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxJsApiPay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, String openId,CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 1.1 添加支付者信息
Map<String,String> payerMap = new HashMap();
payerMap.put("openid",openId);
paramsMap.put("payer",payerMap);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.JSAPI_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("prepay_id");
}
return null;
}
/**
* 创建微信支付订单-APP方式
*
* @param wxPayConfig 微信配置信息
* @param basePayData 基础请求信息,商品标题、商家订单id、订单价格
* @param wxPayClient 微信请求客户端()
* @return 微信支付二维码地址
*/
public static String wxAppPay(WxPayConfig wxPayConfig, WeChatBasePayData basePayData, CloseableHttpClient wxPayClient) {
// 1.获取请求参数的Map格式
Map<String, Object> paramsMap = getBasePayParams(wxPayConfig, basePayData);
// 2.获取请求对象
HttpPost httpPost = getHttpPost(wxPayConfig, WxApiType.APP_PAY, paramsMap);
// 3.完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = wxPayClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
throw new DefaultException("微信支付请求失败");
}
// 4.解析response对象
HashMap<String, String> resultMap = resolverResponse(response);
if (resultMap != null) {
// native请求返回的是二维码链接,前端将链接转换成二维码即可
return resultMap.get("prepay_id");
}
return null;
}
/**
* 解析响应数据
* @param response 发送请求成功后,返回的数据
* @return 微信返回的参数
*/
private static HashMap<String, String> resolverResponse(CloseableHttpResponse response) {
try {
// 1.获取请求码
int statusCode = response.getStatusLine().getStatusCode();
// 2.获取返回值 String 格式
final String bodyAsString = EntityUtils.toString(response.getEntity());
Gson gson = new Gson();
if (statusCode == 200) {
// 3.如果请求成功则解析成Map对象返回
HashMap<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
return resultMap;
} else {
if (StringUtils.isNoneBlank(bodyAsString)) {
log.error("微信支付请求失败,提示信息:{}", bodyAsString);
// 4.请求码显示失败,则尝试获取提示信息
HashMap<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
throw new DefaultException(resultMap.get("message"));
}
log.error("微信支付请求失败,未查询到原因,提示信息:{}", response);
// 其他异常,微信也没有返回数据,这就需要具体排查了
throw new IOException("request failed");
}
} catch (Exception e) {
e.printStackTrace();
throw new DefaultException(e.getMessage());
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取请求对象(Post请求)
*
* @param wxPayConfig 微信配置类
* @param apiType 接口请求地址
* @param paramsMap 请求参数
* @return Post请求对象
*/
private static HttpPost getHttpPost(WxPayConfig wxPayConfig, WxApiType apiType, Map<String, Object> paramsMap) {
// 1.设置请求地址
HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(apiType.getType()));
// 2.设置请求数据
Gson gson = new Gson();
String jsonParams = gson.toJson(paramsMap);
// 3.设置请求信息
StringEntity entity = new StringEntity(jsonParams, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
return httpPost;
}
/**
* 封装基础通用请求参数
*
* @param wxPayConfig 微信的配置文件
* @param basePayData 微信支付基础请求数据
* @return 封装后的map对象
*/
private static Map<String, Object> getBasePayParams(WxPayConfig wxPayConfig, WeChatBasePayData basePayData) {
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("appid", wxPayConfig.getAppid());
paramsMap.put("mchid", wxPayConfig.getMchId());
// 如果商品名称过长则截取
String title = basePayData.getTitle().length() > 62 ? basePayData.getTitle().substring(0, 62) : basePayData.getTitle();
paramsMap.put("description", title);
paramsMap.put("out_trade_no", basePayData.getOrderId());
paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(basePayData.getNotify().getType()));
Map<String, Integer> amountMap = new HashMap<>();
amountMap.put("total", basePayData.getPrice().multiply(new BigDecimal("100")).intValue());
paramsMap.put("amount", amountMap);
return paramsMap;
}
}
————————————————————————————————
java微信支付v3系列——1.微信支付准备工作
java微信支付v3系列——2.微信支付基本配置
java微信支付v3系列——3.订单创建准备操作
java微信支付v3系列——4.创建订单的封装及使用
java微信支付v3系列——5.微信支付成功回调
java微信支付v3系列——6.微信支付查询订单API
java微信支付v3系列——7.微信支付之申请退款
java微信支付v3系列——8.微信支付之退款成功回调
java微信支付v3系列——9.微信支付之商家转账API
————————————————————————————————
版权声明:本文为CSDN博主「CV大魔王」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45740561/article/details/128402504
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2022-03-22 Js/Jquery获取iframe中的元素
2017-03-22 Redis:默认配置文件redis.conf详解
2017-03-22 Redis:五种数据类型的简单增删改查
2017-03-22 使用控制台对Redis执行增删改查命令
2010-03-22 Visual Studio 设置:包括根据不同类型的开发活动对集成开发环境 (IDE) 所做的各种自定义设置
2010-03-22 VB.Net : ApplicationEvents类中,创建主程序的快捷方式 , 捕获程序未Try的错误及抛出相关的类和方法名 , 是否联机等相关。。