【微信支付】小微商户进件 接口分析与源码实现

一、小微商户能力介绍 (摘自 微信小微商户介绍

1. 快速进件

2. 支持零钱、借记卡、信用卡支付方式

3. 交易手续费支持11档枚举值

4. 每日结算款T+1日自动提现至商户个人银行卡

具体不多说了,请看官方文档。

小微商户进件接口的开放大大降低成为微信支付商户的门槛,当然前提是提供服务者拥有微信支付服务商身份。

具体接口操作步骤如下(本文代码用的是WxJava相关的类库,githhub地址:https://github.com/Wechat-Group/WxJava):

第一步:申请入驻接口

这里相应的 WxPayMicroSubmitRequest,与 WxPayMicroSubmitResult 等都是根据相关接口整合出来的,这里不再详细描述

 public R wxMicroSubmit(@RequestBody WxPayMicroSubmitRequest wxPayMicroSubmitRequest) throws Exception {
        //构造riskGetcertficatesRequest
        WxPayRiskGetcertficatesRequest riskGetcertficatesRequest = new WxPayRiskGetcertficatesRequest(WxPayConstants.SignType.HMAC_SHA256);
        riskGetcertficatesRequest.checkAndSign(wxPayService.getConfig());

        //请求证书序列号 cert_sn
        String certSnUrl = wxPayService.getPayBaseUrl() + "/risk/getcertficates";
        String certSnResponseContent = wxPayService.post(certSnUrl,riskGetcertficatesRequest.toXML(),false);
        WxPayRiskGetcertficatesResult wxPayRiskGetcertficatesResult = WxPayRiskGetcertficatesResult.fromXML(certSnResponseContent,WxPayRiskGetcertficatesResult.class);

        /**
         * 填充 wxPayMicroSubmitRequest 字段
         */
        //平台证书序列号
        wxPayMicroSubmitRequest.setCertSn(wxPayRiskGetcertficatesResult.getCertSn());
        //业务申请编号 micro + 时间戳
        wxPayMicroSubmitRequest.setBusinessCode("micro" + DateUtils.format(new Date(),"YYYYMMddHHmmssSSS"));
        //费率
        wxPayMicroSubmitRequest.setRate("0.6%");

        //消息加密前 创建SellerMicroSubmitInfoEntity 并赋值
        SellerMicroSubmitInfoEntity sellerMicroSubmitInfoEntity = new SellerMicroSubmitInfoEntity();
        BeanUtils.copyProperties(wxPayMicroSubmitRequest,sellerMicroSubmitInfoEntity);

        //1.敏感信息加密处理
        wxPayMicroSubmitRequest.rsaEncryptField((WxPayServiceImpl)wxPayService);

        //2.调用checkAndSign 补充系统参数
        wxPayMicroSubmitRequest.checkAndSign(wxPayService.getConfig());
        String microSubmitUrl = wxPayService.getPayBaseUrl() + "/applyment/micro/submit";
        String responseContent =  wxPayService.post(microSubmitUrl,wxPayMicroSubmitRequest.toXML(),true);
        WxPayMicroSubmitResult wxPayMicroSubmitResult = WxPayMicroSubmitResult.fromXML(responseContent,WxPayMicroSubmitResult.class);

        if("SUCCESS".equals(wxPayMicroSubmitResult.getReturnCode())){
            //如果请求成功,则保存小微企业申请数据
            //设置 applymentId
            sellerMicroSubmitInfoEntity.setApplymentId(wxPayMicroSubmitResult.getApplymentId());
            //保存
            sellerMicroSubmitInfoService.saveOrUpdate(sellerMicroSubmitInfoEntity);

            return R.ok().put("wxPayMicroSubmitResult",wxPayMicroSubmitResult);
        } else{
            return R.error(wxPayMicroSubmitResult.getReturnMsg()).put("wxPayMicroSubmitResult",wxPayMicroSubmitResult);
        }
    }

 

申请注入接口需要几个前提接口这里一并都列一下:

1.平台证书及序列号获取接口

2.图片上传接口

3.敏感信息加密

第一个接口上面的代码已经实现,这里专讲第二个

图片上传接口  

下面是 示例代码:

public R uploadMedia(@RequestParam("media") MultipartFile media, WxPayUploadmMediaRequest wxPayUploadmMediaRequest) throws IOException, WxPayException {
        String uploadMediaUrl = this.wxService.getPayBaseUrl() + "/secapi/mch/uploadmedia";
        //强转成子类
        WxPayServiceImpl wxPayService = (WxPayServiceImpl)this.wxService;

        //计算文件哈希
        String medisHash = md5HashCode(media.getInputStream());

        //设置文件哈希
        wxPayUploadmMediaRequest.setMediaHash(medisHash);

        //微信支付签名
        wxPayUploadmMediaRequest.setSignType(WxPayConstants.SignType.HMAC_SHA256);
        wxPayUploadmMediaRequest.checkAndSign(this.wxService.getConfig());

        //创建httpClient
        HttpClientBuilder httpClientBuilder = wxPayService.createHttpClientBuilder(true);

        HttpPost httpPost = wxPayService.createHttpPost(uploadMediaUrl);
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        // 文件流
        multipartEntityBuilder.addTextBody("mch_id", wxPayUploadmMediaRequest.getMchId(), ContentType.MULTIPART_FORM_DATA);
        multipartEntityBuilder.addBinaryBody("media", media.getInputStream(), ContentType.IMAGE_JPEG, media.getOriginalFilename());
        multipartEntityBuilder.addTextBody("media_hash", wxPayUploadmMediaRequest.getMediaHash(), ContentType.MULTIPART_FORM_DATA);
        multipartEntityBuilder.addTextBody("sign_type", wxPayUploadmMediaRequest.getSignType(), ContentType.MULTIPART_FORM_DATA);
        multipartEntityBuilder.addTextBody("sign", wxPayUploadmMediaRequest.getSign(), ContentType.MULTIPART_FORM_DATA);

        HttpEntity entity = multipartEntityBuilder.build();
        httpPost.setEntity(entity);
        httpPost.addHeader(HTTP.CONTENT_TYPE, "multipart/form-data; charset=UTF-8");

        WxPayUploadMediaResult wxPayUploadMediaResult = null;
        try(CloseableHttpClient httpClient = httpClientBuilder.build()){
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            wxPayUploadMediaResult = WxPayUploadMediaResult.fromXML(responseString,WxPayUploadMediaResult.class);
            this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", uploadMediaUrl, "", responseString);

        }
        catch (Exception e) {
            throw new WxPayException(e.getMessage(), e);
        }
        finally {
            httpPost.releaseConnection();
        }

        //this.wxService.post()
        return R.ok().put("mediaId",wxPayUploadMediaResult.getMediaId());
    }

    public static String md5HashCode(InputStream fis) {
        try {
            MessageDigest MD5 = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[8192];
            int length;
            while ((length = fis.read(buffer)) != -1) {
                MD5.update(buffer, 0, length);
            }
            return new String(Hex.encodeHex(MD5.digest()));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

注意这里的multipartEntityBuilder相关配置  很容易出错 

 

关于第三个敏感数据加密这个地方一定要注意一下,要先根据平台证书解密指引 这个接口 解密出来public_key 然后才能成功调用加密方法,官方有示例代码这里就不示例了 。

 

最后写一下查询进件的状态接口:

接口传入  applymentId 或者 businessCode

public R wxMicroGetstate(@RequestBody WxPayMicroGetStateRequest wxPayMicroGetStateRequest) throws WxPayException {

        wxPayMicroGetStateRequest.checkAndSign(wxPayService.getConfig());
        String microSubmitUrl = wxPayService.getPayBaseUrl() + "/applyment/micro/getstate";
        String responseContent =  wxPayService.post(microSubmitUrl,wxPayMicroGetStateRequest.toXML(),true);
        WxPayMicroGetStateResult wxPayMicroGetStateResult = WxPayMicroGetStateResult.fromXML(responseContent,WxPayMicroGetStateResult.class);

        //判断是否审核通过
        if("SUCCESS".equals(wxPayMicroGetStateResult.getReturnCode()) && "SUCCESS".equals(wxPayMicroGetStateResult.getResultCode())){
            //如果通过则...
            return R.ok().put("wxPayMicroGetStateResult",wxPayMicroGetStateResult);
        }
        return R.error(wxPayMicroGetStateResult.getReturnMsg()).put("wxPayMicroGetStateResult",wxPayMicroGetStateResult);
    }

 

posted @ 2019-09-09 15:53  Human_nature  阅读(4780)  评论(3编辑  收藏  举报