對接微信支付使用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也要單獨使用,會使用兩次,這個很重要!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM