首先需要准备开发环境
1基础配置
wxpay:
merchantId: 直连商户号
notify_url: 回调url
apiv3Secretkey: APIv3秘钥
privateKeyFile: 商户API私钥,用作支付签名
serial_no: 商户API证书序列号,一年后期,后期后需要手动到商户后台下载,再更新库
<!--wechatpay-apache-httpclient 微信V3版支付相关-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.7.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
创建订单表
CREATE TABLE `orator_wx_order` (
`id` varchar(50) NOT NULL,
`prepay_id` varchar(255) DEFAULT NULL COMMENT '预订单标识',
`transaction_id` varchar(50) DEFAULT NULL COMMENT '微信支付订单号',
`user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
`openid` varchar(50) DEFAULT NULL COMMENT '用户openid',
`total_amount` decimal(50,2) DEFAULT NULL COMMENT '订单总金额',
`pay_amount` decimal(50,2) DEFAULT NULL COMMENT '支付金额',
`shop_id` varchar(50) DEFAULT NULL COMMENT '商品id',
`description` varchar(255) DEFAULT NULL COMMENT '商品描述',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
`success_time` datetime DEFAULT NULL COMMENT '支付成功时间',
`time_expire` datetime DEFAULT NULL COMMENT '交易结束时间',
`pay_status` int(2) DEFAULT NULL COMMENT '支付状态(1待支付2支付完成)',
`trade_type` varchar(50) DEFAULT NULL COMMENT '支付方式JSAPI:公众号支付 \r\nNATIVE:扫码支付 \r\nAPP:APP支付 \r\nMICROPAY:付款码支付 \r\nMWEB:H5支付 \r\nFACEPAY:刷脸支付 ',
`trade_state` varchar(50) DEFAULT NULL COMMENT 'SUCCESS:支付成功 \r\nREFUND:转入退款 \r\nNOTPAY:未支付 \r\nCLOSED:已关闭 \r\nREVOKED:已撤销(付款码支付) \r\nUSERPAYING:用户支付中(付款码支付) \r\nPAYERROR:支付失败(其他原因,如银行返回失败) ',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
引入工具类
/***************************
* 作者: gbing
* 时间: 2021/3/30 09:20
* 描述:
************************/
public class WxPayCommon {
//请求网关
public static final String BASE_URL_PREX = "https://api.mch.weixin.qq.com/";
//编码
public static final String CHARSET = "UTF-8";
//支付链接
public static final String V3_APP="v3/pay/transactions/app";
public static final String V3_JSAPI="v3/pay/transactions/jsapi";
public static final String V3_NATIVE="v3/pay/transactions/native";
public static final String V3_H5="v3/pay/transactions/h5";
}
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class AesUtil {
static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;
private final byte[] aesKey;
public AesUtil(byte[] key) {
if (key.length != KEY_LENGTH_BYTE) {
throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");
}
this.aesKey = key;
}
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
throws GeneralSecurityException, IOException {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
cipher.updateAAD(associatedData);
return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(e);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException(e);
}
}
}
model (非必须 只是为了页面效果简洁)
@Data
public class PaymentCallback {
/**
* 通知的唯一ID
*/
private String id;
/**
* 通知创建的时间,格式为yyyyMMddHHmmss
*/
private String create_time;
/**
* 通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS
*/
private String event_type;
/**
* 通知的资源数据类型,支付成功通知为encrypt-resource
*/
private String resource_type;
/**
* 加密信息
*/
private Resource resource;
/**
* 微信支付平台证书序列号
*/
private String serialNo;
}
import lombok.Data;
/**
* 微信支付结果通知中加密的信息
*
* @author anYanSen
* @since 2020/7/15 14:03
*/
@Data
public class Resource {
/**
* 对开启结果数据进行加密的加密算法,目前只支持AEAD_AES_256_GCM
*/
private String algorithm;
/**
* Base64编码后的开启/停用结果数据密文
*/
private String ciphertext;
/**
* 附加数据
*/
private String associated_data;
/**
* 加密使用的随机串
*/
private String nonce;
}
import lombok.Data;
import java.util.Date;
/***************************
* 作者: gbing
* 时间: 2021/3/29 11:32
* 描述:
************************/
@Data
public class PayWechat {
/**
* APIv3秘钥
*/
private String apiv3Secretkey;
/**
* 商户API私钥,用作支付签名
*/
private String merchaantsSecretkey;
/**
* 商户API证书序列号,一年后期,后期后需要手动到商户后台下载,再更新库
*/
private String certificateSerialNumber;
/**
* 微信平台支付证书编号
*/
private String wechatSerialNumber;
}
可以和上面PayWechat合成一个
import lombok.Data;
/**
* 扩展微信支付配置,添加JSAPI下单API相关参数
*
* @author anYanSen
* @since 2020/7/14 15:12
*/
@Data
public class Transactions extends PayWechat{
/**
* 公众号ID
*/
private String appid;
/**
* 直连商户号
*/
private String mchid;
/**
* 商品描述
*/
private String description;
/**
* 商户订单号 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
*/
private String outTradeNo;
/**
* 总金额,单位分
*/
private Integer total;
/**
* 用户在直连商户appid下的唯一标识。
*/
private String openid;
private String notifyUrl;
}
合成一个如下所示--与上面二选一:
package cn.aimanrenjian.orator.model;
import lombok.Data;
/**
* 扩展微信支付配置,添加JSAPI下单API相关参数
*/
@Data
public class Transactions {
/**
* 公众号ID
*/
private String appid;
/**
* 直连商户号
*/
private String mchid;
/**
* APIv3秘钥
*/
private String apiv3Secretkey ;
/**
* 商户API私钥,用作支付签名
*/
private String merchaantsSecretkey ;
/**
* 商户API证书序列号,一年后期,后期后需要手动到商户后台下载,再更新库
*/
private String certificateSerialNumber;
/**
* 商品描述
*/
private String description;
/**
* 商户订单号 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
*/
private String outTradeNo;
/**
* 总金额,单位分
*/
private Integer total;
/**
* 用户在直连商户appid下的唯一标识。
*/
private String openid;
/**
* 回调接口信息
*/
private String notifyUrl;
}
Controller层
//生成微信支付信息
@PostMapping("/pay/transactions")
public TMessage transactions1(@RequestBody OratorWxOrder oratorWxOrder) {
//transactions也可以自定义成工具类获取所需要的的参数信息
Transactions transactions=payService.buildTransactions(oratorWxOrder) ;
String prepay_id =payService.V3PayGet(WxPayCommon.V3_JSAPI,oratorWxOrder,transactions);
//生成签名返回前端
JSONObject signJson = null;
try {
signJson = payService.WxTuneUp(prepay_id, transactions.getAppid(), transactions.getApiv3Secretkey());
} catch (Exception e) {
e.printStackTrace();
}
return UtilMessage.success(signJson);
}
//微信回调
@PostMapping(value = "/wxnoty")
public void wxnoty(HttpServletRequest request, HttpServletResponse response) throws Exception {
OratorWxOrder oratorWxOrder =new OratorWxOrder();
Transactions transactions=payService.buildTransactions(oratorWxOrder) ;
String out_trade_no = payService.notify(request, response, transactions.getApiv3Secretkey());
//TODO 更新订单
System.out.println(out_trade_no);
}
//查询订单信息
@GetMapping("/transactions/out_trade_no/{out_trade_no}")
public TMessage queryPayOrderStatus(@PathVariable("out_trade_no") String outTradeNo) throws Exception {
return wxService.queryPayOrderStatus(outTradeNo);
}
service层
import cn.aimanrenjian.common.utility.UtilityIdGenerator;
import cn.aimanrenjian.common.wx.util.AesUtil;
import cn.aimanrenjian.common.wx.util.WxPayCommon;
import cn.aimanrenjian.orator.db.domain.OratorWxOrder;
import cn.aimanrenjian.orator.model.Transactions;
import cn.aimanrenjian.orator.service.WeChatPayService;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import okhttp3.HttpUrl;
import org.apache.http.HttpEntity;
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.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.*;
/***************************
* 作者: gbing
* 时间: 2021/3/29 17:25
* 描述:
************************/
@Service
public class PayService {
@Value("${wxpay.appId}")
private String appId;
@Value("${wxpay.notifyUrl}")
private String notifyUrl;
@Value("${wxpay.merchantId}")
private String merchantId;
@Value("${wxpay.apiv3Secretkey}")
private String apiv3Secretkey;
@Value("${wxpay.serialNumber}")
private String serialNumber;
@Value("${wxpay.privateKey}")
private String privateKey;
//封装支付需要参数信息
public Transactions buildTransactions(OratorWxOrder oratorWxOrder) {
Transactions transactions = new Transactions();
transactions.setAppid(appId);
transactions.setMchid(merchantId);
//回调接口
transactions.setNotifyUrl(notifyUrl);
transactions.setApiv3Secretkey(apiv3Secretkey);
transactions.setMerchaantsSecretkey(privateKey);
transactions.setCertificateSerialNumber(serialNumber);
//生成流水单号
transactions.setOutTradeNo(UtilityIdGenerator.getSequenceNo());
transactions.setDescription("在线充值");
// 微信支付金额,单位分
BigDecimal settleMonery = new BigDecimal(oratorWxOrder.getPayAmount() + "").multiply(new BigDecimal("100"));
Integer total = settleMonery.setScale(0, BigDecimal.ROUND_DOWN).intValue();
transactions.setTotal(total);
return transactions;
}
/**
* 微信支付下单
*
* @param url 请求地址(只需传入域名之后的路由地址)
* @param jsonStr 请求体 json字符串 此参数与微信官方文档一致
* @param mercId 商户ID
* @param serial_no 证书序列号
* @param privateKey 私钥的路径
* @return 订单支付的参数
* @throws Exception
*/
public String V3PayGet( String url, OratorWxOrder oratorWxOrder,Transactions transactions){
JSONObject signJson = null;
String mercId=transactions.getMchid();
String serial_no=transactions.getWechatSerialNumber();
String privateKeyFilePath=transactions.getMerchaantsSecretkey();
//构建需要上传信息
String jsonStr=buildTransactions(oratorWxOrder,transactions).toString();
try {
// 带签名支付信息
String body = "";
//创建httpclient对象
CloseableHttpClient client = HttpClients.createDefault();
//创建post方式请求对象
HttpPost httpPost = new HttpPost(WxPayCommon.BASE_URL_PREX+url);
//装填参数
StringEntity s = new StringEntity(jsonStr, WxPayCommon.CHARSET);
s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
//设置参数到请求对象中
httpPost.setEntity(s);
String post = getToken("POST", HttpUrl.parse(WxPayCommon.BASE_URL_PREX+url),
mercId, serial_no, privateKeyFilePath, jsonStr);
//设置header信息
//指定报文头【Content-type】、【User-Agent】
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Authorization",
"WECHATPAY2-SHA256-RSA2048 " + post);
//执行请求操作,并拿到结果(同步阻塞)
CloseableHttpResponse response = client.execute(httpPost);
//获取结果实体
HttpEntity entity = response.getEntity();
if (entity != null) {
//按指定编码转换结果实体为String类型
body = EntityUtils.toString(entity, WxPayCommon.CHARSET);
}
EntityUtils.consume(entity);
//释放链接
response.close();
switch (url) {
case WxPayCommon.V3_APP://返回APP支付所需的参数
JSONObject jsonObject = JSONObject.parseObject(body);
//TODO 这里也可以保存一些订单业务
// if (jsonObject == null) {
// return UtilMessage.fail("下单有误,请重试!");
// }
// oratorWxOrder.setId(transactions.getOutTradeNo());
// oratorWxOrder.setPrepayId(jsonObject.getString("prepayId"));
// oratorWxOrder.setPayStatus(1);
// oratorWxOrder.setOpenid(transactions.getOpenid());
// oratorWxOrder.setCreateDate(new Date());
// // oratorWxOrder.setUserId(userId);
// oratorWxOrderMapper.insertSelective(oratorWxOrder);
return jsonObject.getString("prepay_id");
case WxPayCommon.V3_JSAPI://返回JSAPI支付所需的参数
return JSONObject.parseObject(body).getString("prepay_id");
case WxPayCommon.V3_NATIVE://返回native的请求地址
return JSONObject.parseObject(body).getString("code_url");
case WxPayCommon.V3_H5://返回h5支付的链接
return JSONObject.parseObject(body).getString("h5_url");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 微信调起支付参数
* 返回参数如有不理解 请访问微信官方文档
* https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_1_4.shtml
*
* @param prepayId 微信下单返回的prepay_id
* @param appId 应用ID(appid)
* @param privateKeyFilePath 私钥的地址
* @return 当前调起支付所需的参数
* @throws Exception
*/
public static JSONObject WxTuneUp(String prepayId, String appId, String privateKeyFilePath) throws Exception {
String time = System.currentTimeMillis() / 1000 + "";
String nonceStr = UUID.randomUUID().toString().replace("-", "");
String packageStr = "prepay_id=" + prepayId;
ArrayList<String> list = new ArrayList<>();
list.add(appId);
list.add(time);
list.add(nonceStr);
list.add(packageStr);
//加载签名
String packageSign = sign(buildSignMessage(list).getBytes(), privateKeyFilePath);
JSONObject jsonObject = new JSONObject();
jsonObject.put("appId", appId);
jsonObject.put("timeStamp", time);
jsonObject.put("nonceStr", nonceStr);
jsonObject.put("packages", packageStr);
jsonObject.put("signType", "RSA");
jsonObject.put("paySign", packageSign);
return jsonObject;
}
/**
* 构造签名串
*
* @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();
}
static String getToken(String method, HttpUrl url, String mercId, String serial_no, String privateKeyFilePath, String body) throws Exception {
String nonceStr = UUID.randomUUID().toString().replace("-", "");
long timestamp = System.currentTimeMillis() / 1000;
String message = buildMessage(method, url, timestamp, nonceStr, body);
String signature = sign(message.getBytes("UTF-8"), privateKeyFilePath);
return "mchid=\"" + mercId + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + serial_no + "\","
+ "signature=\"" + signature + "\"";
}
/**
* 生成签名
*
* @param message 请求体
* @param privateKeyFilePath 私钥的路径
* @return 生成base64位签名信息
* @throws Exception
*/
static String sign(byte[] message, String privateKeyFilePath) throws Exception {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(getPrivateKey(privateKeyFilePath));
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
/**
* 获取私钥。
*
* @param privateKey 私钥文件路径 (required)
* @return 私钥对象
*/
static PrivateKey getPrivateKey(String privateKey) throws IOException {
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
return merchantPrivateKey;
}
/**
* 组装签名加载
*
* @param method 请求方式
* @param url 请求地址
* @param timestamp 请求时间
* @param nonceStr 请求随机字符串
* @param body 请求体
* @return 组装的字符串
*/
static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
String canonicalUrl = url.encodedPath();
if (url.encodedQuery() != null) {
canonicalUrl += "?" + url.encodedQuery();
}
return method + "\n"
+ canonicalUrl + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ body + "\n";
}
public JSONObject buildTransactions (OratorWxOrder oratorWxOrder, Transactions transactions){
JSONObject paramJson = new JSONObject();
// 公众号ID
paramJson.put("appid", transactions.getAppid());
// 直连商户号
paramJson.put("mchid", transactions.getMchid());
// 商品描述
paramJson.put("description", oratorWxOrder.getDescription());
// 商户订单号
paramJson.put("out_trade_no", UtilityIdGenerator.getSequenceNo());
// 通知地址
paramJson.put("notify_url", transactions.getNotifyUrl());
// 金额
JSONObject amountJson = new JSONObject();
// 总金额,单位分
// 微信支付金额,单位分
BigDecimal settleMonery = new BigDecimal(oratorWxOrder.getPayAmount() + "").multiply(new BigDecimal("100"));
Integer total = settleMonery.setScale(0, BigDecimal.ROUND_DOWN).intValue();
amountJson.put("total", total);
// 货币类型,CNY:人民币
amountJson.put("currency", "CNY");
paramJson.put("amount", amountJson);
// 支付者
JSONObject payerJson = new JSONObject();
//用户在直连商户appid下的唯一标识。
payerJson.put("openid", "o63BM1TxPC4AyUhA00097rfwed5M");
paramJson.put("payer", payerJson);
return paramJson;
}
/**
* 处理微信异步回调
*
* @param request
* @param response
* @param privateKey 32的秘钥
*/
public static String notify(HttpServletRequest request, HttpServletResponse response, String privateKey) throws Exception {
Map<String, String> map = new HashMap<>(12);
String result = readData(request);
// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号
String plainText = verifyNotify(result, privateKey);
if (StrUtil.isNotEmpty(plainText)) {
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "SUCCESS");
} else {
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "签名错误");
}
response.setHeader("Content-type", ContentType.JSON.toString());
response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
response.flushBuffer();
String out_trade_no = JSONObject.parseObject(plainText).getString("out_trade_no");
return out_trade_no;
}
/**
* 处理返回对象
*
* @param request
* @return
*/
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();
}
}
}
}
/**
* v3 支付异步通知验证签名
*
* @param body 异步通知密文
* @param key api 密钥
* @return 异步通知明文
* @throws Exception 异常信息
*/
static String verifyNotify(String body, String key) throws Exception {
// 获取平台证书序列号
cn.hutool.json.JSONObject resultObject = JSONUtil.parseObj(body);
cn.hutool.json.JSONObject resource = resultObject.getJSONObject("resource");
String cipherText = resource.getStr("ciphertext");
String nonceStr = resource.getStr("nonce");
String associatedData = resource.getStr("associated_data");
AesUtil aesUtil = new AesUtil(key.getBytes(StandardCharsets.UTF_8));
// 密文解密
return aesUtil.decryptToString(
associatedData.getBytes(StandardCharsets.UTF_8),
nonceStr.getBytes(StandardCharsets.UTF_8),
cipherText
);
}
public TMessage queryPayOrderStatus(final String outTradeNo) throws Exception {
OratorWxOrder oratorWxOrder = oratorWxOrderMapper.selectByPrimaryKey(outTradeNo);
if (oratorWxOrder.getPayStatus()==2){
return UtilMessage.success("购买成功");
}
Transactions transactions = new Transactions();
transactions.setAppid(appId);
transactions.setMchid(merchantId);
//回调接口
transactions.setNotifyUrl(notifyUrl);
transactions.setApiv3Secretkey(apiv3Secretkey);
transactions.setMerchaantsSecretkey(privateKey);
transactions.setCertificateSerialNumber(serialNumber);
//生成流水单号
transactions.setOutTradeNo(outTradeNo);
TMessage tMessage = weChatPayService.queryPayOrderStatus1(transactions);
if (tMessage.getFlag()==0){
oratorWxOrder.setPayStatus(2);
oratorWxOrderMapper.updateByPrimaryKey(oratorWxOrder);
}
return tMessage;
}
public TMessage queryPayOrderStatus1(Transactions transactions) throws Exception {
//加密生成签名
//微信查询订单信息 如果body为空 需要传递"" 而不是null 否则会出现签名错误的情况
String generateSignature = WXPayUtil.generateSignature("GET",
"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + transactions.getOutTradeNo() + "?mchid=" + transactions.getMchid(),
"", transactions.getMchid(),
transactions.getMerchaantsSecretkey(), transactions.getCertificateSerialNumber());
// 微信JSAPI下单API
URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + transactions.getOutTradeNo()+ "?mchid=" + transactions.getMchid());
HttpGet httpPost = new HttpGet(uriBuilder.build());
httpPost.addHeader("Accept", "application/json");
httpPost.setHeader("Authorization",
"WECHATPAY2-SHA256-RSA2048 " + generateSignature);
httpPost.setHeader("Content-Type","application/json");
CloseableHttpResponse response = null;
try {
//创建httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
response = httpClient.execute(httpPost);
//获取结果实体
HttpEntity entity = response.getEntity();
if (response.getStatusLine().getStatusCode() != 200) {
return UtilMessage.fail("在线充值订单查询接口有误!");
}
JSONObject parseObject = JSON.parseObject(EntityUtils.toString(entity, "UTF-8"));
String tradeState = parseObject.getString("trade_state");
EntityUtils.consume(entity);
if ("SUCCESS".equals(tradeState)) {
return UtilMessage.success("支付成功!");
} else {
return UtilMessage.fail(parseObject.getString("trade_state_desc"));
}
} catch (Exception e){
e.getMessage();
}finally {
response.close();
}
//与上面代码二选一
// HttpResponse response = null;
// // 生成签名
// String merchaantsSecretkey = transactions.getMerchaantsSecretkey();
// String signature =
// WXPayUtil.generateSignature("GET",
// "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + transactions.getOutTradeNo()
// + "?mchid=" + transactions.getMchid(),
// "" , transactions.getMchid(),merchaantsSecretkey
// , transactions.getCertificateSerialNumber());
//
// // 从微信那边获取微信平台证书
// String authorization = "";
// authorization += WXPayUtil.SCHEAM + " ";
// authorization += signature;
// System.out.println("authorization = " + authorization);
// try {
// response = HttpRequest.get("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" +
// transactions.getOutTradeNo() + "?mchid=" + transactions.getMchid())
// .header("Content-Type", "application/json")
// .header("Accept", "application/json")
// .header("Authorization", authorization)
// .execute();
// if (response.getStatus() != 200) {
// return UtilMessage.fail("在线充值订单查询接口有误!");
// }
// JSONObject jsonObject = JSON.parseObject(response.body());
// String tradeState = jsonObject.getString("trade_state");
// if ("SUCCESS".equals(tradeState)) {
// return UtilMessage.success("购买成功!");
// } else {
// return UtilMessage.fail(jsonObject.getString("trade_state_desc"));
// }
// } catch (Exception e) {
// e.printStackTrace();
// } finally {
// response.close();
// }
return UtilMessage.fail("支付成功!");
}
}