博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
H5游戏接微信小游戏的支付,满满的都是坑!
阅读量:6859 次
发布时间:2019-06-26

本文共 5970 字,大约阅读时间需要 19 分钟。

h5小游戏接微信的支付,简直是在为难我胖虎,说多了都是泪。

  准备工作:
    准备工作一定要做好,不然很容易出错。首先是session_key这个字段,这个session_key是登录的时候需要用到的,根据code从wx.login获取到。登录成功后直接用客户端保存起来,后面支付的时候要用来签名。

    其次是access_token,这个access_token不是登陆验证用到的那个,我们先看看微信文档里面怎么说。

  是不是很坑,但是支付的时候签名必须要access_token。首先我想到的是存到数据库中,后来我写到监听器中了,但是不知道对不对,代码如下:

private static String weixin_token = "";    private static Long weixin_token_time = System.currentTimeMillis();    private final static String appId = ConfigHolder.getConfig().getString("gmweb.weixin.AppId");    private final static String secret = ConfigHolder.getConfig().getString("gmweb.weixin.Secret");    public static String getWeixinToken() throws Exception{        boolean is = true;        if(weixin_token == null || weixin_token.equals("")){            is = false;        }        if((System.currentTimeMillis()-weixin_token_time)/1000>3600){            is = false;        }        if(!is){            ObjectMapper mapper = new ObjectMapper();            String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret+"";            String tokenResult = HttpUtils.sendHttpGet(tokenUrl);            if(tokenResult!=null&&!tokenResult.equals("")){                Map map = mapper.readValue(tokenResult, Map.class);                if(map!=null&&map.size()>0){                    weixin_token = (String)map.get("access_token");                    weixin_token_time = System.currentTimeMillis();                }            }        }        return weixin_token;    }

    不管哪里用到access_token,都从getWeixinToken()这里面拿,保证唯一性(注意我这里是每隔1个小时拿一次)。好的access_token准备完毕,还剩下米大师签名这个密钥。这个也很坑,其实这个字段就是微信给你的沙箱appkey。

=========================================================================================================================================================好的准备工作完毕:三个字段 session_key、access_toke、米大师密钥

=========================================================================================================================================================

接下来就按照文档进行验证了,小心点一般都没问题(PS:签名的时候参数是按照scii码来进行签名的)

1、从前端获取参数

2、米大师签名,mp_sig签名

  注意这里面坑也不少。

  先贴代码:

token = StartupListener.getWeixinToken();      String signStr = "amt=" + amt +"&appid=" + appid + "&bill_no=" + bill_no + "&offer_id=" + offer_id + "&openid=" + openid                + "&pf=" + pf + "&ts=" + ts + "&zone_id=" + zone_id                + "&org_loc=/cgi-bin/midas/sandbox/pay&method=POST&secret=" + miDaShi;;        String sign = HmacSHA256.sha256_HMAC(signStr, miDaShi);        String mp_signStr = "access_token="+token+"&amt="+amt+"&appid="+appid + "&bill_no=" + bill_no +                "&offer_id="+offer_id+"&openid="+openid+"&pf="+pf+                "&sig="+sign+"&ts="+ts+"&zone_id="+zone_id+                "&org_loc=/cgi-bin/midas/sandbox/pay&method=POST&session_key="+sessionKey;        String mp_sign = HmacSHA256.sha256_HMAC(mp_signStr, sessionKey);

  

  附上sha256_HMAC代码

public static String sha256_HMAC(String message, String secret) {        String hash = "";        try {            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");            sha256_HMAC.init(secret_key);            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());            hash = byteArrayToHexString(bytes);            System.out.println(hash);        }        catch (Exception e) {            System.out.println("Error HmacSHA256 ===========" + e.getMessage());        }        return hash;    }

 

3、发送请求

  好吧,发送请求我也遇到个坑,如果参数不是按照json格式发送,会提示参数缺失。

  

Map
param = new HashMap
(); param.put("openid", openid); param.put("appid", appid); param.put("offer_id", offer_id); param.put("ts", Long.valueOf(ts)); param.put("zone_id", zone_id); param.put("pf", pf); param.put("amt", amt); param.put("bill_no", bill_no); param.put("sig", sign); param.put("mp_sig", mp_sign); String signResult=HttpUtils.sendHttpPost4(sandUrl+"?"+"access_token="+token, param); //sandUlr:https://api.weixin.qq.com/cgi-bin/midas/sandbox/pay

  另外附上sendHttpPost4的代码

public static String sendHttpPost4(String URL, Map
map) { try { URL url = new URL(URL); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestMethod("POST"); connection.setUseCaches(false); connection.setInstanceFollowRedirects(true); connection.setRequestProperty("connection", "Keep-Alive"); // connection.setRequestProperty("Content-Type", // "text/plain; charset=utf-8"); connection.connect(); // POST请求 DataOutputStream out = new DataOutputStream( connection.getOutputStream()); JSONObject obj = new JSONObject(); for (Map.Entry
entry : map.entrySet()) { obj.element(entry.getKey(), entry.getValue()); } log.info("pay json is "+obj.toString()); out.writeBytes(obj.toString()); out.flush(); out.close(); // 读取响应 BufferedReader reader = new BufferedReader(new InputStreamReader( connection.getInputStream())); String lines; StringBuffer sb = new StringBuffer(""); while ((lines = reader.readLine()) != null) { lines = new String(lines.getBytes(), "utf-8"); sb.append(lines); } //System.out.println(sb); reader.close(); connection.disconnect(); return sb.toString(); } catch (Exception e) { e.printStackTrace(); return ""; } }

最后就是解析signResult了,根据返回信息判断是否成功。以上!

转载于:https://www.cnblogs.com/yzdtofly/p/9402782.html

你可能感兴趣的文章
在rem布局下使用背景图片以及sprite
查看>>
JAVA设计模式之【抽象工厂模式】
查看>>
数字电视的电子节目指南(EPG)及其系统
查看>>
11 复用与多址
查看>>
附录A 编译安装Hadoop
查看>>
android studio building project info 错误
查看>>
【Scala】Scala之Control Structures
查看>>
三星手机拍照,从图库选择照片旋转问题完美解决
查看>>
算法笔记_173:历届试题 斐波那契(Java)
查看>>
菜鸟版JAVA设计模式—外观模式
查看>>
EasyUI----动态拼接EasyUI控件
查看>>
PHP session 跨子域问题总结 ini_set('session.cookie_domain', ".domain.com")
查看>>
Office WPS如何在页眉页脚添加一条横线
查看>>
站在 Android 开发的角度,聊聊 Airbnb 的 Lottie!!!
查看>>
数组去重Demo引出的思考
查看>>
javascript怎么禁用浏览器后退按钮
查看>>
AtomicLong可以被原子地读取和写入的底层long值的操作
查看>>
Android studio 将 Module 打包成 Jar 包
查看>>
Java中抽象类和抽象方法的区别
查看>>
任务调度JOB
查看>>