JAVA 微信APPV3支付(保姆级)
扭曲的影子 2024-07-18 15:35:06 阅读 89
2024.05.07更新方法
更新WXPaySignatureCertificateUtil.java 工具类 详细看3.1
许多人对AutoUpdateCertificatesVerifier验证有疑问
所以此次更新使用Verifier验证
这里有两种验证证书方式
AutoUpdateCertificatesVerifier和Verifier
两者自选使用
2024.02.05更新方法
去掉了重复代码 更新以下
更新验证签名方法
更新回调验签方法
更新随机字符串使用
小程序去下面
java微信小程序v3支付(保姆级)
java微信商户转账(保姆级)
现在Java微信支付文章五花八门 看不懂 看的懵 掺杂业务逻辑不知名的返回封装 爆红一片 不妨看看这篇
由于微信更新了0.4.9版本 部分使用微信支付会解析报错 原因是微信内置了Jackson2.13.xxx依赖会与springboot这个Jackson产生冲突 可能会无法升级依赖 因为升级了也会使用老版本依赖
解决方法需要把微信支付解析 验签等方法分离重写 目前没时间写文章 无法自行解决的请私信
1.加入Maven依赖
<code> <!-- 微信支付V3 目前新版本-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.9</version>
</dependency>
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<String, AutoUpdateCertificatesVerifier> 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"));code>
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<String, Verifier> 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"));code>
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("无效的密钥格式");
}
}
}
创建WXPayConstants.java类
/**
* 常量
*/
public class WXPayConstants {
public static final String DOMAIN_API = "https://api.mch.weixin.qq.com/v3";
//app下单
public static final String PAY_TRANSACTIONS_APP = "/pay/transactions/app";
//微信支付回调
public static final String WECHAT_PAY_NOTIFY_URL =
"https://xxx.xxxx.com/deal/api/appPayment/weChatPayNotify";
//申请退款
public static final String REFUND_DOMESTIC_REFUNDS = "/refund/domestic/refunds";
//微信退款回调
public static final String WECHAT_REFUNDS_NOTIFY_URL = "https://xxx.xxxx.com/api/appPayment/weChatPayRefundsNotify";
//关闭订单
public static final String PAY_TRANSACTIONS_OUT_TRADE_NO = "/pay/transactions/out-trade-no/{}/close";
}
这里以APP支付和退款为例
创建WechatPaymentService.java
/**
* @author 影子
*/
public interface WechatPaymentService
{
/**
* 微信商品支付
* @param payParam
* @return
*/
public Map<String, Object>weChatDoUnifiedOrder() throws Exception;
/**
* 微信支付回调通知
* @param
* @return
*/
public Map<String, Object> weChatNotificationHandler(HttpServletRequest request, HttpServletResponse response);
/**
*微信关闭订单
* @param outTradeNo
* @return
*/
public Map<String, Object> closeOrder(String outTradeNo);
/**
* 申请退款
* @param
* @return
*/
public Map<String, Object> weChatPayRefundsNotify(HttpServletRequest request);
/**
* 微信退款
* @param outTradeNo 订单号
* @return
*/
public Map<String, Object> weChatRefunds(String outTradeNo);
}
创建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 Map<String, Object>weChatDoUnifiedOrder() {
Map<String,Object> 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("description","描述")
.put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL)//回调
.put("out_trade_no", "订单号");
rootNode.putObject("amount")
.put("total","总金额");
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;
//随机字符串 这个是微信支付maven自带的 也可以用其它的
//这个是v2支付依赖自带的工具包 可以去掉了
//String nonceStr = WXPayUtil.generateNonceStr();
//该方法org.apache.commons.lang3.RandomStringUtils依赖自带随机生成字符串 RandomStringUtils.randomAlphanumeric(32) 代表生成32位
String nonceStr = RandomStringUtils.randomAlphanumeric(32);
//生成带签名支付信息
String paySign = WXPaySignatureCertificateUtil.appPaySign(String.valueOf(timestamp), nonceStr, prepayId);
Map<String, String> param = new HashMap<>();
param.put("appid", WxV3PayConfig.APP_ID);
param.put("partnerid", WxV3PayConfig.Mch_ID);
param.put("prepayid", prepayId);
param.put("package", "Sign=WXPay");
param.put("noncestr", nonceStr);
param.put("timestamp", String.valueOf(timestamp));
param.put("sign", paySign);
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<String, Object> weChatNotificationHandler(HttpServletRequest request, HttpServletResponse response){
Map<String,Object> 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<String, Object> closeOrder(String outTradeNo) {
Map<String,Object> map = new HashMap<>();
try {
//验证证书
CloseableHttpClient httpClient = WXPaySignatureCertificateUtil.checkSign();
//关闭订单
String url = StrFormatter.format(WXPayConstants.DOMAIN_API+WXPayConstants.PAY_TRANSACTIONS_OUT_TRADE_NO, outTradeNo);
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//2.添加商户id
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode rootNode = objectMapper.createObjectNode();
rootNode.put("mchid", WxV3PayConfig.Mch_ID);
objectMapper.writeValue(bos, rootNode);
//3.调起微信关单接口
httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode() == 204);
//无数据(Http状态码为204) 微信返回结果无数据 状态码为204 成功
if (response.getStatusLine().getStatusCode() == 204) {
//code 退款码请前往微信支付文档查询
map.put("code",200);
map.put("message", "关闭订单成功!");
return map;
}
} catch (Exception e) {
log.error("关单失败:" + outTradeNo + e);
}
return null;
}
/**
* 微信退款
* @param outTradeNo 订单号
* @return
*/
@Override
public Map<String, Object> weChatRefunds(String outTradeNo) {
Map<String,Object> 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<String,Object> weChatPayRefundsNotify(HttpServletRequest request) {
Map<String,Object> 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;
}
}
代码可复制粘贴使用 无业务逻辑代码 支付代码简洁
如果更换支付类型如:APP、二维码支付、扫码支付、JSAPI支付
请看以下示例二维码支付代码
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3"+"/pay/transactions/native");
HttpPost httpPost = new HttpPost("这里更换")
整体不变只需要微信返回正确状态码内处理即可 如以下返回为 二维码支付参数
//完成签名并执行请求
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);
map.put("code",200);
map.put("message", "下单成功");
map.put("data", object);
return map;
}
map.put("code",500);
map.put("message", "下单失败");
map.put("data", response);
return map;
修改方式 根据官方文档返回参数类型为准
你学废了吗?
上一篇: Java MyBatis实战:QueryWrapper中的and和or拼接技巧
下一篇: 第二篇【AI与传奇开心果系列】Python的AI技术点库案例示例:详解AI工业应用算法原理
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。