- 米大师支付mp_sig签名一直提示错误
参数排序没有问题,accesstoken没有问题,sessionkey也没有问题 @官方[代码]/** [代码][代码] [代码][代码]* [代码][代码] [代码][代码]* @author zhd[代码][代码] [代码][代码]* @version 2018年6月5日 [代码][代码] [代码][代码]*/[代码][代码]public[代码] [代码]class[代码] [代码]WeChatPay {[代码][代码] [代码] [代码] [代码][代码]/**[代码][代码] [代码][代码]* 签名验证[代码][代码] [代码][代码]* @param billno[代码][代码] [代码][代码]* @param userid[代码][代码] [代码][代码]* @param openkey[代码][代码] [代码][代码]* @param zoneid[代码][代码] [代码][代码]* @param appid[代码][代码] [代码][代码]* @param itemid[代码][代码] [代码][代码]* @param count[代码][代码] [代码][代码]* @param pf[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String SignVerify(String openid, String offerid, String ts,String zoneid, String pf, String amt, String billno, String accesstoken,String sessionkey){[代码][代码] [代码] [代码] [代码][代码]String appid = ChannelInfo.getInstance().getWeChatAppId();[代码][代码]//AppId[代码][代码] [代码] [代码] [代码][代码]String secret = ChannelInfo.getInstance().getWeChatSecret();[代码][代码]//米大师秘钥[代码] [代码] [代码][代码]Map<String,String> sigParams = [代码][代码]new[代码] [代码]HashMap<String, String>();[代码][代码] [代码] [代码] [代码][代码]sigParams.put([代码][代码]"openid"[代码][代码],openid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"appid"[代码][代码],appid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"offer_id"[代码][代码],offerid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"ts"[代码][代码],ts);[代码][代码] [代码][代码]sigParams.put([代码][代码]"zone_id"[代码][代码],zoneid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"pf"[代码][代码],pf);[代码][代码] [代码] [代码] [代码][代码]//制作sig签名[代码][代码] [代码][代码]String sig = makeSig(sigParams, [代码][代码]"secret"[代码][代码],secret);[代码][代码] [代码][代码]if[代码] [代码](sig.equals([代码][代码]""[代码][代码])) {[代码][代码] [代码] [代码] [代码][代码]return[代码] [代码]null[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]//制作mp_sig签名[代码][代码] [代码][代码]sigParams.put([代码][代码]"access_token"[代码][代码],accesstoken);[代码][代码] [代码][代码]sigParams.put([代码][代码]"sig"[代码][代码],sig);[代码][代码] [代码] [代码] [代码][代码]String mpSig = makeSig(sigParams, [代码][代码]"session_key"[代码][代码],sessionkey);[代码][代码] [代码] [代码] [代码][代码]JSONObject json = [代码][代码]new[代码] [代码]JSONObject();[代码][代码] [代码] [代码] [代码][代码]json.put([代码][代码]"openid"[代码][代码], openid);[代码][代码] [代码][代码]json.put([代码][代码]"appid"[代码][代码], appid);[代码][代码] [代码][代码]json.put([代码][代码]"offer_id"[代码][代码], offerid);[代码][代码] [代码][代码]json.put([代码][代码]"ts"[代码][代码], Long.valueOf(ts));[代码][代码] [代码][代码]json.put([代码][代码]"zone_id"[代码][代码], zoneid);[代码][代码] [代码][代码]json.put([代码][代码]"pf"[代码][代码], pf);[代码][代码] [代码][代码]json.put([代码][代码]"amt"[代码][代码], Integer.valueOf(amt));[代码][代码] [代码][代码]json.put([代码][代码]"bill_no"[代码][代码], billno);[代码][代码] [代码][代码]json.put([代码][代码]"sig"[代码][代码], sig);[代码][代码] [代码][代码]json.put([代码][代码]"mp_sig"[代码][代码], mpSig);[代码][代码] [代码] [代码] [代码][代码]String sandboxUrl = [代码][代码]"https://api.weixin.qq.com/cgi-bin/midas/sandbox/pay?access_token="[代码][代码];//沙箱环境[代码][代码] [代码][代码]String formalUrl = [代码][代码]"https://api.weixin.qq.com/cgi-bin/midas/pay?access_token="[代码][代码];//正式环境[代码][代码] [代码] [代码] [代码][代码]String result = util.doPost(sandboxUrl+accesstoken, json.toString());[代码][代码] [代码][代码]System.out.println([代码][代码]"+++++++++++++++++++++++++++++++ :"[代码][代码]+result);[代码][代码] [代码][代码]return[代码] [代码]result;[代码][代码] [代码] [代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]/**[代码][代码] [代码][代码]* 制作sig签名[代码][代码] [代码][代码]* @param sigParams[代码][代码] [代码][代码]* @param secret[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String makeSig(Map<String,String> sigParams, String secretName,String secretValue){[代码][代码] [代码] [代码] [代码][代码]//sig签名[代码][代码] [代码][代码]String sig=[代码][代码]""[代码][代码];[代码][代码] [代码][代码]try[代码] [代码]{[代码][代码] [代码] [代码] [代码][代码]//对参与米大师签名的参数按照key=value的格式,并按照参数名ASCII字典序升序排序[代码][代码] [代码][代码]String stringA = getSortQueryString(sigParams);[代码][代码] [代码][代码]String stringSignTemp = stringA+[代码][代码]"&org_loc=/cgi-bin/midas/getbalance&method=POST&"[代码][代码]+secretName+[代码][代码]"="[代码][代码]+secretValue;[代码][代码] [代码][代码]//使用HMAC-SHA256得到签名[代码][代码] [代码][代码]sig = sha256_HMAC(secretValue,stringSignTemp);[代码][代码] [代码] [代码] [代码][代码]} [代码][代码]catch[代码] [代码](Exception e) {[代码][代码] [代码][代码]// TODO Auto-generated catch block[代码][代码] [代码][代码]e.printStackTrace();[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]return[代码] [代码]sig;[代码][代码] [代码] [代码] [代码][代码]}[代码] [代码] [代码][代码]/**[代码][代码] [代码][代码]* 获取得到排序好的查询字符串[代码][代码] [代码][代码]* @param params 请求参数[代码][代码] [代码][代码]* @param isContainSignature 是否包含signature参数[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String getSortQueryString(Map<String,String> params) [代码][代码]throws[代码] [代码]Exception {[代码][代码] [代码] [代码] [代码][代码]Object[] keys = params.keySet().toArray();[代码][代码] [代码][代码]Arrays.sort(keys);[代码][代码] [代码][代码]StringBuffer sb = [代码][代码]new[代码] [代码]StringBuffer();[代码][代码] [代码][代码]for[代码][代码](Object key : keys){[代码][代码] [代码][代码]sb.append(String.valueOf(key)).append([代码][代码]"="[代码][代码]).append(params.get(String.valueOf(key))).append([代码][代码]"&"[代码][代码]);[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]String text = sb.toString();[代码][代码] [代码][代码]if[代码][代码](text.endsWith([代码][代码]"&"[代码][代码])) {[代码][代码] [代码][代码]text=text.substring([代码][代码]0[代码][代码],text.length()-[代码][代码]1[代码][代码]);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]text;[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]/**[代码][代码] [代码][代码]* sha256_HMAC加密[代码][代码] [代码][代码]* [代码][代码] [代码][代码]* @param message[代码][代码] [代码][代码]* 消息[代码][代码] [代码][代码]* @param secret[代码][代码] [代码][代码]* 秘钥[代码][代码] [代码][代码]* @return 加密后字符串[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String sha256_HMAC(String secret, String message) {[代码][代码] [代码][代码]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);[代码][代码] [代码][代码]} [代码][代码]catch[代码] [代码](Exception e) {[代码][代码] [代码][代码]System.out.println([代码][代码]"Error HmacSHA256 ==========="[代码] [代码]+ e.getMessage());[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]hash;[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]/**[代码][代码] [代码][代码]* 将加密后的字节数组转换成字符串[代码][代码] [代码][代码]* [代码][代码] [代码][代码]* @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();[代码][代码] [代码][代码]}[代码][代码] [代码] [代码]}[代码]
2018-07-02 - 米大师支付mp_sig签名一直提示错误
参数排序没有问题,accesstoken没有问题,sessionkey也没有问题 [代码]/**[代码][代码] [代码][代码]* 签名验证[代码][代码] [代码][代码]* @param billno[代码][代码] [代码][代码]* @param userid[代码][代码] [代码][代码]* @param openkey[代码][代码] [代码][代码]* @param zoneid[代码][代码] [代码][代码]* @param appid[代码][代码] [代码][代码]* @param itemid[代码][代码] [代码][代码]* @param count[代码][代码] [代码][代码]* @param pf[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String SignVerify(String openid, String offerid, String ts,String zoneid, String pf, String amt, String billno, String accesstoken,String sessionkey){[代码][代码] [代码] [代码] [代码][代码]String appid = ChannelInfo.getInstance().getWeChatAppId();//AppId[代码][代码] [代码][代码] [代码][代码]String secret = ChannelInfo.getInstance().getWeChatSecret();//米大师秘钥[代码][代码] [代码][代码] [代码] [代码] [代码][代码][代码]Map<String,String> sigParams = new HashMap<String, String>();[代码]string, string="">/string,>[代码][代码] [代码] [代码] [代码][代码]sigParams.put([代码][代码]"openid"[代码][代码],openid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"appid"[代码][代码],appid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"offer_id"[代码][代码],offerid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"ts"[代码][代码],ts);[代码][代码] [代码][代码]sigParams.put([代码][代码]"zone_id"[代码][代码],zoneid);[代码][代码] [代码][代码]sigParams.put([代码][代码]"pf"[代码][代码],pf);[代码][代码] [代码] [代码] [代码][代码]//制作sig签名[代码][代码] [代码][代码]String sig = makeSig(sigParams, [代码][代码]"secret"[代码][代码],secret);[代码][代码] [代码][代码]if[代码] [代码](sig.equals([代码][代码]""[代码][代码])) {[代码][代码] [代码] [代码] [代码][代码]return[代码] [代码]null[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]//制作mp_sig签名[代码][代码] [代码][代码]sigParams.put([代码][代码]"access_token"[代码][代码],accesstoken);[代码][代码] [代码][代码]sigParams.put([代码][代码]"sig"[代码][代码],sig);[代码][代码] [代码] [代码] [代码][代码]String mpSig = makeSig(sigParams, [代码][代码]"session_key"[代码][代码],sessionkey);[代码][代码] [代码] [代码] [代码][代码]JSONObject json = [代码][代码]new[代码] [代码]JSONObject();[代码][代码] [代码] [代码] [代码][代码]json.put([代码][代码]"openid"[代码][代码], openid);[代码][代码] [代码][代码]json.put([代码][代码]"appid"[代码][代码], appid);[代码][代码] [代码][代码]json.put([代码][代码]"offer_id"[代码][代码], offerid);[代码][代码] [代码][代码]json.put([代码][代码]"ts"[代码][代码], Long.valueOf(ts));[代码][代码] [代码][代码]json.put([代码][代码]"zone_id"[代码][代码], zoneid);[代码][代码] [代码][代码]json.put([代码][代码]"pf"[代码][代码], pf);[代码][代码] [代码][代码]json.put([代码][代码]"amt"[代码][代码], Integer.valueOf(amt));[代码][代码] [代码][代码]json.put([代码][代码]"bill_no"[代码][代码], billno);[代码][代码] [代码][代码]json.put([代码][代码]"sig"[代码][代码], sig);[代码][代码] [代码][代码]json.put([代码][代码]"mp_sig"[代码][代码], mpSig);[代码][代码] [代码] [代码] [代码][代码]String sandboxUrl = [代码][代码]"https://api.weixin.qq.com/cgi-bin/midas/sandbox/pay?access_token="[代码][代码];//沙箱环境[代码][代码] [代码][代码]String formalUrl = [代码][代码]"https://api.weixin.qq.com/cgi-bin/midas/pay?access_token="[代码][代码];//正式环境[代码][代码] [代码] [代码] [代码][代码]String result = util.doPost(sandboxUrl+accesstoken, json.toString());[代码][代码] [代码][代码]System.out.println([代码][代码]"+++++++++++++++++++++++++++++++ :"[代码][代码]+result);[代码][代码] [代码][代码]return[代码] [代码]result;[代码][代码] [代码] [代码] [代码][代码]}[代码][代码] [代码][代码]/**[代码][代码] [代码][代码]* 制作sig签名[代码][代码] [代码][代码]* @param sigParams[代码][代码] [代码][代码]* @param secret[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码]public[代码] [代码]static[代码] [代码]String makeSig(Mapstring,string>sigParams, String secretName,String secretValue){/string,string>[代码][代码] [代码] [代码] [代码][代码]//sig签名[代码][代码] [代码][代码]String sig=[代码][代码]""[代码][代码];[代码][代码] [代码][代码]try[代码] [代码]{[代码][代码] [代码] [代码] [代码][代码]//对参与米大师签名的参数按照key=value的格式,并按照参数名ASCII字典序升序排序[代码][代码] [代码][代码]String stringA = getSortQueryString(sigParams);[代码][代码] [代码][代码]String stringSignTemp = stringA+[代码][代码]"&org_loc=/cgi-bin/midas/getbalance&method=POST&"[代码][代码]+secretName+[代码][代码]"="[代码][代码]+secretValue;[代码][代码] [代码][代码]//使用HMAC-SHA256得到签名[代码][代码] [代码][代码]sig = sha256_HMAC(secretValue,stringSignTemp);[代码][代码] [代码] [代码] [代码][代码]} [代码][代码]catch[代码] [代码](Exception e) {[代码][代码] [代码][代码]// TODO Auto-generated catch block[代码][代码] [代码][代码]e.printStackTrace();[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]return[代码] [代码]sig;[代码][代码] [代码] [代码]}[代码][代码] [代码][代码]/**[代码][代码] [代码][代码]* 获取得到排序好的查询字符串[代码][代码] [代码][代码]* @param params 请求参数[代码][代码] [代码][代码]* @param isContainSignature 是否包含signature参数[代码][代码] [代码][代码]* @return[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]public[代码] [代码]static[代码] [代码]String getSortQueryString(Mapstring,string>params)/string,string>[代码][代码]throws[代码] [代码]Exception {[代码][代码] [代码] [代码] [代码][代码]Object[] keys = params.keySet().toArray();[代码][代码] [代码][代码]Arrays.sort(keys);[代码][代码] [代码][代码]StringBuffer sb = [代码][代码]new[代码] [代码]StringBuffer();[代码][代码] [代码][代码]for[代码][代码](Object key : keys){[代码][代码] [代码][代码]sb.append(String.valueOf(key)).append([代码][代码]"="[代码][代码]).append(params.get(String.valueOf(key))).append([代码][代码]"&"[代码][代码]);[代码][代码] [代码][代码]}[代码][代码] [代码] [代码] [代码][代码]String text = sb.toString();[代码][代码] [代码][代码]if[代码][代码](text.endsWith([代码][代码]"&"[代码][代码])) {[代码][代码] [代码][代码]text=text.substring([代码][代码]0[代码][代码],text.length()-[代码][代码]1[代码][代码]);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]text;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]/**[代码][代码] [代码][代码]* sha256_HMAC加密[代码][代码] [代码][代码]* [代码][代码] [代码][代码]* @param message[代码][代码] [代码][代码]* 消息[代码][代码] [代码][代码]* @param secret[代码][代码] [代码][代码]* 秘钥[代码][代码] [代码][代码]* @return 加密后字符串[代码][代码] [代码][代码]*/[代码][代码]public[代码] [代码]static[代码] [代码]String sha256_HMAC(String secret, String message) {[代码][代码] [代码][代码]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);[代码][代码] [代码][代码]} [代码][代码]catch[代码] [代码](Exception e) {[代码][代码] [代码][代码]System.out.println([代码][代码]"Error HmacSHA256 ==========="[代码] [代码]+ e.getMessage());[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]hash;[代码][代码]}[代码][代码] [代码][代码]/**[代码][代码] [代码][代码]* 将加密后的字节数组转换成字符串[代码][代码] [代码][代码]* [代码][代码] [代码][代码]* @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();[代码][代码]}[代码]
2018-06-29