JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)

2024.10.16预计更新说明

在这里给大家说明一下 AutoUpdateCertificatesVerifier在微信官方停止更新了 虽然不影响使用 但我在这里给大家道歉没有及时更新一直使用不更新的方法 所以我们得跟上技术迭代的脚步 预计十月底之前有时间给大家更新最新版验证证书和验签方法 其它方法不变。

目前此方法不影响正常使用。

2024.09.24更新说明

许多人对两个微信支付依赖不清楚是什么关系区别
这里解释一下


 com.github.wechatpay-apiv3
 wechatpay-java
 0.2.14
官方原封maven依赖
 
 com.github.wechatpay-apiv3
 wechatpay-apache-httpclient
 0.4.9
官方扩展封装maven依赖 使用HttpClient构造内部请求
​​​​​​​如果你是使用Apache HttpClient的商户开发者
可以使用它构造HttpClient。得到的HttpClient在执行请求时将自动携带身份认证信息,
并检查应答的微信支付签名。
上述为微信支付github库原述 
所以有人疑惑微信要求传入认证信息 
我这里不需要填写因为全部已经封装进HttpClient里了 
这里我又通过官方封装的源码实例分离出验证方法简化验证过程 
只要商户证书秘钥等正确一致 基本上直接通
这里放上微信maven库可仔细查看各个不同支付封装的解释 wechatpay-apiv3 · GitHub

为了你们能看懂我操碎了心!

2024.05.07更新方法

更新WXPaySignatureCertificateUtil.java 工具类 详细看3.1

许多人对AutoUpdateCertificatesVerifier验证有疑问 

所以此次更新使用Verifier验证

这里有两种验证证书方式

AutoUpdateCertificatesVerifier和Verifier

两者自选使用

app去下面

JAVA 微信APPV3支付(保姆级)

现在Java微信支付文章五花八门 看不懂 看的懵 掺杂业务逻辑不知名的返回封装 爆红一片 不妨看看这篇

 1.加入Maven依赖


 
 com.github.wechatpay-apiv3
 wechatpay-apache-httpclient
 0.4.9
 

 2.创建WxV3PayConfig.java配置类 

/**
 * implements WXPayConfig
 */
@Data
public class WxV3PayConfig {
 //平台证书序列号
 public static String mchSerialNo = "xxxxxxxxxxxxxx";
 //appID
 public static String APP_ID = "xxxxxxxxxxxxxx";
 //商户id
 public static String Mch_ID = "xxxxxxxxxxxxxx";
 // API V3密钥
 public static String apiV3Key = "xxxxxxxxxxxxxx";
 
 }

3.创建WXPaySignatureCertificateUtil.java 工具类

使用AutoUpdateCertificatesVerifier验证

复制粘贴即可

/***
*
*包都在这
*
*
*
*/
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;
import lombok.SneakyThrows;
import org.apache.http.impl.client.CloseableHttpClient;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class WXPaySignatureCertificateUtil {
 
 
 
 
 /**
 * 证书验证
 * 自动更新的签名验证器
 */
 public static CloseableHttpClient checkSign() throws IOException {
 //验签
 CloseableHttpClient httpClient = null;
 PrivateKey merchantPrivateKey = WXPaySignatureCertificateUtil.getPrivateKey();
 httpClient = WechatPayHttpClientBuilder.create()
 .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey)
 .withValidator(new WechatPay2Validator(WXPaySignatureCertificateUtil.getVerifier(WxV3PayConfig.mchSerialNo)))
 .build();
 
 return httpClient;
 }
 
 
 
 
 /**
 * 保存微信平台证书
 */
 private static final ConcurrentHashMap verifierMap = new ConcurrentHashMap();
 
 /**
 * 功能描述:获取平台证书,自动更新
 * 注意:这个方法内置了平台证书的获取和返回值解密
 */
 static AutoUpdateCertificatesVerifier getVerifier() {
 String mchSerialNo = WxV3PayConfig.mchSerialNo;
 AutoUpdateCertificatesVerifier verifier = null;
 if (verifierMap.isEmpty() || !verifierMap.containsKey(mchSerialNo)) {
 verifierMap.clear();
 try {
 //传入证书
 PrivateKey privateKey = getPrivateKey();
 //刷新
 PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey);
 WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer);
 verifier = new AutoUpdateCertificatesVerifier(credentials
 , WxV3PayConfig.apiV3Key.getBytes("utf-8"));
 verifierMap.put(verifier.getValidCertificate().getSerialNumber()+"", verifier);
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 }
 } else {
 verifier = verifierMap.get(mchSerialNo);
 }
 return verifier;
 }
 
 
 
 /**
 * app生成带签名支付信息
 *
 * @param timestamp 时间戳
 * @param nonceStr 随机数
 * @param prepayId 预付单
 * @return 支付信息
 * @throws Exception
 */
 public static String appPaySign(String timestamp, String nonceStr, String prepayId) throws Exception {
 //上传私钥
 PrivateKey privateKey = getPrivateKey();
 String signatureStr = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId)
 .collect(Collectors.joining("\n", "", "\n"));
 Signature sign = Signature.getInstance("SHA256withRSA");
 sign.initSign(privateKey);
 sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
 return Base64.getEncoder().encodeToString(sign.sign());
 }
 
 /**
 * 小程序及其它支付生成带签名支付信息
 *
 * @param timestamp 时间戳
 * @param nonceStr 随机数
 * @param prepayId 预付单
 * @return 支付信息
 * @throws Exception
 */
 public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) throws Exception {
 //上传私钥
 PrivateKey privateKey = getPrivateKey();
 String signatureStr = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId)
 .collect(Collectors.joining("\n", "", "\n"));
 Signature sign = Signature.getInstance("SHA256withRSA");
 sign.initSign(privateKey);
 sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
 return Base64.getEncoder().encodeToString(sign.sign());
 }
 
 
 /**
 * 获取私钥。
 * 证书路径 本地使用如: D:\\微信平台证书工具\\7.9\\apiclient_key.pem
 * 证书路径 线上使用如: /usr/apiclient_key.pem
 * String filename 私钥文件路径 (required)
 * @return 私钥对象
 */
 public static PrivateKey getPrivateKey() throws IOException {
 String content = new String(Files.readAllBytes(Paths.get("D:\\微信平台证书工具\\7.9\\apiclient_key.pem")), "utf-8");
 try {
 String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
 .replace("-----END PRIVATE KEY-----", "")
 .replaceAll("\\s+", "");
 
 KeyFactory kf = KeyFactory.getInstance("RSA");
 return kf.generatePrivate(
 new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
 } catch (NoSuchAlgorithmException e) {
 throw new RuntimeException("当前Java环境不支持RSA", e);
 } catch (InvalidKeySpecException e) {
 throw new RuntimeException("无效的密钥格式");
 }
 }
 
}

3.1.更新创建WXPaySignatureCertificateUtil.java 工具类

使用Verifier验证

/***
*
*包都在这
*
*
*
*/
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;
import lombok.SneakyThrows;
import org.apache.http.impl.client.CloseableHttpClient;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class WXPaySignatureCertificateUtil {
 
 
 
 
 private static final ConcurrentHashMap verifierMaps = new ConcurrentHashMap();
 
 
 /**
 * 证书验证
 * 自动更新的签名验证器
 */
 public static CloseableHttpClient checkSign() throws IOException {
 //验签
 CloseableHttpClient httpClient = null;
 PrivateKey merchantPrivateKey = WXPaySignatureCertificateUtil.getPrivateKey();
 httpClient = WechatPayHttpClientBuilder.create()
 .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey)
 .withValidator(new WechatPay2Validator(WXPaySignatureCertificateUtil.getVerifier(WxV3PayConfig.mchSerialNo)))
 .build();
 
 return httpClient;
 }
 
 
 
 /**
 * 功能描述:获取平台证书,自动更新
 * 注意:这个方法内置了平台证书的获取和返回值解密
 */
 public static Verifier getVerifiers(String mchSerialNo) {
 Verifier verifier = null;
 if (verifierMaps.isEmpty() || !verifierMaps.containsKey(mchSerialNo)) {
 verifierMaps.clear();
 try {
 PrivateKey privateKey = getPrivateKey();
 //刷新
 PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey);
 WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer);
 verifier = new AutoUpdateCertificatesVerifier(credentials
 , apiV3Key.getBytes("utf-8"));
 verifierMaps.put(verifier.getValidCertificate().getSerialNumber()+"", verifier);
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 } catch (IOException e) {
 throw new RuntimeException(e);
 }
 } else {
 verifier = verifierMaps.get(mchSerialNo);
 }
 return verifier;
 }
 
 
 /**
 * app生成带签名支付信息
 *
 * @param timestamp 时间戳
 * @param nonceStr 随机数
 * @param prepayId 预付单
 * @return 支付信息
 * @throws Exception
 */
 public static String appPaySign(String timestamp, String nonceStr, String prepayId) throws Exception {
 //上传私钥
 PrivateKey privateKey = getPrivateKey();
 String signatureStr = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId)
 .collect(Collectors.joining("\n", "", "\n"));
 Signature sign = Signature.getInstance("SHA256withRSA");
 sign.initSign(privateKey);
 sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
 return Base64.getEncoder().encodeToString(sign.sign());
 }
 
 /**
 * 小程序及其它支付生成带签名支付信息
 *
 * @param timestamp 时间戳
 * @param nonceStr 随机数
 * @param prepayId 预付单
 * @return 支付信息
 * @throws Exception
 */
 public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) throws Exception {
 //上传私钥
 PrivateKey privateKey = getPrivateKey();
 String signatureStr = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId)
 .collect(Collectors.joining("\n", "", "\n"));
 Signature sign = Signature.getInstance("SHA256withRSA");
 sign.initSign(privateKey);
 sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
 return Base64.getEncoder().encodeToString(sign.sign());
 }
 
 
 /**
 * 获取私钥。
 * 证书路径 本地使用如: D:\\微信平台证书工具\\7.9\\apiclient_key.pem
 * 证书路径 线上使用如: /usr/apiclient_key.pem
 * String filename 私钥文件路径 (required)
 * @return 私钥对象
 */
 public static PrivateKey getPrivateKey() throws IOException {
 String content = new String(Files.readAllBytes(Paths.get("D:\\微信平台证书工具\\7.9\\apiclient_key.pem")), "utf-8");
 try {
 String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
 .replace("-----END PRIVATE KEY-----", "")
 .replaceAll("\\s+", "");
 
 KeyFactory kf = KeyFactory.getInstance("RSA");
 return kf.generatePrivate(
 new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
 } catch (NoSuchAlgorithmException e) {
 throw new RuntimeException("当前Java环境不支持RSA", e);
 } catch (InvalidKeySpecException e) {
 throw new RuntimeException("无效的密钥格式");
 }
 }
 
}

4.创建WXPayConstants.java类

package com.yingzi.smallprogram.util.wxPay;
/**
 * 常量
 */ 
public class WXPayConstants {
 public static final String DOMAIN_API = "https://api.mch.weixin.qq.com/v3";
 public static final String FAIL = "FAIL";
 public static final String SUCCESS = "SUCCESS";
 public static final Object RESOURCE_NOT_EXISTS = "RESOURCE_NOT_EXISTS";
 public static final Object USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL";
 public static final String RSA = "RSA";
 //jsapi下单
 public static final String JSAPI_TRANSACTIONS_APP = "/pay/transactions/jsapi";
 //申请退款
 public static final String REFUND_DOMESTIC_REFUNDS = "/refund/domestic/refunds";
 //jsapi微信支付回调
 public static final String WECHAT_PAY_NOTIFY_URL = "https://xxx.xxx.top/xxx/applet/api/appOrderPay/weChatPayNotify";
 //jspi微信退款回调
 public static final String WECHAT_REFUNDS_NOTIFY_URL = "https://xxx.xxx.top/xxx/applet/api/appOrderPay/weChatPayRefundsNotify";
}

这里以小程序支付和退款为例

5.创建WechatPaymentService.java

/**
 * @author 影子
 */
public interface WechatPaymentService
{
 /**
 * 微信商品支付
 * @param payParam
 * @return
 */
 public MapweChatDoUnifiedOrder() throws Exception;
 /**
 * 微信支付回调通知
 * @param
 * @return
 */
 public Map weChatNotificationHandler(HttpServletRequest request, HttpServletResponse response);
 /**
 * 申请退款
 * @param
 * @return
 */
 public Map weChatPayRefundsNotify(HttpServletRequest request);
 
 /**
 * 微信退款回调
 * @param outTradeNo 订单号
 * @return
 */
 public Map weChatRefunds(String outTradeNo);
}

6.创建WeChatPaymentServiceImpl.java

/*
*
* 照顾找包困难的朋友吧
*
*/
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.ByteArrayOutputStream;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.wxpay.sdk.WXPayUtil;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import org.apache.http.client.methods.CloseableHttpResponse;
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;
public class WeChatPaymentServiceImpl implements WechatPaymentService {
 /**
 * V3微信支付统一下单
 *
 * @param payParam
 * @return
 * 
 */
 @Override
 public MapweChatDoUnifiedOrder() {
 Map map =new HashMap();
 //支付总金额
 BigDecimal totalPrice = BigDecimal.ZERO;
 totalPrice = totalPrice.add(BigDecimal.valueOf(600));
 //转换金额保留两位小数点
 Integer money=new BigDecimal(String.valueOf(totalPrice)).movePointRight(2).intValue();
 try {
 //验证证书
 CloseableHttpClient httpClient = WXPaySignatureCertificateUtil.checkSign();
 //app下单
 HttpPost httpPost = new HttpPost(WXPayConstants.DOMAIN_API+WXPayConstants.PAY_TRANSACTIONS_APP);
 httpPost.addHeader("Accept", "application/json");
 httpPost.addHeader("Content-type", "application/json; charset=utf-8");
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 ObjectMapper objectMapper = new ObjectMapper();
 ObjectNode rootNode = objectMapper.createObjectNode();
 rootNode.put("mchid", "商户id")
 .put("appid", "APPID")
 .put("out_trade_no", "订单号");
 .put("description","描述")
 .put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL);
 rootNode.putObject("amount")
 .put("total",money);
 rootNode.putObject("payer")
 .put("openid","openid");
 objectMapper.writeValue(bos, rootNode);
 httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
 //完成签名并执行请求
 CloseableHttpResponse response = httpClient.execute(httpPost);
 //获取返回状态
 int statusCode = response.getStatusLine().getStatusCode();
 if (statusCode == 200) { //处理成功
 String result = EntityUtils.toString(response.getEntity(), "UTF-8");
 JSONObject object = JSONObject.parseObject(result);
 //获取预付单
 String prepayId = object.getString("prepay_id");
 //生成签名
 Long timestamp = System.currentTimeMillis() / 1000;
 //随机字符串
 //该方法org.apache.commons.lang3.RandomStringUtils依赖自带随机生成字符串 RandomStringUtils.randomAlphanumeric(32) 代表生成32位
 String nonceStr = RandomStringUtils.randomAlphanumeric(32);
 Map param = new HashMap();
 //生成带签名支付信息
 String paySign = WXPaySignatureCertificateUtil.jsApiPaySign(String.valueOf(timestamp), nonceStr, prepayId);
 Map param = new HashMap();
 param.put("package", "prepay_id="+prepayId);
 param.put("noncestr", nonceStr);
 param.put("timestamp", String.valueOf(timestamp));
 param.put("paySign", paySign);
 param.put("signType", RSA);
 map.put("code",200);
 map.put("message", "下单成功");
 map.put("data", param);
 return map;
 }
 map.put("code",200);
 map.put("message", "下单失败");
 map.put("data", response);
 return map;
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 /**
 * 微信支付回调通知
 * @return
 */
 @Override
 public Map weChatNotificationHandler(HttpServletRequest request, HttpServletResponse response){
 Map map = new HashMap();
 try {
 BufferedReader br = request.getReader();
 String str = null;
 StringBuilder sb = new StringBuilder();
 while ((str = br.readLine())!=null) {
 sb.append(str);
 }
 // 构建request,传入必要参数
 NotificationRequest requests = new NotificationRequest.Builder()
 .withSerialNumber(request.getHeader("Wechatpay-Serial"))
 .withNonce(request.getHeader("Wechatpay-Nonce"))
 .withTimestamp(request.getHeader("Wechatpay-Timestamp"))
 .withSignature(request.getHeader("Wechatpay-Signature"))
 .withBody(String.valueOf(sb))
 .build();
 //验签
 NotificationHandler handler = new NotificationHandler(WXPaySignatureCertificateUtil.getVerifier(), WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
 //解析请求体
 Notification notification = handler.parse(requests);
 String decryptData = notification.getDecryptData();
 //解析
 JSONObject jsonObject = JSONObject.parseObject(decryptData);
 //支付状态交易状态,枚举值: SUCCESS:支付成功 REFUND:转入退款 NOTPAY:未支付 CLOSED:已关闭 REVOKED:已撤销(付款码支付)
 // USERPAYING:用户支付中(付款码支付) PAYERROR:支付失败(其他原因,如银行返回失败)
 String trade_state = String.valueOf(jsonObject.get("trade_state"));
 if (trade_state.equals("SUCCESS")) {
 //订单号
 String orderNumber = String.valueOf(jsonObject.get("out_trade_no"));
 //微信支付微信生成的订单号
 String transactionId = String.valueOf(jsonObject.get("transaction_id"));
 //省略查询订单
 //此处处理业务
 map.put("code",SUCCESS);
 map.put("message","成功");
 //消息推送成功
 return map;
 }
 map.put("code",RESOURCE_NOT_EXISTS);
 map.put("message", "订单不存在");
 return map;
 }catch (Exception e) {
 e.printStackTrace();
 }
 map.put("code",FAIL);
 map.put("message", "失败");
 return map;
 }
 /**
 * 微信退款
 * @param outTradeNo 订单号
 * @return
 */
 @Override
 public Map weChatRefunds(String outTradeNo) {
 Map map = new HashMap();
 //退款总金额
 BigDecimal totalPrice = BigDecimal.ZERO;
 totalPrice = totalPrice.add(BigDecimal.valueOf(600));
 //转换金额
 Integer money=new BigDecimal(String.valueOf(totalPrice)).movePointRight(2).intValue();
 
 try {
 //验证证书
 CloseableHttpClient httpClient = WXPaySignatureCertificateUtil.checkSign();
 //申请退款接口
 HttpPost httpPost = new HttpPost(WXPayConstants.DOMAIN_API+WXPayConstants.REFUND_DOMESTIC_REFUNDS);
 httpPost.addHeader("Accept", "application/json");
 httpPost.addHeader("Content-type","application/json; charset=utf-8");
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 ObjectMapper objectMapper = new ObjectMapper();
 ObjectNode rootNode = objectMapper.createObjectNode();
 //微信支付订单号
 rootNode.put("transaction_id", "微信支付订单号")
 //退款订单号
 .put("out_refund_no","生成退款订单号")
 .put("notify_url","退款回调");
 //退款金额
 rootNode.putObject("amount")
 .put("refund", "100.00")
 //原订单金额
 .put("total", "100.00")
 .put("currency","CNY");
 objectMapper.writeValue(bos, rootNode);
 httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
 CloseableHttpResponse response = httpClient.execute(httpPost);
 //退款成功返回消息
 String bodyAsString = EntityUtils.toString(response.getEntity());
 JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
 if (jsonObject.get("status").equals("SUCCESS") || jsonObject.get("status").equals("PROCESSING")) {
 //code返回
 map.put("code",200);
 map.put("message", "退款成功");
 return map;
 }
 }catch (Exception e) {
 e.printStackTrace();
 }
 map.put("code",500);
 map.put("message", "申请退款失败!");
 map.put("data", jsonObject);
 return map;
 }
 /**
 * 申请退款回调
 * @param request
 * @return
 */
 @Override
 public Map weChatPayRefundsNotify(HttpServletRequest request) {
 Map map = new HashMap();
 try {
 BufferedReader br = request.getReader();
 String str = null;
 StringBuilder sb = new StringBuilder();
 while ((str = br.readLine())!=null) {
 sb.append(str);
 }
 // 构建request,传入必要参数
 NotificationRequest requests = new NotificationRequest.Builder()
 .withSerialNumber(request.getHeader("Wechatpay-Serial"))
 .withNonce(request.getHeader("Wechatpay-Nonce"))
 .withTimestamp(request.getHeader("Wechatpay-Timestamp"))
 .withSignature(request.getHeader("Wechatpay-Signature"))
 .withBody(String.valueOf(sb))
 .build();
 //验签
 NotificationHandler handler = new NotificationHandler(WXPaySignatureCertificateUtil.getVerifier(), WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
 //解析请求体
 Notification notification = handler.parse(requests);
 String decryptData = notification.getDecryptData();
 //解析
 JSONObject jsonObject = JSONObject.parseObject(decryptData);
 String refund_status = String.valueOf(jsonObject.get("refund_status"));
 if (refund_status.equals("SUCCESS")) {
 //订单号
 String orderNumber = String.valueOf(jsonObject.get("out_trade_no"));
 //微信支付订单号
 String transactionId = String.valueOf(jsonObject.get("transaction_id"));
 //这里是处理业务逻辑
 
 
 //code 退款码请前往微信支付文档查询
 map.put("code","RESOURCE_NOT_EXISTS");
 map.put("message", "订单不存在");
 return map;
 }
 }catch (Exception e) {
 e.printStackTrace();
 }
 map.put("code","USER_ACCOUNT_ABNORMAL");
 map.put("message", "退款请求失败");
 return map;
 }
}

代码可复制粘贴使用 无业务逻辑代码 支付代码简洁

修改方式 根据官方文档返回参数类型为准

你学废了吗?

作者:扭曲的影子原文地址:https://blog.csdn.net/qq_37544675/article/details/136043759

%s 个评论

要回复文章请先登录注册