zoukankan      html  css  js  c++  java
  • 微信商户支付

      先吐槽下微信,完全就是个坑,文档确实有,但是个别细节没有提,有些得自己试。

      下面总结下微信商户支付的开发,用处一般是用户从商户提现。

      首先,要获取提现用户的openId,openId是用户对于公众号的唯一标识,openId是用户在公众 号中的唯一标识,一个openId只属于一个公众号。openId在用户关注公众号之类的活动中可以得到。

      接下来按照微信的文档,准备需要提交的参数:

      

            Map<String, Object> paras = new HashMap<>();
            paras.put("mch_appid" , "*******");
        ......    

      然后是根据参数生成签名:

      生成前要对参数根据参数名的ascii码顺序排序:

      

            List<Map.Entry<String, Object>> list = new ArrayList<>(paras.entrySet());
            Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
                public int compare(Map.Entry<String, Object> kv1, Map.Entry<String, Object> kv2) {
                    return kv1.getKey().compareTo(kv2.getKey());
                }
            });    

      生成签名:

        private String getSign(List<Map.Entry<String, Object>> list) {
            StringBuffer para = new StringBuffer();
    
            if (!list.isEmpty()) {
                for (Map.Entry<String, Object> one : list) {
                    String value = String.valueOf(one.getValue());
                    if (isNotEmpty(value)){
                        para.append("&")
                                .append(one.getKey())
                                .append("=")
                                .append(one.getValue());
                    }
                }
                para.deleteCharAt(0);
                para.append("&key=" + WXConstants.SECRET_KEY);
            }
    
            return Md5Util.encodeUpper(para.toString());
        }

      注意:所有参数后需要加入秘钥,并且key一定要放在最后,秘钥在商户后台的API安全中设置

      然后要以同样的顺序生成xml格式的参数,这个参数里要加入签名sign,key是不需要加进来的。

      

        private String getWXPara(List<Map.Entry<String, Object>> list){
            StringBuffer para = new StringBuffer();
            para.append("<xml>");
    
            for (Map.Entry<String, Object> one : list){
                para.append(String.format("<%s>", one.getKey()))
                        .append(String.format("<![CDATA[%s]]>", one.getValue()))
                        .append(String.format("</%s>", one.getKey()));
            }
    
            para.append("</xml>");
            return para.toString();
        }

      有了参数就可以通过微信提供的接口提交数据了,提交时是需要证书的,证书在商户平台API安全中下载。

      带着证书发送:

            public String post(String para, String pathCA, String key) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
            log.info("wx.post, {} : request {} & para : {}
    ", this.name, this.url, para);
            StringEntity entity = new StringEntity(para, EscapeUtil.CHARSET_UTF8);
            HttpPost post = new HttpPost(url);
            post.setEntity(entity);
    
            CloseableHttpClient client = getSSLClient(pathCA, key);
            CloseableHttpResponse response = client.execute(post);
    
            int httpCode = response.getStatusLine().getStatusCode();
            byte[] bs = EntityUtils.toByteArray(response.getEntity());
            String result = new String(bs, EscapeUtil.CHARSET_UTF8);
            if (httpCode != 200){
                log.warn("wx.post.httpCodeErr, {} : return {} & httpCode : {} & content : {} & para : {}
    ", this.name, httpCode, result, this.url, para);
            }
            log.info("wx.post, {} : return {} & para : {}
    ", this.name, result, para);
            return content;
        }
        private CloseableHttpClient getSSLClient(final String pathCA, final String key) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
            KeyStore keyStore  = KeyStore.getInstance(WXConstants.CERT_TYPE);
            FileInputStream instream = new FileInputStream(new File(pathCA));try {
                keyStore.load(is, key.toCharArray());
            } finally {
                is.close();
            }
    
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, key.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { WXConstants.SSL_PROTOCOL },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            return httpclient;
        }

      如果人品还过得去,一般就可以了,不过还有一个小坑,微信文档上说返回成功的时候返回值中会有sign,不过实际上其实是没有的。。。

  • 相关阅读:
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结v2
    JS设置cookie、读取cookie、删除cookie
    Atitit 图像处理30大经典算法attilax总结
    Atitit数据库层次架构表与知识点 attilax 总结
    Atitit 游戏的通常流程 attilax 总结 基于cocos2d api
    Atitti css transition Animation differ区别
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
    Atitit 全屏模式的cs桌面客户端软件gui h5解决方案 Kiosk模式
    Atitit 混合叠加俩张图片的处理 图像处理解决方案 javafx blend
    Atitit  rgb yuv  hsv HSL 模式和 HSV(HSB) 图像色彩空间的区别
  • 原文地址:https://www.cnblogs.com/saaav/p/4514915.html
Copyright © 2011-2022 走看看