Prechádzať zdrojové kódy

微信支付--小程序下单
微信支付--账单实体类

wujiefeng 1 rok pred
rodič
commit
7be275dcfb
29 zmenil súbory, kde vykonal 1006 pridanie a 18 odobranie
  1. 21 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/PrePayModel.java
  2. 27 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/WxNotifyResourceModel.java
  3. 18 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxAmount.java
  4. 32 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxNotifyParam.java
  5. 13 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxPayer.java
  6. 64 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxTransactionsParam.java
  7. 41 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/ret/CommentException.java
  8. 92 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultContent.java
  9. 33 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultException.java
  10. 11 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultMessage.java
  11. 38 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultState.java
  12. 17 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/types/PaymentType.java
  13. 22 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/types/WalletType.java
  14. 24 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/types/WxPayType.java
  15. 35 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/wxPaymentV3/WechatNotifyController.java
  16. 38 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/wxPaymentV3/WechatPayV3Controller.java
  17. 12 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/PrepayOrderDao.java
  18. 8 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/extend/PrepayOrderDaoExtend.java
  19. 10 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/impl/PrepayOrderDaoImpl.java
  20. 2 3
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/dataConfig/WxV3PayConfig.java
  21. 54 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/tradebill/Tradebill.java
  22. 2 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/wallet/Wallet.java
  23. 68 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/wechatPay/WxOrder.java
  24. 49 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/model/WxTransactionsModel.java
  25. 14 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wallet/WalletService.java
  26. 0 14
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPayment/WxPaymentService.java
  27. 78 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPaymentV3/WxPayNotifyService.java
  28. 182 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPaymentV3/WxPaymentService.java
  29. 1 1
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/wx/WechatCUtil.java

+ 21 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/PrePayModel.java

@@ -0,0 +1,21 @@
+package com.zhongshu.payment.client.model;
+
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+@Data
+public class PrePayModel {
+
+    private String timeStamp;
+
+    private String nonceStr;
+
+    private String packAge;
+
+    private String signType;
+
+    private String paySign;
+}

+ 27 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/WxNotifyResourceModel.java

@@ -0,0 +1,27 @@
+package com.zhongshu.payment.client.model;
+
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+public class WxNotifyResourceModel {
+
+    //加密算法
+    private String algorithm;
+
+    //Base64编码后的开启/停用结果数据密文
+    private String ciphertext;
+
+    //附加数据
+    private String associated_data;
+
+    //原始回调类型
+    private String original_type;
+
+    //加密使用的随机串
+    private String nonce;
+
+}

+ 18 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxAmount.java

@@ -0,0 +1,18 @@
+package com.zhongshu.payment.client.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+public class WxAmount {
+
+    @Schema(name = "金额(分)", required = true, example = "100")
+    private Integer total;
+
+    @Schema(name = "货币种类:境内支持人民币(CNY)", required = false, example = "CNY")
+    private String currency = "CNY";
+}

+ 32 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxNotifyParam.java

@@ -0,0 +1,32 @@
+package com.zhongshu.payment.client.model.param;
+
+import com.zhongshu.payment.client.model.WxNotifyResourceModel;
+import lombok.Data;
+
+/**
+ * 用于接受微信通知的参数
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+public class WxNotifyParam {
+
+    private String id;
+
+    //通知创建的时间
+    private String create_time;
+
+    //通知的类型
+    private String event_type;
+
+    //通知的资源数据类型
+    private String resource_type;
+
+    //通知资源数据
+    private WxNotifyResourceModel resource;
+
+    //回调摘要
+    private String summary;
+
+
+}

+ 13 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxPayer.java

@@ -0,0 +1,13 @@
+package com.zhongshu.payment.client.model.param;
+
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+public class WxPayer {
+
+    private String openid;
+}

+ 64 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/model/param/WxTransactionsParam.java

@@ -0,0 +1,64 @@
+package com.zhongshu.payment.client.model.param;
+
+import com.wechat.pay.java.service.refund.model.Amount;
+import com.zhongshu.payment.client.types.WxPayType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * 微信支付下单参数
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+public class WxTransactionsParam {
+
+//    // 公众号ID(必填)
+//    private String appid;
+//
+//    // 直连商户号(必填)
+//    private String mchid;
+
+    // 项目id
+    private String oid;
+
+    @Schema(name = "微信授权code",required = true, example = "21321")
+    private String jsCode;
+
+    // 商品描述(必填)
+    @Schema(name = "商品描述",required = true, example = "充值服务")
+    private String description;
+
+//    // 商户订单号(必填)
+//    private String outTradeNo;
+
+//    // 交易结束时间 yyyy-MM-DDTHH:mm:ss+TIMEZONE
+//    private String timeExpire;
+
+    // 附加数据
+    @Schema(name = "附加数据",required = false, example = "备注")
+    private String attach;
+
+//    // 通知地址(必填)
+//    private String notifyUrl;
+
+    // 订单金额(必填)
+    @Schema(name = "订单金额",required = true, example = "")
+    private WxAmount amount;
+
+//    // 支付者信息:openid(必填)
+//    private WxPayer payer;
+
+    // 交易地点
+    @Schema(name = "附加数据",required = true)
+    private String sceneInfo;
+
+    //下单类型
+    private WxPayType wxPayType;
+
+    //获取openid
+    private String jscode;
+
+}

+ 41 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/ret/CommentException.java

@@ -0,0 +1,41 @@
+package com.zhongshu.payment.client.ret;
+
+/**
+ * @Author: wy
+ * @Date: 2023/6/6 16:43
+ */
+public class CommentException extends RuntimeException {
+
+    private ResultState resultState;
+
+    private String message;
+
+    /**
+     * 参数校验异常构造方法
+     */
+    public CommentException(String message) {
+        this.message = message;
+    }
+
+    public CommentException(ResultState resultState, String message) {
+        this.resultState = resultState;
+        this.message = message;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public ResultState getResultState() {
+        return resultState;
+    }
+
+    public void setResultState(ResultState resultState) {
+        this.resultState = resultState;
+    }
+}

+ 92 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultContent.java

@@ -0,0 +1,92 @@
+package com.zhongshu.payment.client.ret;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.*;
+
+import java.util.Optional;
+
+/**
+ * 结果
+ *
+ * @param <T>
+ */
+@Builder
+@ToString(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultContent<T> {
+
+    //内容
+    @Getter
+    @Setter
+    private T content;
+
+    //状态
+    @Getter
+    @Setter
+    private ResultState state;
+
+    //文本
+    @Getter
+    @Setter
+    private String msg;
+
+
+    //异常
+    @Getter
+    @Setter
+    private ResultException exception;
+
+
+    /**
+     * 获取内容
+     *
+     * @return
+     */
+    public Optional<T> optionalContent() {
+        return Optional.ofNullable(this.content);
+    }
+
+    public static <T> ResultContent build(ResultState state, T content) {
+        return ResultContent.builder().state(state).content(content).msg(state.getRemark()).build();
+    }
+
+    public static <T> ResultContent build(boolean bool) {
+        return build(bool ? ResultState.Success : ResultState.Fail, null);
+    }
+
+    public static <T> ResultContent build(ResultState state) {
+        return build(state, null);
+    }
+
+    public static <T> ResultContent buildContent(T content) {
+        return build(content == null ? ResultState.Fail : ResultState.Success, content);
+    }
+
+    public static <T> ResultContent buildFail(String msg) {
+        return ResultContent.builder().state(ResultState.Fail).msg(msg).build();
+    }
+
+    public static <T> ResultContent buildSuccess(String msg) {
+        return build(ResultState.Success, msg);
+    }
+
+    public static <T> ResultContent buildSuccess(T content) {
+        return build(ResultState.Success, content);
+    }
+
+    public static <T> ResultContent buildSuccess() {
+        return build(ResultState.Success, ResultState.Success.getRemark());
+    }
+
+    public boolean isSuccess()
+    {
+        return ResultState.Success.equals(this.state);
+    }
+
+    public boolean isFailed()
+    {
+        return !ResultState.Success.equals(this.state);
+    }
+}

+ 33 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultException.java

@@ -0,0 +1,33 @@
+package com.zhongshu.payment.client.ret;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 结果集异常
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultException {
+
+    private String type;
+    private String cls;
+    private String message;
+
+
+    /**
+     * 创建异常对象
+     *
+     * @param e
+     * @return
+     */
+    public static ResultException build(Exception e) {
+        ResultException exception = new ResultException();
+        exception.type = e.getClass().getSimpleName();
+        exception.cls = e.getClass().getName();
+        exception.message = e.getMessage();
+        return exception;
+    }
+}

+ 11 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultMessage.java

@@ -0,0 +1,11 @@
+package com.zhongshu.payment.client.ret;
+
+/**
+ * @author TRX
+ * @date 2024/5/31
+ */
+public class ResultMessage {
+    public static final String DATA_NOT_EXIST = "数据不存在:%s";
+
+    public static final String NAME_EXIST = "名称已存在:%s";
+}

+ 38 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/ret/ResultState.java

@@ -0,0 +1,38 @@
+package com.zhongshu.payment.client.ret;
+
+import lombok.Getter;
+
+/**
+ * 结果状态模板
+ */
+public enum ResultState {
+
+    Success("成功"),
+    Fail("失败"),
+    Error("错误"),
+    Exception("异常"),
+    Robot("机器验证"),
+
+    UserExit("用户存在"),
+    UserNotExit("用户不存在"),
+    UserOrPassWordError("用户名或密码错误"),
+
+    NOT_TOKEN_ERROR("token获取失败"),
+    NOT_AUTH_ERROR("需要授权"),
+    EXPIRE_ERROR( "token已过期"),
+    INVALID_TOKEN("无效token"),
+    LOGIN_REQUIRED("需要登录"),
+    CODE_ERROR("验证码错误"),
+
+    AccountNotNull("账户不能为空"),
+    AccountExists("用户存在"),
+    AccountNotExists("账户不存在"),
+    ;
+
+    @Getter
+    private String remark;
+
+    ResultState(String remark) {
+        this.remark = remark;
+    }
+}

+ 17 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/types/PaymentType.java

@@ -0,0 +1,17 @@
+package com.zhongshu.payment.client.types;
+
+import lombok.Getter;
+
+public enum PaymentType {
+    Wechat("微信"),
+    UnionPay("银联"),
+
+    ;
+
+    @Getter
+    private String remark;
+
+    PaymentType(String remark) {
+        this.remark = remark;
+    }
+}

+ 22 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/types/WalletType.java

@@ -0,0 +1,22 @@
+package com.zhongshu.payment.client.types;
+
+import lombok.Getter;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+public enum WalletType {
+
+    Project("项目(商户)"),
+    SubProject("子项目(子商户)"),
+    H5("h5"),
+    ;
+
+    @Getter
+    private String remark;
+
+    WalletType(String remark) {
+        this.remark = remark;
+    }
+}

+ 24 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/types/WxPayType.java

@@ -0,0 +1,24 @@
+package com.zhongshu.payment.client.types;
+
+import lombok.Getter;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+public enum WxPayType {
+
+    Mini("小程序"),
+    H5("h5"),
+    App("app"),
+    JSAPI("JSAPI"),
+    Native("扫码支付"),
+    ;
+
+    @Getter
+    private String remark;
+
+    WxPayType(String remark) {
+        this.remark = remark;
+    }
+}

+ 35 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/wxPaymentV3/WechatNotifyController.java

@@ -0,0 +1,35 @@
+package com.zhongshu.payment.server.core.controller.wxPaymentV3;
+
+import com.zhongshu.payment.server.core.service.wxPaymentV3.WxPayNotifyService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Slf4j
+@RestController
+@RequestMapping("/wechat/v3/notify")
+@Tag(name = "微信支付通知回调")
+public class WechatNotifyController {
+
+    @Autowired
+    WxPayNotifyService wxPayNotifyService;
+
+
+    @Operation(summary = "支付通知回调")
+    @PostMapping(value = "payNotify", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public void payNotify(HttpServletRequest request){
+        log.info("收到微信支付通知");
+        wxPayNotifyService.payNotify(request);
+    }
+}

+ 38 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/wxPaymentV3/WechatPayV3Controller.java

@@ -0,0 +1,38 @@
+package com.zhongshu.payment.server.core.controller.wxPaymentV3;
+
+import com.zhongshu.payment.client.model.param.WxTransactionsParam;
+import com.zhongshu.payment.client.ret.ResultContent;
+import com.zhongshu.payment.server.core.service.wxPaymentV3.WxPaymentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Slf4j
+@RestController
+@RequestMapping("/wechat/v3/pay")
+@Tag(name = "微信支付接口")
+public class WechatPayV3Controller {
+
+    @Autowired
+    WxPaymentService wxPaymentService;
+
+    @Operation(summary = "下单")
+    @PostMapping(value = "transactions", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public Object transactions(@RequestBody WxTransactionsParam param){
+        return wxPaymentService.prepay(param);
+    }
+
+    @Operation(summary = "获取openid")
+    @GetMapping (value = "getOpenid")
+    public Object transactions(@Parameter(name = "jscode")@RequestParam(name = "jscode") String jscode){
+        return wxPaymentService.getOpenid(jscode);
+    }
+}

+ 12 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/PrepayOrderDao.java

@@ -0,0 +1,12 @@
+package com.zhongshu.payment.server.core.dao;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.payment.server.core.dao.extend.PrepayOrderDaoExtend;
+import com.zhongshu.payment.server.core.domain.wechatPay.PrepayOrder;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+public interface PrepayOrderDao extends MongoDao<PrepayOrder>, PrepayOrderDaoExtend {
+}

+ 8 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/extend/PrepayOrderDaoExtend.java

@@ -0,0 +1,8 @@
+package com.zhongshu.payment.server.core.dao.extend;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+public interface PrepayOrderDaoExtend {
+}

+ 10 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/impl/PrepayOrderDaoImpl.java

@@ -0,0 +1,10 @@
+package com.zhongshu.payment.server.core.dao.impl;
+
+import com.zhongshu.payment.server.core.dao.extend.PrepayOrderDaoExtend;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+public class PrepayOrderDaoImpl implements PrepayOrderDaoExtend {
+}

+ 2 - 3
PaymentServer/src/main/java/com/zhongshu/payment/server/core/dataConfig/WxV3PayConfig.java

@@ -28,9 +28,8 @@ public class WxV3PayConfig {
     //认证类型
     public static String AuthenticationType = "WECHATPAY2-SHA256-RSA2048";
 
-    //
-    public static String keyAlias = "Tenpay Certificate";
+    //私钥地址
+    public static String privateKeyPath = "D:/WJF/ZSWL/application/PaymentCenter/PaymentServer/src/main/resources/apiclient_key.pem";
 
-    public static String keyPath = "";
 
 }

+ 54 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/tradebill/Tradebill.java

@@ -0,0 +1,54 @@
+package com.zhongshu.payment.server.core.domain.tradebill;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.payment.client.types.PaymentType;
+import com.zhongshu.payment.server.core.domain.wallet.Wallet;
+import com.zhongshu.payment.server.core.domain.wechatPay.WxOrder;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 账单
+ * @author wjf
+ * @date 2024/7/24
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class Tradebill extends SuperEntity {
+
+    @DBRef(lazy = true)
+    @Schema(name = "关联账户")
+    private Wallet wallet;
+
+    @Schema(name = "支付类型")
+    private PaymentType paymentType;
+
+    @Schema(name = "交易金额(分)")
+    private BigDecimal amount = BigDecimal.ZERO;
+
+    @Schema(name = "订单状态")
+    private String state;
+
+    @Schema(name = "收入/支出")
+    private String s;
+
+    @Schema(name = "交易时间")
+    private Long tradeTime;
+
+    @Schema(name = "关联微信订单")
+    @DBRef(lazy = true)
+    private WxOrder wxOrder;
+
+    @Schema(name = "关联银联订单")
+    private WxOrder unionOrder;
+}

+ 2 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/wallet/Wallet.java

@@ -1,6 +1,7 @@
 package com.zhongshu.payment.server.core.domain.wallet;
 
 import com.zhongshu.payment.client.types.DataState;
+import com.zhongshu.payment.client.types.WalletType;
 import com.zhongshu.payment.server.core.domain.base.SuperMain;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
@@ -33,4 +34,5 @@ public class Wallet extends SuperMain {
     @Schema(description = "钱包状态:是否可用")
     private DataState dataState = DataState.Enable;
 
+    private WalletType walletType;
 }

+ 68 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/wechatPay/WxOrder.java

@@ -0,0 +1,68 @@
+package com.zhongshu.payment.server.core.domain.wechatPay;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * 预支付交易单
+ * @author wjf
+ * @date 2024/7/22
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class WxOrder extends SuperEntity {
+
+//    @Schema(description = "项目id")
+//    private String oid;
+//
+//    @Schema(description = "用户id")
+//    private String userId;
+
+    @Schema(description = "appId")
+    private String appId;
+
+    @Schema(description = "直连商户号")
+    private String mchId;
+
+    @Schema(description = "商品描述")
+    private String description;
+
+    @Schema(description = "充值订单号")
+    private String outTradeNo;
+
+    @Schema(description = "交易结束时间(订单失效时间)")
+    private String expireTime;
+
+    @Schema(description = "附加数据")
+    private String attach;
+
+    @Schema(description = "回调通知地址")
+    private String notifyUrl;
+
+    @Schema(description = "订单优惠标记")
+    private String goodsTag;
+
+    @Schema(description = "电子发票入口开放标识")
+    private Boolean supportFapiao;
+
+    @Schema(description = "金额(分)")
+    private Integer total;
+
+    @Schema(name = "货币种类:境内支持人民币(CNY)")
+    private String currency = "CNY";
+
+    @Schema(description = "openId")
+    private String openId;
+
+    @Schema(description = "支付时间")
+    private Long payTime;
+
+}

+ 49 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/model/WxTransactionsModel.java

@@ -0,0 +1,49 @@
+package com.zhongshu.payment.server.core.model;
+
+import com.zhongshu.payment.client.model.param.WxAmount;
+import com.zhongshu.payment.client.model.param.WxPayer;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Map;
+
+/**
+ * 微信支付--下单请求参数
+ * @author wjf
+ * @date 2024/7/23
+ */
+@Data
+@Accessors(chain = true)
+public class WxTransactionsModel {
+
+    // 公众号ID(必填)
+    private String appid;
+
+    // 直连商户号(必填)
+    private String mchid;
+
+    // 商品描述(必填)
+    private String description;
+
+    // 商户订单号(必填)
+    private String out_trade_no;
+
+    // 交易结束时间 yyyy-MM-DDTHH:mm:ss+TIMEZONE
+    private String timeExpire;
+
+    // 附加数据
+    private String attach;
+
+    // 通知地址(必填)
+    private String notify_url;
+
+    // 订单金额(必填)
+    private WxAmount amount;
+
+    // 支付者信息:openid(必填)
+    private WxPayer payer;
+
+    // 交易地点
+    private String sceneInfo;
+
+}

+ 14 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wallet/WalletService.java

@@ -0,0 +1,14 @@
+package com.zhongshu.payment.server.core.service.wallet;
+
+import groovy.util.logging.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+
+@Slf4j
+@Service
+public class WalletService {
+}

+ 0 - 14
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPayment/WxPaymentService.java

@@ -1,14 +0,0 @@
-package com.zhongshu.payment.server.core.service.wxPayment;
-
-import com.zhongshu.payment.server.core.service.base.SuperService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-/**
- * @author TRX
- * @date 2024/7/22
- */
-@Slf4j
-@Service
-public class WxPaymentService extends SuperService {
-}

+ 78 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPaymentV3/WxPayNotifyService.java

@@ -0,0 +1,78 @@
+package com.zhongshu.payment.server.core.service.wxPaymentV3;
+
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.notification.NotificationConfig;
+import com.wechat.pay.java.core.notification.NotificationParser;
+import com.wechat.pay.java.core.notification.RequestParam;
+import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
+import com.zhongshu.payment.server.core.dataConfig.WxV3PayConfig;
+import groovy.util.logging.Slf4j;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jline.internal.Log;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;
+import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.WECHAT_PAY_SIGNATURE;
+
+/**
+ * @author wjf
+ * @date 2024/7/24
+ */
+@Service
+@Slf4j
+public class WxPayNotifyService {
+
+    public void payNotify(HttpServletRequest request) {
+        try {
+            //读取请求体的信息
+            ServletInputStream inputStream = request.getInputStream();
+            StringBuffer stringBuffer = new StringBuffer();
+            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+            String s;
+            //读取回调请求体
+            while ((s = bufferedReader.readLine()) != null) {
+                stringBuffer.append(s);
+            }
+            String body = stringBuffer.toString();
+            String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
+            String nonce = request.getHeader(WECHAT_PAY_NONCE);
+            String signType = request.getHeader("Wechatpay-Signature-Type");
+            String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
+            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
+            // 如果已经初始化了 RSAAutoCertificateConfig,可直接使用
+            // 没有的话,则构造一个
+//            log.error(JSON.toJSONString(wxPayV3Bean));
+            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
+                    .merchantId(WxV3PayConfig.Mch_ID)
+                    .privateKeyFromPath(WxV3PayConfig.privateKeyPath)
+                    .merchantSerialNumber(WxV3PayConfig.mchSerialNo)
+                    .apiV3Key(WxV3PayConfig.apiV3Key)
+                    .build();
+            // 初始化 NotificationParser
+            NotificationParser parser = new NotificationParser(config);
+            RequestParam requestParam=new RequestParam.Builder()
+                    .serialNumber(serialNo)
+                    .nonce(nonce)
+                    .signature(signature)
+                    .timestamp(timestamp)
+                    // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
+                    .signType(signType)
+                    .body(body)
+                    .build();
+            Transaction parse = parser.parse(requestParam, Transaction.class);
+            System.out.println("parse = " + parse);
+            //parse.getTradeState().equals("SUCCESS");说明支付成功
+            if (parse.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){
+                //你的业务代码
+                Log.info("微信支付成功");
+            }
+            Log.info("微信支付异常:{}", parse.getTradeState());
+        } catch (Exception e) {
+            Log.info("微信支付回调验签错误:{}", e.getMessage());
+        }
+    }
+}

+ 182 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/wxPaymentV3/WxPaymentService.java

@@ -0,0 +1,182 @@
+package com.zhongshu.payment.server.core.service.wxPaymentV3;
+
+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.notification.NotificationConfig;
+import com.wechat.pay.java.core.notification.NotificationParser;
+import com.wechat.pay.java.core.notification.RequestParam;
+import com.wechat.pay.java.core.util.NonceUtil;
+import com.wechat.pay.java.core.util.PemUtil;
+import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
+import com.wechat.pay.java.service.payments.jsapi.model.Amount;
+import com.wechat.pay.java.service.payments.jsapi.model.Payer;
+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.wechat.MiniAppUserInfoVo;
+import com.zhongshu.payment.client.model.PrePayModel;
+import com.zhongshu.payment.client.model.param.WxTransactionsParam;
+import com.zhongshu.payment.client.ret.ResultContent;
+import com.zhongshu.payment.client.ret.ResultState;
+import com.zhongshu.payment.server.core.dataConfig.WxV3PayConfig;
+import com.zhongshu.payment.server.core.service.base.SuperService;
+import com.zhongshu.payment.server.core.utils.wx.WechatCUtil;
+import io.netty.util.internal.StringUtil;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jline.internal.Log;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+import static cn.hutool.crypto.SignUtil.sign;
+import static cn.hutool.crypto.SignUtil.signParamsSha256;
+import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;
+import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.WECHAT_PAY_SIGNATURE;
+
+/**
+ * @author TRX
+ * @date 2024/7/22
+ */
+@Slf4j
+@Service
+public class WxPaymentService extends SuperService {
+
+    @Autowired
+    WechatCUtil wechatCUtil;
+
+    public static com.wechat.pay.java.service.payments.jsapi.JsapiService service;
+
+    // 初始化商户配置
+    public Config RSAAutoCertificateConfig(){
+        return new RSAAutoCertificateConfig.Builder()
+                .merchantId(WxV3PayConfig.Mch_ID)
+                // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+                .privateKeyFromPath(WxV3PayConfig.privateKeyPath)
+                .merchantSerialNumber(WxV3PayConfig.mchSerialNo)
+                .apiV3Key(WxV3PayConfig.apiV3Key)
+                .build();
+    }
+
+    @SneakyThrows
+    public Object getOpenid(String jscode){
+        MiniAppUserInfoVo miniAppUserInfo = wechatCUtil.getMiniAppUserInfo(jscode);
+        if (miniAppUserInfo==null || StringUtil.isNullOrEmpty(miniAppUserInfo.getOpenid())){
+            log.info("无法获取用户信息");
+            return ResultContent.buildFail("无法获取用户信息");
+        }
+        log.info("用户openid:{}", miniAppUserInfo.getOpenid());
+        return ResultContent.buildContent(miniAppUserInfo);
+    }
+
+    @SneakyThrows
+    public String getOpenId(String jscode){
+        MiniAppUserInfoVo miniAppUserInfo = wechatCUtil.getMiniAppUserInfo(jscode);
+        if (miniAppUserInfo==null || StringUtil.isNullOrEmpty(miniAppUserInfo.getOpenid())){
+            log.info("无法获取用户信息");
+            return null;
+        }
+        log.info("用户openid:{}", miniAppUserInfo.getOpenid());
+        return miniAppUserInfo.getOpenid();
+    }
+
+    /** @Author wjf
+     * @Description //TODO 预支付下单
+     * @Date 2024/7/24
+     * @Param
+     * @return
+    **/
+    public ResultContent prepay(WxTransactionsParam param){
+
+        String openId = getOpenId(param.getJscode());
+        if (StringUtil.isNullOrEmpty(openId)){
+            return ResultContent.buildFail("获取用户openid失败");
+        }
+        // 初始化商户配置
+        Config config = RSAAutoCertificateConfig();
+        // 初始化服务
+        service = new com.wechat.pay.java.service.payments.jsapi.JsapiService.Builder().config(config).build();
+        // ... 调用接口
+        try {
+            PrepayRequest request = new PrepayRequest();
+            // 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
+            // 调用接口
+            request.setAppid("wx92ae04fb0f325887");
+            request.setMchid("1680033836");
+            request.setDescription("充值服务");
+            request.setOutTradeNo("A1111111");
+            request.setNotifyUrl("http://8.137.120.225:8080/paymentserver-wjf/wechat/v3/notify/payNotify");
+            Amount amount = new Amount();
+            amount.setTotal(10);
+            amount.setCurrency("CNY");
+            request.setAmount(amount);
+            Payer payer = new Payer();
+            payer.setOpenid("oSd8L7Wlucyn7a8g3SZCOeLrSUKY");
+            request.setPayer(payer);
+            PrepayResponse response = service.prepay(request);
+
+            PrePayModel prePayModel = buildPrepayResultModel(response);
+            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("编码错误");
+        }
+    }
+
+    @NotNull
+    private PrePayModel buildPrepayResultModel(PrepayResponse response) throws UnsupportedEncodingException {
+        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(WxV3PayConfig.APP_ID, timeStamp, prePayModel.getNonceStr(), prePayModel.getPackAge());
+        String signature = sign(WxV3PayConfig.privateKeyPath, sign.getBytes("utf-8"));
+        prePayModel.setPaySign(signature);
+        return prePayModel;
+    }
+
+    @SneakyThrows
+    public String sign(String privateKeyPath, byte[] message){
+        Signature sign = Signature.getInstance("SHA256withRSA");
+        PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(WxV3PayConfig.privateKeyPath);
+        sign.initSign(privateKey);
+        sign.update(message);
+        return Base64.getEncoder().encodeToString(sign.sign());
+    }
+
+    public String buildMessage(String appid, long timestamp, String nonceStr, String prepayId) {
+
+        return appid + "\n"
+                + timestamp + "\n"
+                + nonceStr + "\n"
+                + prepayId + "\n";
+    }
+}

+ 1 - 1
PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/wx/WechatCUtil.java

@@ -127,7 +127,7 @@ public class WechatCUtil {
     }
 
     public MiniAppUserInfoVo getMiniAppUserInfo(String jsCode) throws Exception {
-        String url = String.format(WECHAT_MINI_APP_AUTH_URL, wechatAuthConfig.getAppid(), wechatAuthConfig.getSecret(), jsCode, "authorization_code");
+        String url = String.format(WECHAT_MINI_APP_AUTH_URL, "wx92ae04fb0f325887", "09c789bfa6d6b66362c0794468a4470a", jsCode, "authorization_code");
         ResponseModel request = HttpClientUtil.request(HttpModel.builder().url(url).build());
         if (200 == request.getCode()) {
             MiniAppUserInfoVo miniAppUserInfoVo = BeanUtil.copyProperties(