国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

微信小程序支付V3版本接口實現(xiàn)

這篇具有很好參考價值的文章主要介紹了微信小程序支付V3版本接口實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一.說明和前期準(zhǔn)備(小程序的V3版本)

特別說明:遇到 java.security.InvalidKeyException: Illegal key size ******* getValidator的錯誤
參考添加鏈接描述
JDK7的下載地址
JDK8的下載地址:

下載后解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
如果安裝了JRE,將兩個jar文件放到%JRE_HOME%\lib\security目錄下覆蓋原來的文件
如果安裝了JDK,還要將兩個jar文件也放到%JDK_HOME%\jre\lib\security目錄下覆蓋原來文件。
微信小程序支付V3版本接口實現(xiàn)

1.場景:小程序項目需要對接微信小程序的支付接口,這里使用的是V3版本

官方文檔鏈接:微信小程支付申請文檔鏈接

1.1按照上面的文檔申請支付

拿到相關(guān)的參數(shù)(小程序的Appid,小程序的appSecret ,商戶秘鑰 PrivateKey,商戶號 Mchid,證書序列號MchSerialNo,V3秘鑰))本人讀取方式為從配置文件中讀取

package com.wxapplet.model;

import java.io.IOException;
import java.util.Properties;

import org.springframework.beans.factory.annotation.Value;

import com.foc.alipay.config.AlipayServiceEnvConstants;
import com.foc.common.util.Constants;

public class WxV3payConfig {

	static {
		/**
		 * 靜態(tài)代碼塊初始化類變量
		 */

		Properties proper = new Properties();
		try {
			proper.clear();
			proper.load(WxV3payConfig.class.getResourceAsStream("/paykey.properties"));
			appletAppid=proper.getProperty("appletAppid");
			appletMchid=proper.getProperty("appletMchid");
			appletPrivateKeyPath=proper.getProperty("appletPrivateKeyPath");
			appletMchSerialNo=proper.getProperty("appletMchSerialNo");
			appletSecret=proper.getProperty("appletSecret");
			appletApiV3Key=proper.getProperty("appletApiV3Key");
		
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static String appletAppid;// 由微信生成的應(yīng)用ID
	public static String appletMchid;// 直連商戶的商戶號,由微信支付生成并下發(fā)。
	public static String appletPrivateKeyPath;// 小程序商戶秘鑰

	public static String appletMchSerialNo;// 商戶證書序列號

	public static String appletSecret;// 小程序 appSecret

	public static String appletApiV3Key;// V3密鑰

	@Value("${appletAppid}")
	public static void setAppletAppid(String appletAppid) {
		WxV3payConfig.appletAppid = appletAppid;
	}

	@Value("${appletMchid}")
	public static void setAppletMchid(String appletMchid) {
		WxV3payConfig.appletMchid = appletMchid;
	}

	@Value("${appletPrivateKeyPath}")
	public static void setAppletPrivateKey(String appletPrivateKeyPath) {
		WxV3payConfig.appletPrivateKeyPath = appletPrivateKeyPath;
	}

	@Value("${appletMchSerialNo}")
	public static void setAppletMchSerialNo(String appletMchSerialNo) {
		WxV3payConfig.appletMchSerialNo = appletMchSerialNo;
	}

	@Value("${appletSecret}")
	public static void setAppletSecret(String appletSecret) {
		WxV3payConfig.appletSecret = appletSecret;
	}

	@Value("${appletApiV3Key}")
	public static void setAppletApiV3Key(String appletApiV3Key) {
		WxV3payConfig.appletApiV3Key = appletApiV3Key;
	}
	
	
	

}

微信小程序支付V3版本接口實現(xiàn)
對應(yīng)的paykey.properties文件

#v3
#ying yong id 
appletAppid=
#shang hu hao
appletMchid=

appletPrivateKeyPath=appletPrivateKey.pem

#zheng shu xu lie hao
appletMchSerialNo=
#appsectet
appletSecret=
#v3 mi yao
appletApiV3Key=

微信小程序支付V3版本接口實現(xiàn)

2.引入相關(guān)的maven包

2.1參考的微信官方文檔

微信開發(fā)指引
微信java給出的示例
微信小程序支付V3版本接口實現(xiàn)

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.4.7</version>
</dependency>

微信小程序支付V3版本接口實現(xiàn)

3.相關(guān)工具類

3.1發(fā)送http請求工具類
package com.wxapplet.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;

@Component
public class AppletHttpClient  {
	
   /**
	 * 將通知參數(shù)轉(zhuǎn)化為字符串
	 * 
	 * @param request
	 * @return
	 */
	public static String readData(HttpServletRequest request) {
		BufferedReader br = null;
		try {
			StringBuilder result = new StringBuilder();
			br = request.getReader();
			for (String line; (line = br.readLine()) != null;) {
				if (result.length() > 0) {
					result.append("\n");
				}
				result.append(line);
			}
			return result.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 獲取商戶的私鑰文件
	 * 
	 * @param filename
	 * @return
	 */
	public PrivateKey getPrivateKey(String filename) {
		InputStream insss = AppletHttpClient.class.getClassLoader().getResourceAsStream(filename);

		// InputStream insss = ClassLoader.getSystemResourceAsStream(filename);
		return PemUtil.loadPrivateKey(insss);
	}

	/**
	 * 獲取http請求對象
	 * 
	 * @param verifier
	 * @return
	 */
	@Bean(name = "wxPayClient")
	public CloseableHttpClient getWxPayClient(AutoUpdateCertificatesVerifier verifier) {

		// 獲取商戶私鑰
		PrivateKey privateKey = getPrivateKey(WxV3payConfig.appletPrivateKeyPath);

		WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
				.withMerchant(WxV3payConfig.appletMchid, WxV3payConfig.appletMchSerialNo, privateKey).withValidator(new WechatPay2Validator(verifier));
		// ... 接下來,你仍然可以通過builder設(shè)置各種參數(shù),來配置你的HttpClient

		// 通過WechatPayHttpClientBuilder構(gòu)造的HttpClient,會自動的處理簽名和驗簽,并進行證書自動更新
		CloseableHttpClient httpClient = builder.build();

		return httpClient;
	}

	/**
	 * 獲取HttpClient,無需進行應(yīng)答簽名驗證,跳過驗簽的流程
	 */
	@Bean(name = "wxPayNoSignClient")
	public CloseableHttpClient getWxPayNoSignClient() {

		// 獲取商戶私鑰
		PrivateKey privateKey = getPrivateKey(WxV3payConfig.appletPrivateKeyPath);

		// 用于構(gòu)造HttpClient
		WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
				// 設(shè)置商戶信息
				.withMerchant(WxV3payConfig.appletMchid, WxV3payConfig.appletMchSerialNo, privateKey)
				// 無需進行簽名驗證、通過withValidator((response) -> true)實現(xiàn)
				.withValidator((response) -> true);

		// 通過WechatPayHttpClientBuilder構(gòu)造的HttpClient,會自動的處理簽名和驗簽,并進行證書自動更新
		CloseableHttpClient httpClient = builder.build();

		return httpClient;
	}
	

	

	
	
	/**
	 * V3  SHA256withRSA 簽名.
	 * @param appid 
	 * @param timeStamp
	 * @param nonceStr
	 * @param prepayId
	 * @param privateKey
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeyException
	 * @throws SignatureException
	 * @throws FileNotFoundException 
	 */
	
	public String getSign1(String appid ,String timeStamp,String nonceStr ,String prepayId  , String  privateKeyPath) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, FileNotFoundException{
		try {
			String signatureStr = Stream.of(appid, timeStamp, nonceStr, prepayId)
		            .collect(Collectors.joining("\n", "", "\n"));
			Signature	sign = Signature.getInstance("SHA256withRSA");
			 InputStream insss = PayCommonUtil.class.getClassLoader().getResourceAsStream(privateKeyPath);
			PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(insss);
			sign.initSign(merchantPrivateKey);
			sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
			return Base64.getEncoder().encodeToString(sign.sign());
		} catch (Exception e) {
			e.printStackTrace();
		}
	    
		return null;
	}
	
	
	/**
	 * 獲取簽名驗證器
	 * 
	 * @return
	 */
	@Bean
	public AutoUpdateCertificatesVerifier  getVerifier() {

		// 獲取商戶私鑰
		PrivateKey privateKey = getPrivateKey(WxV3payConfig.appletPrivateKeyPath);

		// 私鑰簽名對象
		PrivateKeySigner privateKeySigner = new PrivateKeySigner(WxV3payConfig.appletMchSerialNo, privateKey);

		// 身份認證對象
		WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(WxV3payConfig.appletMchid, privateKeySigner);

		// 使用定時更新的簽名驗證器,不需要傳入證書
		AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(wechatPay2Credentials,
				WxV3payConfig.appletApiV3Key.getBytes(StandardCharsets.UTF_8));

		return verifier;

	}
}

3.2進行下單操作

微信小程序支付V3版本接口實現(xiàn)
這里使用JSAPI下單,微信小程序JSAPI下單參考

     String appId =WxV3payConfig.appletAppid; // 
			 String mchId =WxV3payConfig.appletMchid; // 商戶號
			 String privateKeyPath =WxV3payConfig.appletPrivateKeyPath;//  你的商戶私鑰路徑

			 
			 String nonceStr = RandomUtil.randomString(32);//隨機字符串
			 
			 

				// 構(gòu)造訂單信息
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("appid",appId); // 小程序的應(yīng)用appid
				jsonObject.put("mchid", mchId); // 直連商戶的商戶號,由微信支付生成并下發(fā)。
				String body = "訂單消費";
				Project project = projectService.findOne(tempPersonalRecord.getProjectId());
				if (project != null && StringUtils.isNotBlank(project.getName())) {
					body = project.getName();
				}
				jsonObject.put("description", body); // 商品描述
				jsonObject.put("out_trade_no", outTradeNo); // 商戶訂單號
				logger.info("total_fee=" + Math.round(tempPersonalRecord.getMoney() * 100) + "");
				JSONObject amoutJson = new JSONObject();
				amoutJson.put("total", tempPersonalRecord.getMoney() * 100); // 總金額,訂單總金額,單位為分
				amoutJson.put("currency", "CNY");// 貨幣類型CNY:人民幣,境內(nèi)商戶號僅支持人民幣。
				jsonObject.put("amount", amoutJson); // 訂單金額信息
				jsonObject.put("notify_url", notifyUrl); // 接收微信支付異步通知回調(diào)地址,通知url必須為直接可訪問的url,不能攜帶參數(shù)。
				
				JSONObject payUser = new JSONObject();
				payUser.put("openid", mfUser.getOpenId());
				jsonObject.put("payer", payUser); // 支付者用戶在商戶appid下的唯一標(biāo)識。
				
				

				// 發(fā)送請求進行JSAPI下單
				 HttpPost httpPost = new  HttpPost(APPLET_JSAPI_URL); 
				 
				 StringEntity entity = new StringEntity(jsonObject.toString(),"utf-8");
				  entity.setContentType("application/json");
			        httpPost.setEntity(entity);
			        httpPost.setHeader("Accept", "application/json");
			      //完成簽名并執(zhí)行請求
			        CloseableHttpResponse response = wxPayClient.execute(httpPost);
			        
			        String reString = EntityUtils.toString(response.getEntity());//響應(yīng)體
			        int statusCode = response.getStatusLine().getStatusCode();//響應(yīng)狀態(tài)碼
			        
			        if (statusCode==200) {//處理成功
			        	logger.info("微信小程序支付響應(yīng)成功,返回的結(jié)果為="+reString);
						
					}else if (statusCode==204) {//處理成功無返回的boy
						logger.info("微信小程序支付響應(yīng)成功");
					}else {
						logger.info("微信小程序響應(yīng)失敗,響應(yīng)碼為="+statusCode+",返回的結(jié)果為="+reString);
						return new ResultVO(ResultCode.ORDERERROR);
					}
			       


				SortedMap<String, String> params = new TreeMap<String, String>();
				String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);// 時間戳
				String preId = "prepay_id=" + JSON.parseObject(reString).getString("prepay_id");
				String paySign = appletHttpClient.getSign1(appId, timeStamp, nonceStr, preId,
						privateKeyPath);// 簽名
				

				rr.put("appId", appId);// appid
				rr.put("timeStamp", timeStamp);// 時間戳
				rr.put("nonceStr", nonceStr);// 隨機字符串
				rr.put("package", "prepay_id=" + JSON.parseObject(reString).getString("prepay_id"));// 訂單詳情擴展字符串
				rr.put("signType", "RSA");// 簽名類型,默認為RSA,僅支持RSA
				rr.put("paySign", paySign);// 簽名
				 rr.put("outTradeNo", tempPersonalRecord.getOutTradeNo());//訂單編號
				return new ResultVO(ResultCode.SUCCESS, rr);
3.3獲取返回的prepay_id稍后返回給前端

4.向前端傳遞調(diào)用wx.requestPayment(OBJECT)發(fā)起微信支付的參數(shù)

Api地址
特別說明:簽名使用的是SHA256 with RSA簽名,并對簽名結(jié)果進行Base64編碼得到簽名值。

4.1生成簽名的工具類
	
	/**
	 * V3  SHA256withRSA 簽名.
	 * @param appid 
	 * @param timeStamp
	 * @param nonceStr
	 * @param prepayId
	 * @param privateKey
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeyException
	 * @throws SignatureException
	 */
	public static String getSign(String appid ,String timeStamp,String nonceStr ,String prepayId  , String  privateKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException{
		try {
			String signatureStr = Stream.of(appid, timeStamp, nonceStr, prepayId)
		            .collect(Collectors.joining("\n", "", "\n"));
			Signature	sign = Signature.getInstance("SHA256withRSA");
			PrivateKey merchantPrivateKey = PemUtil
			        .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
			sign.initSign(merchantPrivateKey);
			sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
			return Base64.getEncoder().encodeToString(sign.sign());
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
		return null;
	}
	

官方簽名參考地址

4.2簽名的生成
	String nonceStr = RandomUtil.randomString(32);// 隨機字符串
	String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);// 時間戳
	String preId = "prepay_id=" + JSON.parseObject(reString).getString("prepay_id");
	
			String paySign = PayCommonUtil.getSign(weChatPub.getAppletAppid(), timeStamp, nonceStr, preId,
					weChatPub.getAppletPrivateKey());// 簽名
			
			rr.put("appId", weChatPub.getAppletAppid());// appid
			rr.put("timeStamp", timeStamp);// 時間戳
			rr.put("nonceStr", nonceStr);// 隨機字符串
			rr.put("package", "prepay_id=" + JSON.parseObject(reString).getString("prepay_id"));// 訂單詳情擴展字符串
			rr.put("signType", "RSA");// 簽名類型,默認為RSA,僅支持RSA
			rr.put("paySign", paySign);// 簽名
			return new ResultVO(ResultCode.SUCCESS, rr);
	
4.3使用對生成的簽名使用官方工具驗簽

工具下載地址
微信小程序支付V3版本接口實現(xiàn)

5.支付成功后微信的回調(diào)

官方的驗簽和解密
微信小程序支付V3版本接口實現(xiàn)

// 構(gòu)建request,傳入必要參數(shù)
 NotificationRequest request = new NotificationRequest.Builder().withSerialNumber(wechatPaySerial)
        .withNonce(nonce)
        .withTimestamp(timestamp)
        .withSignature(signature)
        .withBody(body)
        .build();
NotificationHandler handler = new NotificationHandler(verifier, apiV3Key.getBytes(StandardCharsets.UTF_8));
// 驗簽和解析請求體
Notification notification = handler.parse(request);
// 從notification中獲取解密報文
System.out.println(notification.getDecryptData());

相關(guān)示例代碼(包含驗簽操作)自己實現(xiàn)的代碼

logger.info("支付成功進入回調(diào)方法--" + DateUtil.formatDate(new Date()));
		Map<String, String> map1 = new HashMap<>();// 應(yīng)答對象
		Gson gson = new Gson();
		Map<String, String> map = new HashMap<>();// 應(yīng)答對象
		String outTradeNo = null;// 商戶訂單號
		String transactionId = null;// 微信支付訂單號
		String timeEnd = null;//
		String openid = null;// 用戶標(biāo)識
		String tradeState = null;// 交易狀態(tài)
	
			
			// 處理通知參數(shù)
			String body = appletHttpClient.readData(request);
			Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
			String requestId = (String) bodyMap.get("id");
				// 獲取驗簽器
				// 加載平臺證書(mchId:商戶號,mchSerialNo:商戶證書序列號,apiV3Key:V3密鑰)
				PrivateKey privateKey =appletHttpClient.getPrivateKey(WxV3payConfig.appletPrivateKeyPath);
				AutoUpdateCertificatesVerifier verifier = appletHttpClient.getVerifier();
				WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest = new WechatPay2ValidatorForRequest(
						verifier, requestId, body);
				// 進行驗簽操作
				if (!wechatPay2ValidatorForRequest.validate(request)) {// 驗簽成功

					logger.error("支付通知驗簽失敗");
					// 失敗應(yīng)答
					response.setStatus(500);
					map.put("code", "ERROR");
					map.put("message", "通知驗簽失敗");
					return gson.toJson(map);

				}
				logger.info("支付通知驗證成功");
				// 獲取明文
				String plainText = wxAPIV3AesUtil.decryptFromResource(bodyMap, WxV3payConfig.appletApiV3Key);
				// 將明文轉(zhuǎn)換成map
				Map<String, String> resultMap = JSON.parseObject(plainText, HashMap.class);
				outTradeNo = resultMap.get("out_trade_no");// 商戶訂單號
				transactionId = resultMap.get("transaction_id");// 微信支付訂單號
				timeEnd = resultMap.get("time_end");//
				openid = resultMap.get("openid");// 用戶標(biāo)識
				tradeState = resultMap.get("trade_state");// 交易狀態(tài)
			
5.1驗簽的工具類
package com.wxapplet.util;

import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;

import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;

public class WechatPay2ValidatorForRequest {
	 protected static final Logger log = LoggerFactory.getLogger(WechatPay2ValidatorForRequest.class);
	    /**
	     * 應(yīng)答超時時間,單位為分鐘
	     */
	    protected static final long RESPONSE_EXPIRED_MINUTES = 5;
	    protected final Verifier verifier;
	    protected final String requestId;
	    protected final String body;


	    public WechatPay2ValidatorForRequest(Verifier verifier, String requestId, String body) {
	        this.verifier = verifier;
	        this.requestId = requestId;
	        this.body = body;
	    }

	    protected static IllegalArgumentException parameterError(String message, Object... args) {
	        message = String.format(message, args);
	        return new IllegalArgumentException("parameter error: " + message);
	    }

	    protected static IllegalArgumentException verifyFail(String message, Object... args) {
	        message = String.format(message, args);
	        return new IllegalArgumentException("signature verify fail: " + message);
	    }

	    //·驗簽
	    public final boolean validate(HttpServletRequest request) throws IOException {
	        try {
	            //處理請求參數(shù)
	            validateParameters(request);

	            //構(gòu)造驗簽名串
	            String message = buildMessage(request);

	            String serial = request.getHeader(WECHAT_PAY_SERIAL);
	            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);

	            //驗簽
	            if (!verifier.verify(serial, message.getBytes(StandardCharsets.UTF_8), signature)) {
	                throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",
	                        serial, message, signature, requestId);
	            }
	        } catch (IllegalArgumentException e) {
	            log.warn(e.getMessage());
	            return false;
	        }

	        return true;
	    }

	    protected final void validateParameters(HttpServletRequest request) {

	        // NOTE: ensure HEADER_WECHAT_PAY_TIMESTAMP at last
	        String[] headers = {WECHAT_PAY_SERIAL, WECHAT_PAY_SIGNATURE, WECHAT_PAY_NONCE, WECHAT_PAY_TIMESTAMP};

	        String header = null;
	        for (String headerName : headers) {
	            header = request.getHeader(headerName);
	            if (header == null) {
	                throw parameterError("empty [%s], request-id=[%s]", headerName, requestId);
	            }
	        }

	        //判斷請求是否過期
	        String timestampStr = header;
	        try {
	            Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));
	            // 拒絕過期請求
	            if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= RESPONSE_EXPIRED_MINUTES) {
	                throw parameterError("timestamp=[%s] expires, request-id=[%s]", timestampStr, requestId);
	            }
	        } catch (DateTimeException | NumberFormatException e) {
	            throw parameterError("invalid timestamp=[%s], request-id=[%s]", timestampStr, requestId);
	        }
	    }

	    protected final String buildMessage(HttpServletRequest request) throws IOException {
	        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
	        String nonce = request.getHeader(WECHAT_PAY_NONCE);
	        return timestamp + "\n"
	                + nonce + "\n"
	                + body + "\n";
	    }

	    protected final String getResponseBody(CloseableHttpResponse response) throws IOException {
	        HttpEntity entity = response.getEntity();
	        return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";
	    }

}

5.2 解密回調(diào)通知的數(shù)據(jù)相關(guān)工具類
@Component
public class WxAPIV3AesUtil {

	/**
	 * 對稱解密
	 * 
	 * @param bodyMap
	 * @return
	 */
	public static String decryptFromResource(Map<String, Object> bodyMap, String apiV3Key)
			throws GeneralSecurityException {

		// 通知數(shù)據(jù)
		Map<String, String> resourceMap = (Map) bodyMap.get("resource");
		// 數(shù)據(jù)密文
		String ciphertext = resourceMap.get("ciphertext");
		// 隨機串
		String nonce = resourceMap.get("nonce");
		// 附加數(shù)據(jù)
		String associatedData = resourceMap.get("associated_data");

		AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
		String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
				nonce.getBytes(StandardCharsets.UTF_8), ciphertext);

		return plainText;
	}


}

參考鏈接

官方微信V3排錯指南
參考1
參考2文章來源地址http://www.zghlxwxcb.cn/news/detail-483327.html

到了這里,關(guān)于微信小程序支付V3版本接口實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • springboot整合IJPay實現(xiàn)微信支付-V3---微信小程序

    springboot整合IJPay實現(xiàn)微信支付-V3---微信小程序

    微信支付適用于許多場合,如小程序、網(wǎng)頁支付、但微信支付相對于其他支付方式略顯麻煩,我們使用IJpay框架進行整合 JPay 讓支付觸手可及, 封裝了微信支付、支付寶支付、銀聯(lián)支付常用的支付方式以及各種常用的接口。不依賴任何第三方 mvc 框架,僅僅作為工具使用簡單

    2024年02月02日
    瀏覽(58)
  • Python對接微信小程序V3接口進行支付,并使用uwsgi+nginx+django進行https部署

    網(wǎng)上找了很多教程,但是很亂很雜,并且教程資源很少且說的詳細。這里就記錄一下分享給大家 共分為以下幾個步驟: 目錄 一、開始前準(zhǔn)備信息 二、使用前端code獲取用戶的openid 三、對接小程序v3接口下單 四、小程序支付的回調(diào) 五、安裝并啟動uwsgi 六、安裝并啟動nginx 七、

    2024年02月12日
    瀏覽(27)
  • Java實現(xiàn)微信小程序V3支付 (完整demo)
  • SpringBoot整合微信小程序支付V3(支付、退款)

    微信支付開發(fā)前,需要先獲取商家信息,包括商戶號、AppId、證書和密鑰。 獲取商戶號 微信商戶平臺 申請成為商戶 = 提交資料 = 簽署協(xié)議 = 獲取商戶號 獲取AppID 微信公眾平臺 注冊服務(wù)號 = 服務(wù)號認證 = 獲取APPID = 綁定商戶號 申請商戶證書 登錄商戶平臺 = 選擇 賬戶中心 = 安

    2024年02月08日
    瀏覽(50)
  • 小程序微信支付V3版本Java集成

    相較于之前的微信支付API,主要區(qū)別是: 遵循統(tǒng)一的REST的設(shè)計風(fēng)格 使用JSON作為數(shù)據(jù)交互的格式,不再使用XML 使用基于非對稱密鑰的SHA256-RSA的數(shù)字簽名算法,不再使用MD5或HMAC-SHA256 不再要求攜帶HTTPS客戶端證書(僅需攜帶證書序列號) 使用AES-256-GCM,對回調(diào)中的關(guān)鍵信息進

    2024年02月11日
    瀏覽(20)
  • 【Java】微信小程序V3支付(后臺)

    【Java】微信小程序V3支付(后臺)

    目錄 ????????相關(guān)官網(wǎng)文檔 ????????1.需要的參數(shù) ????????2.引入庫 ????????3.用到的工具類 ????????4.支付下單實現(xiàn) ????????5.支付回調(diào) 接入前準(zhǔn)備-小程序支付 | 微信支付商戶平臺文檔中心 微信支付-JSAPI下單 獲取平臺證書列表-文檔中心-微信支付商戶平

    2024年02月12日
    瀏覽(53)
  • SpringBoot 整合微信小程序微信支付V3 jsapi (支付、退款)

    SpringBoot 整合微信小程序微信支付V3 jsapi (支付、退款)

    最近的一個微信小程序項目里有用到微信支付,網(wǎng)上找的資料都是特別亂,看起來特別懵,結(jié)合了好多文章的內(nèi)容,終于做了出來,可能我的這個博文看起來也是特別亂,但是是可以直接C走簡單改一改就可以用的。(支付成功回調(diào),和退款回調(diào)因為昨天剛在阿里申請的域名還

    2024年04月25日
    瀏覽(25)
  • PHP實現(xiàn)對微信支付v3版本回調(diào)數(shù)據(jù)的解密

    PS:本文使用了微信官方給出的demo來實現(xiàn)對回調(diào)數(shù)據(jù)的解密,本文主要對微信官方給出的demo如何使用作出部分個人講解,以及對解密前后數(shù)據(jù)的格式進行展示 PHP類:這是微信官方給出的demo

    2024年02月15日
    瀏覽(22)
  • 【微信小程序】Java實現(xiàn)微信支付(小程序支付JSAPI-V3)java-sdk工具包(包含支付出現(xiàn)的多次回調(diào)的問題解析,接口冪等性)

    【微信小程序】Java實現(xiàn)微信支付(小程序支付JSAPI-V3)java-sdk工具包(包含支付出現(xiàn)的多次回調(diào)的問題解析,接口冪等性)

    ? ? ? 對于一個沒有寫過支付的小白,打開微信支付官方文檔時徹底懵逼 ,因為 微信支付文檔太過詳細, 導(dǎo)致我無從下手,所以寫此文章,幫助第一次寫支付的小伙伴梳理一下。 一、流程分為三個接口:(這是前言,先看一遍,保持印象,方便理解代碼) 1、第一個接口:

    2024年01月16日
    瀏覽(31)
  • java微信小程序支付V2版本(親測有效)

    java微信小程序支付V2版本(親測有效)

    MCHID(商戶號) 就是商戶注冊之后,微信支付給你的唯一的數(shù)字 APPID(小程序的appid) SSLFILE(微信支付需要申請證書,這個字段就是把申請的證書下載之后,存放在你服務(wù)器的某個文件夾的路徑) NOTIFYURL(支付成功之后,微信會給你這個url發(fā)送一條支付成功的消息) APIKEY(證書的秘鑰

    2024年02月09日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包