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微信支付文章五花八门 看不懂 看的懵 掺杂业务逻辑不知名的返回封装 爆红一片 不妨看看这篇
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;
}
}
代码可复制粘贴使用 无业务逻辑代码 支付代码简洁
修改方式 根据官方文档返回参数类型为准
你学废了吗?
JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)JAVA 微信小程序V3支付(保姆级) 【代码】JAVA 微信小程序V3支付(保姆级)