微信支付之扫码支付实例

Posted zengnansheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信支付之扫码支付实例相关的知识,希望对你有一定的参考价值。

本例是采用微信扫码支付模式二

 

增加maven依赖

<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.2.0</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.2.0</version>
</dependency>

 

 

付款二维码

<img src="${pageContext.request.contextPath}/WxPay/getQRCode?orderId=1" />

 

WxPayController

package com.zns.controller;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.github.wxpay.sdk.WXPayConstants.SignType;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;

@Controller
@RequestMapping("/WxPay")
public class WxPayController {
    protected final Logger logger = Logger.getLogger(WxPayController.class);
    // api密钥 在支付商户后台设置获取
    protected String apiKey = "";
    // 公众账号开发者appId
    protected String appId = "";
    // 微信支付分配的商户号
    protected String mchId = "";
    // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
    protected String requestIp = "";
    // 统一下单url
    protected String unifiedorderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    // 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
    protected String notifyUrl = "域名/WxPay/notifyUrl";

    // 统一下单生成二维码
    @RequestMapping("/getQRCode")
    public void getQRCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, String> data = new HashMap<String, String>();
        data.put("appid", appId);
        data.put("mch_id", mchId);
        // 随机字符串,长度要求在32位以内
        data.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32));
        // 商品简单描述
        data.put("body", "充值中心-开通会员");
        // 商户系统内部订单号,要求32个字符内
        data.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
        data.put("fee_type", "CNY");
        // 订单总金额,单位为分
        data.put("total_fee", "1");
        // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
        data.put("spbill_create_ip", requestIp);
        // 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
        data.put("notify_url", notifyUrl);
        // 取值如下:JSAPI,NATIVE,APP等
        data.put("trade_type", "NATIVE");
        // trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
        data.put("product_id", "1");

        String reqXmlStr = WXPayUtil.generateSignedXml(data, apiKey, SignType.MD5);

        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(unifiedorderUrl).openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());
            buffOutStr.write(reqXmlStr.getBytes());
            buffOutStr.flush();
            buffOutStr.close();
            // 获取输入流
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            StringBuffer sb = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }

            System.out.println("接口响应返回结果为:" + sb.toString());
            // 接口返回的是xml格式字符串数据 转成map
            Map<String, String> resMap = WXPayUtil.xmlToMap(sb.toString());
            String qrcodeUrl = "";
            if (resMap.get("return_code").equals("SUCCESS") && resMap.get("result_code").equals("SUCCESS")) {
                qrcodeUrl = resMap.get("code_url");
            }
            System.out.println("支付二维码url为:" + qrcodeUrl);
            // zxing 生成二维码
            int width = 200;
            int height = 200;
            String format = "png";
            Hashtable hints = new Hashtable();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(qrcodeUrl, BarcodeFormat.QR_CODE, width, height,
                    hints);
            OutputStream out = null;
            out = response.getOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, format, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 支付结果异步通知回调
    @RequestMapping("/notifyUrl")
    public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取参数
        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();

        String receiveXml = sb.toString();
        String resXml = "";
        // 判断签名是否正确
        if (!WXPayUtil.isSignatureValid(receiveXml, apiKey)) {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[签名失败]]></return_msg>" + "</xml> ";
        }

        // 接收到的是xml格式字符串数据 转成map
        Map<String, String> receiveMap = WXPayUtil.xmlToMap(receiveXml);
        if (receiveMap.get("return_code").equals("SUCCESS")) {
            // 业务处理 省略。。。

            // 通知微信.异步确认成功.必写.不然会一直通知后台.一定次数之后就认为交易失败了.
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[支付异常]]></return_msg>" + "</xml> ";
        }
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }
}

 


以上是关于微信支付之扫码支付实例的主要内容,如果未能解决你的问题,请参考以下文章

java实现微信支付之扫码支付

微信支付教程系列之扫码支付

微信支付教程系列之扫码支付

微信支付之扫码支付

微信支付之扫码支付模式二

微信支付之扫码APP小程序支付接入详解