diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxConst.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxConst.java index fe3d4e4..07a290b 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxConst.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxConst.java @@ -16,7 +16,7 @@ public interface WxConst { /** * 沙箱 */ - String SANDBOXNEW = "sandboxnew/"; + String SANDBOXNEW = "xdc/apiv2sandbox/"; String SUCCESS = "SUCCESS"; String FAIL = "FAIL"; diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/DefaultWxPayAssistService.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/DefaultWxPayAssistService.java index 3bf1e68..54897ff 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/DefaultWxPayAssistService.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/DefaultWxPayAssistService.java @@ -43,10 +43,10 @@ public class DefaultWxPayAssistService implements WxPayAssistService { private HttpRequestTemplate requestTemplate; - private WxPayService wxPayService; + private WxPayServiceInf wxPayService; - public DefaultWxPayAssistService(WxPayService wxPayService) { + public DefaultWxPayAssistService(WxPayServiceInf wxPayService) { this.wxPayService = wxPayService; payConfigStorage = wxPayService.getPayConfigStorage(); requestTemplate = wxPayService.getHttpRequestTemplate(); @@ -111,7 +111,7 @@ public class DefaultWxPayAssistService implements WxPayAssistService { return responseBody; } for (Header header : headers) { - if ("Wechatpay-Serial".equals(header.getName())) { + if (WxConst.WECHATPAY_SERIAL.equals(header.getName())) { // 更新平台证书的序列号,需要每次都更新,因为这个可能会改变 payConfigStorage.getCertEnvironment().setPlatformSerialNumber(header.getValue()); break; @@ -138,7 +138,7 @@ public class DefaultWxPayAssistService implements WxPayAssistService { * 构建请求实体 * 这里也做签名处理 * - * @param url url + * @param url url * @param body 请求内容体 * @param method 请求方法 * @return 请求实体 @@ -158,7 +158,9 @@ public class DefaultWxPayAssistService implements WxPayAssistService { entity.addHeader(new BasicHeader("Authorization", WxConst.SCHEMA.concat(token))); entity.addHeader(new BasicHeader("User-Agent", "Pay-Java-Parent")); entity.addHeader(new BasicHeader("Accept", APPLICATION_JSON.getMimeType())); - return entity; + + + return wxPayService.hookHttpEntity(entity); } @@ -210,5 +212,4 @@ public class DefaultWxPayAssistService implements WxPayAssistService { } - } diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayService.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayService.java index 3a25ab5..3170155 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayService.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayService.java @@ -75,7 +75,7 @@ import com.egzosn.pay.wx.v3.utils.WxConst; * date 2021/10/6 * */ -public class WxPayService extends BasePayService implements TransferService { +public class WxPayService extends BasePayService implements TransferService, WxPayServiceInf { /** @@ -123,12 +123,13 @@ public class WxPayService extends BasePayService implements * * @return 辅助api */ + @Override public WxPayAssistService getAssistService() { if (null == assistService) { assistService = new DefaultWxPayAssistService(this); - //在这预先进行初始化 - assistService.refreshCertificate(); } + //在这预先进行初始化 + assistService.refreshCertificate(); return assistService; } @@ -144,7 +145,7 @@ public class WxPayService extends BasePayService implements // new Thread(() -> { payConfigStorage.loadCertEnvironment(); wxParameterStructure = new WxParameterStructure(payConfigStorage); - getAssistService(); + setApiServerUrl(WxConst.URI); // }).start(); } @@ -155,11 +156,14 @@ public class WxPayService extends BasePayService implements * @param apiServerUrl api服务器地址 * @return 自身 */ + @Override public WxPayService setApiServerUrl(String apiServerUrl) { this.apiServerUrl = apiServerUrl; + getAssistService(); return this; } + @Override public String getApiServerUrl() { return apiServerUrl; } @@ -218,14 +222,9 @@ public class WxPayService extends BasePayService implements Certificate certificate = getAssistService().getCertificate(serial); - Map attr = noticeParams.getAttr(); - - if (Util.isEmpty(attr)) { - throw new PayErrorException(new WxPayError(FAILURE, "请勿置空NoticeParams.attr中的数据")); - } //这里为微信回调时的请求内容体,原值数据 - String body = (String) attr.get(WxConst.RESP_BODY); + String body = noticeParams.getBodyStr(); //签名信息 String signText = StringUtils.joining("\n", timestamp, nonce, body); @@ -362,6 +361,7 @@ public class WxPayService extends BasePayService implements String body = IOUtils.toString(is); noticeParams = JSON.parseObject(body, WxNoticeParams.class); noticeParams.setAttr(new MapGen(WxConst.RESP_BODY, body).getAttr()); + noticeParams.setBodyStr(body); Resource resource = noticeParams.getResource(); String associatedData = resource.getAssociatedData(); String nonce = resource.getNonce(); @@ -703,14 +703,15 @@ public class WxPayService extends BasePayService implements } } - if (transactionType == com.egzosn.pay.wx.v3.bean.WxTransferType.QUERY_BATCH_BY_BATCH_ID || transactionType == com.egzosn.pay.wx.v3.bean.WxTransferType.QUERY_BATCH_BY_OUT_BATCH_NO) { + if (transactionType == WxTransferType.QUERY_BATCH_BY_BATCH_ID || transactionType == WxTransferType.QUERY_BATCH_BY_OUT_BATCH_NO) { OrderParaStructure.loadParameters(parameters, WxConst.NEED_QUERY_DETAIL, assistOrder); OrderParaStructure.loadParameters(parameters, WxConst.OFFSET, assistOrder); OrderParaStructure.loadParameters(parameters, WxConst.LIMIT, assistOrder); OrderParaStructure.loadParameters(parameters, WxConst.DETAIL_STATUS, assistOrder); } - String requestBody = JSON.toJSONString(parameters); + + String requestBody = UriVariables.getMapToParameters(parameters); return getAssistService().doExecute(requestBody, assistOrder.getTransactionType(), uriVariables.toArray()); } @@ -728,7 +729,7 @@ public class WxPayService extends BasePayService implements */ @Override public Map transferQuery(String outNo, String wxTransferType) { - throw new PayErrorException(new WxPayError("", "V3不支持转账查询")); + throw new PayErrorException(new WxPayError("", "V3不支持此转账查询:替代方法transferQuery(AssistOrder assistOrder)")); } diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayServiceInf.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayServiceInf.java new file mode 100644 index 0000000..01080b9 --- /dev/null +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayServiceInf.java @@ -0,0 +1,67 @@ +package com.egzosn.pay.wx.v3.api; + +import com.egzosn.pay.common.api.PayService; +import com.egzosn.pay.common.bean.NoticeParams; +import com.egzosn.pay.common.bean.TransactionType; +import com.egzosn.pay.common.http.HttpStringEntity; + +/** + * @author Egan + * @email egan@egzosn.com + * @date 2023/9/11 + */ +public interface WxPayServiceInf extends PayService { + /** + * 辅助api + * + * @return 辅助api + */ + WxPayAssistService getAssistService(); + + /** + * 设置api服务器地址 + * + * @param apiServerUrl api服务器地址 + * @return 自身 + */ + WxPayService setApiServerUrl(String apiServerUrl); + + String getApiServerUrl(); + + /** + * 根据交易类型获取url + * + * @param transactionType 交易类型 + * @return 请求url + */ + @Override + String getReqUrl(TransactionType transactionType); + + /** + * 验签,使用微信平台证书. + * + * @param noticeParams 通知参数 + * @return the boolean + */ + @Override + boolean verify(NoticeParams noticeParams); + + /** + * 签名 + * + * @param content 需要签名的内容 不包含key + * @param characterEncoding 字符编码 + * @return 签名结果 + */ + @Override + String createSign(String content, String characterEncoding); + + /** + * http 实体 钩子 + * @param entity 实体 + * @return 返回处理后的实体 + */ + default HttpStringEntity hookHttpEntity(HttpStringEntity entity){ + return entity; + } +} diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxProfitSharingService.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxProfitSharingService.java index d030742..d4bc919 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxProfitSharingService.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxProfitSharingService.java @@ -1,30 +1,29 @@ package com.egzosn.pay.wx.v3.api; import java.io.InputStream; -import java.security.PrivateKey; import java.util.Date; import java.util.Map; +import org.apache.http.message.BasicHeader; + import com.alibaba.fastjson.JSONObject; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.BillType; import com.egzosn.pay.common.bean.MethodType; import com.egzosn.pay.common.bean.NoticeParams; -import com.egzosn.pay.common.bean.NoticeRequest; import com.egzosn.pay.common.bean.OrderParaStructure; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.common.bean.PayOrder; -import com.egzosn.pay.common.bean.PayOutMessage; import com.egzosn.pay.common.bean.RefundOrder; import com.egzosn.pay.common.bean.RefundResult; import com.egzosn.pay.common.bean.TransferOrder; import com.egzosn.pay.common.bean.result.PayException; import com.egzosn.pay.common.exception.PayErrorException; import com.egzosn.pay.common.http.HttpConfigStorage; +import com.egzosn.pay.common.http.HttpStringEntity; import com.egzosn.pay.common.http.UriVariables; import com.egzosn.pay.common.util.DateUtils; import com.egzosn.pay.common.util.MapGen; -import com.egzosn.pay.common.util.sign.encrypt.RSA2; import com.egzosn.pay.wx.bean.WxPayError; import com.egzosn.pay.wx.bean.WxTransferType; import com.egzosn.pay.wx.v3.bean.WxProfitSharingTransactionType; @@ -70,8 +69,8 @@ public class WxProfitSharingService extends WxPayService implements ProfitSharin @Override protected void initAfter() { // new Thread(() -> { - payConfigStorage.loadCertEnvironment(); - getAssistService(); + payConfigStorage.loadCertEnvironment(); + setApiServerUrl(WxConst.URI); // }).start(); } @@ -121,6 +120,17 @@ public class WxProfitSharingService extends WxPayService implements ProfitSharin return getAssistService().doExecute(parameters, order); } + /** + * http 实体 钩子 + * + * @param entity 实体 + * @return 返回处理后的实体 + */ + @Override + public HttpStringEntity hookHttpEntity(HttpStringEntity entity) { + entity.addHeader(new BasicHeader(WxConst.WECHATPAY_SERIAL, payConfigStorage.getCertEnvironment().getPlatformSerialNumber())); + return entity; + } /** * 返回创建的订单信息 @@ -148,19 +158,6 @@ public class WxProfitSharingService extends WxPayService implements ProfitSharin } - /** - * 签名 - * - * @param content 需要签名的内容 不包含key - * @param characterEncoding 字符编码 - * @return 签名结果 - */ - @Override - public String createSign(String content, String characterEncoding) { - PrivateKey privateKey = payConfigStorage.getCertEnvironment().getPrivateKey(); - return RSA2.sign(content, privateKey, characterEncoding); - } - /** * 将请求参数或者请求流转化为 Map * diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/bean/CertEnvironment.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/bean/CertEnvironment.java index c1c4360..4b226a3 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/bean/CertEnvironment.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/bean/CertEnvironment.java @@ -3,6 +3,8 @@ package com.egzosn.pay.wx.v3.bean; import java.security.PrivateKey; import java.security.PublicKey; +import com.egzosn.pay.common.util.str.StringUtils; + /** * 证书模式运行时环境 * @@ -32,8 +34,6 @@ public class CertEnvironment { private String platformSerialNumber; - - public CertEnvironment() { } @@ -68,6 +68,9 @@ public class CertEnvironment { } public String getPlatformSerialNumber() { + if (StringUtils.isEmpty(platformSerialNumber)) { + setPlatformSerialNumber(serialNumber); + } return platformSerialNumber; } diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/utils/WxConst.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/utils/WxConst.java index 38ab1bd..b491eb5 100644 --- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/utils/WxConst.java +++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/utils/WxConst.java @@ -83,6 +83,7 @@ public final class WxConst { public static final String OFFSET = "offset"; public static final String LIMIT = "limit"; public static final String DETAIL_STATUS = "detail_status"; + public static final String WECHATPAY_SERIAL = "Wechatpay-Serial"; }