美文网首页
小程序之微信退款

小程序之微信退款

作者: 何事西风悲画扇_4b46 | 来源:发表于2018-12-22 09:49 被阅读0次

    需要些的文章有点多,时间太少,我就先随便写写,后面有空闲在优化。

    开始 小程序js 页面我就不放了 就一个按钮自己写测试


    //申请退款
    
      sqtk: function (e) {
    
        var that = this;
    
        var that = this;
    
        var outRefundNo = "1165166525";
    
        var openId = "o7Rrj5M-METpuTV8mNxv6_6gn1sw";
    
        var tradeNo = "85511613375";
    
        var amount = "0.01";
    
        console.log('申请退款' + e.currentTarget.dataset.wmddid)
    
        wx.showModal({
    
          title: '提示',
    
          content: '申请退款么',
    
          success: function (res) {
    
            if (res.confirm) {
    
              wx.request({
    
                url: 'http://**/app/refund',
    
                method: 'POST',
    
                data: {
    
                  openId: openId,
    
                  tradeNo: tradeNo,
    
                  amount: amount,
    
                  outRefundNo: outRefundNo,
    
                  refundAmount: amount
    
                },    //参数为键值对字符串
    
                header: {
    
                  //设置参数内容类型为x-www-form-urlencoded
    
                  "Accept": "*/*", 'Content-Type': 'application/json'
    
                },
    
                success: function (e) {
    
                  var data = e.data.wxPayResponse;
    
                }
    
              })
    
            } else if (res.cancel) {
    
              console.log('用户点击取消')
    
            }
    
          }
    
        })
    
      }
    

    服务端接口

    AppWxPayController.java

    退款申请+回调

        @PostMapping("refund")
    
        @ApiOperation("微信退款申请")
    
        public R refund(@RequestBody PayParam payParam){
    
        WxPayEntity wxPayEntity=wxPayService.refund(payParam);
    
        return R.ok().put("wxPayResponse", wxPayEntity);
    
        }
    
        @PostMapping("refundNotifyUrl")
    
        @ApiOperation("微信退款回调")
    
        public String refundNotifyUrl(HttpServletRequest request){
    
        String xmlString = WxPayUtils.getXmlString(request);
    
            logger.info("----微信退款回调接收到的数据如下:---" + xmlString);
    
        return wxPayService.refundAsyncNotify(xmlString);
    
        }
    

    service+实现类 WxPayService.java

    /** 微信申请退款
    
    * <p>Title: refund</p> 
    
    * <p>Description: </p> 
    
    * @return 
    
    */ 
    
    WxPayEntity refund(PayParam payParam);
    
    /**
    
        * 微信退款异步通知
    
        * @param notifyData 异步通知内容
    
        * @return
    
        */
    
    String refundAsyncNotify(String notifyData);
    

    WxPayServiceImpl.java


    /* (non-Javadoc)
    
    * <p>Title: refund</p> 
    
    * <p>Description: 退款申请</p> 
    
    * @param payParam
    
    * @return 
    
    * @see com.alpha.modules.wxpay.service.WxPayService#refund(com.alpha.modules.wxpay.form.PayParam) 
    
    */
    
    @Override
    
    public WxPayEntity refund(PayParam payParam) {
    
    WxRefundResponse response = null;
    
            try {
    
                //组请求参数
    
            WxRefundRequest request = new WxRefundRequest();
    
                request.setAppid(WxConfigure.getAppID());
    
                request.setMchId(WxConfigure.getMch_id());
    
                request.setNonceStr(WxPayUtils.getRandomStr(32));
    
                request.setSignType("MD5");
    
                request.setOutTradeNo(payParam.getTradeNo());
    
                request.setOutRefundNo(payParam.getOutRefundNo());
    
                request.setTotalFee(WxPayUtils.yuanToFen(payParam.getAmount()));
    
                request.setRefundFee(WxPayUtils.yuanToFen(payParam.getRefundAmount()));
    
                request.setNotifyUrl(WxConfigure.getRefundNotifyUrl());
    
                request.setSign(WxPayUtils.signByMD5(request, WxConfigure.getKey()));
    
                Retrofit retrofit=null;
    
                try {
    
                OkHttpClient client=initCert();// 加载证书
    
                  retrofit = new Retrofit.Builder()
    
                        .baseUrl("https://api.mch.weixin.qq.com")
    
                        .addConverterFactory(SimpleXmlConverterFactory.create())
    
                        .client(client)
    
                        .build();
    
                } catch (Exception e) {
    
                    e.printStackTrace();
    
                }
    
                String xml = WxPayUtils.objToXML(request);
    
                RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
    
                Call<WxRefundResponse> call = retrofit.create(WxPayApi.class).REFUND_RESPONSE_CALL(requestBody);
    
                Response<WxRefundResponse> retrofitResponse = call.execute();
    
                response = retrofitResponse.body();
    
                if(!response.getReturnCode().equals("SUCCESS")) {
    
                    throw new RuntimeException("【微信退款】发起退款, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());
    
                }
    
                if (!response.getResultCode().equals("SUCCESS")) {
    
                    throw new RuntimeException("【微信退款】发起退款, resultCode != SUCCESS, err_code = " + response.getErrCode() + " err_code_des=" + response.getErrCodeDes());
    
                }
    
            } catch (IllegalAccessException e) {
    
                e.printStackTrace();
    
            } catch (IOException e) {
    
                e.printStackTrace();
    
            }
    
    return buildWxRefundResponse(response);
    
    }
    
    /**
    
        * 加载证书
    
        *
    
        */
    
    private static OkHttpClient initCert() throws Exception {
    
            // 证书密码,默认为商户ID
    
            String key = WxConfigure.getMch_id();
    
            // 证书的路径
    
            String path = WxConfigure.getCertPath();
    
            // 指定读取证书格式为PKCS12
    
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
    
            // 读取本机存放的PKCS12证书文件
    
            FileInputStream instream = new FileInputStream(new File(path));
    
            try {
    
                // 指定PKCS12的密码(商户ID)
    
                keyStore.load(instream, key.toCharArray());
    
            } finally {
    
                instream.close();
    
            }
    
            SSLContext sslcontext = SSLContexts
    
                    .custom()
    
                    .loadKeyMaterial(keyStore, key.toCharArray())
    
                    .build();
    
            // 设置OkHttpClient的SSLSocketFactory
    
            return  new OkHttpClient.Builder()
    
                    .addInterceptor(chain -> {
    
                        // 请求头
    
                        Request request = chain.request().newBuilder()
    
                        .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") 
    
                        .addHeader("Accept-Encoding", "gzip, deflate") 
    
                        .addHeader("Connection", "keep-alive") 
    
                        .addHeader("Accept", "*/*") 
    
                                .build();
    
                        return chain.proceed(request);
    
                    })
    
                    // 超时时间
    
                    .readTimeout(5, TimeUnit.MINUTES)
    
                    .connectTimeout(5, TimeUnit.MINUTES)
    
                    // HTTPS
    
                    .sslSocketFactory(sslcontext.getSocketFactory())
    
                    // Hostname domain.com not verified
    
                    .hostnameVerifier((s, sslSession) -> true)
    
                    .build();
    
        }
    
    private WxPayEntity buildWxRefundResponse(WxRefundResponse wxRefundResponse) {
    
            String timeStamps = String.valueOf(System.currentTimeMillis() / 1000L); //微信接口时间戳为10位字符串
    
            WxPayEntity wxPayEntity = new WxPayEntity();
    
            try {
    
                wxPayEntity.setTimeStamp(timeStamps);
    
                wxPayEntity.setNonceStr(WxPayUtils.getRandomStr(32));
    
                wxPayEntity.setAppid(WxConfigure.getAppID());
    
                wxPayEntity.setSignType("MD5");
    
            } catch (Exception e) {
    
                e.printStackTrace();
    
            }
    
            logger.info("【微信退款】退款申请通知:"+wxPayEntity.getOutTradeNo()+"退款申请成功");
    
            return wxPayEntity;
    
        }
    
    /* (non-Javadoc) 
    
    * <p>Title: refundAsyncNotify</p> 
    
    * <p>Description: 退款回调通知</p> 
    
    * @param notifyData
    
    * @return 
    
    * @see com.alpha.modules.wxpay.service.WxPayService#refundAsyncNotify(java.lang.String) 
    
    */
    
    @Override
    
    public String refundAsyncNotify(String notifyData) {
    
    WxRefundNotifyResponse wxRefundNotifyResponse = (WxRefundNotifyResponse) WxPayUtils.xmlToObj(notifyData, WxRefundNotifyResponse.class);
    
            try {
    
            if(!wxRefundNotifyResponse.getReturnCode().equals("SUCCESS")) {
    
                    throw new RuntimeException("【微信退款】退款成功通知, returnCode != SUCCESS, returnMsg = " + wxRefundNotifyResponse.getReturnMsg());
    
                }
    
            if(StringUtils.isNoneBlank(wxRefundNotifyResponse.getReqInfo())){
    
            String reqInfo=AESUtils.decode(notifyData, WxConfigure.getKey());
    
            WxRefundNotifyReqinfo  wxRefundNotifyReqinfo= (WxRefundNotifyReqinfo) WxPayUtils.xmlToObj(reqInfo,WxRefundNotifyReqinfo.class);
    
            if(wxRefundNotifyReqinfo.getRefundStatus().equals("SUCCESS")){
    
            //查询transaction_id 是否为空  为空就修改订单状态
    
            }
    
            logger.info("【微信退款】退款成功通知:"+wxRefundNotifyReqinfo.getOutTradeNo()+"退款成功");
    
            }
    
            } catch (Exception e) {
    
    // TODO Auto-generated catch block
    
    e.printStackTrace();
    
    }
    
        return  WxPayUtils.returnXML(wxRefundNotifyResponse.getReturnCode());
    
    }
    

    这里有个坑,就是解码是256位的,而正常的是128位,需要替换2个jre的jar包

    问题还没完,因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件, 从官方网站下载JCE无限制权限策略文件,注意自己JDK的版本别下错了。将local_policy.jar和US_export_policy.jar这两个文件替换%JRE_HOME%\lib\security和%JDK_HOME%\jre\lib\security下原来的文件,注意先备份原文件。

    官方网站提供了JCE无限制权限策略文件的下载:

    JDK6的下载地址:

    http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

    JDK7的下载地址:

    http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

    JDK8的下载地址:

    http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

    下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。

    然后后面一篇放实体类吧 我就不文字描述了。
    下一篇:[微信支付实体类补发]
    (https://www.jianshu.com/p/fd73ea49040e)

    相关文章

      网友评论

          本文标题:小程序之微信退款

          本文链接:https://www.haomeiwen.com/subject/toxikqtx.html