最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2020年06月17日 10:32:27   作者:悟能的師兄  
這篇文章主要介紹了SpringBoot 微信退款功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一:微信支付證書配置

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

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 創(chuàng)建時(shí)間:2020-06-15 16:19
 * @Copyright Copyright by 
 * @Direction 類說明
 */
public class WeChatConfigUtil {
 
  private static byte[] certData;
 
  /****
   * @throws Exception
   */
  static {
    try {
      //從微信商戶平臺(tái)下載的安全證書存放的目錄
      //String certPath = "D:\\config\\apiclient_cert.p12";
      //File file = new File(certPath);
      //InputStream certStream = new FileInputStream(file);
      //使用springboot配置文件內(nèi)讀取的方式
      ClassPathResource classPathResource = new ClassPathResource("\\user_key\\apiclient_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  請(qǐng)求URL
   * @param data 退款參數(shù)
   * @return
   * @throws Exception
   */
  public static String doRefund(String mchId, String url, String data) throws Exception {
    /**
     * 注意PKCS12證書 是從微信商戶平臺(tái)-》賬戶設(shè)置-》 API安全 中下載的
     */
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    //這里自行實(shí)現(xiàn)我是使用數(shù)據(jù)庫配置將證書上傳到了服務(wù)器可以使用 FileInputStream讀取本地文件
    //ByteArrayInputStream inputStream = FileUtil.getInputStream("https://############################.p12");
    ByteArrayInputStream inputStream = new ByteArrayInputStream(WeChatConfigUtil.certData);
    try {
      //這里寫密碼..默認(rèn)是你的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();
    }
  }
 
}

三:發(fā)起訂單退款操作

/**
 * 封裝查詢請(qǐng)求數(shù)據(jù)
 * @param tradeRefund 	退款訂單請(qǐng)求信息
 * @param path				數(shù)據(jù)訪問PATH
 * @return
 */
private static SortedMap<String, Object> refundData( TradeRefund tradeRefund , String path ) throws Exception {
	//構(gòu)建參數(shù)
	Map<String, String> dataMap = new HashMap<>();
	dataMap.put("appid","wx#################");
	dataMap.put("mch_id","137#############");
	//自行實(shí)現(xiàn)該隨機(jī)串
	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數(shù)據(jù)轉(zhuǎn)xml
	String requestXML = getRequestXml( dataMap );
	logger.info( "訂單退款請(qǐng)求參數(shù):\n" + requestXML );
	//發(fā)起退款
	String responseXml = WeChatConfigUtil.doRefund( WeichatPayConfigure.MCH_ID , "https://api.mch.weixin.qq.com/secapi/pay/refund", requestXML );
}
 
/** 
 * @author 
 * @date 2016-4-22 
 * @Description:將請(qǐng)求參數(shù)轉(zhuǎn)換為xml格式的string 
 * @param parameters 
 *      請(qǐng)求參數(shù) 
 * @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
 *      請(qǐng)求參數(shù) 
 * @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; 
  } 
 
  /***
   * 簡(jiǎn)化版本
   * @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 對(duì)象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字節(jié)更新摘要
			mdInst.update(btInput);
			// 獲得密文
			byte[] md = mdInst.digest();
			// 把密文轉(zhuǎn)換成十六進(jìn)制的字符串形式
			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:將請(qǐng)求參數(shù)轉(zhuǎn)換為xml格式的string 
 * @param parameters 
 *      請(qǐng)求參數(shù) 
 * @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(); 
} 

四:請(qǐng)求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

需注意這兩個(gè)參數(shù)我使用的是out_trade_no

總結(jié)

到此這篇關(guān)于SpringBoot 微信退款功能的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot 微信退款內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot啟動(dòng)自動(dòng)終止也不報(bào)錯(cuò)的原因及解決

    SpringBoot啟動(dòng)自動(dòng)終止也不報(bào)錯(cuò)的原因及解決

    這篇文章主要介紹了SpringBoot啟動(dòng)自動(dòng)終止也不報(bào)錯(cuò)的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 詳解Mybatis分頁插件 - 示例代碼

    詳解Mybatis分頁插件 - 示例代碼

    這篇文章主要介紹了詳解Mybatis分頁插件 - 示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧。
    2016-12-12
  • MyBatis異常-Property ''configLocation'' not specified, using default MyBatis Configuration

    MyBatis異常-Property ''configLocation'' not specified, using d

    今天小編就為大家分享一篇關(guān)于MyBatis異常-Property 'configLocation' not specified, using default MyBatis Configuration,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Spring詳細(xì)講解7種事務(wù)傳播方式

    Spring詳細(xì)講解7種事務(wù)傳播方式

    Spring事務(wù)傳播機(jī)制是指,包含多個(gè)事務(wù)的方法在相互調(diào)用時(shí),事務(wù)是如何在這些方法間傳播的。本文通過示例詳細(xì)介紹了Spring的事務(wù)傳播機(jī)制,需要的可以參考一下
    2023-01-01
  • Java中List排序的3種常見方法總結(jié)

    Java中List排序的3種常見方法總結(jié)

    在Java編程中List對(duì)象的排序是一個(gè)常見的需求,List接口提供了多種排序方法,這篇文章主要給大家介紹了關(guān)于Java中List排序的3種常見方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • java實(shí)現(xiàn)文本文件刪除空行的示例分享

    java實(shí)現(xiàn)文本文件刪除空行的示例分享

    這篇文章主要介紹了java實(shí)現(xiàn)文本文件刪除空行的示例,需要的朋友可以參考下
    2014-04-04
  • thymeleaf實(shí)現(xiàn)前后端數(shù)據(jù)交換的示例詳解

    thymeleaf實(shí)現(xiàn)前后端數(shù)據(jù)交換的示例詳解

    Thymeleaf?是一款用于渲染?XML/XHTML/HTML5?內(nèi)容的模板引擎,當(dāng)通過?Web?應(yīng)用程序訪問時(shí),Thymeleaf?會(huì)動(dòng)態(tài)地替換掉靜態(tài)內(nèi)容,使頁面動(dòng)態(tài)顯示,這篇文章主要介紹了thymeleaf實(shí)現(xiàn)前后端數(shù)據(jù)交換,需要的朋友可以參考下
    2022-07-07
  • Java中的分割字符串?split(“.”)無效問題

    Java中的分割字符串?split(“.”)無效問題

    這篇文章主要介紹了Java中的分割字符串?split(“.”)無效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案

    Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案

    本文主要介紹了Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 關(guān)于spring.factories失效原因分析及解決

    關(guān)于spring.factories失效原因分析及解決

    這篇文章主要介紹了關(guān)于spring.factories失效原因分析及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

墨竹工卡县| 永嘉县| 东丽区| 宁化县| 林芝县| 澳门| 遵义市| 闽清县| 休宁县| 唐河县| 宜宾县| 永丰县| 苏州市| 成安县| 嵊州市| 基隆市| 牡丹江市| 长岛县| 微博| 郧西县| 苍南县| 长寿区| 阿拉善盟| 邵武市| 和田市| 克什克腾旗| 密云县| 邵东县| 马边| 云梦县| 邻水| 丰城市| 大荔县| 中宁县| 珠海市| 汾阳市| 阿拉善盟| 勐海县| 岗巴县| 横山县| 临清市|