更新了商品管理模块

This commit is contained in:
chen-xin-zhi 2024-12-10 09:31:22 +08:00
parent 37c501ebfd
commit 534d5714b3
7 changed files with 861 additions and 861 deletions

View File

@ -1,43 +1,43 @@
package com.cultural.heritage.controller.wxPayDemo;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @author weikai
*/
public class HttpUtils {
/**
* 将通知参数转化为字符串
* @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();
}
}
}
}
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import jakarta.servlet.http.HttpServletRequest;
//
//import java.io.BufferedReader;
//import java.io.IOException;
//
///**
// * @author weikai
// */
//public class HttpUtils {
//
// /**
// * 将通知参数转化为字符串
// * @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();
// }
// }
// }
// }
//}

View File

@ -1,110 +1,110 @@
package com.cultural.heritage.controller.wxPayDemo;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import jakarta.servlet.http.HttpServletRequest;
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 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);
/**
* 应答超时时间单位为分钟
*/
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 {
//处理请求参数
validateParameters(request);
//构造验签名串
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) : "";
}
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
//import jakarta.servlet.http.HttpServletRequest;
//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 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);
// /**
// * 应答超时时间单位为分钟
// */
// 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 {
// //处理请求参数
// validateParameters(request);
//
// //构造验签名串
// 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) : "";
// }
//}

View File

@ -1,55 +1,55 @@
package com.cultural.heritage.controller.wxPayDemo;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum WxApiType {
/**
*
*/
/**
* Native下单
*/
NATIVE_PAY("/v3/pay/transactions/native"),
/**
* 查询订单
*/
ORDER_QUERY_BY_NO("/v3/pay/transactions/out-trade-no/%s"),
/**
* 关闭订单
*/
CLOSE_ORDER_BY_NO("/v3/pay/transactions/out-trade-no/%s/close"),
/**
* 申请退款
*/
DOMESTIC_REFUNDS("/v3/refund/domestic/refunds"),
/**
* 查询单笔退款
*/
DOMESTIC_REFUNDS_QUERY("/v3/refund/domestic/refunds/%s"),
/**
* 申请交易账单
*/
TRADE_BILLS("/v3/bill/tradebill"),
/**
* 申请资金账单
*/
FUND_FLOW_BILLS("/v3/bill/fundflowbill");
/**
* 类型
*/
private final String type;
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import lombok.AllArgsConstructor;
//import lombok.Getter;
//
//@AllArgsConstructor
//@Getter
//public enum WxApiType {
//
// /**
// *
// */
//
// /**
// * Native下单
// */
// NATIVE_PAY("/v3/pay/transactions/native"),
//
// /**
// * 查询订单
// */
// ORDER_QUERY_BY_NO("/v3/pay/transactions/out-trade-no/%s"),
//
// /**
// * 关闭订单
// */
// CLOSE_ORDER_BY_NO("/v3/pay/transactions/out-trade-no/%s/close"),
//
// /**
// * 申请退款
// */
// DOMESTIC_REFUNDS("/v3/refund/domestic/refunds"),
//
// /**
// * 查询单笔退款
// */
// DOMESTIC_REFUNDS_QUERY("/v3/refund/domestic/refunds/%s"),
//
// /**
// * 申请交易账单
// */
// TRADE_BILLS("/v3/bill/tradebill"),
//
// /**
// * 申请资金账单
// */
// FUND_FLOW_BILLS("/v3/bill/fundflowbill");
//
//
// /**
// * 类型
// */
// private final String type;
//}

View File

@ -1,26 +1,26 @@
package com.cultural.heritage.controller.wxPayDemo;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum WxNotifyType {
/**
* 支付通知
*/
NATIVE_NOTIFY("/api/wx-pay/notify/native"),
/**
* 退款结果通知
*/
REFUND_NOTIFY("/api/wx-pay/notify/refunds");
/**
* 类型
*/
private final String type;
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import lombok.AllArgsConstructor;
//import lombok.Getter;
//
//@AllArgsConstructor
//@Getter
//public enum WxNotifyType {
//
// /**
// * 支付通知
// */
// NATIVE_NOTIFY("/api/wx-pay/notify/native"),
//
//
// /**
// * 退款结果通知
// */
// REFUND_NOTIFY("/api/wx-pay/notify/refunds");
//
// /**
// * 类型
// */
// private final String type;
//}

View File

@ -1,142 +1,142 @@
package com.cultural.heritage.controller.wxPayDemo;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
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;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
@Configuration
@ConfigurationProperties(prefix = "wx.pay") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
@Slf4j
public class WxPayConfig {
// 商户号
private String mchId;
// 商户API证书序列号
private String mchSerialNo;
// 商户私钥文件
private String privateKeyPath;
// APIv3密钥
private String apiV3Key;
// APPID
private String appid;
// 微信服务器地址
private String domain;
// 接收结果通知地址
private String notifyDomain;
/**
* 获取商户的私钥文件
*
* @param filename
* @return
*/
private PrivateKey getPrivateKey(String filename) {
try {
return PemUtil.loadPrivateKey(new FileInputStream(filename));
} catch (FileNotFoundException e) {
throw new RuntimeException("私钥文件不存在", e);
}
}
/**
* 获取签名验证器
*
* @return
*/
@Bean
public ScheduledUpdateCertificatesVerifier getVerifier() {
log.info("获取签名验证器");
//获取商户私钥
PrivateKey privateKey = getPrivateKey(privateKeyPath);
//私钥签名对象
PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
//身份认证对象
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
// 使用定时更新的签名验证器不需要传入证书
ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
wechatPay2Credentials,
apiV3Key.getBytes(StandardCharsets.UTF_8));
return verifier;
}
/**
* 获取http请求对象
*
* @param verifier
* @return
*/
@Bean(name = "wxPayClient")
public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier) {
log.info("获取httpClient");
//获取商户私钥
PrivateKey privateKey = getPrivateKey(privateKeyPath);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, privateKey)
.withValidator(new WechatPay2Validator(verifier));
// ... 接下来你仍然可以通过builder设置各种参数来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签并进行证书自动更新
CloseableHttpClient httpClient = builder.build();
return httpClient;
}
/**
* 获取HttpClient无需进行应答签名验证跳过验签的流程
*/
@Bean(name = "wxPayNoSignClient")
public CloseableHttpClient getWxPayNoSignClient() {
log.info("无需进行应答签名验证,获取httpClient");
//获取商户私钥
PrivateKey privateKey = getPrivateKey(privateKeyPath);
//用于构造HttpClient
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
//设置商户信息
.withMerchant(mchId, mchSerialNo, privateKey)
//无需进行签名验证通过withValidator((response) -> true)实现
.withValidator((response) -> true);
// 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签并进行证书自动更新
CloseableHttpClient httpClient = builder.build();
return httpClient;
}
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
//import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
//import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
//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;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
//import java.io.FileInputStream;
//import java.io.FileNotFoundException;
//import java.nio.charset.StandardCharsets;
//import java.security.PrivateKey;
//
//@Configuration
//@ConfigurationProperties(prefix = "wx.pay") //读取wxpay节点
//@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
//@Slf4j
//public class WxPayConfig {
//
// // 商户号
// private String mchId;
//
// // 商户API证书序列号
// private String mchSerialNo;
//
// // 商户私钥文件
// private String privateKeyPath;
//
// // APIv3密钥
// private String apiV3Key;
//
// // APPID
// private String appid;
//
// // 微信服务器地址
// private String domain;
//
// // 接收结果通知地址
// private String notifyDomain;
//
//
// /**
// * 获取商户的私钥文件
// *
// * @param filename
// * @return
// */
// private PrivateKey getPrivateKey(String filename) {
//
// try {
// return PemUtil.loadPrivateKey(new FileInputStream(filename));
// } catch (FileNotFoundException e) {
// throw new RuntimeException("私钥文件不存在", e);
// }
// }
//
// /**
// * 获取签名验证器
// *
// * @return
// */
// @Bean
// public ScheduledUpdateCertificatesVerifier getVerifier() {
//
// log.info("获取签名验证器");
//
// //获取商户私钥
// PrivateKey privateKey = getPrivateKey(privateKeyPath);
//
// //私钥签名对象
// PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
//
// //身份认证对象
// WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
//
// // 使用定时更新的签名验证器不需要传入证书
// ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
// wechatPay2Credentials,
// apiV3Key.getBytes(StandardCharsets.UTF_8));
//
// return verifier;
// }
//
// /**
// * 获取http请求对象
// *
// * @param verifier
// * @return
// */
// @Bean(name = "wxPayClient")
// public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier) {
//
// log.info("获取httpClient");
//
// //获取商户私钥
// PrivateKey privateKey = getPrivateKey(privateKeyPath);
//
// WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
// .withMerchant(mchId, mchSerialNo, privateKey)
// .withValidator(new WechatPay2Validator(verifier));
// // ... 接下来你仍然可以通过builder设置各种参数来配置你的HttpClient
//
// // 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签并进行证书自动更新
// CloseableHttpClient httpClient = builder.build();
//
// return httpClient;
// }
//
// /**
// * 获取HttpClient无需进行应答签名验证跳过验签的流程
// */
// @Bean(name = "wxPayNoSignClient")
// public CloseableHttpClient getWxPayNoSignClient() {
//
// log.info("无需进行应答签名验证,获取httpClient");
//
//
// //获取商户私钥
// PrivateKey privateKey = getPrivateKey(privateKeyPath);
//
// //用于构造HttpClient
// WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
// //设置商户信息
// .withMerchant(mchId, mchSerialNo, privateKey)
// //无需进行签名验证通过withValidator((response) -> true)实现
// .withValidator((response) -> true);
//
// // 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签并进行证书自动更新
// CloseableHttpClient httpClient = builder.build();
//
// return httpClient;
// }
//
//}

View File

@ -1,361 +1,361 @@
package com.cultural.heritage.controller.wxPayDemo;
import com.google.gson.Gson;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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.web.bind.annotation.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/wx-pay")
@Slf4j
public class WxPayController {
@Resource
private CloseableHttpClient wxPayClient;
@Resource
//无需应答签名
private CloseableHttpClient wxPayNoSignClient;
@Resource
private WxPayConfig wxPayConfig;
/**
* Native下单
*/
@PostMapping("/native")
public void nativePay() throws Exception {
log.info("发起支付请求 v3");
log.info("调用统一下单API");
//调用统一下单API
HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));
// 请求body参数
Gson gson = new Gson();
HashMap<String, Object> paramsMap = new HashMap<>();
paramsMap.put("appid", wxPayConfig.getAppid());// APPID
paramsMap.put("mchid", wxPayConfig.getMchId());// 商户id
paramsMap.put("description", "魏凯的小商铺"); // 订单描述
paramsMap.put("out_trade_no", "123456789987"); // 订单号
paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));// 二维码扫描支付成功后进行回调
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("total", 1); // 金额 以分为单位 这里写1分钱 订单号123456789987对应的金额为1分
amountMap.put("currency", "CNY");
paramsMap.put("amount", amountMap);
//将参数转换成json字符串
String jsonParams = gson.toJson(paramsMap);
log.info("请求参数 ===> {}" + jsonParams);
StringEntity entity = new StringEntity(jsonParams, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求这个地方就是mchId与商户证书密钥进行校验
try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
if (statusCode == 200) { //处理成功
log.info("成功, 返回结果 = " + bodyAsString);
} else if (statusCode == 204) { //处理成功无返回Body
log.info("成功");
} else {
log.info("Native下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
throw new IOException("request failed");
}
//响应结果
HashMap resultMap = gson.fromJson(bodyAsString, HashMap.class);
//二维码
String codeUrl = (String) resultMap.get("code_url");
log.info("二维码为: " + codeUrl);
}
}
/**
* 查询订单
*/
@GetMapping("/query/{orderNo}")
public void queryOrder(@PathVariable String orderNo) throws Exception {
log.info("查询订单");
log.info("查单接口调用 ===> {}", orderNo);
// 拼接url
String url = String.format(WxApiType.ORDER_QUERY_BY_NO.getType(), orderNo);
url = wxPayConfig.getDomain().concat(url).concat("?mchid=").concat(wxPayConfig.getMchId());
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
if (statusCode == 200) { //处理成功
log.info("成功, 返回结果 = " + bodyAsString);
} else if (statusCode == 204) { //处理成功无返回Body
log.info("成功");
} else {
log.info("查单接口调用,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
throw new IOException("request failed");
}
}
}
/**
* 用户取消订单
*/
@PostMapping("/cancel/{orderNo}")
public void cancel(@PathVariable String orderNo) throws Exception {
log.info("关单接口的调用,订单号 ===> {}", orderNo);
//创建远程请求对象
String url = String.format(WxApiType.CLOSE_ORDER_BY_NO.getType(), orderNo);
url = wxPayConfig.getDomain().concat(url);
HttpPost httpPost = new HttpPost(url);
//组装json请求体
Gson gson = new Gson();
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put("mchid", wxPayConfig.getMchId());
String jsonParams = gson.toJson(paramsMap);
log.info("请求参数 ===> {}", jsonParams);
//将请求参数设置到请求对象中
StringEntity entity = new StringEntity(jsonParams, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求
try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
if (statusCode == 200) { //处理成功
log.info("成功200");
} else if (statusCode == 204) { //处理成功无返回Body
log.info("成功204");
} else {
log.info("Native下单失败,响应码 = " + statusCode);
throw new IOException("request failed");
}
}
}
/**
* 用户申请退款
*/
@PostMapping("/refunds/{orderNo}")
public void refunds(@PathVariable String orderNo) throws Exception {
log.info("申请退款");
log.info("调用退款API");
//调用统一下单API
String url = wxPayConfig.getDomain().concat(WxApiType.DOMESTIC_REFUNDS.getType());
HttpPost httpPost = new HttpPost(url);
// 请求body参数
Gson gson = new Gson();
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("out_trade_no", orderNo);//订单编号
paramsMap.put("out_refund_no", "123456");//退款单编号 随便填
paramsMap.put("reason", "随便填一个");//退款原因
paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.REFUND_NOTIFY.getType()));//退款成功通知地址
Map<String, java.io.Serializable> amountMap = new HashMap<String, java.io.Serializable>();
amountMap.put("refund", 1);//退款金额 这里的金额应该根据订单id查询出来
amountMap.put("total", 1);//原订单金额 这里的金额应该根据订单id查询出来
amountMap.put("currency", "CNY");//退款币种
paramsMap.put("amount", amountMap);
//将参数转换成json字符串
String jsonParams = gson.toJson(paramsMap);
log.info("请求参数 ===> {}" + jsonParams);
StringEntity entity = new StringEntity(jsonParams, "utf-8");
entity.setContentType("application/json");//设置请求报文格式
httpPost.setEntity(entity);//将请求报文放入请求对象
httpPost.setHeader("Accept", "application/json");//设置响应报文格式
//完成签名并执行请求并完成验签
try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
//解析响应结果
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 退款返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("退款异常, 响应码 = " + statusCode + ", 退款返回结果 = " + bodyAsString);
}
}
}
/**
* 查询退款
*/
@GetMapping("/query-refund/{refundNo}")
public void queryRefund(@PathVariable String refundNo) throws Exception {
log.info("查询退款");
log.info("查询退款接口调用 ===> {}", refundNo);
String url = String.format(WxApiType.DOMESTIC_REFUNDS_QUERY.getType(), refundNo);
url = wxPayConfig.getDomain().concat(url);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 查询退款返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("查询退款异常, 响应码 = " + statusCode + ", 查询退款返回结果 = " + bodyAsString);
}
}
}
/**
* 获取账单url 这个url无法在浏览器打开
*/
@GetMapping("/querybill/{billDate}/{type}")
public void queryTradeBill(@PathVariable String billDate, @PathVariable String type) throws Exception {
log.info("获取账单url");
log.warn("申请账单接口调用 {}", billDate);
String url = "";
if ("tradebill".equals(type)) {
url = WxApiType.TRADE_BILLS.getType();
} else if ("fundflowbill".equals(type)) {
url = WxApiType.FUND_FLOW_BILLS.getType();
} else {
throw new RuntimeException("不支持的账单类型");
}
url = wxPayConfig.getDomain().concat(url).concat("?bill_date=").concat(billDate);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Accept", "application/json");
//使用wxPayClient发送请求得到响应
try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 申请账单返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("申请账单异常, 响应码 = " + statusCode + ", 申请账单返回结果 = " + bodyAsString);
}
//获取账单下载地址
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
log.info("账单链接;" + resultMap.get("download_url"));
}
}
/**
* 下载账单
*/
@GetMapping("/downloadbill/{billDate}/{type}")
public void downloadBill(@PathVariable String billDate, @PathVariable String type) throws Exception {
log.info("下载账单");
log.warn("下载账单接口调用 {}, {}", billDate, type);
//获取账单url地址
String downloadUrl = this.queryBill(billDate, type);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(downloadUrl);
httpGet.addHeader("Accept", "application/json");
//使用wxPayClient发送请求得到响应
try (CloseableHttpResponse response = wxPayNoSignClient.execute(httpGet)) {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 下载账单返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("下载账单异常, 响应码 = " + statusCode + ", 下载账单返回结果 = " + bodyAsString);
}
}
}
/**
* 申请账单
*/
public String queryBill(String billDate, String type) throws Exception {
log.warn("申请账单接口调用 {}", billDate);
String url = "";
if ("tradebill".equals(type)) {
url = WxApiType.TRADE_BILLS.getType();
} else if ("fundflowbill".equals(type)) {
url = WxApiType.FUND_FLOW_BILLS.getType();
} else {
throw new RuntimeException("不支持的账单类型");
}
url = wxPayConfig.getDomain().concat(url).concat("?bill_date=").concat(billDate);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Accept", "application/json");
//使用wxPayClient发送请求得到响应
try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 申请账单返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("申请账单异常, 响应码 = " + statusCode + ", 申请账单返回结果 = " + bodyAsString);
}
//获取账单下载地址
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
return resultMap.get("download_url");
}
}
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import com.google.gson.Gson;
//import jakarta.annotation.Resource;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.http.client.methods.CloseableHttpResponse;
//import org.apache.http.client.methods.HttpGet;
//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.web.bind.annotation.*;
//
//import java.io.IOException;
//import java.util.HashMap;
//import java.util.Map;
//
//@RestController
//@RequestMapping("/api/wx-pay")
//@Slf4j
//public class WxPayController {
//
// @Resource
// private CloseableHttpClient wxPayClient;
//
// @Resource
// //无需应答签名
// private CloseableHttpClient wxPayNoSignClient;
//
// @Resource
// private WxPayConfig wxPayConfig;
//
// /**
// * Native下单
// */
// @PostMapping("/native")
// public void nativePay() throws Exception {
//
// log.info("发起支付请求 v3");
//
// log.info("调用统一下单API");
//
// //调用统一下单API
// HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));
//
// // 请求body参数
// Gson gson = new Gson();
// HashMap<String, Object> paramsMap = new HashMap<>();
// paramsMap.put("appid", wxPayConfig.getAppid());// APPID
// paramsMap.put("mchid", wxPayConfig.getMchId());// 商户id
// paramsMap.put("description", "魏凯的小商铺"); // 订单描述
// paramsMap.put("out_trade_no", "123456789987"); // 订单号
// paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));// 二维码扫描支付成功后进行回调
//
// Map<String, Object> amountMap = new HashMap<>();
// amountMap.put("total", 1); // 金额 以分为单位 这里写1分钱 订单号123456789987对应的金额为1分
// amountMap.put("currency", "CNY");
//
// paramsMap.put("amount", amountMap);
//
// //将参数转换成json字符串
// String jsonParams = gson.toJson(paramsMap);
// log.info("请求参数 ===> {}" + jsonParams);
//
// StringEntity entity = new StringEntity(jsonParams, "utf-8");
// entity.setContentType("application/json");
// httpPost.setEntity(entity);
// httpPost.setHeader("Accept", "application/json");
//
// //完成签名并执行请求这个地方就是mchId与商户证书密钥进行校验
// try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
// int statusCode = response.getStatusLine().getStatusCode();//响应状态码
// if (statusCode == 200) { //处理成功
// log.info("成功, 返回结果 = " + bodyAsString);
// } else if (statusCode == 204) { //处理成功无返回Body
// log.info("成功");
// } else {
// log.info("Native下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
// throw new IOException("request failed");
// }
// //响应结果
// HashMap resultMap = gson.fromJson(bodyAsString, HashMap.class);
// //二维码
// String codeUrl = (String) resultMap.get("code_url");
//
// log.info("二维码为: " + codeUrl);
//
// }
// }
//
// /**
// * 查询订单
// */
// @GetMapping("/query/{orderNo}")
// public void queryOrder(@PathVariable String orderNo) throws Exception {
//
// log.info("查询订单");
//
// log.info("查单接口调用 ===> {}", orderNo);
//
// // 拼接url
// String url = String.format(WxApiType.ORDER_QUERY_BY_NO.getType(), orderNo);
// url = wxPayConfig.getDomain().concat(url).concat("?mchid=").concat(wxPayConfig.getMchId());
//
// HttpGet httpGet = new HttpGet(url);
// httpGet.setHeader("Accept", "application/json");
//
// //完成签名并执行请求
// try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
// int statusCode = response.getStatusLine().getStatusCode();//响应状态码
// if (statusCode == 200) { //处理成功
// log.info("成功, 返回结果 = " + bodyAsString);
// } else if (statusCode == 204) { //处理成功无返回Body
// log.info("成功");
// } else {
// log.info("查单接口调用,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
// throw new IOException("request failed");
// }
// }
// }
//
//
// /**
// * 用户取消订单
// */
// @PostMapping("/cancel/{orderNo}")
// public void cancel(@PathVariable String orderNo) throws Exception {
//
// log.info("关单接口的调用,订单号 ===> {}", orderNo);
//
// //创建远程请求对象
// String url = String.format(WxApiType.CLOSE_ORDER_BY_NO.getType(), orderNo);
// url = wxPayConfig.getDomain().concat(url);
// HttpPost httpPost = new HttpPost(url);
//
// //组装json请求体
// Gson gson = new Gson();
// Map<String, String> paramsMap = new HashMap<>();
// paramsMap.put("mchid", wxPayConfig.getMchId());
// String jsonParams = gson.toJson(paramsMap);
// log.info("请求参数 ===> {}", jsonParams);
//
// //将请求参数设置到请求对象中
// StringEntity entity = new StringEntity(jsonParams, "utf-8");
// entity.setContentType("application/json");
// httpPost.setEntity(entity);
// httpPost.setHeader("Accept", "application/json");
//
// //完成签名并执行请求
// try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
// int statusCode = response.getStatusLine().getStatusCode();//响应状态码
// if (statusCode == 200) { //处理成功
// log.info("成功200");
// } else if (statusCode == 204) { //处理成功无返回Body
// log.info("成功204");
// } else {
// log.info("Native下单失败,响应码 = " + statusCode);
// throw new IOException("request failed");
// }
// }
// }
//
// /**
// * 用户申请退款
// */
// @PostMapping("/refunds/{orderNo}")
// public void refunds(@PathVariable String orderNo) throws Exception {
//
// log.info("申请退款");
// log.info("调用退款API");
// //调用统一下单API
// String url = wxPayConfig.getDomain().concat(WxApiType.DOMESTIC_REFUNDS.getType());
// HttpPost httpPost = new HttpPost(url);
//
// // 请求body参数
// Gson gson = new Gson();
// Map<String, Object> paramsMap = new HashMap<>();
// paramsMap.put("out_trade_no", orderNo);//订单编号
// paramsMap.put("out_refund_no", "123456");//退款单编号 随便填
// paramsMap.put("reason", "随便填一个");//退款原因
// paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.REFUND_NOTIFY.getType()));//退款成功通知地址
//
// Map<String, java.io.Serializable> amountMap = new HashMap<String, java.io.Serializable>();
// amountMap.put("refund", 1);//退款金额 这里的金额应该根据订单id查询出来
// amountMap.put("total", 1);//原订单金额 这里的金额应该根据订单id查询出来
// amountMap.put("currency", "CNY");//退款币种
// paramsMap.put("amount", amountMap);
//
// //将参数转换成json字符串
// String jsonParams = gson.toJson(paramsMap);
// log.info("请求参数 ===> {}" + jsonParams);
//
// StringEntity entity = new StringEntity(jsonParams, "utf-8");
// entity.setContentType("application/json");//设置请求报文格式
// httpPost.setEntity(entity);//将请求报文放入请求对象
// httpPost.setHeader("Accept", "application/json");//设置响应报文格式
//
// //完成签名并执行请求并完成验签
// try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
// //解析响应结果
// String bodyAsString = EntityUtils.toString(response.getEntity());
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode == 200) {
// log.info("成功, 退款返回结果 = " + bodyAsString);
// } else if (statusCode == 204) {
// log.info("成功");
// } else {
// throw new RuntimeException("退款异常, 响应码 = " + statusCode + ", 退款返回结果 = " + bodyAsString);
// }
// }
// }
//
// /**
// * 查询退款
// */
// @GetMapping("/query-refund/{refundNo}")
// public void queryRefund(@PathVariable String refundNo) throws Exception {
//
// log.info("查询退款");
// log.info("查询退款接口调用 ===> {}", refundNo);
//
// String url = String.format(WxApiType.DOMESTIC_REFUNDS_QUERY.getType(), refundNo);
// url = wxPayConfig.getDomain().concat(url);
//
// //创建远程Get 请求对象
// HttpGet httpGet = new HttpGet(url);
// httpGet.setHeader("Accept", "application/json");
//
// //完成签名并执行请求
// try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode == 200) {
// log.info("成功, 查询退款返回结果 = " + bodyAsString);
// } else if (statusCode == 204) {
// log.info("成功");
// } else {
// throw new RuntimeException("查询退款异常, 响应码 = " + statusCode + ", 查询退款返回结果 = " + bodyAsString);
// }
// }
// }
//
// /**
// * 获取账单url 这个url无法在浏览器打开
// */
// @GetMapping("/querybill/{billDate}/{type}")
// public void queryTradeBill(@PathVariable String billDate, @PathVariable String type) throws Exception {
//
// log.info("获取账单url");
//
// log.warn("申请账单接口调用 {}", billDate);
//
// String url = "";
// if ("tradebill".equals(type)) {
// url = WxApiType.TRADE_BILLS.getType();
// } else if ("fundflowbill".equals(type)) {
// url = WxApiType.FUND_FLOW_BILLS.getType();
// } else {
// throw new RuntimeException("不支持的账单类型");
// }
//
// url = wxPayConfig.getDomain().concat(url).concat("?bill_date=").concat(billDate);
//
// //创建远程Get 请求对象
// HttpGet httpGet = new HttpGet(url);
// httpGet.addHeader("Accept", "application/json");
//
// //使用wxPayClient发送请求得到响应
// try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());
//
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode == 200) {
// log.info("成功, 申请账单返回结果 = " + bodyAsString);
// } else if (statusCode == 204) {
// log.info("成功");
// } else {
// throw new RuntimeException("申请账单异常, 响应码 = " + statusCode + ", 申请账单返回结果 = " + bodyAsString);
// }
// //获取账单下载地址
// Gson gson = new Gson();
// Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
// log.info("账单链接;" + resultMap.get("download_url"));
// }
// }
//
// /**
// * 下载账单
// */
// @GetMapping("/downloadbill/{billDate}/{type}")
// public void downloadBill(@PathVariable String billDate, @PathVariable String type) throws Exception {
//
// log.info("下载账单");
// log.warn("下载账单接口调用 {}, {}", billDate, type);
//
// //获取账单url地址
// String downloadUrl = this.queryBill(billDate, type);
// //创建远程Get 请求对象
// HttpGet httpGet = new HttpGet(downloadUrl);
// httpGet.addHeader("Accept", "application/json");
//
// //使用wxPayClient发送请求得到响应
// try (CloseableHttpResponse response = wxPayNoSignClient.execute(httpGet)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode == 200) {
// log.info("成功, 下载账单返回结果 = " + bodyAsString);
// } else if (statusCode == 204) {
// log.info("成功");
// } else {
// throw new RuntimeException("下载账单异常, 响应码 = " + statusCode + ", 下载账单返回结果 = " + bodyAsString);
// }
// }
//
// }
//
// /**
// * 申请账单
// */
// public String queryBill(String billDate, String type) throws Exception {
// log.warn("申请账单接口调用 {}", billDate);
//
// String url = "";
// if ("tradebill".equals(type)) {
// url = WxApiType.TRADE_BILLS.getType();
// } else if ("fundflowbill".equals(type)) {
// url = WxApiType.FUND_FLOW_BILLS.getType();
// } else {
// throw new RuntimeException("不支持的账单类型");
// }
//
// url = wxPayConfig.getDomain().concat(url).concat("?bill_date=").concat(billDate);
//
// //创建远程Get 请求对象
// HttpGet httpGet = new HttpGet(url);
// httpGet.addHeader("Accept", "application/json");
//
// //使用wxPayClient发送请求得到响应
// try (CloseableHttpResponse response = wxPayClient.execute(httpGet)) {
// String bodyAsString = EntityUtils.toString(response.getEntity());
//
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode == 200) {
// log.info("成功, 申请账单返回结果 = " + bodyAsString);
// } else if (statusCode == 204) {
// log.info("成功");
// } else {
// throw new RuntimeException("申请账单异常, 响应码 = " + statusCode + ", 申请账单返回结果 = " + bodyAsString);
// }
//
// //获取账单下载地址
// Gson gson = new Gson();
// Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
// return resultMap.get("download_url");
// }
// }
//
//}

View File

@ -1,124 +1,124 @@
package com.cultural.heritage.controller.wxPayDemo;
import com.google.gson.Gson;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/wx-pay/notify")
@Slf4j
public class WxPayNotifyController {
@Resource
private Verifier verifier;
/**
* 订单支付成功回调
*/
@PostMapping("/native")
public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
Gson gson = new Gson();
Map<String, String> map = new HashMap<>();//应答对象
try {
//处理通知参数
String body = HttpUtils.readData(request);
Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
String requestId = (String) bodyMap.get("id");
log.info("支付通知的id ===> {}", requestId);
//签名的验证
WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
= new WechatPay2ValidatorForRequest(verifier, requestId, body);
if (!wechatPay2ValidatorForRequest.validate(request)) {
log.error("通知验签失败");
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "通知验签失败");
return gson.toJson(map);
}
log.info("通知验签成功");
//处理订单 这里可以对订单进行处理 比如订单支付成功 修改数据库订单表订单状态为已支付
// processOrder(bodyMap);
//应答超时
//模拟接收微信端的重复通知
TimeUnit.SECONDS.sleep(5);
//成功应答
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "成功");
return gson.toJson(map);
} catch (Exception e) {
e.printStackTrace();
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "失败");
return gson.toJson(map);
}
}
@PostMapping("/refunds")
public String refundsNotify(HttpServletRequest request, HttpServletResponse response){
log.info("退款通知执行");
Gson gson = new Gson();
Map<String, String> map = new HashMap<>();//应答对象
try {
//处理通知参数
String body = HttpUtils.readData(request);
Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
String requestId = (String)bodyMap.get("id");
log.info("支付通知的id ===> {}", requestId);
//签名的验证
WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
= new WechatPay2ValidatorForRequest(verifier, requestId, body);
if(!wechatPay2ValidatorForRequest.validate(request)){
log.error("通知验签失败");
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "通知验签失败");
return gson.toJson(map);
}
log.info("通知验签成功");
//处理退款单 订单退款成功 修改订单表中订单状态为已退款
// processRefund(bodyMap);
//成功应答
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "成功");
return gson.toJson(map);
} catch (Exception e) {
e.printStackTrace();
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "失败");
return gson.toJson(map);
}
}
}
//package com.cultural.heritage.controller.wxPayDemo;
//
//
//import com.google.gson.Gson;
//import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
//import jakarta.annotation.Resource;
//import jakarta.servlet.http.HttpServletRequest;
//import jakarta.servlet.http.HttpServletResponse;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import java.util.HashMap;
//import java.util.Map;
//import java.util.concurrent.TimeUnit;
//
//@RestController
//@RequestMapping("/api/wx-pay/notify")
//@Slf4j
//public class WxPayNotifyController {
// @Resource
// private Verifier verifier;
//
// /**
// * 订单支付成功回调
// */
// @PostMapping("/native")
// public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
//
// Gson gson = new Gson();
// Map<String, String> map = new HashMap<>();//应答对象
//
// try {
// //处理通知参数
// String body = HttpUtils.readData(request);
// Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
// String requestId = (String) bodyMap.get("id");
// log.info("支付通知的id ===> {}", requestId);
//
// //签名的验证
// WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
// = new WechatPay2ValidatorForRequest(verifier, requestId, body);
// if (!wechatPay2ValidatorForRequest.validate(request)) {
//
// log.error("通知验签失败");
// //失败应答
// response.setStatus(500);
// map.put("code", "ERROR");
// map.put("message", "通知验签失败");
// return gson.toJson(map);
// }
// log.info("通知验签成功");
//
// //处理订单 这里可以对订单进行处理 比如订单支付成功 修改数据库订单表订单状态为已支付
//// processOrder(bodyMap);
//
// //应答超时
// //模拟接收微信端的重复通知
// TimeUnit.SECONDS.sleep(5);
//
// //成功应答
// response.setStatus(200);
// map.put("code", "SUCCESS");
// map.put("message", "成功");
// return gson.toJson(map);
//
// } catch (Exception e) {
// e.printStackTrace();
// //失败应答
// response.setStatus(500);
// map.put("code", "ERROR");
// map.put("message", "失败");
// return gson.toJson(map);
// }
// }
//
// @PostMapping("/refunds")
// public String refundsNotify(HttpServletRequest request, HttpServletResponse response){
//
// log.info("退款通知执行");
// Gson gson = new Gson();
// Map<String, String> map = new HashMap<>();//应答对象
//
// try {
// //处理通知参数
// String body = HttpUtils.readData(request);
// Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
// String requestId = (String)bodyMap.get("id");
// log.info("支付通知的id ===> {}", requestId);
//
// //签名的验证
// WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
// = new WechatPay2ValidatorForRequest(verifier, requestId, body);
// if(!wechatPay2ValidatorForRequest.validate(request)){
//
// log.error("通知验签失败");
// //失败应答
// response.setStatus(500);
// map.put("code", "ERROR");
// map.put("message", "通知验签失败");
// return gson.toJson(map);
// }
// log.info("通知验签成功");
//
// //处理退款单 订单退款成功 修改订单表中订单状态为已退款
//// processRefund(bodyMap);
//
// //成功应答
// response.setStatus(200);
// map.put("code", "SUCCESS");
// map.put("message", "成功");
// return gson.toJson(map);
//
// } catch (Exception e) {
// e.printStackTrace();
// //失败应答
// response.setStatus(500);
// map.put("code", "ERROR");
// map.put("message", "失败");
// return gson.toJson(map);
// }
// }
//}