微信支付模式二java
阅读原文时间:2023年07月08日阅读:1

这个星期写了下微信支付模式二,在这里进行下整理

微信支付官方文档

1. 需要的配置..具体看下面的链接.

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=3_1

2. 熟悉微信的支付流程(模式二)

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

3.将下面的配置填好,我是写在yml里面.第一个没用到,说是公众号那里用到了,可以不用

.

4.下载微信里面的sdk,然后全部放入项目里面

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

下面就是具体的代码…微信支付模式二是先将金额订单号等一些参数放入二维码中,这个二维码只有2个小时,然后顾客扫码支付

需要的jar包

  <dependency>  
<groupId>com.google.zxing</groupId>  
<artifactId>core</artifactId>  

3.3.3


org.jdom jdom 1.1


xml-apis xml-apis 1.4.01

5.先是写二维码的

util ---2个

/**
* @ClassName: QRCodeUtil
* @Description: 二维码工具类
*/
public class QRCodeUtil {

/**
* 生成base64二维码
*
* @param content
* @return
* @throws Exception
*/
public static String createQrCode(String content) throws Exception {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Hashtable hints = new Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
ImageIO.write(image, "JPG", out);
return Base64.encodeBase64String(out.toByteArray());
}
}
}

public class CommonUtil {
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

}

controller  ----这里可以直接传参数,订单号,类型

serviceImpl

@Override
public ApiResult toPay(String orderUserId, String payType) {
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的订单号");
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的支付状态");
}
if(!"3".equals(orderUserInfoDto.getStatus())){
return ApiResult.result(ApiResult.defaultErrorCode,"未知的订单状态");
}
// 1为微信支付
if ("1".equals(payType)) {
SortedMap parameters = new TreeMap();
// 公众账号ID-------appId
parameters.put("appid", weChatConfig.getWxAppId());
// 商户号---------mch_id
parameters.put("mch_id", weChatConfig.getWxMchId());
// 随机字符串------nonce_str
parameters.put("nonce_str", WXPayUtil.generateNonceStr());
// 商品描述-------body
parameters.put("body", weChatConfig.getBody());
// 商户订单号------out_trade_no
parameters.put("out_trade_no", orderUserId);
// 标价币种-------fee_type(默认为人民币)
parameters.put("fee_type", "CNY");
// 标价金额-------total_fee(默认为分)
BigDecimal transValue = new BigDecimal("100");
// 计算微信的总金额乘以100
BigDecimal bTotalPrice = orderUserInfoDto.getTotalPrice().multiply(transValue);
int totalFee = bTotalPrice.intValue();
parameters.put("total_fee", String.valueOf(totalFee));
// 通知地址-------notify_url(回调地址)
parameters.put("notify_url", weChatConfig.getNotifyUrl());
// 交易类型-----trade_type
parameters.put("trade_type", "NATIVE");
// 签名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(parameters, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
parameters.put("sign", generateSignature);
String generateSignedXml = null;
try {
generateSignedXml = WXPayUtil.generateSignedXml(parameters, weChatConfig.getWxApiKey());
} catch (Exception e) {
e.printStackTrace();
}
log.info("二维码信息------" + generateSignedXml);
String result = CommonUtil.httpsRequest(weChatConfig.getWxPayUnifiedorderUrl(), "POST", generateSignedXml);
Map map;
try {
map = WXPayUtil.xmlToMap(result);
String returnCode = map.get("return_code");
String resultCode = map.get("result_code");
if (returnCode.equalsIgnoreCase("SUCCESS") && resultCode.equalsIgnoreCase("SUCCESS")) {
String content = map.get("code_url");
String imgs = QRCodeUtil.createQrCode(content);
return ApiResult.result("data:image/jpeg;base64," + imgs);
} else {
return ApiResult.result(ApiResult.defaultErrorCode, "微信签名错误");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return ApiResult.result(ApiResult.defaultErrorCode, "未知错误");
}

6,支付回调-----就是二维码的那个回调地址,如果是本地测试的话,可能下载个花生壳将本地的地址映射出去

controller

serviceImpl    --->这里主要注意就是第一次回调成功的话,要把正确的信息返回给微信,不然微信会在那几个时间一直回调,这个回调就会一直改状态

public String weChatNotify(HttpServletRequest request, HttpServletResponse response) {
// 读取参数
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();

// 解析xml成map
Map map = WXPayUtil.xmlToMap(sb.toString());
log.info("支付回调---" + map.toString());
String res = "OK";
String resXml = "" + "" + "" + "";
// 判断签名是否正确
if (WXPayUtil.isSignatureValid(map, weChatConfig.getWxApiKey())) {
if ("SUCCESS".equals(map.get("return_code").toString())) {
// 用户订单号
String orderUserId = (String) map.get("out_trade_no");
// 微信支付订单号
String payOrderId = (String) map.get("transaction_id");
// 支付时间
String endTime = (String) map.get("time_end");
// 支付金额
BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());
/**
* 1,判断是否有这个订单号 2,判断支付金额与用于订单表的金额是否一致 3,修改支付状态,并修改商户的状态,
*/
log.info("用户订单id--------"+orderUserId);
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return "未知的订单号";
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return "未知的支付状态";
}
if (!"3".equals(orderUserInfoDto.getStatus())) {
return "未知的订单状态";
}
if (total_fee.compareTo(orderUserInfoDto.getTotalPrice().multiply(new BigDecimal("100"))) != 0) {
return "支付金额与用户订单金额不一致";
}
// 用户订单表的修改
OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();
orderUserInfoDto1.setId(orderUserId);
orderUserInfoDto1.setStatus("4");
orderUserInfoDto1.setPayStatus("1");
orderUserInfoDto1.setPayType("1");
orderUserInfoDto1.setPaySerial(payOrderId);
log.info("----------------时间---"+endTime);
orderUserInfoDto1.setPayTime(dateTime(endTime));
orderUserInfoService.updateByPk(orderUserInfoDto1);
// 商户订单表的修改
List orderMerchantInfoDtoList = orderMerchantInfoService
.listByField("order_user_info_id", orderUserId);
for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {
if ("3".equals(merchantInfoDto.getStatus())) {
String id = merchantInfoDto.getId();
OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();
orderMerchantInfoDto.setId(id);
orderMerchantInfoDto.setStatus("4");
orderMerchantInfoDto.setPayStatus("1");
orderMerchantInfoDto.setPayTime(dateTime(endTime));
orderMerchantInfoService.updateByPk(orderMerchantInfoDto);
}
}
log.info(resXml);
return resXml;
} else {
return "错误的签名";
}
}
return "未知错误";
}

7,客户支付成功了,但是状态没改,可以写个定时任务,查询当天未支付的订单是否支付,我这里只写了通过订单号和类型查询单个的是否支付

controller

serviceImpl

@Override
public ApiResult weChatNotifyDto(String orderUserId, String payType) {
/**
* 1,数据库进行查询,如果显示已支付则直接返回成功
* 2,未支付,调用微信接口
*/
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if("1".equals(orderUserInfoDto.getPayStatus())){
return ApiResult.result("支付已完成");
}
Map data = new HashMap<>();
data.put("appid", weChatConfig.getWxAppId());
data.put("mch_id", weChatConfig.getWxMchId());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("out_trade_no", orderUserId);
// 签名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(data, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
data.put("sign", generateSignature);
Map result = null;
try {
result = wxPay.orderQuery(data);
} catch (Exception e) {
e.printStackTrace();
}
// 如果用户已支付
if("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("trade_state"))){
//修改状态
// 微信支付订单号
String payOrderId = result.get("transaction_id");
// 支付时间
String endTime = result.get("time_end");

  // 用户订单表的修改  
  OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();  
  orderUserInfoDto1.setId(orderUserId);  
  orderUserInfoDto1.setStatus("4");  
  orderUserInfoDto1.setPayStatus("1");  
  orderUserInfoDto1.setPayType("1");  
  orderUserInfoDto1.setPaySerial(payOrderId);  
  orderUserInfoDto1.setPayTime(dateTime(endTime));  
  orderUserInfoService.updateByPk(orderUserInfoDto1);  
  // 商户订单表的修改  
  List<OrderMerchantInfoDto> orderMerchantInfoDtoList = orderMerchantInfoService  
        .listByField("order\_user\_info\_id", orderUserId);  
  for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {  
     if ("3".equals(merchantInfoDto.getStatus())) {  
        String id = merchantInfoDto.getId();  
        OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();  
        orderMerchantInfoDto.setId(id);  
        orderMerchantInfoDto.setStatus("4");  
        orderMerchantInfoDto.setPayStatus("1");  
        orderMerchantInfoDto.setPayTime(dateTime(endTime));  
        orderMerchantInfoService.updateByPk(orderMerchantInfoDto);  
     }  
  }  
  return ApiResult.result("支付已完成");  

}
return ApiResult.result(ApiResult.defaultErrorCode, "订单未支付");
}

    暂时先这样,有时间再补充