小程序之微信退款

需要些的文章有點(diǎn)多,時(shí)間太少奇徒,我就先隨便寫寫捷沸,后面有空閑在優(yōu)化。

開始 小程序js 頁(yè)面我就不放了 就一個(gè)按鈕自己寫測(cè)試


//申請(qǐng)退款

  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('申請(qǐng)退款' + e.currentTarget.dataset.wmddid)

    wx.showModal({

      title: '提示',

      content: '申請(qǐng)退款么',

      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

            },    //參數(shù)為鍵值對(duì)字符串

            header: {

              //設(shè)置參數(shù)內(nèi)容類型為x-www-form-urlencoded

              "Accept": "*/*", 'Content-Type': 'application/json'

            },

            success: function (e) {

              var data = e.data.wxPayResponse;

            }

          })

        } else if (res.cancel) {

          console.log('用戶點(diǎn)擊取消')

        }

      }

    })

  }

服務(wù)端接口

AppWxPayController.java

退款申請(qǐng)+回調(diào)

    @PostMapping("refund")

    @ApiOperation("微信退款申請(qǐng)")

    public R refund(@RequestBody PayParam payParam){

    WxPayEntity wxPayEntity=wxPayService.refund(payParam);

    return R.ok().put("wxPayResponse", wxPayEntity);

    }

    @PostMapping("refundNotifyUrl")

    @ApiOperation("微信退款回調(diào)")

    public String refundNotifyUrl(HttpServletRequest request){

    String xmlString = WxPayUtils.getXmlString(request);

        logger.info("----微信退款回調(diào)接收到的數(shù)據(jù)如下:---" + xmlString);

    return wxPayService.refundAsyncNotify(xmlString);

    }

service+實(shí)現(xiàn)類 WxPayService.java

/** 微信申請(qǐng)退款

* <p>Title: refund</p> 

* <p>Description: </p> 

* @return 

*/ 

WxPayEntity refund(PayParam payParam);

/**

    * 微信退款異步通知

    * @param notifyData 異步通知內(nèi)容

    * @return

    */

String refundAsyncNotify(String notifyData);

WxPayServiceImpl.java


/* (non-Javadoc)

* <p>Title: refund</p> 

* <p>Description: 退款申請(qǐng)</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 {

            //組請(qǐng)求參數(shù)

        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("【微信退款】發(fā)起退款, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());

            }

            if (!response.getResultCode().equals("SUCCESS")) {

                throw new RuntimeException("【微信退款】發(fā)起退款, 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 {

        // 證書密碼厂财,默認(rèn)為商戶ID

        String key = WxConfigure.getMch_id();

        // 證書的路徑

        String path = WxConfigure.getCertPath();

        // 指定讀取證書格式為PKCS12

        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        // 讀取本機(jī)存放的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();

        // 設(shè)置OkHttpClient的SSLSocketFactory

        return  new OkHttpClient.Builder()

                .addInterceptor(chain -> {

                    // 請(qǐng)求頭

                    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);

                })

                // 超時(shí)時(shí)間

                .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); //微信接口時(shí)間戳為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("【微信退款】退款申請(qǐng)通知:"+wxPayEntity.getOutTradeNo()+"退款申請(qǐng)成功");

        return wxPayEntity;

    }

/* (non-Javadoc) 

* <p>Title: refundAsyncNotify</p> 

* <p>Description: 退款回調(diào)通知</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 是否為空  為空就修改訂單狀態(tài)

        }

        logger.info("【微信退款】退款成功通知:"+wxRefundNotifyReqinfo.getOutTradeNo()+"退款成功");

        }

        } catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

    return  WxPayUtils.returnXML(wxRefundNotifyResponse.getReturnCode());

}

這里有個(gè)坑芋簿,就是解碼是256位的,而正常的是128位璃饱,需要替換2個(gè)jre的jar包

問題還沒完与斤,因?yàn)槟承﹪?guó)家的進(jìn)口管制限制,Java發(fā)布的運(yùn)行環(huán)境包中的加解密有一定的限制荚恶。比如默認(rèn)不允許256位密鑰的AES加解密撩穿,解決方法就是修改策略文件, 從官方網(wǎng)站下載JCE無(wú)限制權(quán)限策略文件谒撼,注意自己JDK的版本別下錯(cuò)了食寡。將local_policy.jar和US_export_policy.jar這兩個(gè)文件替換%JRE_HOME%\lib\security和%JDK_HOME%\jre\lib\security下原來(lái)的文件,注意先備份原文件廓潜。

官方網(wǎng)站提供了JCE無(wú)限制權(quán)限策略文件的下載:

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。

然后后面一篇放實(shí)體類吧 我就不文字描述了辩蛋。
下一篇:[微信支付實(shí)體類補(bǔ)發(fā)]
(http://www.reibang.com/p/fd73ea49040e)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呻畸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子悼院,更是在濱河造成了極大的恐慌擂错,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件樱蛤,死亡現(xiàn)場(chǎng)離奇詭異钮呀,居然都是意外死亡剑鞍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門爽醋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚁署,“玉大人,你說(shuō)我怎么就攤上這事蚂四」飧辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵遂赠,是天一觀的道長(zhǎng)久妆。 經(jīng)常有香客問我,道長(zhǎng)跷睦,這世上最難降的妖魔是什么筷弦? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮抑诸,結(jié)果婚禮上烂琴,老公的妹妹穿的比我還像新娘。我一直安慰自己蜕乡,他們只是感情好奸绷,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著层玲,像睡著了一般号醉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辛块,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天扣癣,我揣著相機(jī)與錄音,去河邊找鬼憨降。 笑死,一個(gè)胖子當(dāng)著我的面吹牛该酗,可吹牛的內(nèi)容都是我干的授药。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼呜魄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼悔叽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起爵嗅,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娇澎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后睹晒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趟庄,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡括细,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戚啥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奋单。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖猫十,靈堂內(nèi)的尸體忽然破棺而出览濒,到底是詐尸還是另有隱情,我是刑警寧澤拖云,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布贷笛,位于F島的核電站,受9級(jí)特大地震影響宙项,放射性物質(zhì)發(fā)生泄漏乏苦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一杉允、第九天 我趴在偏房一處隱蔽的房頂上張望邑贴。 院中可真熱鬧,春花似錦叔磷、人聲如沸拢驾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)繁疤。三九已至,卻和暖如春秕狰,著一層夾襖步出監(jiān)牢的瞬間稠腊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工鸣哀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留架忌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓我衬,卻偏偏與公主長(zhǎng)得像叹放,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挠羔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容