发起请求的时候
这边请求微信的接口中不管是 支付请求,退款请求,关单请求都绕不开一些统一的用法
支付请求
APP支付下单请求
String appUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/app";
/** 请求body参数 这个是我封装过的参数
* APP的APPID,自己生成的订单号,微信商户号,自己的商品描述,提供给微信的回调地址,支付金额
**/
WechatPayModel wechatPayModel = new WechatPayModel(config.getAppId(), payParams.getOrderNo(), config.getMerchantId(), payParams.getOrderSubject(),
config.getCallBackUrl(), payParams.getAmount());
//构建微信支付请求参数
String reqdata = JSON.toJSONString(wechatPayModel);
//配置请求相关
HttpPost httpPost = new HttpPost(h5Url);
StringEntity entity = new StringEntity(reqdata, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//获取一个证书请求client 关键在这
CloseableHttpClient closeableHttpClient = getWechatHttpClient(config.getMerchantId(), config.getMerchantSerialNumber(), config.getMerchantPrivateKey());
closeableHttpClient.execute(httpPost);
退款请求
APP退款请求
String refundUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
//根据请求参数要求构建 退款金额 退款货币种类 退款原订单金额
Map<String, Object> amount = new HashMap<>();
amount.put("refund", unifyPayParams.getRefundAmount());
amount.put("currency", "CNY");
amount.put("total", unifyPayParams.getAmount());
CreateRefundRequest createRefundRequest = new CreateRefundRequest();
//然后构建请求参数 回调地址 订单号 退款单号
createRefundRequest
.setNotify_url(config.getCallBackUrl())
.setOut_refund_no(unifyPayParams.getRefundOrderNo())
.setOut_trade_no(unifyPayParams.getOrderNo())
.setReason(unifyPayParams.getRemark())
.setAmount(amount);
//配置请求相关
String reqdata = JSON.toJSONString(createRefundRequest);
HttpPost httpPost = new HttpPost(h5Url);
StringEntity entity = new StringEntity(reqdata, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//获取一个证书请求client 关键在这
CloseableHttpClient closeableHttpClient = getWechatHttpClient(config.getMerchantId(), config.getMerchantSerialNumber(), config.getMerchantPrivateKey());
closeableHttpClient.execute(httpPost);
关单请求
APP关单请求
String URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + outTradeNo + "/close";
//关单需要一个订单号及商户号 配置请求参数
JSONObject json = new JSONObject();
json.put("mchid", config.getMerchantId());
StringEntity entity = new StringEntity(json.toJSONString(), StandardCharsets.UTF_8);
HttpPost httpPost = new HttpPost(URL);
entity.setContentType("application/json");
httpPost.setHeader("Accept", "application/json");
httpPost.setEntity(entity);
//获取一个证书请求client 关键在这
CloseableHttpClient closeableHttpClient = getWechatHttpClient(config.getMerchantId(), config.getMerchantSerialNumber(), config.getMerchantPrivateKey());
closeableHttpClient.execute(httpPost);
每种请求都是构建完了各自请求参数后,最后都会统一生成一个请求客户端用于请求微信接口
//这里就是获取一个httpClient的地方 参数为商户号 ,证书序列号(也叫证书编号),私钥
private CloseableHttpClient getWechatHttpClient(String merchantId, String merchantSerialNumber, String merchantPrivateKey) throws Exception {
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey privateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(merchantPrivateKey.getBytes("utf-8")));
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
new PrivateKeySigner(merchantSerialNumber, privateKey)), config.getV3Key().getBytes(StandardCharsets.UTF_8));
// 从证书管理器中获取verifier
Verifier verifier = certificatesManager.getVerifier(merchantId);
//构建请求客户端
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, privateKey)
.withValidator(new WechatPay2Validator(verifier));
return builder.build();
}
通过上述的一系列请求就可以实现向微信发送请求了,请求的各种参数,请参考我的另一个博文简单的微信支付APP篇
接收回调的时候
一般来说请求了微信后 都会获取到对应的回调信息 都是异步处理的
支付回调
APP支付通知
//一般来说如果你只有一个商户号收款就不需要第二个参数了 商户号
public void wxNotifyHandler(HttpServletRequest request, Long mchInfoId) {
log.debug("-----------------微信回调开始-----------------------------");
//微信回调平台证书序列号
String serialNumber = request.getHeader("Wechatpay-Serial");
//微信回调应答随机串 Wechatpay-Nonce
String nonce = request.getHeader("Wechatpay-Nonce");
//微信回调应答时间戳 Wechatpay-Timestamp
String timestamp = request.getHeader("Wechatpay-Timestamp");
//微信回调签名值从请求头中获取 Wechatpay-Signature
String signature = request.getHeader("Wechatpay-Signature");
//然后获取微信回调中的应答体
String body = "";
BufferedReader reader = request.getReader();
String line = "";
StringBuffer inputString = new StringBuffer();
while ((line = reader.readLine()) != null) {
inputString.append(line);
}
if (!"".contentEquals(inputString)) {
body = inputString.toString();
}
reader.close();
//如果回调中的不是成功没必要走下去了
if (!body.contains("TRANSACTION.SUCCESS")) {
return;
}
//关键再这个工具类中的解密及验签
WechatUtils wechatUtils = wechatPayService.getNotifyPayUtil(mchInfoId);
String result = wechatUtils.decrypt(body, serialNumber, nonce, timestamp, signature);
log.debug("微信回调解密信息:{}", result);
//后续就是自己的逻辑操作了
//这里只是指定了一下商户号的配置
WechatUtils wechatUtils = wechatPayService.getNotifyPayUtil(mchInfoId);
。。。
//然后用商户号的配置去解密 微信回调应答体,请求头中证书序列号,请求头中应答随机串,请求头中应答时间戳,请求头中签名值
public String decrypt(String body, String serialNumber, String nonce, String timestamp, String signature) throws Exception {
//配置一个用于验签和解密的配置
NotificationRequest request = new NotificationRequest.Builder()
.withSerialNumber(serialNumber)
.withNonce(nonce)
.withTimestamp(timestamp)
.withSignature(signature)
.withBody(body)
.build();
//获取verifi验证者 商户号 证书序列号 私钥 用于验签
Verifier verifier = getVerifier(config.getMerchantId(), config.getMerchantSerialNumber(), config.getMerchantPrivateKey());
//用于构建一个处理器
NotificationHandler handler = new NotificationHandler(verifier, config.getV3Key().getBytes(StandardCharsets.UTF_8));
// 验签和解析请求体
Notification notification = handler.parse(request);
// 从notification中获取解密报文
return notification.getDecryptData();
}
//获取请求一个verifi验证者
public Verifier getVerifier(String merchantId, String merchantSerialNumber, String merchantPrivateKey) throws Exception {
PrivateKey privateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(merchantPrivateKey.getBytes("utf-8")));
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
new PrivateKeySigner(merchantSerialNumber, privateKey)), config.getV3Key().getBytes(StandardCharsets.UTF_8));
// 从证书管理器中获取verifi
return certificatesManager.getVerifier(merchantId);
}
这里就是请求微信和接收微信的相关记录及配置了,如有帮助不胜荣幸。