微信支付:小微商户申请入驻第一步:平台证书序列号的获取
程序员文章站
2024-01-24 13:54:22
文档地址 申请入驻文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_2 平台证书获取文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_11 ......
文档地址
申请入驻文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_2
平台证书获取文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_11
1. 微信支付商户平台升级api证书,升级后才可成功调用本接口。
具体操作看:http://kf.qq.com/faq/180824brqnqb180824m6v2ya.html
需要注意的问题,不要着急关闭软件,等全部完成之后再关闭。
2. 平台证书获取(不需要证书)
查看文档,得知我们需要的参数
- mch_id : 商户号
- nonce_str:随机字符串,不大于32位
- sign:签名
- sign_type:签名类型
- mch_key:签名参数
为了方便,首先,导入jar
- 解析xml 需要dom4j
- 由于我们需要从后台调用微信的接口,需要httpclient
<dependency> <groupid>dom4j</groupid> <artifactid>dom4j</artifactid> <version>1.6.1</version> </dependency> <dependency> <groupid>jaxen</groupid> <artifactid>jaxen</artifactid> <version>1.1.6</version> </dependency> <dependency> <groupid>org.apache.httpcomponents</groupid> <artifactid>httpclient</artifactid> <version>4.5.6</version> </dependency>
这边需要注意的,就是加密,暂只支持hmac-sha256,下面提供工具类
java代码
package com.li.utils; import lombok.extern.slf4j.slf4j; import org.apache.commons.lang3.stringutils; import javax.crypto.mac; import javax.crypto.spec.secretkeyspec; import java.util.map; import java.util.sortedmap; import java.util.treemap; /** * 签名加密工具类 * * @author bertonlee */ @slf4j public class signutil { /** * 微信证书hmac-sha256签名 * * @param params * @param secret * @return */ public static string wechatcertficatessignbysha256(map<string, string> params, string secret) { // 需要保证排序 sortedmap<string, string> sortedmap = new treemap<>(params); // 将参数拼接成字符串 stringbuilder tosign = new stringbuilder(); for (string key : sortedmap.keyset()) { string value = params.get(key); if (stringutils.isnotempty(value) && !"sign".equals(key) && !"key".equals(key)) { tosign.append(key).append("=").append(value).append("&"); } } tosign.append("key=").append(secret); return sha256_hmac(tosign.tostring(), secret); } /** * 加密hmac-sha256 * * @param message * @param secret * @return */ private static string sha256_hmac(string message, string secret) { 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()); string sign = bytearraytohexstring(bytes); sign = sign.touppercase(); return sign; } catch (exception e) { log.error("sha256_hmac加密异常", e); } return null; } /** * 加密后的字节转字符串 * * @param b * @return */ private static string bytearraytohexstring(byte[] b) { stringbuilder hs = new stringbuilder(); string stmp = null; 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(); } }
- 其中主要方法wechatcertficatessignbysha256
- 将参数排序后进行拼接,规则查看微信官方的加密规则
- 然后进行加密
- secret 也就是我们的api 密钥
实现代码
package com.li.getcertficates.service.impl; import com.li.getcertficates.service.certficatesservice; import com.li.utils.signutil; import lombok.extern.slf4j.slf4j; import org.apache.http.httpheaders; import org.apache.http.httpresponse; import org.apache.http.client.methods.httppost; import org.apache.http.entity.contenttype; import org.apache.http.entity.stringentity; import org.apache.http.impl.client.closeablehttpclient; import org.apache.http.impl.client.httpclients; import org.apache.http.util.entityutils; import org.dom4j.document; import org.dom4j.documenthelper; import org.springframework.stereotype.service; import java.util.hashmap; import java.util.map; import java.util.uuid; @service @slf4j public class certficatesserviceimpl implements certficatesservice { @override public string getcertficates() { // 初始化一个httpclient closeablehttpclient httpclient = httpclients.createdefault(); // post请求 httppost httppost = new httppost("https://api.mch.weixin.qq.com/risk/getcertficates"); /** * 这边需要您提供微信分配的商户号跟api密钥 */ map<string, string> param = new hashmap<>(4); param.put("mch_id", "微信分配的商户号"); param.put("nonce_str", uuid.randomuuid().tostring().replace("-", "")); // 暂只支持hmac-sha256 加密 param.put("sign_type", "hmac-sha256"); // 对你的参数进行加密处理 param.put("sign", signutil.wechatcertficatessignbysha256(param, "api密钥(mch_key)")); httppost.setentity(new stringentity(map2xml(param), "utf-8")); httppost.setheader(httpheaders.content_type, contenttype.application_xml.getmimetype()); try { httpresponse httpresponse = httpclient.execute(httppost); log.info("获取平台证书响应 {}", httpresponse); if (httpresponse != null && httpresponse.getstatusline().getstatuscode() == 200) { string responseentity = entityutils.tostring(httpresponse.getentity()); document document = documenthelper.parsetext(responseentity); if ("success".equalsignorecase(document.selectsinglenode("//return_code").getstringvalue()) && "success".equalsignorecase(document.selectsinglenode("//result_code").getstringvalue())) { return document.selectsinglenode("//certificates").getstringvalue(); } log.error("请求平台证书序号响应异常 {}", document.selectsinglenode("//return_msg").getstringvalue()); } } catch (exception e) { log.error("执行httpclient请求平台证书序号错误 {}", e); } return null; } /** * map对象转xml * * @param map * @return */ private string map2xml(map<string, string> map) { stringbuilder result = new stringbuilder(); result.append("<xml>"); if (map != null && map.keyset().size() > 0) { map.foreach((key, value) -> { result.append("<" + key + "><![cdata["); result.append(value); result.append("]]></" + key + ">"); }); } result.append("</xml>"); return result.tostring(); } }
- 具体逻辑不难,单纯调个接口,响应结果
可以自己写个main方法,也可以写个单元测试
最终请求参数
<xml> <sign_type>hmac-sha256</sign_type> <nonce_str>qazwsxedcrfvtgbyhnujmiklopasdwefka</nonce_str> <mch_id>商户号</mch_id> <sign>fd29b578b31c509b45b7c2779803d9e41b68e6b84aeb1ebde47dca00049b649b</sign> </xml>
响应结果
<xml> <return_code><![cdata[success]]></return_code> <return_msg><![cdata[ok]]></return_msg> <result_code><![cdata[success]]></result_code> <nonce_str><![cdata[pndrnzsfzpp2ieuq]]></nonce_str> <sign><![cdata[ad5919f5fe6d77c308abee1a4021cb9839c3f04d7c2fe68fc765011ea3bbeb0f]]></sign> <mch_id><![cdata[1900006511]]></mch_id> <certificates><![cdata[{"data":[{"serial_no":"42a5c4f7f70d57d0576bbeda0e0928d6e5c4f003","effective_time":"2017-08-18 14:52:04","expire_time":"2022-08-17 14:52:04","encrypt_certificate":{"algorithm":"aead_aes_256_gcm","nonce":"bfcb2bd59c97","associated_data":"certificate","ciphertext":"vq4n+llnvtihav5gqao44mbybsaz3bz4md3m4f+ouquejrp+/v4ga//uzqnq1g0royqnsmfcsrfj7ittcp0tbyregpyqbkd4nslif/m1o01jd/9nzd3pbwbujenuzve1cumo+fookabyr+z5afesxuumvl5qabd3yj+5gumiktcqcn4w6rls/w2ydo3o3t9swtl5a/5w+u/wsb9/uefnow6nd+2mawrm1gk5trtkbgvkmt699sm4p0puns3d4g3slz6zeyify3+x+nzrxnq+ov7i4e/wkp1s3qjd3vctdc4j5btvpcvdeirbmzztkzmj+qhhirvpxqimttowspcctcptut4v/zrilmihesdrudv7zj4984+4tzbqmq/mt1bwbs8rykye2uufmxsmyoecw06ttkxduz7m2qske4ktlreregpatymglepmnjpsmx/cnwasahcibwn2onjacubdmgflbv05owblkezm4srgzr9emdix/n469tusj3yxvlun2k6xaaem5wpx/hc15r1o1rhpnljgzpzokovpmcyqw5/0ubqgaaatxoggr6l2mrssp9au4j0hix/sjfrjaovxeztvsm+1ogljmrvlz+jxjtd/al7x2xsjtleyyggp4en4aac4dtwuncaazhhf9r7e+bifyopa2ff+exxc9kzuylywg9bwkojwhkykz7nm669gxljlyeu6w9gia8sa3hksfelfcptan7ev9bjrbowqymn7rzeyvizkjhju3ge04oimejfy4ft8jahzaot8bqnvp4g2zt65r4jqwxebfqojnh5sdrltl+3ocqkgmx+1wccaj9zkqxy9efdwzgjlzwoysjvibdqfeayo1przlcf9mbufygh0vblrlsx3vicc/q6oukx2ojrw1hp3sdtfgzms2oe1+xicymlpglhumzgkgywl7zxbotixkkqan46zd7hnctwhhxmjqxcoauognekk1frzrbv0eujhes8gbzvzs7+xm1sr8dktnmqyevfesuy143nft1gk+/bjr+0l2dz0zgpjgas4ykbkwdstng0a/jzrbmryry+fajwgfvhlvcxxd5b51kx1p3pxcqdme3k0al+40glilbegfuvpxhz04bvgxiwhferpndvwvxfzhg7majmpws0pfzjupzexuy+jxif5oyhlcyjnl2jwnncwdzm5afwyqy5oqi88lcobx1x+fguztkaopk8/2zca7uu9ilsyvbf801wagindhxsnemodorpe0lviye/ax7rqehq2q3f2jnmpp6efp1kzst6nswlbf1m5tvx/paspbyowncgrwxla68l5e03scplszrjwp7h3ucgxq9frlgoynf7ocrr0ivisrgvmsdqdtpiwwhb+uoaw4347htqsehrhyqdr6ftryianb+h+6snrjany/cozfv11j03w6h9lmx95ojgywf8cei8s3pnkhpq90o7euq2pmfs/wwxl3zyjfps8oy05zr4ykrnwir4l2x1rycvov34aazvsvr93fvnphty3yf+i6sdwb4ygaxaymm/conns7wrxme44in+yztpdui+8mz5egtbaqjjzrgnrbdnb515ooxg6gk+ev+bjkmxxxonqgoklcci5pn+wrrokxryhfzbyskld/rkg+t3js23no1tyoejewvatmq97i9ofxnrwxozdl9e87jlj26wm+vsbm/snafeh0eu0owwyvskg7evue7xxcberxc8m87muk6ajo/ihhivyleb/d+wg2r0gv7vesajyc2n3zai1oz78wmmtmj6iqxgdc20unmgyx0ieb+cxpjwejefv72arstqzumuzw3yhvd4l7ozq0b6y2gao88monn9nevnydq5ivsg0bsgutxcfwjhygxlyqiggikvkxeq+bbxfpnxbogkb43cm"}}]}]]></certificates> </xml>
如上,其他基础响应外,多了个certificates
- data里面的serial_no,我们申请入驻需要的参数就是这个
- 其次是encrypt_certificate,主要用来平台证书解密成密钥,为申请入驻接口敏感信息加密处理,后面申请入驻时详细讲解
第一步完成,欲知后事如何,且听下回分解
版权声明:本文为不会代码的小白原创文章,转载需添加小白地址 :