前言
对于controller层 ,如果有几种支付类型,我们可以这样定义。
//类型3为微信app支付 ,这里我们讲类型3
这里是service层的app支付调用的方法。
前言
我觉得前两篇我没有把实战代码写上来,并且讲的有点乱,可能小伙伴们还是有点懵逼的,而且我找遍整个csdn,居然全是旧的代码,而且还有很多陷阱居然都不提醒一下萌新,为了大家不再饱受微信支付这个不明不白又麻烦的东西的折磨,我觉得我有必要再出一门,最新,尽量简洁详细的支付说明,并不是只有搞app支付可以看,搞其他的都可以看,比如我的第二篇已有对native支付的介绍,但是讲的有点乱。所以我才决定写此篇文章,如果大家实现了,请在评论区留言点赞收藏。
顺便说一下,最好就先有一点微信支付的基础在来看我的文章,因为这里我不会把所有的知识都讲一遍,可以先看我的第一篇和第二篇文章了解一下。
我也不想讲太多了,因为我相信你们已经看腻了,我直接上代码解释。
我先讲清楚微信支付的大坑
因为有的伙伴可能已经看了无数篇文章,改了无数次代码,其实很有可能你的代码是对的,但是因为某个坑的原因。如果是jdk1.8或者以前版本的,大家先别看代码了,先看这个大坑。
为了让文章看起来更清晰一点,我放到一个专门的文章。
微信支付调起失败或者llegal key size解密大坑(已解决)
对于controller层 ,如果有几种支付类型,我们可以这样定义。
/**
* 支付接口
*/
@RequestMapping(value = "/alipay/pay.action", method = RequestMethod.GET)
public @ResponseBody
MessageBean alipay(String userId, String money, String familyId, String userPhone, String type) throws Exception {
//定义一个参数的接受类,方便封装参数传递。
PayVo payVo = new PayVo();
payVo.setUserId(userId);
payVo.setUserPhone(userPhone);
payVo.setMoney(money);
payVo.setFamilyId(familyId);
//类型1为支付宝
if (type.equals("1") || type == "1") {
PayReturnVo returnVo = alipayService.alipay(payVo);
return MessageUtil.success(returnVo);
}
//类型2为微信native支付
else if (type.equals("2") || type == "2") {
PayReturnVo returnVo = wxpayService.wxPay(payVo);
return MessageUtil.success(returnVo);
}
//类型3为微信app支付 ,这里我们讲类型3
else if (type.equals("3") || type == "3") {
// WeChatPayAppDatas returnVo = wxpayService.appWxPay(payVo);
JSONObject object = wxpayService.appWxPay(payVo);
return MessageUtil.success(object);
}
return MessageUtil.failure("失败了");
}
//类型3为微信app支付 ,这里我们讲类型3
这里是service层的app支付调用的方法。
我会把里面的方法都在下面一 、一的列举出来,方便你们cv和理解。
/**
* Wx-直接App支付
*
* @param payVo
* @return
*/
@Override
public JSONObject appWxPay(PayVo payVo) throws Exception {
// 捐赠的订单流水编号 (在后面我有写把这个工具类代码写上)
String orderNumber = GenerateNumUtil.generateOrder();
// 1:封装请求参数
Map<String, Object> map = new HashMap();
map.put("mchid", WechatPayConfig.mchId);
map.put("appid", WechatPayConfig.appId);
map.put("out_trade_no", orderNumber);
map.put("description", "微信支付捐款");
map.put("notify_url", WechatPayConfig.notifyUrl);
//这个参数微信文档有,是一个对象来的.
Map<String, Object> amount = new HashMap();
//订单金额 单位分 (在后面我有写把这个工具类代码写上)
amount.put("total", Integer.parseInt(WechatPayUtils.getMoney(payVo.getMoney())));
amount.put("currency", "CNY");
map.put("amount", amount);
// 附属参数
Map<String, Object> attachMap = new HashMap();
attachMap.put("userId", payVo.getUserId());
attachMap.put("orderNumber", orderNumber);
attachMap.put("price", payVo.getMoney());
attachMap.put("userPhone", payVo.getUserPhone());
map.put("attach", JSONUtils.obj2String(attachMap));
// 2:转换成json字符串,开始微信支付请求
ObjectMapper objectMapper = new ObjectMapper();
String body = null;
try {
body = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//随机字符串,不长于32位。推荐随机数生成算法。(在后面我有写把这个工具类代码写上)
String nonce_str = WechatPayUtils.getNonceStr();
// 3:请求统一微信-拉取app下单接口
Map<String, Object> stringObjectMap = HttpUtils.doPost(WechatPayConfig.appUnifiedOrderUrl, body);
// 4:定制前端需要的返回数据
String prepay_id = stringObjectMap.get("prepay_id").toString();
//拿到prepay_id ,去实现app的调起APP支付,也就是跳转到微信进行支付。
JSONObject object = WechatPayUtils.WxTuneUp(prepay_id, WechatPayConfig.appId);
//传入上面生成的订单号
object.put("orderNumber",orderNumber);
System.out.println("获取的预支付订单号:" +prepay_id);
System.out.println("封装的object数据是:"+object.toString());
//至此,如果你代码没错的话,就可以完成唤醒微信,然后进行支付的。但是支付成功后,是有回调的
//你们看了这么多,或者看了我前面的文章,我就不解释了,后面我们开始讲回调的代码.
return object;
}
看不懂方法代表什么没关系,下面会每一个调用的方法。
// 捐赠的订单流水编号
String orderNumber = GenerateNumUtil.generateOrder();
/**
* 根据时间生成随机订单号
* 雪花算法
*/
public class GenerateNumUtil {
// 全局自增数
private static int count = 0;
// 每毫秒秒最多生成多少订单(最好是像9999这种准备进位的值)
private static final int total = 99;
// 格式化的时间字符串
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
// 获取当前时间年月日时分秒毫秒字符串
private static String getNowDateStr() {
return sdf.format(new Date());
}
// 记录上一次的时间,用来判断是否需要递增全局数
private static String now = null;
/*
* 生成一个订单号
* 雪花算法
*/
public static String generateOrder() {
String datastr = getNowDateStr();
if (datastr.equals(now)) {
count++;// 自增
} else {
count = 1;
now = datastr;
}
int countInteger = String.valueOf(total).length() - String.valueOf(count).length();// 算补位
String bu = "";// 补字符串
for (int i = 0; i < countInteger; i++) {
bu += "0";
}
bu += String.valueOf(count);
if (count >= total) {
count = 0;
}
return datastr + bu;
}
}
上面出现的方法如果是 WechatPayUtils调用的,那都在下面。需要的工具类里面自己找哈 ctrl+f ,直接查,拿来用就好了。
我们先来看这一行代码
// 3:请求统一微信-拉取app下单接口
第一次请求微信支付,生成token签名信息,返回prepay_id
也就是上面的这一行代码
Map<String, Object> stringObjectMap = HttpUtils.doPost(WechatPayConfig.appUnifiedOrderUrl, body);
public static Map<String, Object> doPost(String url, String body) throws Exception {
//httpClient 即初始化微信客服端,那么有什么用呢,下面这个代码相信你看中文可以看懂吧
//意思就是 用这个客服端去执行, 那么执行什么呢,当然是执行我们放入的参数httpPost啦!
httpClient.execute(httpPost);
CloseableHttpClient httpClient = HttpClients.createDefault();
//new一个http 的post方法。get为这样 HttpGet httpget = new HttpGet(url);
// 这些微信V3文档都是有的,链接在下面 //https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay2_0.shtml
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;chartset=utf-8");
httpPost.addHeader("Accept", "application/json");
try {
/* body为我们的参数,url是我们的app下单接口地址,也就
是"https://api.mch.weixin.qq.com/v3/pay/transactions/app"
getToken的目的是为了签名
签名是什么可以看我第一篇文章. http://t.csdn.cn/YzeVf
下面这链接是微信签名的文档,
https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml */
//这个方法,下面的WechatPayUtils工具类有。
String token = WechatPayUtils.getToken("POST", new URL(url), body);
//设置http头 Authorization: 认证类型 签名信息
httpPost.setHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 " + token);
if (body == null) {
throw new IllegalArgumentException("data参数不能为空");
}
StringEntity stringEntity = new StringEntity(body, "utf-8");
httpPost.setEntity(stringEntity);
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
//获得请求体信息,也就是返回的参数,特点是调起支付的prepay_id也在里面
HttpEntity httpEntity = httpResponse.getEntity();
//响应状态码
int statusCode = httpResponse.getStatusLine().getStatusCode();
//响应体
String jsonResult = EntityUtils.toString(httpEntity);
if (statusCode == 200) {
//处理成功
System.out.println("成功, 返回结果 = " + jsonResult);
return JSON.readValue(jsonResult, HashMap.class);
} else if (statusCode == 204) {
//处理成功,无返回Body
System.out.println("处理成功,无返回Body");
} else {
System.out.println("Native下单失败,响应码 = " + statusCode + ",返回结果 = " + jsonResult);
System.err.println("微信支付错误信息" + EntityUtils.toString(httpEntity));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
WechatPayUtils工具类的代码
public class WechatPayUtils {
/**
* 元转换成分
* 微信传输金额以分为单位,需转换
*
* @param money
* @return
*/
//对应上面的代码
// amount.put("total", Integer.parseInt(WechatPayUtils.getMoney(payVo.getMoney())));
public static String getMoney(String money) {
if (money == null || money.equalsIgnoreCase("0")) {
return "";
}
// 金额转化为分为单位
// 处理包含, ¥ 或者$的金额
String currency = money.replaceAll("\\$|\\¥|\\,", "");
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0L;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
/**
* 获取私钥。(因为私钥需要通过商户证书来获取)
*
* @param filename 私钥文件路径 (required)
* @return 私钥对象
*/
//有两种方法。
方法一,也是最新版的。推荐用这个。
# 示例:私钥存储在文件
public static PrivateKey getPrivateKey(String filename) throws IOException {
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
//如果是把项目放到服务器上,那就是服务器的/为开始(根目录开始)
//也就是 你输入命令 pwd 显示的目录
new FileInputStream("存放位置"));
}
方法二
public static PrivateKey getPrivateKey(String filename) throws IOException {
System.out.println("filename:" + filename);
String content = new String(Files.readAllBytes(Paths.get(filename)), "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("无效的密钥格式");
}
}
/**
* 生成token 把请求地址URL和参数进行加密处理
* 为什么要签名:对请求参数和请求地址进行加密
*
* @param method
* @param url
* @param body
* @return
* @throws Exception
*/
public static String getToken(String method, URL url, String body) throws Exception {
//下面有这个方法,生成随机数
String nonceStr = getNonceStr();
long timestamp = System.currentTimeMillis() / 1000;
//下面有这个buildMessage 构成签名串的方法
String message = buildMessage(method, url, timestamp, nonceStr, body);
//下面有这个sign计算签名的方法
String signature = sign(message.getBytes("utf-8"));
return "mchid=\"" + WechatPayConfig.mchId + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + WechatPayConfig.mchSerialNo + "\","
+ "signature=\"" + signature + "\"";
}
/**
* 生成签名
*
* @param message
* @return
* @throws Exception
*/
public static String sign(byte[] message) throws Exception {
Signature sign = Signature.getInstance("SHA256withRSA");
// 商户私钥
sign.initSign(WechatPayConfig.privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
/**
* 生成签名串
*
* @param method
* @param url
* @param timestamp
* @param nonceStr
* @param body
* @return
*/
public static String buildMessage(String method, URL url, long timestamp, String nonceStr, String body) {
// 第二步,获取请求的绝对URL,并去除域名部分得到参与签名的URL。如果请求中有查询参数,URL末尾应附加有'?'和对应的查询字符串。
String canonicalUrl = url.getPath();
if (url.getQuery() != null) {
canonicalUrl += "?" + url.getQuery();
}
return method + "\n"
+ canonicalUrl + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ body + "\n";
}
/**
* 生成随机数
*
* @return
*/
public static String getNonceStr() {
return UUID.randomUUID().toString()
.replaceAll("-", "")
.substring(0, 32);
}
/**
* 获取平台证书
*
* @return
*/
//推荐使用微信支付提供的SDK。你也可以查看下列编程语言的示例代码。
public static Map<String, X509Certificate> refreshCertificate() throws Exception {
Map<String, X509Certificate> certificateMap = new HashMap();
// 1: 执行get请求
JsonNode jsonNode = HttpUtils.doGet(WechatPayConfig.certificatesUrl);
// 2: 获取平台验证的相关参数信息
JsonNode data = jsonNode.get("data");
if (data != null) {
for (int i = 0; i < data.size(); i++) {
JsonNode encrypt_certificate = data.get(i).get("encrypt_certificate");
//对关键信息进行解密
AesUtil aesUtil = new AesUtil(WechatPayConfig.v3Key.getBytes());
String associated_data = encrypt_certificate.get("associated_data").toString().replaceAll("\"", "");
String nonce = encrypt_certificate.get("nonce").toString().replaceAll("\"", "");
String ciphertext = encrypt_certificate.get("ciphertext").toString().replaceAll("\"", "");
//证书内容
String certStr = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
//证书内容转成证书对象
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(
new ByteArrayInputStream(certStr.getBytes("utf-8"))
);
String serial_no = data.get(i).get("serial_no").toString().replaceAll("\"", "");
certificateMap.put(serial_no, x509Cert);
}
}
return certificateMap;
}
/**
* 构造签名串
*
* @param signMessage 待签名的参数
* @return 构造后带待签名串
*/
static String buildSignMessage(ArrayList<String> signMessage) {
if (signMessage == null || signMessage.size() <= 0) {
return null;
}
StringBuilder sbf = new StringBuilder();
for (String str : signMessage) {
sbf.append(str).append("\n");
}
return sbf.toString();
}
/*
* 获取appid后,调起支付
*/
public static JSONObject WxTuneUp(String prepay_id, String appId) throws Exception {
String time = System.currentTimeMillis() / 1000 + "";
String noncestr = UUID.randomUUID().toString().replace("-", "");
//或者 String noncestr = getNonceStr() ;
ArrayList<String> list = new ArrayList<>();
list.add(appId);
list.add(time);
list.add(noncestr);
list.add(prepay_id);
//二次签名,调起支付需要重新签名,注意这个是buildSignMessage()
String packageSign = sign(buildSignMessage(list).getBytes());
JSONObject jsonObject = new JSONObject();
jsonObject.put("appid", appId);
jsonObject.put("partnerid", WechatPayConfig.mchId);
jsonObject.put("prepayid", prepay_id);
jsonObject.put("package", WechatPayConfig.PACKAGE);
jsonObject.put("noncestr", noncestr);
jsonObject.put("timestamp", time);
jsonObject.put("signtype", "RSA");
jsonObject.put("sign", packageSign);
return jsonObject;
}
/**
<<<<<<< HEAD
* 处理返回的回调对象
*
* @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();
}
}
}
}
public static Verifier getVerifier() throws Exception {
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(WechatPayConfig.mchId, new WechatPay2Credentials(WechatPayConfig.mchId,
new PrivateKeySigner(WechatPayConfig.mchSerialNo, WechatPayConfig.privateKey)), WechatPayConfig.v3Key.getBytes(StandardCharsets.UTF_8));
// 从证书管理器中获取verifier
Verifier verifier = certificatesManager.getVerifier(WechatPayConfig.mchId);
return verifier;
}
//这个接口也是最新的,自动签名和验签,也非常方便,不过这篇文章我没用,如果你要用,可以这样。
// httpClient.execute(httpPost); ,把这个httpClient 客服端直接换成这个就好了
//比如把 httpClient.execute(httpPost); 换成 WechatPayUtils.getWxPayClient(Verifier verifier).execute(httpPost); 就好了。
public static CloseableHttpClient getWxPayClient(Verifier verifier) throws IOException {
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(WechatPayConfig.mchId, WechatPayConfig.mchSerialNo, WechatPayConfig.privateKey)
.withValidator(new WechatPay2Validator(verifier));
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
CloseableHttpClient httpClient = builder.build();
return httpClient;
}
}
大家最讨厌的回调来啦 ,里面有 "回调验签和解密超简单代码"
@ResponseBody
@RequestMapping(value = "/wxpay/notifyUrl", method = RequestMethod.POST)
public String wxPayCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
Gson gson =new Gson();
String body =WechatPayUtils.readData(request);
String serialNumber = request.getHeader("Wechatpay-Serial");
String nonce = request.getHeader("Wechatpay-Nonce");
String timestamp = request.getHeader("Wechatpay-Timestamp");
String signature = request.getHeader("Wechatpay-Signature");
Map<String,String> map =new HashMap<>();
// 回调验签和解密 ,这个是最新的sdk方法,全网找不到几个用这个方法,所以大家可能有点陌生
//https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient 不信在文档这看
//我的微信第二篇文章有解释说明,这里不解释了.
NotificationRequest Nrequest = new NotificationRequest.Builder().withSerialNumber(serialNumber)
.withNonce(nonce)
.withTimestamp(timestamp)
.withSignature(signature)
.withBody(body)
.build();
NotificationHandler handler = new NotificationHandler(WechatPayUtils.getVerifier(), WechatPayConfig.v3Key.getBytes(StandardCharsets.UTF_8));
//JSON.parseObject,是将Json字符串转化为相应的对象;JSON.toJSONString则是将对象转化为Json字符串.用 Gson.toJson也行
try {
// 验签和解析请求体
Notification notification = handler.parse(Nrequest);
// 从notification中获取解密报文。
String plainText = notification.getDecryptData();
//把密文变成map,方便拿取
Map resultMap =gson.fromJson(plainText,HashMap.class);
log.info("验签成功");
//下面就处理业务逻辑,我就不把代码放出来了,你想怎样处理就怎样.
if (wxpayService.payRecord(resultMap)) {
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "成功");
log.info("入库成功");
}
//成功应答
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "成功");
return gson.toJson(map);
} catch (Exception e) {
log.error("验签失败");
//应答失败
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "验签失败");
return gson.toJson(map);
}
}
基本配置类
@Data
public class WechatPayConfig {
/**
* 微信商户号
*/
public static String mchId = "";
/**
* 微信开放平台的APPID
* */
public static String appId = "";
/**
* 回调报文解密V3密钥key
*/
public static String v3Key = "";
/**
* 微信获取平台证书列表地址
*/
public static String certificatesUrl = "https://api.mch.weixin.qq.com/v3/certificates";
/**
* 微信Native下单URL
*/
public static String unifiedOrderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
/**
* 微信App下单URL
*/
public static String appUnifiedOrderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/app";
/**
* 微信小程序的单URL
*/
public static String unifiedOrderUrlJS;
/**
* 异步接收微信支付结果通知的回调地址
*/
public static String notifyUrl = "";
/**
* 微信证书私钥
*/
public static PrivateKey privateKey;
public static String PACKAGE="Sign=WXPay";
static {
try {
privateKey = WechatPayUtils.getPrivateKey("证书放的地址");
/**
* logo
*/
/* public static String logo;*/
/**
* 微信商家api序列号
*/
public static String mchSerialNo = "";
// 定义全局容器 保存微信平台证书公钥
public static Map<String, X509Certificate> certificateMap = new ConcurrentHashMap<>();
HttpUtils的工具类
package com.tuorong.family.common.pay.wx_pay.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import org.apache.http.HttpEntity;
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.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class HttpUtils {
private static final ObjectMapper JSON = new ObjectMapper();
/**
* get方法
*
* @param url
* @return
*/
public static JsonNode doGet(String url) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet httpget = new HttpGet(url);
httpget.addHeader("Content-Type", "application/json;charset=UTF-8");
httpget.addHeader("Accept", "application/json");
try {
String token = WechatPayUtils.getToken("GET", new URL(url), "");
httpget.addHeader("Authorization", token);
CloseableHttpResponse httpResponse = httpClient.execute(httpget);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
String jsonResult = EntityUtils.toString(httpResponse.getEntity());
return JSON.readTree(jsonResult);
} else {
System.err.println(EntityUtils.toString(httpResponse.getEntity()));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 封装post
*
* @return
*/
public static Map<String, Object> doPost(String url, String body) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;chartset=utf-8");
httpPost.addHeader("Accept", "application/json");
try {
// 1:发起微信支付的真正请求
String token = WechatPayUtils.getToken("POST", new URL(url), body);
// httpPost.addHeader("Authorization", token);
httpPost.setHeader("Authorization",
"WECHATPAY2-SHA256-RSA2048 " + token);
if (body == null) {
throw new IllegalArgumentException("data参数不能为空");
}
构建消息实体
StringEntity stringEntity = new StringEntity(body, "utf-8");
httpPost.setEntity(stringEntity);
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
//响应状态码
int statusCode = httpResponse.getStatusLine().getStatusCode();
//响应体
String jsonResult = EntityUtils.toString(httpEntity);
if (statusCode == 200) {
//处理成功
System.out.println("成功, 返回结果 = " + jsonResult);
return JSON.readValue(jsonResult, HashMap.class);
} else if (statusCode == 204) {
//处理成功,无返回Body
System.out.println("处理成功,无返回Body");
} else {
System.out.println("Native下单失败,响应码 = " + statusCode + ",返回结果 = " + jsonResult);
System.err.println("微信支付错误信息" + EntityUtils.toString(httpEntity));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
好啦,我觉得我应该把所有的东西都列出来了,如果少了什么,请麻烦在评论区告诉我。