微信扫码支付总结

微信扫码支付总结

1.扫码支付流程

    微信扫码支付,流程很简单,就是将你要付款的一些信息放到集合里面,然后用微信SDK来生成对应的URL,再根据URL生成对应的二维码,扫码支付后,微信后台会有回调,异步通知(需要在服务器打印日志查看).

2.配置

[SDK调用示例](https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA.zip)

    <dependency>
        <groupId>com.github.wxpay</groupId>
        <artifactId>wxpay-sdk</artifactId>
        <version>适应版本</version>
    </dependency>

新建一个配置类实现WXPayConfig接口,里面会配置AppID,MchID,Key,这些需要在公司的商户平台上获取.

    private byte[] certData;

    /*public WeChatConf() throws Exception {
        String certPath = "/apiclient_cert.p12";
        //String certPath = "退款需要存的证书路径";
        File file = new File(certPath);
        InputStream certStream = new FileInputStream(file);
        this.certData = new byte[(int) file.length()];
        certStream.read(this.certData);
        certStream.close();
    }*/

    public String getAppID() {
        return AppId;
    }

    public String getMchID() {
        return MchID;
    }

    public String getKey() {
        return Key;
    }


    public InputStream getCertStream() {
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    public int getHttpReadTimeoutMs() {
        return 10000;
    }

3.开始实现功能

    WeChatConf weChatConf = null;
    try {
    	weChatConf = new WeChatConf();
    } catch (Exception e) {
    	e.printStackTrace();
    }
    //账号信息
    String appId = weChatConf.getAppID();
    //商业号
    String mch_id = weChatConf.getMchID();
    //支付秘钥
    String key = weChatConf.getKey();
    Map<String, String> data = new HashMap<String, String>();
    data.put("appid", 公众账号ID);
    data.put("mch_id", 商业号);
    data.put("nonce_str", 随机字符串);
    data.put("body", 商品描述);
    data.put("out_trade_no", 商户订单号,不可重复);
    data.put("fee_type", "CNY");//标价币种(默认人民币)
    data.put("total_fee", totalFee+"");//标价金额,单位:分
    data.put("spbill_create_ip", 终端IP);
    data.put("notify_url", 通知地址,必须是外网能访问的地址);
    data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
    String sign = null;
    try {		//WXPayUtil在上方链接下载的SDK中可以找到
    	sign = WXPayUtil.generateSignature(data,key,WXPayConstants.SignType.MD5);
    } catch (Exception e) {
    	e.printStackTrace();
    }
    data.put("sign", sign);   //签名
    
    WXPay wxpay = new WXPay(weChatConf);
    Map<String, String> mss = null;
    try {
    	mss = wxpay.unifiedOrder(data);
    } catch (Exception e) {
    	e.printStackTrace();
    }
    String codeUrl = mss.get("code_url");//此处是微信微信返回的需生成二维码的URL

写到这里,当时出了问题,根据官方提供的技术,是后台用个方法生成二维码然后用流输出到前台,因为是支付图片,是不能保存到本地的,可是我当时做的时候,只有当浏览器为兼容模式的情况下才会显示二维码,极速模式下不显示,搞的很头大.因为支付宝支付的话就是直接返回一个URL就可以了,二维码生成的问题交给阿里后台解决,所以我也换了一个思路,直接甩给前台返回一个URL,二维码就在前台生成.

到这里的话,其实支付已经完成一大半了,不过我感觉支付宝和微信就差在回调这个地方了.支付宝是直接给你返回一个状态,结果微信是需要写个回调接口,还得自己去查看回调结果,然后再给微信返回接受情况.

下面我们来看一下回调接口,微信的回调数据需要用流来接收


	String returnPage = "";
    String notifyData = "";
    InputStream is = request.getInputStream();
    StringBuffer sb = new StringBuffer();
    String s = null;
    BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    while ((s = in.readLine()) != null) {
    	sb.append(s);
    }
    in.close();
    is.close();
    notifyData = sb.toString();
    Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);// 转换成map
    if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
        // 签名正确
        //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
        resXml = "<xml>" + "<return_codSUCCESS]]></return_code>"
        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
    } else {
        // 签名错误,如果数据里没有sign字段,也认为是签名错误
        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();

    写到这里,整体的二维码支付就结束了.另外,二维码在前台生成的话,是需要再写一个轮询接口的,检测订单状态是否付款,然后根据返回结果,在前台跳转支付成功/支付失败.刚刚工作不久,有写的不好的地方接受点评,给大佬们留个问题,前台生成二维码支付会不会有安全问题,需要怎么解决?
posted on 2018-11-02 10:46  苏严Syan丶  阅读(407)  评论(3编辑  收藏  举报