Java微信扫码支付模式二Demo ,整合官网直接运行版本

下载

代码下载链接: 点击下载

概述

技术:spirngboot+微信扫码支付模式二+google生成二维码+html+jquery+mevan
运行环境:eclipse/idea+java jdk 1.8+
场景介绍:扫码支付模式二,用于web网站。用户点击支付后,根据商品生成的二维码,用户扫码完成支付,手机提示支付成功,微信支付系统把交易结果发送到回调接口中。

详细

一、相关配置

微信公众号AppID(登录微信公众平台–>开发–>基本设置–>开发者ID(AppID))

微信公众号AppSecret(登录微信公众平台–>开发–>基本设置–>开发者密码(AppSecret))

微信支付商户号(登录微信商户平台–>账户中心–>商户信息–>基本账户信息–>微信支付商户号)

微信支付商户API**(登录微信商户平台–>账户中心–>API安全–>API**–>设置API**)

application.properties 文件 (Demo上都有官网的默认值,不需要修改直接使用,省心!)
Java微信扫码支付模式二Demo ,整合官网直接运行版本

支付扫码模式二,流程图
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

SDK与DEMO下载
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

二、目录结构

Java微信扫码支付模式二Demo ,整合官网直接运行版本

三、准备工作

(1)内网穿透工具

让外网能直接访问,你本地的服务,场景用于,接口调试,支付方面等等。

为了大家找了一个,免费配置简单的。绝对不是卖广告,之前用过花生壳,麻烦到要死坑哇~,现在的所有穿透都要身份证登记,很正常国家出了对应的法规。

下载地址:https://natapp.cn/#download

配置和使用说明:https://blog.csdn.net/kingrome2017/article/details/77989442

四、功能讲解

(1)访问首页

打开WxPayController.java

/* 二维码首页*/
@RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String wxPayList(Model model){
//商户订单号
model.addAttribute(“outTradeNo”,WxUtil.mchOrderNo());
return “/wxPayList”;
}

我们和穿透工具连在一起使用
SpringBoot 默认端口号为:8080,穿透工具映射端口设置为:8080
双击,natapp.exe 执行
Java微信扫码支付模式二Demo ,整合官网直接运行版本

127.0.0:8080 <=> http://9xnrh8.natappfree.cc
Java微信扫码支付模式二Demo ,整合官网直接运行版本
Java微信扫码支付模式二Demo ,整合官网直接运行版本
修改,application.properties
划重点,添加内网穿透链接记得重启服务
Java微信扫码支付模式二Demo ,整合官网直接运行版本

(2)生成二维码

从页面看到,有订单流水号和支付金额,0.01 代表一分钱。支付金额可以修改的,点击’生成二维码’按钮,然后把订单流水号和支付金额传到后台。
控制类:

final private String signType = WxConstants.SING_MD5;
/* 统一下单-生成二维码*/
@RequestMapping(value = {"/wxPay/payUrl"})
public void payUrl(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = “totalFee”)Double totalFee,
@RequestParam(value = “outTradeNo”)String outTradeNo) throws Exception{
WxUtil.writerPayImage(response,wxMenuService.wxPayUrl(totalFee,outTradeNo,signType));
}

实现类:

@Override
public String wxPayUrl(Double totalFee,String outTradeNo,String signType) throws Exception {
HashMap<String, String> data = new HashMap<String, String>();
//公众账号ID
data.put(“appid”, WxConfig.appID);
//商户号
data.put(“mch_id”, WxConfig.mchID);
//随机字符串
data.put(“nonce_str”, WxUtil.getNonceStr());
//商品描述
data.put(“body”,“测试支付”);
//商户订单号
data.put(“out_trade_no”,outTradeNo);
//标价币种
data.put(“fee_type”,“CNY”);
//标价金额
data.put(“total_fee”,String.valueOf(Math.round(totalFee * 100)));
//用户的IP
data.put(“spbill_create_ip”,“123.12.12.123”);
//通知地址
data.put(“notify_url”,WxConfig.unifiedorderNotifyUrl);
//交易类型
data.put(“trade_type”,“NATIVE”);
//签名类型
data.put(“sign_type”,signType);
//签名
data.put(“sign”,WxUtil.getSignature(data, WxConfig.key,signType));
String requestXML = WxUtil.mapToXml(data);
String reponseString = HttpsClient.httpsRequestReturnString(WxConstants.PAY_UNIFIEDORDER,HttpsClient.METHOD_POST,requestXML);
Map<String,String> resultMap = WxUtil.processResponseXml(reponseString,signType);
if(resultMap.get(WxConstants.RETURN_CODE).equals(“SUCCESS”)){
return resultMap.get(“code_url”);
}
return null;
}

最终返回一个,二维码链接 → 转成二维码图片

/** 生成支付二维码 @param response 响应 @param contents url链接 @throws Exception*/
public static void writerPayImage(HttpServletResponse response, String contents) throws Exception{
ServletOutputStream out = response.getOutputStream();
try {
Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType,Object>();
hints.put(EncodeHintType.CHARACTER_SET,“UTF-8”);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.MARGIN, 0);
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,300,300,hints);
MatrixToImageWriter.writeToStream(bitMatrix,“jpg”,out);
}catch (Exception e){
throw new Exception(“生成二维码失败!”);
}finally {
if(out != null){
out.flush();
out.close();
}
}
}

Java微信扫码支付模式二Demo ,整合官网直接运行版本

启动一个定时器,每个2秒去扫描是否已经支付~

(3)支付

Java微信扫码支付模式二Demo ,整合官网直接运行版本

Java微信扫码支付模式二Demo ,整合官网直接运行版本

(4)支付完毕

Java微信扫码支付模式二Demo ,整合官网直接运行版本

(5)回调接口

收到微信支付结果通知后,请严格按照示例返回参数给微信支付

/统一下单-通知链接/
@RequestMapping(value = {"/wxPay/unifiedorderNotify"})
public void unifiedorderNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
//商户订单号
String outTradeNo = null;
String xmlContent = “” +
“<return_code><![CDATA[FAIL]]></return_code>” +
“<return_msg><![CDATA[签名失败]]></return_msg>” +
“”;
try{
String requstXml = WxUtil.getStreamString(request.getInputStream());
System.out.println("requstXml : " + requstXml);
Map<String,String> map = WxUtil.xmlToMap(requstXml);
String returnCode= map.get(WxConstants.RETURN_CODE);
//校验一下
if(StringUtils.isNotBlank(returnCode) && StringUtils.equals(returnCode,“SUCCESS”) && WxUtil.isSignatureValid(map, WxConfig.key,signType)){
//商户订单号
outTradeNo = map.get(“out_trade_no”);
System.out.println("outTradeNo : "+ outTradeNo);
//微信支付订单号
String transactionId = map.get(“transaction_id”);
System.out.println("transactionId : "+ transactionId);
//支付完成时间
SimpleDateFormat payFormat= new SimpleDateFormat(“yyyyMMddHHmmss”);
Date payDate = payFormat.parse(map.get(“time_end”));
SimpleDateFormat systemFormat= new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
System.out.println(“支付时间:” + systemFormat.format(payDate));
//临时缓存
WxConfig.setPayMap(outTradeNo,“SUCCESS”);
xmlContent = “” +
“<return_code><![CDATA[SUCCESS]]></return_code>” +
“<return_msg><![CDATA[OK]]></return_msg>” +
“”;
}
}catch (Exception e){
e.printStackTrace();
}
WxUtil.responsePrint(response,xmlContent);
}

Java微信扫码支付模式二Demo ,整合官网直接运行版本

更多的信息,请看官网
官网相关链接:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8

(6)微信支付,关于XML解析存在的安全问题指引

代码已修改
Java微信扫码支付模式二Demo ,整合官网直接运行版本

更多的信息,请看官网
官网相关链接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5

因为相关配置,我是从官网下载的,所以支付后还有退款功能(退款要等很多天,请耐心等待),是不是很神奇~
Java微信扫码支付模式二Demo ,整合官网直接运行版本

代码下载链接: 点击下载

还有微信登录,自定义微信公众号菜单创建-修改-删除功能(前台-数据库保存),微信公众号接受、回复信息Demo

但是,没有官网例子直接运行的,很多地方不能截图,后面我想想怎么做吧~

谢谢大家观看~