收藏
回答

米大师支付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();
   }
     
}


回答关注问题邀请回答
收藏

4 个回答

  • 2018-07-02

    String result = util.doPost(sandboxUrl+accesstoken, json.toString());

    这个用的是sandboxUrl的方法,参数中的

    org_loc=/cgi-bin/midas/getbalance
    改成
    /cgi-bin/midas/sandbox/getbalance


    2018-07-02
    有用 1
    回复 1
    • 张惠栋
      张惠栋
      2018-07-02
      /**
          * 制作sig签名
          * @param sigParams
          * @param secret
          * @return
          */
         public static String makeSig(Map<String,String> sigParams, String secretName,String secretValue){
              
           //sig签名
             String sig="";
              try {
                   
                  String stringA = getSortQueryString(sigParams);
                  String stringSignTemp = stringA+"&org_loc=/cgi-bin/midas/sandbox/getbalance&method=POST&"+secretName+"="+secretValue;
                  sig = sha256_HMAC(secretValue,stringSignTemp);
                   
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
               
          return sig;
              
         }


      2018-07-02
      回复
  • 恶魔仁
    恶魔仁
    2018-07-04

    看代码是签名的时候漏了把 amt、bill_no的参数也加进去.

    2018-07-04
    有用 1
    回复 5
    • 张惠栋
      张惠栋
      2018-07-05

      这两个参数是不参与签名的


      2018-07-05
      回复
    • 疯狂的小辣椒
      疯狂的小辣椒
      2018-07-05回复张惠栋

      你好,这两个参数也要参与签名的

      2018-07-05
      回复
    • 张惠栋
      张惠栋
      2018-07-05回复疯狂的小辣椒

      这两个参数是参与sig的签名还是mp_sig的签名?,你们的文档上并没有说要这两个参数啊

      2018-07-05
      回复
    • 张惠栋
      张惠栋
      2018-07-05回复疯狂的小辣椒

      谢谢,问题已解决,原因是扣游戏币的时候没有让这两个参与签名

      2018-07-05
      回复
    • toms
      toms
      2018-12-05回复疯狂的小辣椒

      扣款接口 amt,bill_no参与sig签名吗?mp_sig不需要?

      2018-12-05
      回复
  • 疯狂的小辣椒
    疯狂的小辣椒
    2018-07-02

    你好,麻烦提供下appid和报错的大致时间点

    2018-07-02
    有用
    回复 7
    • 张惠栋
      张惠栋
      2018-07-02


      appid:wxff3e227af64fe390

      报错的大致时间点 :2018.07.02    17:29:43

      2018-07-02
      回复
    • 疯狂的小辣椒
      疯狂的小辣椒
      2018-07-02回复张惠栋

      好的,反馈已收到,有结果会立即回复

      2018-07-02
      回复
    • 张惠栋
      张惠栋
      2018-07-04回复疯狂的小辣椒

      还没结果么,都好多天了,这也太耽误事了

      2018-07-04
      回复
    • 张惠栋
      张惠栋
      2018-07-04回复疯狂的小辣椒

      @ 小辣椒        什么时候能给结果啊

      2018-07-04
      回复
    • 疯狂的小辣椒
      疯狂的小辣椒
      2018-07-04回复张惠栋

      你好,麻烦现在重试一下,如若还不能解决问题,请重新提供下报错的大致时间点

      2018-07-04
      回复
    查看更多(2)
  • 张惠栋
    张惠栋
    2018-07-02

    刚改了试了还是不行,

    errcode":90009,"errmsg":"mp_sig error hint: [MVugGa03061530]

    2018-07-02
    有用
    回复 2
登录 后发表内容