微信小程序

来源:互联网 发布:linux搭建lamp服务器 编辑:程序博客网 时间:2024/06/16 19:38

基于微信小程序的微信支付(JAVA)

  1. 数据准备
    • 由于是基于微信小程序的微信支付,所以要先准备微信小程序的相关信息。都有AppID,Appsecret,商户号,api密钥,回调地址。还有相关为支付的URL
    • 统一下单的URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
    • 这里使用的加密方式都是MD5加密。
  2. 支付流程
    -微信小程序支付流程

    -用户在进入小程序用户在进入小程序进行下单,小程序向商户的后端发起下单请求,商户的后端向微信后台发起登录,然后微信后台返回Openid,商户的后端自己生成商户订单,再次调用支付统一下单的API把订单发给微信后台,然后微信后台返回预支付信息(prepay_id),商户后端再把返回的数据提取并进行再次签名返回给微信小程序,然后微信小程序再用返回的数据进行调用微信小程序的微信支付API调出支付框来让用户进行确认支付,确认后微信小程序把相关的数据在此发给微信后台,并接收支付结果进行显示。最后微信后台会调用其中回调地址的参数进行回调来再次传输下单的相关数据。

  3. 开始支付(统一下单)

    1. 获得用户Openid
      通过微信小程序调用API(wx.login)来获得code, 然后再通过code在自己的服务器调用https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
      获得code的微信小程序API
      通过code获取Openid
      2.统一下单
      关于统一下单API请看:微信支付统一下单
      下面是支付代码(有一些相关必要的属性在这里没有赋值数据,但是必须要进行赋值):
        //制作订单号        String out_trade_no = "2015136327"+new Date().getTime();        //获得IP地址        InetAddress ip = InetAddress.getLocalHost();        String spbill_create_ip = ip.toString().split("/")[1];        //获得相关信息        String total_fee = request.getParameter("total_fee");        String attach = request.getParameter("attach");        String body = new String(request.getParameter("body"));        //获取code        String code = request.getParameter("code");        //发起请求用code获得相关返回数据处理得到openid        String openid=JSONObject.fromObject(htp.Post("https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+                "&js_code=" + code + "&grant_type=authorization_code", null)).getString("openid");        //相关数据组合第一次加密        String sign = MD5Util.MD5("appid=" + appid + "&attach=" + attach                + "&body=" + body + "&mch_id=" + mch_id + "&nonce_str="                + nonce_str + "&notify_url=" + notify_url + "&openid=" + openid                + "&out_trade_no=" + out_trade_no + "&spbill_create_ip="                + spbill_create_ip + "&total_fee=" + total_fee + "&trade_type="                + trade_type + "&key=" + key);        response.setContentType("text/html");        String formData=  "<xml>";        formData += "<appid>" + appid + "</appid>";        formData += "<attach>" + attach + "</attach>";        formData += "<body>" + body + "</body>";        formData += "<mch_id>" + mch_id + "</mch_id>";        formData += "<nonce_str>" + nonce_str + "</nonce_str>";        formData += "<notify_url>" + notify_url + "</notify_url>";        formData += "<openid>" + openid + "</openid>";        formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>";        formData += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";        formData += "<total_fee>" + total_fee + "</total_fee>";        formData += "<trade_type>" + trade_type + "</trade_type>";        formData += "<sign>" + sign + "</sign>";        formData += "</xml>";        //获得预支付 id        String message = htp.Post("https://api.mch.weixin.qq.com/pay/unifiedorder", formData);        String prepay_id=message.split("\\<prepay\\_id\\>\\<\\!\\[CDATA\\[",2)[1].split("]]></prepay_id>",2)[0];        //返回前端数据 组合加密 封装成JSON格式返回        String timeStamp=Long.toString(new Date().getTime());        String paySign =new MD5Util().MD5("appId="+appid+"&nonceStr="+ nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" +  timeStamp+ "&key="+key).toUpperCase();        Map map = new HashMap();        map.put("nonce_str", nonce_str);//随机字符串        map.put("paySign", paySign);//第二次加密        map.put("timeStamp", timeStamp);//时间戳        map.put("prepay_id", "prepay_id="+prepay_id);//预支付id        map.put("out_trade_no", out_trade_no);//订单号        JSONObject data = JSONObject.fromObject(map);        response.getWriter().write(data.toString());
htp.Post的方法
    public static String sendPost(String url, String param) {        PrintWriter out = null;        BufferedReader in = null;        String result = "";        try {            URL realUrl = new URL(url);            // 打开和URL之间的连接            URLConnection conn = realUrl.openConnection();            // 设置通用的请求属性            conn.setRequestProperty("accept", "*/*");            conn.setRequestProperty("connection", "Keep-Alive");            conn.setRequestProperty("user-agent",                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");            // 发送POST请求必须设置如下两行            conn.setDoOutput(true);            conn.setDoInput(true);            // 获取URLConnection对象对应的输出流            out = new PrintWriter(conn.getOutputStream());            // 发送请求参数            out.print(param);            // flush输出流的缓冲            out.flush();            // 定义BufferedReader输入流来读取URL的响应            in = new BufferedReader(                    new InputStreamReader(conn.getInputStream(),"utf-8"));            String line;            while ((line = in.readLine()) != null) {                result += line;            }        } catch (Exception e) {            System.out.println("发送 POST 请求出现异常!"+e);            e.printStackTrace();        }        //使用finally块来关闭输出流、输入流        finally{            try{                if(out!=null){                    out.close();                }                if(in!=null){                    in.close();                }            }            catch(IOException ex){                ex.printStackTrace();            }        }        return result;    } 

MD5加密工具类

import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Util {     public static String MD5(String sourceStr) {            String result = "";            try {                MessageDigest md = MessageDigest.getInstance("MD5");                md.update(sourceStr.getBytes());                byte b[] = md.digest();                int i;                StringBuffer buf = new StringBuffer("");                for (int offset = 0; offset < b.length; offset++) {                    i = b[offset];                    if (i < 0)                        i += 256;                    if (i < 16)                        buf.append("0");                    buf.append(Integer.toHexString(i));                }                result = buf.toString().toUpperCase();                System.out.println("MD5(" + sourceStr + ",32) = " + result);                System.out.println("MD5(" + sourceStr + ",16) = " + buf.toString().substring(8, 24));            } catch (NoSuchAlgorithmException e) {                System.out.println(e);            }            return result;        }}

微信小程序端代码:

wxpay:function(){var that = this    wx.login({      success: function (res) {        var codes = res.code;        wx.request({        //自己支付接口地址 这里的url需要修改          url: 'http://localhost:8080/dingzhit/pay/unifiedorder',          method: 'POST',          header: {            "Content-Type": "application/x-www-form-urlencoded"          },          data: {            total_fee:'1',            code: codes,            attach: "付款",            body: "支付宝",          },          success: function (res) {            console.log(res)            that.setData({ out_trade_no: res.data.out_trade_no})            wx.requestPayment({              timeStamp: res.data.timeStamp,              nonceStr: res.data.nonce_str,              package: res.data.prepay_id,              signType: 'MD5',              paySign: res.data.paySign,              success: function (res) {                // success                 console.log(res)              },              fail: function (res) {                // fail                  console.log(res)                console.log("支付失败")              },              complete: function () {                // complete                  console.log("pay complete")              }            })          }        })      }    });  },
  • 开发过程中的坑
    • 有关加密错误
      如果告诉的是加密的错误可以点击这里的加密相关信息,感觉自己加密写的没有错但是还是报错的话可以用一下官方的签名算法,但是请不要用360浏览器打开,由于浏览器的兼容问题可能会没有校验工具。
原创粉丝点击