一、步骤
1、获取用户标识openid等步骤请查询我博客——微信小程序支付(JAVA);
2、申请退款
3、退款回调
二、代码展示
1、小程序代码:
//退款
refund: function (openId) {
var that = this;
wx.request({
url: 'http://t7hhri.natappfree.cc/wechat/refund',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
data: {
'openid': openId,
'orderId': '036b2f8a56904804b3eb1da907735bc1',
'deposit': '1'
},
success: function (res) {
console.log('refund:' + JSON.stringify(res.data));
}
})
}
2、后台代码
@RequestMapping(value = "/refund") @ResponseBodypublicObject refund(HttpServletRequest request) throwsException { JsonResult jsonResult = newJsonResult(); String code = MessageUtil.CODE_SUCCESS;//状态码String msg = MessageUtil.MSG_00;//提示信息PageData pd = newPageData(); try{ pd = this.getPageData(); if(!pd.containsKey("orderId") || StringUtils.isEmpty(pd.getString("orderId"))){ code = MessageUtil.CODE_ERROR; msg = MessageUtil.MSG_NULL; }else{// int isCanCancel = diveService.cancelOrder(pd);intisCanCancel = 1; if(isCanCancel == 1){ String nonce_str = getRandomStringByLength(32); String orderId = pd.getString("orderId"); PageData data = newPageData(); data.put("appid", Configure.getAppID()); data.put("mch_id", Configure.getMch_id()); data.put("nonce_str", nonce_str); data.put("sign_type","MD5"); data.put("out_trade_no", orderId);//商户订单号data.put("out_refund_no", UuidUtil.get32UUID());//商户订单号data.put("total_fee", "1");//支付金额,这边需要转成字符串类型,否则后面的签名会失败data.put("refund_fee", "1"); data.put("notify_url", Configure.getNotify_url_refund());//退改成功后的回调地址String prestr = PayUtil.createLinkString(data); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口String mysign = PayUtil.sign(prestr, Configure.getKey(), "utf-8").toUpperCase(); data.put("sign", mysign); String result = CertHttpUtil.postData(Configure.getRefundPath(),PayUtil.GetMapToXML(data)); System.out.println(result); Map rep = PayUtil.doXMLParse(result); System.out.println(rep); } } jsonResult.setCode(code); jsonResult.setMessage(msg); }catch(Exception e) { jsonResult.setCode(MessageUtil.CODE_ERROR); jsonResult.setMessage(MessageUtil.MSG_01); logger.error(e.toString(), e); } returnjsonResult; }packagecom.fh.wx;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.security.KeyStore;importjavax.net.ssl.SSLContext;importorg.apache.http.HttpEntity;importorg.apache.http.HttpResponse;importorg.apache.http.client.config.RequestConfig;importorg.apache.http.client.methods.HttpPost;importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;importorg.apache.http.conn.ssl.SSLContexts;importorg.apache.http.entity.StringEntity;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.util.EntityUtils;/*** Created by 菜园子 on 2018/7/4.*/public classCertHttpUtil { private static intsocketTimeout= 10000;// 连接超时时间,默认10秒private static intconnectTimeout= 30000;// 传输超时时间,默认30秒private staticRequestConfig requestConfig;// 请求器的配置private staticCloseableHttpClient httpClient;// HTTP请求器/*** 通过Https往API post xml数据*@paramurlAPI地址*@paramxmlObj要提交的XML数据对象*@return*/public staticString postData(String url, String xmlObj) { // 加载证书try{ initCert(); } catch(Exception e) { e.printStackTrace(); } String result = null; HttpPost httpPost = newHttpPost(url); // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别StringEntity postEntity = newStringEntity(xmlObj, "UTF-8"); httpPost.addHeader("Content-Type", "text/xml"); httpPost.setEntity(postEntity); // 根据默认超时限制初始化requestConfigrequestConfig= RequestConfig.custom() .setSocketTimeout(socketTimeout) .setConnectTimeout(connectTimeout) .build(); // 设置请求器的配置httpPost.setConfig(requestConfig); try{ HttpResponse response = null; try{ response = httpClient.execute(httpPost); } catch(IOException e) { e.printStackTrace(); } HttpEntity entity = response.getEntity(); try{ result = EntityUtils.toString(entity, "UTF-8"); } catch(IOException e) { e.printStackTrace(); } } finally{ httpPost.abort(); } returnresult; } /*** 加载证书**/private static voidinitCert() throwsException { // 证书密码,默认为商户IDString key = Configure.getMch_id(); // 证书的路径String path = Configure.getCertPath(); // 指定读取证书格式为PKCS12KeyStore keyStore = KeyStore.getInstance("PKCS12"); // 读取本机存放的PKCS12证书文件FileInputStream instream = newFileInputStream(newFile(path)); try{ // 指定PKCS12的密码(商户ID)keyStore.load(instream, key.toCharArray()); } finally{ instream.close(); } SSLContext sslcontext = SSLContexts .custom() .loadKeyMaterial(keyStore, key.toCharArray()) .build(); // 指定TLS版本SSLConnectionSocketFactory sslsf = newSSLConnectionSocketFactory( sslcontext, newString[] { "TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); // 设置httpclient的SSLSocketFactoryhttpClient= HttpClients .custom() .setSSLSocketFactory(sslsf) .build(); }}
3、退款回调/*退款回调*/@RequestMapping(value = "/refundResult")@ResponseBodypublic voidrefundResult(HttpServletRequest request, HttpServletResponse response) throwsException { String reqParams = StreamUtil.read(request.getInputStream()); Map result = PayUtil.doXMLParse(reqParams); String return_code = (String) result.get("return_code");//返回状态码if(return_code.equals("SUCCESS")) { } StringBuffer sb = newStringBuffer("xmlreturn_code![CDATA[SUCCESS]]/return_codereturn_msg![CDATA[OK]]/return_msg/xml"); response.getWriter().write(sb.toString());}注意:找不到的工具类请找我的上一篇博——微信小程序支付(JAVA)