Skip to content

支付宝条码付付款成功后的签名校验问题

egan edited this page Nov 4, 2017 · 1 revision

##支付宝条码付付款成功后的签名校验问题

直接进入正题:

条码付付款成功后,会得到一个字符串,例如:


{"alipay_trade_pay_response":{"code":"10000","msg":"Success","buyer_logon_id":"kvi***@sandbox.com","buyer_pay_amount":"0.01","buyer_user_id":"2088102170221273","fund_bill_list":[{"amount":"0.01","fund_channel":"ALIPAYACCOUNT"}],"gmt_payment":"2017-06-15 23:06:26","invoice_amount":"0.01","open_id":"20880038359752799212582612714327","out_trade_no":"de0255710ed84cbdb5cd3f212cacc070","point_amount":"0.00","receipt_amount":"0.01","total_amount":"0.01","trade_no":"2017061521001004270200314093"},"sign":"UY8zCR1LFGNbWgxj/Im1eAVFt9E5SFOra6uASnRc/2Ia0Y46pOvx52HlsWOSetBEb9HEPcJ5MP42D/0CnEGc/FtXMHiaIPcSq/b52KNsKSzFQXFU+xxn/QKqkfi6MZEfjIqwzm7WWQTT1Y3sfFVyMCjDoFN8FobNXdw/U2kqYqA="}

这是一个json串,这里如果直接把json转成Map之类的进行排序并过滤sgin,你会发现签名根本就通不过的。 查阅资料后得知,签名的字符串是alipay_trade_pay_response对应的值。 这里我们怎么进行获取他的值呢?

####两种方式:

    一种是将json串转化为json对象或者自定义对象等。

    第二种是进行字符串截取。

聪明的人会选择第一种,因为第二种会有不确定因素存在,

但是在选择第一种的同时你会遇到key错乱问题,所以你还是校验不通过的, 接着你说那么进行有序的排序下,这里你没有注意的点就是那个json好像也不是你想象的那么有序,所以还是校验不通过

####那么支付宝的人是怎样对这个json进行签名的呢?

经过认真排查alipay_trade_pay_response对应的json串发现,除了codemsg外的key都是按照自然排序的。这样就好办了。

解决方案如下:


        String json = "{\"alipay_trade_pay_response\":{\"code\":\"10000\",\"msg\":\"Success\",\"buyer_logon_id\":\"kvi***@sandbox.com\",\"buyer_pay_amount\":\"0.01\",\"buyer_user_id\":\"2088102170221273\",\"fund_bill_list\":[{\"amount\":\"0.01\",\"fund_channel\":\"ALIPAYACCOUNT\"}],\"gmt_payment\":\"2017-06-15 23:06:26\",\"invoice_amount\":\"0.01\",\"open_id\":\"20880038359752799212582612714327\",\"out_trade_no\":\"de0255710ed84cbdb5cd3f212cacc070\",\"point_amount\":\"0.00\",\"receipt_amount\":\"0.01\",\"total_amount\":\"0.01\",\"trade_no\":\"2017061521001004270200314093\"},\"sign\":\"UY8zCR1LFGNbWgxj/Im1eAVFt9E5SFOra6uASnRc/2Ia0Y46pOvx52HlsWOSetBEb9HEPcJ5MP42D/0CnEGc/FtXMHiaIPcSq/b52KNsKSzFQXFU+xxn/QKqkfi6MZEfjIqwzm7WWQTT1Y3sfFVyMCjDoFN8FobNXdw/U2kqYqA=\"}";
        //得到alipay_trade_pay_response的值并添加至TreeMap中,这里进行自然排序
        TreeMap response = new TreeMap(JSON.parseObject(json).getJSONObject("alipay_trade_pay_response"));
        //链式,按添加顺序进行排序
        LinkedHashMap<Object, Object> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("code", response.remove("code") );
        linkedHashMap.put("msg", response.remove("msg") );
        linkedHashMap.putAll(response);
        String sginText = JSON.toJSONString(linkedHashMap)
        System.out.println(sginText);