|
|
@@ -1,122 +0,0 @@
|
|
|
-package com.zhongshu.payment.server.core.service.pay.impl;
|
|
|
-
|
|
|
-import com.github.microservice.models.type.PaymentType;
|
|
|
-import com.wechat.pay.java.core.Config;
|
|
|
-import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
|
|
-import com.wechat.pay.java.core.exception.HttpException;
|
|
|
-import com.wechat.pay.java.core.exception.MalformedMessageException;
|
|
|
-import com.wechat.pay.java.core.exception.ServiceException;
|
|
|
-import com.wechat.pay.java.core.util.NonceUtil;
|
|
|
-import com.wechat.pay.java.core.util.PemUtil;
|
|
|
-import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
|
|
|
-import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
|
|
|
-import com.zhongshu.card.client.model.payment.paySetting.WxPayConfigModel;
|
|
|
-import com.zhongshu.payment.client.annotation.PayAnnotationService;
|
|
|
-import com.zhongshu.payment.client.model.PrePayModel;
|
|
|
-import com.github.microservice.net.ResultContent;
|
|
|
-import com.zhongshu.payment.server.core.service.pay.SuperPayService;
|
|
|
-import lombok.SneakyThrows;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
-
|
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
-import java.security.PrivateKey;
|
|
|
-import java.security.Signature;
|
|
|
-import java.util.Base64;
|
|
|
-
|
|
|
-/**
|
|
|
- * @author TRX
|
|
|
- * @date 2024/8/21
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Component
|
|
|
-@PayAnnotationService(paymentType = PaymentType.WeChat, remark = "微信支付方式")
|
|
|
-public class WeChatPayService extends SuperPayService {
|
|
|
-
|
|
|
- public static com.wechat.pay.java.service.payments.jsapi.JsapiService service;
|
|
|
-
|
|
|
- // 初始化商户配置
|
|
|
- public static Config RSAAutoCertificateConfig(String mchId, String privateKeyPath, String mchSerialNo, String apiV3Key) {
|
|
|
- return new RSAAutoCertificateConfig.Builder()
|
|
|
- .merchantId(mchId)
|
|
|
- // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
|
|
- .privateKeyFromPath(privateKeyPath)
|
|
|
- .merchantSerialNumber(mchSerialNo)
|
|
|
- .apiV3Key(apiV3Key)
|
|
|
- .build();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 支付下单
|
|
|
- *
|
|
|
- * @param request
|
|
|
- * @param configModel
|
|
|
- * @return
|
|
|
- */
|
|
|
- @Override
|
|
|
- public ResultContent<PrePayModel> createOrder(PrepayRequest request, WxPayConfigModel configModel) {
|
|
|
- String privateKeyPath = configModel.getPrivateKeyPath();
|
|
|
- if (configModel.getPrivateKeyType().equals("local")) {
|
|
|
- privateKeyPath = Thread.currentThread().getContextClassLoader().getResource("").getPath() + configModel.getPrivateKeyPath();
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化商户配置
|
|
|
- Config config = RSAAutoCertificateConfig(configModel.getMchId(), privateKeyPath, configModel.getMchSerialNo(), configModel.getApiV3Key());
|
|
|
- // 初始化服务
|
|
|
- service = new com.wechat.pay.java.service.payments.jsapi.JsapiService.Builder().config(config).build();
|
|
|
- // ... 调用接口
|
|
|
- try {
|
|
|
- // 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
|
|
|
- request.setAppid(configModel.getAppId());
|
|
|
- request.setMchid(configModel.getMchId());
|
|
|
- request.setNotifyUrl("https://api.dev.qk.zonelife.cn/paymentserver/wechat/v3/notify/payNotify/" + request.getOutTradeNo());
|
|
|
-// request.setNotifyUrl(configModel.getNotifyUrl());
|
|
|
- // 调用接口
|
|
|
- PrepayResponse response = service.prepay(request);
|
|
|
-
|
|
|
- PrePayModel prePayModel = new PrePayModel();
|
|
|
- prePayModel.setNonceStr(NonceUtil.createNonce(10));
|
|
|
- prePayModel.setPackAge("prepay_id=" + response.getPrepayId());
|
|
|
- prePayModel.setSignType("RSA");
|
|
|
- long timeStamp = System.currentTimeMillis() / 1000;
|
|
|
- prePayModel.setTimeStamp(Long.toString(timeStamp));
|
|
|
-
|
|
|
- String sign = buildMessage(configModel.getAppId(), timeStamp, prePayModel.getNonceStr(), prePayModel.getPackAge());
|
|
|
- String signature = sign(privateKeyPath, sign.getBytes("utf-8"));
|
|
|
- prePayModel.setPaySign(signature);
|
|
|
- return ResultContent.buildContent(prePayModel);
|
|
|
- } catch (HttpException e) { // 发送HTTP请求失败
|
|
|
- // 调用e.getHttpRequest()获取请求打印日志或上报监控,更多方法见HttpException定义
|
|
|
- log.info("请求失败1:{}", e.getHttpRequest());
|
|
|
- return ResultContent.buildFail("发送HTTP请求失败");
|
|
|
- } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
|
|
|
- // 调用e.getResponseBody()获取返回体打印日志或上报监控,更多方法见ServiceException定义
|
|
|
- log.info("请求失败2:{}", e.getResponseBody());
|
|
|
- return ResultContent.buildFail(e.getErrorMessage());
|
|
|
- } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
|
|
|
- // 调用e.getMessage()获取信息打印日志或上报监控,更多方法见MalformedMessageException定义
|
|
|
- log.info("请求失败3:{}", e.getMessage());
|
|
|
- return ResultContent.buildFail("服务返回成功,返回体类型不合法,或者解析返回体失败");
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- log.info("请求失败4:{}", e.getMessage());
|
|
|
- return ResultContent.buildFail("编码错误");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @SneakyThrows
|
|
|
- public String sign(String privateKeyPath, byte[] message) {
|
|
|
- Signature sign = Signature.getInstance("SHA256withRSA");
|
|
|
- PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(privateKeyPath);
|
|
|
- sign.initSign(privateKey);
|
|
|
- sign.update(message);
|
|
|
- return Base64.getEncoder().encodeToString(sign.sign());
|
|
|
- }
|
|
|
-
|
|
|
- private String buildMessage(String appid, long timestamp, String nonceStr, String prepayId) {
|
|
|
- return appid + "\n"
|
|
|
- + timestamp + "\n"
|
|
|
- + nonceStr + "\n"
|
|
|
- + prepayId + "\n";
|
|
|
- }
|
|
|
-
|
|
|
-}
|