diff --git a/api-third/src/main/java/com/heyu/api/jsapi/JsapiPrepay.java b/api-third/src/main/java/com/heyu/api/jsapi/JsapiPrepay.java index 2a60334..14b372e 100644 --- a/api-third/src/main/java/com/heyu/api/jsapi/JsapiPrepay.java +++ b/api-third/src/main/java/com/heyu/api/jsapi/JsapiPrepay.java @@ -79,8 +79,7 @@ public class JsapiPrepay { public DirectAPIv3JsapiPrepayResponse prePay(Long tradeOrderId, Long amount, - String openid - ) { + String openid) { DirectAPIv3JsapiPrepayRequest request = new DirectAPIv3JsapiPrepayRequest(); request.setAppid(appid); request.setMchid(mchid); @@ -103,7 +102,11 @@ public class JsapiPrepay { } - public DirectAPIv3QueryResponse queryOrder(QueryByWxTradeNoRequest request) { + public DirectAPIv3QueryResponse queryOrder(String transactionId) { + + QueryByWxTradeNoRequest request = new QueryByWxTradeNoRequest(); + request.transactionId = transactionId; + request.mchid = mchid; String HOST = "https://api.mch.weixin.qq.com"; String METHOD = "GET"; String uri = "/v3/pay/transactions/id/{transaction_id}"; @@ -114,7 +117,6 @@ public class JsapiPrepay { if (!queryString.isEmpty()) { uri = uri + "?" + queryString; } - Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); reqBuilder.addHeader("Accept", "application/json"); reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); @@ -141,11 +143,50 @@ public class JsapiPrepay { } } + public void close(String tradeOrderId) { + String HOST = "https://api.mch.weixin.qq.com"; + String METHOD = "POST"; + String PATH = "/v3/pay/transactions/out-trade-no/{out_trade_no}/close"; + CloseOrderRequest request = new CloseOrderRequest(); + request.setOutTradeNo(tradeOrderId); + request.setMchid(mchid); + String uri = PATH; + uri = uri.replace("{out_trade_no}", WXPayUtility.urlEncode(request.outTradeNo)); + String reqBody = WXPayUtility.toJson(request); + Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); + reqBuilder.addHeader("Accept", "application/json"); + reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); + reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, reqBody)); + reqBuilder.addHeader("Content-Type", "application/json"); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); + reqBuilder.method(METHOD, requestBody); + Request httpRequest = reqBuilder.build(); + + // 发送HTTP请求 + OkHttpClient client = new OkHttpClient.Builder().build(); + try (Response httpResponse = client.newCall(httpRequest).execute()) { + String respBody = WXPayUtility.extractBody(httpResponse); + if (httpResponse.code() >= 200 && httpResponse.code() < 300) { + // 2XX 成功,验证应答签名 + WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, + httpResponse.headers(), respBody); + + return; + } else { + throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); + } + } catch (IOException e) { + throw new UncheckedIOException("Sending request to " + uri + " failed.", e); + } + } + + + + public DirectAPIv3JsapiPrepayResponse doPay(DirectAPIv3JsapiPrepayRequest request) { String uri = PATH; String reqBody = WXPayUtility.toJson(request); - Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); reqBuilder.addHeader("Accept", "application/json"); reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); diff --git a/api-third/src/main/java/com/heyu/api/jsapi/dto/CloseOrderRequest.java b/api-third/src/main/java/com/heyu/api/jsapi/dto/CloseOrderRequest.java new file mode 100644 index 0000000..82818bb --- /dev/null +++ b/api-third/src/main/java/com/heyu/api/jsapi/dto/CloseOrderRequest.java @@ -0,0 +1,15 @@ +package com.heyu.api.jsapi.dto; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +@Data +public class CloseOrderRequest { + @SerializedName("mchid") + public String mchid; + + @SerializedName("out_trade_no") + @Expose(serialize = false) + public String outTradeNo; +} \ No newline at end of file diff --git a/api-web/api-interface/src/main/java/com/heyu/api/controller/vv/AppWeiXinPayNotifyController.java b/api-web/api-interface/src/main/java/com/heyu/api/controller/vv/AppWeiXinPayNotifyController.java index 47e1666..f08ffdf 100644 --- a/api-web/api-interface/src/main/java/com/heyu/api/controller/vv/AppWeiXinPayNotifyController.java +++ b/api-web/api-interface/src/main/java/com/heyu/api/controller/vv/AppWeiXinPayNotifyController.java @@ -91,7 +91,7 @@ public class AppWeiXinPayNotifyController { // AES-GCM解密方法 private String decrypt(String ciphertext, String associatedData, String nonce) throws Exception { // 将APIv3密钥转为字节数组 - byte[] key = apiv3key.getBytes(StandardCharsets.UTF_8); + byte[] key = apiv3key.getBytes(StandardCharsets.UTF_8) Key secretKey = new SecretKeySpec(key, "AES"); // 使用AES-GCM解密 @@ -107,10 +107,8 @@ public class AppWeiXinPayNotifyController { private void updateOrderStatus(String outTradeNo, String transactionId) { try { - QueryByWxTradeNoRequest request = new QueryByWxTradeNoRequest(); - request.transactionId = transactionId; - request.mchid = mchid; - DirectAPIv3QueryResponse response = jsapiPrepay.queryOrder(request); + + DirectAPIv3QueryResponse response = jsapiPrepay.queryOrder(transactionId); VvTradeOrderEntity tradeOrderEntity = tradeOrderDao.selectVvTradeOrderById(NumberUtil.objToLong(outTradeNo)); tradeOrderEntity.setTradeInfo(JSON.toJSONString(response));