• 对接微信支付使用HMAC-SHA256使用签名算法实现方式


    最近做微信押金支付对接,很多坑,心累!这里提醒一下各位:

    首先,确保自己商户号进了白名单,没有需要联系客服,否则接口是调不通的,会一直提示参数错误

    其次,确保接口文档是最新的,最好去官网去看,否则可能会有问题,我就是被这个坑了好久,以为拿到的接口文档是对的,结果参数一直有问题

    ,最后发现是文档有问题,而且官网上文档也有问题,我已经发现好几个了,比如fee_type这个参数,明明写着不是必填,但是一定要填,否则会报签名错误之类的返回码

    所以文档也有可能不及时,所以最好就是自己再三确认之后,多与客服沟通,可以节省很多时间!!

    还有一点就是签名问题了,因为押金支付这部分接口只支持HMAC-SHA256算法,所以要单独实现,这里还有个坑,就是中文问题

    实际中服务器上使用中文加密,会不一致,但是本地是好的,所以统一使用utf-8就可以了,随后严格按照签名生成要求即可!

    下面是代码:

    /**
         * HmacSHA256类型签名
         * @param map
         * @return
         * @throws UnsupportedEncodingException 
         * @throws NoSuchAlgorithmException 
         * @throws InvalidKeyException 
         */
        public static String paySignDesposit(Map<String, Object> map, String key) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException{
        	Map<String, String> params = new HashMap<String, String>();
        	Set<String> set = map.keySet();
        	for (String string : set) {
        		if(!map.get(string).equals("")){
        			params.put(string, String.valueOf(map.get(string)));
        		}
    		}
        	String string1 = createSign(params);
        	String stringSignTemp = string1 + "&key=" + key;
            //return DigestUtils.sha256Hex(stringSignTemp).toUpperCase();
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            //  utf-8 : 解决中文加密不一致问题,必须指定编码格式
        	return byteArrayToHexString(sha256_HMAC.doFinal(stringSignTemp.getBytes("utf-8"))).toUpperCase();
        }
    

      

        /**
         * 将加密后的字节数组转换成字符串
         *
         * @param b 字节数组
         * @return 字符串
         */
        private static String byteArrayToHexString(byte[] b) {
            StringBuilder hs = new StringBuilder();
            String stmp;
            for (int n = 0; b!=null && n < b.length; n++) {
                stmp = Integer.toHexString(b[n] & 0XFF);
                if (stmp.length() == 1)
                    hs.append('0');
                hs.append(stmp);
            }
            return hs.toString().toLowerCase();
        }
    

      

        /**
         * 构造package
         * @param params
         * @return
         * @throws UnsupportedEncodingException
         */
        public static String createSign(Map<String, String> params) throws UnsupportedEncodingException {
            Set<String> keysSet = params.keySet();
            Object[] keys = keysSet.toArray();
            Arrays.sort(keys);
            StringBuffer temp = new StringBuffer();
            boolean first = true;
            for (Object key : keys) {
                if (first) {
                    first = false;
                } else {
                    temp.append("&");
                }
                temp.append(key.toString()).append("=");
                Object value = params.get(key);
                String valueString = "";
                if (null != value) {
                    valueString = value.toString();
                }
                temp.append(valueString);
            }
            return temp.toString();
        }
    

      这里还有一点要注意,就是需要加密的字符串后面要拼接key的,key也要单独使用,会使用两次,这个很重要!!!

  • 相关阅读:
    学习angularjs的ng-hide和ng-disabled
    Angularjs实现select的下拉列表
    练习ng-show和ng-hide的方法
    练习angularjs的ng-click的应用
    ng-include文件实现ng-repeat
    JQuery加载html网页
    指定时间内网站访问次数的监控
    AWK 技巧(取倒列,过滤行,匹配,不匹配,内置变量等)
    Linux下FastDFS分布式存储-总结及部署记录
    Linux下IP SAN共享存储操作记录
  • 原文地址:https://www.cnblogs.com/houzheng/p/10168335.html
Copyright © 2020-2023  润新知