国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

SpringBoot 微信退款功能的示例代碼

瀏覽:78日期:2022-06-17 11:13:44

一:微信支付證書配置

SpringBoot 微信退款功能的示例代碼

二:證書讀取以及讀取后的使用

package com.zhx.guides.assistant.config.wechatpay; import org.apache.commons.io.IOUtils;import org.apache.http.HttpEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.ssl.SSLContexts;import org.apache.http.util.EntityUtils;import org.springframework.core.io.ClassPathResource; import javax.net.ssl.SSLContext;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.security.KeyStore; /** * @Class WeChatConfigUtil * @Version 1.0 * @Date 創建時間:2020-06-15 16:19 * @Copyright Copyright by * @Direction 類說明 */public class WeChatConfigUtil { private static byte[] certData; /**** * @throws Exception */ static { try { //從微信商戶平臺下載的安全證書存放的目錄 //String certPath = 'D:configapiclient_cert.p12'; //File file = new File(certPath); //InputStream certStream = new FileInputStream(file); //使用springboot配置文件內讀取的方式 ClassPathResource classPathResource = new ClassPathResource('user_keyapiclient_cert.p12'); InputStream certStream = classPathResource.getInputStream(); WeChatConfigUtil.certData = IOUtils.toByteArray(certStream); certStream.read(WeChatConfigUtil.certData); certStream.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 開始退款操作 * * @param mchId 商戶ID * @param url 請求URL * @param data 退款參數 * @return * @throws Exception */ public static String doRefund(String mchId, String url, String data) throws Exception { /** * 注意PKCS12證書 是從微信商戶平臺-》賬戶設置-》 API安全 中下載的 */ KeyStore keyStore = KeyStore.getInstance('PKCS12'); //這里自行實現我是使用數據庫配置將證書上傳到了服務器可以使用 FileInputStream讀取本地文件 //ByteArrayInputStream inputStream = FileUtil.getInputStream('https://############################.p12'); ByteArrayInputStream inputStream = new ByteArrayInputStream(WeChatConfigUtil.certData); try { //這里寫密碼..默認是你的MCHID keyStore.load(inputStream, mchId.toCharArray()); } finally { inputStream.close(); } SSLContext sslcontext = SSLContexts.custom()//這里也是寫密碼的.loadKeyMaterial(keyStore, mchId.toCharArray()).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,SSLConnectionSocketFactory.getDefaultHostnameVerifier()); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); try { HttpPost httpost = new HttpPost(url); httpost.setEntity(new StringEntity(data, 'UTF-8')); CloseableHttpResponse response = httpclient.execute(httpost); try {HttpEntity entity = response.getEntity();//接受到返回信息String jsonStr = EntityUtils.toString(response.getEntity(), 'UTF-8');EntityUtils.consume(entity);return jsonStr; } finally {response.close(); } } finally { httpclient.close(); } } }

三:發起訂單退款操作

/** * 封裝查詢請求數據 * @param tradeRefund 退款訂單請求信息 * @param path數據訪問PATH * @return */private static SortedMap<String, Object> refundData( TradeRefund tradeRefund , String path ) throws Exception {//構建參數Map<String, String> dataMap = new HashMap<>();dataMap.put('appid','wx#################');dataMap.put('mch_id','137#############');//自行實現該隨機串dataMap.put('nonce_str',Core.MD5('12344'));dataMap.put('out_trade_no','P190808170038402889c5318502');dataMap.put('out_refund_no','P190808170038402889c5318502');dataMap.put('total_fee','1');dataMap.put('refund_fee','1');dataMap.put('refund_desc','退款');//生成簽名String sign = PayToolUtil.createSign('UTF-8', dataMap , WeichatPayConfigure.API_KEY );//WXPayUtil.generateSignature(dataMap, 'rv4###################');dataMap.put('sign', sign);//map數據轉xmlString requestXML = getRequestXml( dataMap );logger.info( '訂單退款請求參數:n' + requestXML );//發起退款String responseXml = WeChatConfigUtil.doRefund( WeichatPayConfigure.MCH_ID , 'https://api.mch.weixin.qq.com/secapi/pay/refund', requestXML );} /** * @author * @date 2016-4-22 * @Description:將請求參數轉換為xml格式的string * @param parameters * 請求參數 * @return */ public static String getRequestXml(SortedMap<Object, Object> parameters) { StringBuffer sb = new StringBuffer(); sb.append('<xml>'); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if ('attach'.equalsIgnoreCase(k) || 'body'.equalsIgnoreCase(k) || 'sign'.equalsIgnoreCase(k)) { sb.append('<' + k + '>' + '<![CDATA[' + v + ']]></' + k + '>'); } else { sb.append('<' + k + '>' + v + '</' + k + '>'); } } sb.append('</xml>'); return sb.toString(); }

/** * @author * @date 2016-4-22 * @Description:sign簽名 * @param characterEncoding * 編碼格式 * @param packageParams * 請求參數 * @return */ public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) { StringBuffer sb = new StringBuffer(); Set es = packageParams.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if (null != v && !''.equals(v) && !'sign'.equals(k) && !'key'.equals(k)) { sb.append(k + '=' + v + '&'); } } sb.append('key=' + API_KEY); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }

package com.zhx.guides.assistant.interfaces.pay.wechatpay.util; import java.security.MessageDigest; public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance('MD5'); if (charsetname == null || ''.equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString .getBytes())); else resultString = byteArrayToHexString(md.digest(resultString .getBytes(charsetname))); } catch (Exception exception) { } return resultString; } /*** * 簡化版本 * @param s * @return */ public final static String MD5(String s) {char hexDigits[] = { ’0’, ’1’, ’2’, ’3’, ’4’, ’5’, ’6’, ’7’, ’8’, ’9’, ’A’, ’B’, ’C’, ’D’, ’E’, ’F’ };try {byte[] btInput = s.getBytes('utf-8');// 獲得MD5摘要算法的 MessageDigest 對象MessageDigest mdInst = MessageDigest.getInstance('MD5');// 使用指定的字節更新摘要mdInst.update(btInput);// 獲得密文byte[] md = mdInst.digest();// 把密文轉換成十六進制的字符串形式int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);} catch (Exception e) {e.printStackTrace();return null;}} private static final String hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; }

/** * @author * @date 2016-4-22 * @Description:將請求參數轉換為xml格式的string * @param parameters * 請求參數 * @return */ public static String getRequestXml(SortedMap<Object, Object> parameters) { StringBuffer sb = new StringBuffer(); sb.append('<xml>'); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if ('attach'.equalsIgnoreCase(k) || 'body'.equalsIgnoreCase(k) || 'sign'.equalsIgnoreCase(k)) { sb.append('<' + k + '>' + '<![CDATA[' + v + ']]></' + k + '>'); } else { sb.append('<' + k + '>' + v + '</' + k + '>'); } } sb.append('</xml>'); return sb.toString(); }

四:請求XML示例

<xml> <appid>wx2421b1c4370ec43b</appid> <mch_id>10000100</mch_id> <nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str> <out_refund_no>1415701182</out_refund_no> <out_trade_no>1415757673</out_trade_no> <refund_fee>1</refund_fee> <total_fee>1</total_fee> <transaction_id></transaction_id> <sign>FE56DD4AA85C0EECA82C35595A69E153</sign></xml>

五:官方信息

官方地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4

需注意這兩個參數我使用的是out_trade_no

SpringBoot 微信退款功能的示例代碼

總結

到此這篇關于SpringBoot 微信退款功能的示例代碼的文章就介紹到這了,更多相關SpringBoot 微信退款內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: 微信
相關文章:
主站蜘蛛池模板: 亚洲一级片免费看 | 欧美一区二区高清 | 成人一级毛片 | 女人张开腿给人桶免费视频 | 97精品国产91久久久久久 | 国产亚洲片| 在线综合+亚洲+欧美中文字幕 | 欧美日韩一区二区三区高清不卡 | 中国一级特黄真人毛片 | 精品一久久香蕉国产线看观 | 日本国产一区二区三区 | 免费观看呢日本天堂视频 | 精品一区二区三区在线视频观看 | 久久国产成人午夜aⅴ影院 久久国产成人亚洲精品影院老金 | 91精品欧美综合在线观看 | 国产日产亚洲精品 | 国产成人精品一区 | 亚洲bbbbbxxxxx精品三十七 | 欧美综合自拍亚洲综合百度 | 美女网站在线观看视频18 | 欧美精品久久天天躁 | 中文字幕在线观看一区 | 欧洲一级毛片免费 | 精品国产免费人成在线观看 | 黄视频欧美 | 一区二区三区免费视频播放器 | 全免费毛片在线播放 | 成年女人看片免费视频频 | 免费午夜扒丝袜www在线看 | 综合爱爱网 | a级毛片免费观看在线播放 a级毛片免费看 | 中文字幕视频免费在线观看 | 国产福利微拍精品一区二区 | 色悠久久久久综合网伊人男男 | 中文字幕精品视频 | 亚洲国产高清视频 | 欧美日韩中文字幕在线观看 | 亚洲免费三级 | 国内精品国语自产拍在线观看55 | 色拍拍噜噜噜aⅴ在线观看 色青青草原桃花久久综合 色婷婷91 | 国产精品国产精品国产三级普 |