微信网页支付生成二维码流程与实现


这里只介绍了微信支付中的Native支付,并只介绍了如何生成二维码,即时序图中的第2步到第4步

官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1

一、时序图

在这里插入图片描述

二、参数

官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

1. 请求参数

必填的都得填,将请求参数放到map集合中,这里说一下几个需要注意的地方:

  • total_fee:标价金额,参数类型为Int,要求传递的金额为整数,单位为分
  • nonce_str:随机字符串,随机字符串,长度要求在32位以内。使用微信SDK中的WXPayUtil.generateNonceStr()方法生成
  • sign:签名,根据前面的所有参数,通过签名算法计算得出的签名值,WXPayUtil.generateSignature(req请求参数map集合, key)
  • 请求参数以 xml 的格式发送。WXPayUtil.mapToXml(请求参数map集合)

2. 响应参数

  • code_url:Native 支付时有返回,此url用于生成支付二维码,然后提供给用户进行扫码支付。
  • 响应参数以 xml 格式返回,微信SDK提供了方法将 xml 字符串转换为 map 集合:WXPayUtil.xmlToMap(xml字符串);

三、实现

1. 获取url

@RequestMapping("/api/wxpay")
@ResponseBody
public Object wxpay(String body,
                    String out_trade_no,
                    String total_feer) throws Exception {

    //请求参数map
    Map<String, String> reqParamMap = new HashMap<>();
    reqParamMap.put("appid", "自己指定");
    reqParamMap.put("mch_id", "自己指定");
    reqParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
    reqParamMap.put("body", body);
    reqParamMap.put("out_trade_no", out_trade_no);

    BigDecimal bigDecimal = new BigDecimal(total_feer);
    BigDecimal multiply = bigDecimal.multiply(new BigDecimal(100));

    reqParamMap.put("total_fee", multiply.toBigInteger().toString());
    reqParamMap.put("spbill_create_ip", "127.0.0.1");
    reqParamMap.put("notify_url", "http://localhost:9090/pay/api/wxpayNotity");
    reqParamMap.put("trade_type","NATIVE");

    reqParamMap.put("product_id", out_trade_no);

    String sign = WXPayUtil.generateSignature(reqParamMap, "指定自己的key");
    reqParamMap.put("sign", sign);

    String requestDataXml = WXPayUtil.mapToXml(reqParamMap);

	CloseableHttpClient httpClient = null;
	CloseableHttpResponse response = null;
	String result = "";
	
	try {
	    //创建httpClient实例
	    httpClient = HttpClients.createDefault();
	    //创建httpPost远程连接实例
	    HttpPost httpPost = new HttpPost(url);
	    //配置请求参数实例
	    RequestConfig requestConfig = RequestConfig.custom()
	            .setConnectTimeout(35000)//设置连接主机服务超时时间
	            .setConnectionRequestTimeout(35000)//设置连接请求超时时间
	            .setSocketTimeout(60000)//设置读取数据连接超时时间
	            .build();
	    //为httpPost实例设置配置
	    httpPost.setConfig(requestConfig);
	    //设置请求参数
	    httpPost.setEntity(new StringEntity(requestDataXml, "UTF-8"));
	    //设置请求头内容
	    httpPost.addHeader("Content-Type", "text/xml");
	
	    //执行post请求得到返回对象
	    response = httpClient.execute(httpPost);
	    //通过返回对象获取数据
	    HttpEntity entity = response.getEntity();
	    //将返回的数据转换为字符串
	    result = EntityUtils.toString(entity);
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    //关闭资源
	    if (null != response) {
	        try {
	            response.close();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	
	    if (null != httpClient) {
	        try {
	            httpClient.close();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	}

    Map<String, String> respParamMap = WXPayUtil.xmlToMap(result);
    return respParamMap;

}

2. 生成二维码

这里使用的是google生成二维码的jar包,相关依赖:

注意:编译器要在1.6以上,默认为1.5

<dependencys>
	<!-- google生成二维码依赖 -->
	<dependency>
	    <groupId>com.google.zxing</groupId>
	    <artifactId>core</artifactId>
	    <version>3.0.0</version>
	</dependency>
	
	<dependency>
	    <groupId>com.google.zxing</groupId>
	    <artifactId>javase</artifactId>
	    <version>3.0.0</version>
	</dependency>
</dependencys>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

代码实现:

@RequestMapping("/loan/gererateQRCode")
public void generateQRCode(HttpServletRequest request, HttpServletResponse response,
                           String out_trade_no,
                           String total_amount) throws Exception {
    
    Map<String ,Object> map = new HashMap<>();
    map.put("out_trade_no", out_trade_no);
    map.put("total_feer", total_amount);
    map.put("body", "微信支付");

	//这里调用上面1中的方法,获取json字符串,HttpClientUtils是我封装的一个工具类,只要知道这句话是调用上面3.1中的方法即可
    String jsonStr = HttpClientUtils.doPost("http://localhost:9094/pay/api/wxpay", map);

	//解析JSON字符串
    JSONObject jsonObject = JSONObject.parseObject(jsonStr);

    String return_code = jsonObject.getString("return_code");

    if (!StringUtils.equals(return_code, "SUCCESS")) {
        //响应不成功相应的处理
    }

    String result_code = jsonObject.getString("result_code");

    if (!StringUtils.equals(result_code, "SUCCESS")) {
        //请求不成功相应的处理
    }

	//获取url
    String code_url = jsonObject.getString("code_url");

    //生成二维码
    //map中存放的是生成二维码的参数
    Map<EncodeHintType,Object> map2 = new HashMap<EncodeHintType, Object>();
    map2.put(EncodeHintType.CHARACTER_SET, "UTF-8");

	//生成二维码,参数依次是:二维码内容,二维码编码方式,长,宽,参数
    BitMatrix encode = new MultiFormatWriter().encode(code_url, BarcodeFormat.QR_CODE, 200, 200, map2);

	//获取输出流,响应到前台
    OutputStream out = response.getOutputStream();

    MatrixToImageWriter.writeToStream(encode,"jpg",out);

    out.flush();
    out.close();
}
发布了45 篇原创文章 · 获赞 46 · 访问量 1817

猜你喜欢

转载自blog.csdn.net/zyx1260168395/article/details/103840095