欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

微信扫码支付总结

程序员文章站 2022-05-14 15:33:21
微信扫码支付总结 1.扫码支付流程 微信扫码支付,流程很简单,就是将你要付款的一些信息放到集合里面,然后用微信SDK来生成对应的URL,再根据URL生成对应的二维码,扫码支付后,微信后台会有回调,异步通知(需要在服务器打印日志查看). 2.配置 "SDK调用示例" com.github.wxpay ......

微信扫码支付总结

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();

    写到这里,整体的二维码支付就结束了.另外,二维码在前台生成的话,是需要再写一个轮询接口的,检测订单状态是否付款,然后根据返回结果,在前台跳转支付成功/支付失败.刚刚工作不久,有写的不好的地方接受点评,给大佬们留个问题,前台生成二维码支付会不会有安全问题,需要怎么解决?