diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
index fde7f7150f..6d227f636d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
@@ -22,6 +22,7 @@
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
@@ -149,6 +150,13 @@ public static Integer yuanToFen(String yuan) {
return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue();
}
+ /**
+ * 元转分
+ */
+ public static Integer yuan2Fen(BigDecimal yuan) {
+ return yuan.multiply(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue();
+ }
+
/**
* 检查请求参数内容,包括必填参数以及特殊约束.
*/
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java
index ffd17efe4d..59dd17ed6c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java
@@ -26,6 +26,17 @@ public class WxPayConstants {
*/
public static final Format QUERY_COMMENT_DATE_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss");
+ /**
+ * 币种类型.
+ */
+ public static class CurrencyType {
+ /**
+ * 人民币.
+ */
+ public static final String CNY = "CNY";
+
+ }
+
/**
* 校验用户姓名选项,企业付款时使用.
*/
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java
new file mode 100644
index 0000000000..b641cbe537
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/RequestUtils.java
@@ -0,0 +1,49 @@
+package com.github.binarywang.wxpay.util;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+/**
+ *
+ * 请求工具类.
+ * Created by Wang_Wong on 2023-04-14.
+ *
+ *
+ * @author Wang_Wong
+ */
+public class RequestUtils {
+
+ /**
+ * 获取请求头数据,微信V3版本回调使用
+ *
+ * @param request
+ * @return 字符串
+ */
+ public static String readData(HttpServletRequest request) {
+ BufferedReader br = null;
+ StringBuilder result = new StringBuilder();
+ try {
+ br = request.getReader();
+ for (String line; (line = br.readLine()) != null; ) {
+ if (result.length() > 0) {
+ result.append("\n");
+ }
+ result.append(line);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return result.toString();
+ }
+
+}
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
index e25efe5cb1..10781cf6ec 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
@@ -2,8 +2,7 @@
import com.github.binarywang.utils.qrcode.QrcodeUtils;
import com.github.binarywang.wxpay.bean.coupon.*;
-import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
-import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResultTest;
+import com.github.binarywang.wxpay.bean.notify.*;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
@@ -11,6 +10,7 @@
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.constant.WxPayConstants.AccountType;
import com.github.binarywang.wxpay.constant.WxPayConstants.BillType;
import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
@@ -19,6 +19,7 @@
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.testbase.ApiTestModule;
import com.github.binarywang.wxpay.testbase.XmlWxPayConfig;
+import com.github.binarywang.wxpay.util.RequestUtils;
import com.github.binarywang.wxpay.util.XmlConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -29,10 +30,14 @@
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Calendar;
import java.util.Date;
+import java.util.Optional;
import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType;
import static org.assertj.core.api.Assertions.assertThat;
@@ -728,9 +733,9 @@ public void testUnifiedOrderV3() throws WxPayException {
//构建金额信息
WxPayUnifiedOrderV3Request.Amount amount = new WxPayUnifiedOrderV3Request.Amount();
//设置币种信息
- amount.setCurrency("CNY");
+ amount.setCurrency(WxPayConstants.CurrencyType.CNY);
//设置金额
- amount.setTotal(1);
+ amount.setTotal(BaseWxPayRequest.yuan2Fen(BigDecimal.ONE));
request.setAmount(amount);
WxPayUnifiedOrderV3Result.JsapiResult result = this.payService.createOrderV3(TradeTypeEnum.JSAPI, request);
@@ -767,6 +772,63 @@ public void testRefundV3() throws WxPayException {
System.out.println(GSON.toJson(result));
}
+ /**
+ * 测试V3支付成功回调
+ * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_5.shtml
+ *
+ * @throws Exception the exception
+ */
+ @Test
+ public void testParseOrderNotifyV3Result(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+ String timestamp = request.getHeader("Wechatpay-Timestamp");
+ Optional.ofNullable(timestamp).orElseThrow(() -> new RuntimeException("时间戳不能为空"));
+
+ String nonce = request.getHeader("Wechatpay-Nonce");
+ Optional.ofNullable(nonce).orElseThrow(() -> new RuntimeException("nonce不能为空"));
+
+ String serialNo = request.getHeader("Wechatpay-Serial");
+ Optional.ofNullable(serialNo).orElseThrow(() -> new RuntimeException("serialNo不能为空"));
+
+ String signature = request.getHeader("Wechatpay-Signature");
+ Optional.ofNullable(signature).orElseThrow(() -> new RuntimeException("signature不能为空"));
+
+ log.info("请求头参数为:timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
+
+ // V2版本请参考com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResultTest里的单元测试
+ final WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = this.payService.parseOrderNotifyV3Result(RequestUtils.readData(request),
+ new SignatureHeader(timestamp, nonce, signature, serialNo));
+ log.info(GSON.toJson(wxPayOrderNotifyV3Result));
+ }
+
+ /**
+ * 测试V3退款成功回调
+ * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_11.shtml
+ *
+ * @throws Exception the exception
+ */
+ @Test
+ public void testParseRefundNotifyV3Result(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+ String timestamp = request.getHeader("Wechatpay-Timestamp");
+ Optional.ofNullable(timestamp).orElseThrow(() -> new RuntimeException("时间戳不能为空"));
+
+ String nonce = request.getHeader("Wechatpay-Nonce");
+ Optional.ofNullable(nonce).orElseThrow(() -> new RuntimeException("nonce不能为空"));
+
+ String serialNo = request.getHeader("Wechatpay-Serial");
+ Optional.ofNullable(serialNo).orElseThrow(() -> new RuntimeException("serialNo不能为空"));
+
+ String signature = request.getHeader("Wechatpay-Signature");
+ Optional.ofNullable(signature).orElseThrow(() -> new RuntimeException("signature不能为空"));
+
+ log.info("支付请求头参数为:timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
+
+ final WxPayRefundNotifyV3Result wxPayRefundNotifyV3Result = this.payService.parseRefundNotifyV3Result(RequestUtils.readData(request),
+ new SignatureHeader(timestamp, nonce, signature, serialNo));
+ log.info(GSON.toJson(wxPayRefundNotifyV3Result));
+ }
+
@Test
public void testRefundQueryV3() throws WxPayException {
WxPayRefundQueryV3Request request = new WxPayRefundQueryV3Request();
@@ -778,10 +840,11 @@ public void testRefundQueryV3() throws WxPayException {
/**
* 测试包含正向代理的测试
+ *
* @throws WxPayException
*/
@Test
- public void testQueryOrderV3WithProxy() {
+ public void testQueryOrderV3WithProxy() {
try {
WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request();
request.setOutTradeNo("n1ZvYqjAg3D3LUBa");