From 18118188e370e45f6e1bd43e5b33fd4c4a156655 Mon Sep 17 00:00:00 2001
From: lin <sbla5888@163.com>
Date: Mon, 08 Apr 2024 16:01:44 +0800
Subject: [PATCH] 微信支付+获取用户的openid

---
 src/main/java/org/springblade/common/config/WxMiniConfig.java                                    |   21 
 src/main/java/org/springblade/modules/pay/entity/RefundInfoEntity.java                           |  102 +
 src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.xml             |   79 +
 src/main/java/org/springblade/common/config/WxPayConfig.java                                     |   39 
 src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java                               |   13 
 src/main/java/org/springblade/modules/wechat/service/WechatService.java                          |   12 
 src/main/java/org/springblade/modules/pay/service/IRefundInfoService.java                        |   46 
 src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.java                           |   60 +
 src/main/java/org/springblade/modules/pay/controller/RefundInfoController.java                   |  125 ++
 src/main/java/org/springblade/modules/pay/service/IWxPayService.java                             |   31 
 src/main/java/org/springblade/modules/pay/controller/WxPayController.java                        |  139 +-
 src/main/java/org/springblade/modules/pay/vo/RefundInfoVO.java                                   |   34 
 src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.java            |   18 
 src/main/java/org/springblade/modules/pay/entity/WeChatMiniAuthorizeVo.java                      |   39 
 src/main/java/org/springblade/modules/pay/service/impl/RefundInfoServiceImpl.java                |  118 ++
 src/main/java/org/springblade/modules/pay/wrapper/PaymentInfoWrapper.java                        |   51 
 src/main/java/org/springblade/modules/pay/controller/OrderInfoController.java                    |  135 ++
 src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.java                            |   44 
 src/main/java/org/springblade/modules/wechat/service/impl/WechatServiceImpl.java                 |   59 +
 src/main/java/org/springblade/modules/pay/dto/PaymentInfoDTO.java                                |   34 
 src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.xml                             |   15 
 src/main/java/org/springblade/modules/pay/vo/PaymentInfoVO.java                                  |   34 
 src/main/java/org/springblade/modules/property/dto/PropertyChargeRecordDTO.java                  |   18 
 src/main/java/org/springblade/modules/pay/vo/OrderInfoVO.java                                    |   34 
 src/main/java/org/springblade/modules/pay/service/impl/PaymentInfoServiceImpl.java               |   88 +
 src/main/java/org/springblade/modules/pay/wrapper/RefundInfoWrapper.java                         |   51 
 src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java                     |  732 +++++++++++--
 src/main/java/org/springblade/modules/pay/controller/PaymentInfoController.java                  |  125 ++
 src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.java                          |   59 +
 src/main/java/org/springblade/modules/pay/service/IPaymentInfoService.java                       |   45 
 src/main/java/org/springblade/modules/pay/dto/OrderInfoDTO.java                                  |   34 
 src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.xml                            |   71 +
 src/main/java/org/springblade/modules/pay/entity/PaymentInfoEntity.java                          |   95 +
 src/main/java/org/springblade/modules/system/entity/User.java                                    |    4 
 src/main/java/org/springblade/modules/pay/service/IOrderInfoService.java                         |   59 +
 src/main/java/org/springblade/modules/pay/wrapper/OrderInfoWrapper.java                          |   51 
 src/main/java/org/springblade/modules/property/service/impl/PropertyChargeRecordServiceImpl.java |    3 
 src/main/java/org/springblade/modules/pay/dto/RefundInfoDTO.java                                 |   34 
 src/main/java/org/springblade/modules/property/entity/PropertyChargeRecord.java                  |  108 +
 src/main/java/org/springblade/modules/pay/entity/OrderInfoEntity.java                            |  100 +
 src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.xml                           |   64 +
 src/main/java/org/springblade/modules/wechat/controller/WechatController.java                    |   33 
 src/main/java/org/springblade/modules/property/service/IPropertyChargeRecordService.java         |    3 
 src/main/resources/application.yml                                                               |   15 
 src/main/java/org/springblade/modules/pay/service/impl/OrderInfoServiceImpl.java                 |  207 +++
 45 files changed, 3,071 insertions(+), 210 deletions(-)

diff --git a/src/main/java/org/springblade/common/config/WxMiniConfig.java b/src/main/java/org/springblade/common/config/WxMiniConfig.java
new file mode 100644
index 0000000..9972e29
--- /dev/null
+++ b/src/main/java/org/springblade/common/config/WxMiniConfig.java
@@ -0,0 +1,21 @@
+package org.springblade.common.config;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "wxmini") //读取wxmini节点
+@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
+@Slf4j
+public class WxMiniConfig {
+
+	// appid
+	private String appid;
+
+	// 小程序appSecret key
+	private String secret;
+
+	private String jscode2sessionUrl;
+}
diff --git a/src/main/java/org/springblade/common/config/WxPayConfig.java b/src/main/java/org/springblade/common/config/WxPayConfig.java
index 1c018b4..3d7edf1 100644
--- a/src/main/java/org/springblade/common/config/WxPayConfig.java
+++ b/src/main/java/org/springblade/common/config/WxPayConfig.java
@@ -18,9 +18,9 @@
 import java.security.PrivateKey;
 
 
-//@Configuration
+@Configuration
 // @PropertySource("classpath:wxpay.properties") //读取配置文件
-//@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
+@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
 @Data //使用set方法将wxpay节点中的值填充到当前类的属性中
 @Slf4j
 public class WxPayConfig {
@@ -111,8 +111,8 @@
 	 *
 	 * @return
 	 */
-//	@Bean
-	public ScheduledUpdateCertificatesVerifier getVerifier(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) {
+	@Bean
+	public ScheduledUpdateCertificatesVerifier getVerifier() {
 
 		log.info("获取签名验证器");
 
@@ -140,8 +140,8 @@
 	 * @param verifier
 	 * @return
 	 */
-//	@Bean(name = "wxPayClient")
-	public CloseableHttpClient getWxPayClient(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) {
+	@Bean(name = "wxPayClient")
+	public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier) {
 
 		log.info("获取httpClient");
 
@@ -150,7 +150,7 @@
 
 		WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
 			.withMerchant(mchId, mchSerialNo, privateKey)
-			.withValidator(new WechatPay2Validator(getVerifier(privateKeyPath, mchSerialNo, mchId, apiV3Key)));
+			.withValidator(new WechatPay2Validator(verifier));
 		// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
 
 		// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
@@ -159,5 +159,30 @@
 		return httpClient;
 	}
 
+	/**
+	 * 获取HttpClient,无需进行应答签名验证,跳过验签的流程
+	 */
+	@Bean(name = "wxPayNoSignClient")
+	public CloseableHttpClient getWxPayNoSignClient() {
+
+		//获取商户私钥
+		PrivateKey privateKey = getPrivateKey(privateKeyPath);
+
+		//用于构造HttpClient
+		WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
+			//设置商户信息
+			.withMerchant(mchId, mchSerialNo, privateKey)
+			//无需进行签名验证、通过withValidator((response) -> true)实现
+			.withValidator((response) -> true);
+
+		// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
+		CloseableHttpClient httpClient = builder.build();
+
+		log.info("== getWxPayNoSignClient END ==");
+
+		return httpClient;
+	}
+
 
 }
+
diff --git a/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java b/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java
index b0f4825..2eed92e 100644
--- a/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java
+++ b/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java
@@ -21,7 +21,18 @@
 	/**
 	 * 退款结果通知
 	 */
-	REFUND_NOTIFY("/wxPay/refunds/notify");
+	REFUND_NOTIFY("/wxPay/refunds/notify"),
+
+	/**
+	 * 添加分账接收方API
+	 */
+	RECEIVERS_ADD("/v3/profitsharing/receivers/add"),
+
+	/**
+	 * 创建分账订单API
+	 *
+	 */
+	PROFITSHARING_ORDERS("/v3/profitsharing/orders");
 
 	/**
 	 * 类型
diff --git a/src/main/java/org/springblade/modules/pay/controller/OrderInfoController.java b/src/main/java/org/springblade/modules/pay/controller/OrderInfoController.java
new file mode 100644
index 0000000..99bca25
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/controller/OrderInfoController.java
@@ -0,0 +1,135 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.modules.pay.vo.OrderInfoVO;
+import org.springblade.modules.pay.wrapper.OrderInfoWrapper;
+import org.springblade.modules.pay.service.IOrderInfoService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 订单信息 控制器
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("blade-orderInfo/orderInfo")
+@Api(value = "订单信息", tags = "订单信息接口")
+public class OrderInfoController extends BladeController {
+
+	private final IOrderInfoService orderInfoService;
+
+	/**
+	 * 订单信息 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入orderInfo")
+	public R<OrderInfoVO> detail(OrderInfoEntity orderInfo) {
+		OrderInfoEntity detail = orderInfoService.getOne(Condition.getQueryWrapper(orderInfo));
+		return R.data(OrderInfoWrapper.build().entityVO(detail));
+	}
+	/**
+	 * 订单信息 分页
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入orderInfo")
+	public R<IPage<OrderInfoVO>> list(OrderInfoEntity orderInfo, Query query) {
+		IPage<OrderInfoEntity> pages = orderInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(orderInfo));
+		return R.data(OrderInfoWrapper.build().pageVO(pages));
+	}
+
+	/**
+	 * 订单信息 自定义分页
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入orderInfo")
+	public R<IPage<OrderInfoVO>> page(OrderInfoVO orderInfo, Query query) {
+		IPage<OrderInfoVO> pages = orderInfoService.selectOrderInfoPage(Condition.getPage(query), orderInfo);
+		return R.data(pages);
+	}
+
+	/**
+	 * 订单信息 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入orderInfo")
+	public R save(@Valid @RequestBody OrderInfoEntity orderInfo) {
+		return R.status(orderInfoService.save(orderInfo));
+	}
+
+	/**
+	 * 创建订单信息
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入orderInfo")
+	public R save(@RequestParam Long propertyChargeRecordId) {
+		return R.data(orderInfoService.createOrderByPropertyChargeRecordId(propertyChargeRecordId));
+	}
+
+	/**
+	 * 订单信息 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入orderInfo")
+	public R update(@Valid @RequestBody OrderInfoEntity orderInfo) {
+		return R.status(orderInfoService.updateById(orderInfo));
+	}
+
+	/**
+	 * 订单信息 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入orderInfo")
+	public R submit(@Valid @RequestBody OrderInfoEntity orderInfo) {
+		return R.status(orderInfoService.saveOrUpdate(orderInfo));
+	}
+
+	/**
+	 * 订单信息 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(orderInfoService.removeBatchByIds(Func.toLongList(ids)));
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/controller/PaymentInfoController.java b/src/main/java/org/springblade/modules/pay/controller/PaymentInfoController.java
new file mode 100644
index 0000000..0c13196
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/controller/PaymentInfoController.java
@@ -0,0 +1,125 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import org.springblade.modules.pay.vo.PaymentInfoVO;
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.modules.pay.wrapper.PaymentInfoWrapper;
+import org.springblade.modules.pay.service.IPaymentInfoService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 支付信息 控制器
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("blade-paymentInfo/paymentInfo")
+@Api(value = "支付信息", tags = "支付信息接口")
+public class PaymentInfoController extends BladeController {
+
+	private final IPaymentInfoService paymentInfoService;
+
+	/**
+	 * 支付信息 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入paymentInfo")
+	public R<PaymentInfoVO> detail(PaymentInfoEntity paymentInfo) {
+		PaymentInfoEntity detail = paymentInfoService.getOne(Condition.getQueryWrapper(paymentInfo));
+		return R.data(PaymentInfoWrapper.build().entityVO(detail));
+	}
+	/**
+	 * 支付信息 分页
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入paymentInfo")
+	public R<IPage<PaymentInfoVO>> list(PaymentInfoEntity paymentInfo, Query query) {
+		IPage<PaymentInfoEntity> pages = paymentInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(paymentInfo));
+		return R.data(PaymentInfoWrapper.build().pageVO(pages));
+	}
+
+	/**
+	 * 支付信息 自定义分页
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入paymentInfo")
+	public R<IPage<PaymentInfoVO>> page(PaymentInfoVO paymentInfo, Query query) {
+		IPage<PaymentInfoVO> pages = paymentInfoService.selectPaymentInfoPage(Condition.getPage(query), paymentInfo);
+		return R.data(pages);
+	}
+
+	/**
+	 * 支付信息 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入paymentInfo")
+	public R save(@Valid @RequestBody PaymentInfoEntity paymentInfo) {
+		return R.status(paymentInfoService.save(paymentInfo));
+	}
+
+	/**
+	 * 支付信息 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入paymentInfo")
+	public R update(@Valid @RequestBody PaymentInfoEntity paymentInfo) {
+		return R.status(paymentInfoService.updateById(paymentInfo));
+	}
+
+	/**
+	 * 支付信息 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入paymentInfo")
+	public R submit(@Valid @RequestBody PaymentInfoEntity paymentInfo) {
+		return R.status(paymentInfoService.saveOrUpdate(paymentInfo));
+	}
+
+	/**
+	 * 支付信息 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(paymentInfoService.removeBatchByIds(Func.toLongList(ids)));
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/controller/RefundInfoController.java b/src/main/java/org/springblade/modules/pay/controller/RefundInfoController.java
new file mode 100644
index 0000000..9a88bd8
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/controller/RefundInfoController.java
@@ -0,0 +1,125 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import org.springblade.modules.pay.service.IRefundInfoService;
+import org.springblade.modules.pay.vo.RefundInfoVO;
+import org.springblade.modules.pay.wrapper.RefundInfoWrapper;
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 退款信息 控制器
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("blade-refundInfo/refundInfo")
+@Api(value = "退款信息", tags = "退款信息接口")
+public class RefundInfoController extends BladeController {
+
+	private final IRefundInfoService refundInfoService;
+
+	/**
+	 * 退款信息 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入refundInfo")
+	public R<RefundInfoVO> detail(RefundInfoEntity refundInfo) {
+		RefundInfoEntity detail = refundInfoService.getOne(Condition.getQueryWrapper(refundInfo));
+		return R.data(RefundInfoWrapper.build().entityVO(detail));
+	}
+	/**
+	 * 退款信息 分页
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入refundInfo")
+	public R<IPage<RefundInfoVO>> list(RefundInfoEntity refundInfo, Query query) {
+		IPage<RefundInfoEntity> pages = refundInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(refundInfo));
+		return R.data(RefundInfoWrapper.build().pageVO(pages));
+	}
+
+	/**
+	 * 退款信息 自定义分页
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入refundInfo")
+	public R<IPage<RefundInfoVO>> page(RefundInfoVO refundInfo, Query query) {
+		IPage<RefundInfoVO> pages = refundInfoService.selectRefundInfoPage(Condition.getPage(query), refundInfo);
+		return R.data(pages);
+	}
+
+	/**
+	 * 退款信息 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入refundInfo")
+	public R save(@Valid @RequestBody RefundInfoEntity refundInfo) {
+		return R.status(refundInfoService.save(refundInfo));
+	}
+
+	/**
+	 * 退款信息 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入refundInfo")
+	public R update(@Valid @RequestBody RefundInfoEntity refundInfo) {
+		return R.status(refundInfoService.updateById(refundInfo));
+	}
+
+	/**
+	 * 退款信息 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入refundInfo")
+	public R submit(@Valid @RequestBody RefundInfoEntity refundInfo) {
+		return R.status(refundInfoService.saveOrUpdate(refundInfo));
+	}
+
+	/**
+	 * 退款信息 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(refundInfoService.removeBatchByIds(Func.toLongList(ids)));
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/controller/WxPayController.java b/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
index 016e4c6..22df1f0 100644
--- a/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
+++ b/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
@@ -1,35 +1,32 @@
 package org.springblade.modules.pay.controller;
 
 import com.google.gson.Gson;
-import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springblade.common.config.WxPayConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springblade.common.utils.HttpUtils;
 import org.springblade.common.utils.WechatPay2ValidatorForRequest;
-import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.tool.api.R;
 import org.springblade.modules.pay.entity.WxPayInfo;
 import org.springblade.modules.pay.service.IWxPayService;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.Map;
 
+@CrossOrigin //跨域
 @RestController
-@AllArgsConstructor
-@RequestMapping("/wxpay")
-@Api(value = "微信支付接口", tags = "微信支付接口")
-public class WxPayController extends BladeController {
+@RequestMapping("/wxPay")
+@Api(tags = "网站微信支付APIv3")
+@Slf4j
+public class WxPayController {
 
-	private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);
-
+	@Resource
 	private IWxPayService wxPayService;
+
 
 	@PostMapping("/save")
 	public R save(@RequestBody WxPayInfo wxPayInfo) {
@@ -57,21 +54,22 @@
 		return R.data(wxPayService.getOpenId(code));
 	}
 
+
 	/**
 	 * jsapi下单
 	 *
-	 * @param productId
+	 * @param properChargeRecordId
 	 * @return
 	 * @throws Exception
 	 */
 	@ApiOperation("调用jsapi统一下单API")
 	@GetMapping("/jsapiPay")
-	public R jsapiPay(@RequestParam("productId") Long productId) throws Exception {
+	public R jsapiPay(@RequestParam("properChargeRecordId") Long properChargeRecordId) throws Exception {
 
-		logger.info("发起支付请求 v3");
+		log.info("发起支付请求 v3");
 
 		//返回支付二维码连接和订单号
-		Map<String, String> map = wxPayService.jsapiPay(productId);
+		Map<String, String> map = wxPayService.jsapiPay(properChargeRecordId);
 
 		return R.data(map);
 	}
@@ -83,55 +81,82 @@
 	@ApiOperation("支付通知")
 	@PostMapping("/native/notify")
 	public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
+		return wxPayService.nativeNotify(request, response);
+	}
 
-		Gson gson = new Gson();
-		Map<String, String> map = new HashMap<>();//应答对象
+	/**
+	 * 用户取消订单
+	 *
+	 * @param orderNo
+	 * @return
+	 * @throws Exception
+	 */
+	@ApiOperation("用户取消订单")
+	@PostMapping("/cancel/{orderNo}")
+	public R cancel(@PathVariable String orderNo) throws Exception {
 
-		try {
+		log.info("取消订单");
 
-			//处理通知参数
-			String body = HttpUtils.readData(request);
-			Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
-			String requestId = (String) bodyMap.get("id");
-			logger.info("支付通知的id ===> {}", requestId);
-			logger.info("支付通知的完整数据 ===> {}", body);
-			//int a = 9 / 0;
-			ScheduledUpdateCertificatesVerifier verifier = new WxPayConfig().getVerifier("111", "111", "111", "111");
-			//签名的验证
-			WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
-				= new WechatPay2ValidatorForRequest(verifier, requestId, body);
-			if (!wechatPay2ValidatorForRequest.validate(request)) {
-				logger.error("通知验签失败");
-				//失败应答
-				response.setStatus(500);
-				map.put("code", "ERROR");
-				map.put("message", "通知验签失败");
-				return gson.toJson(map);
-			}
-			logger.info("通知验签成功");
+		wxPayService.cancelOrder(orderNo);
+		return R.data("订单已取消");
+	}
 
-			//处理订单
-			wxPayService.processOrder(bodyMap);
+	/**
+	 * 查询订单
+	 *
+	 * @param orderNo
+	 * @return
+	 * @throws Exception
+	 */
+	@ApiOperation("查询订单")
+	@GetMapping("/query/{orderNo}")
+	public R queryOrder(@PathVariable String orderNo) throws Exception {
 
-			//应答超时
-			//模拟接收微信端的重复通知
-			// TimeUnit.SECONDS.sleep(5);
+		log.info("查询订单");
 
-			//成功应答
-			response.setStatus(200);
-			map.put("code", "SUCCESS");
-			map.put("message", "成功");
-			return gson.toJson(map);
+		String result = wxPayService.queryOrder(orderNo);
+		return R.data("result", result);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			//失败应答
-			response.setStatus(500);
-			map.put("code", "ERROR");
-			map.put("message", "失败");
-			return gson.toJson(map);
-		}
+	}
 
+
+	@ApiOperation("申请退款")
+	@PostMapping("/refunds/{orderNo}/{reason}")
+	public R refunds(@PathVariable String orderNo, @PathVariable String reason) throws Exception {
+
+		log.info("申请退款");
+		wxPayService.refund(orderNo, reason);
+		return R.success("退款申请成功");
+	}
+
+	/**
+	 * 查询退款
+	 *
+	 * @param refundNo
+	 * @return
+	 * @throws Exception
+	 */
+	@ApiOperation("查询退款")
+	@GetMapping("/query-refund/{refundNo}")
+	public R queryRefund(@PathVariable String refundNo) throws Exception {
+
+		log.info("查询退款");
+
+		String result = wxPayService.queryRefund(refundNo);
+		return R.data("result", result);
+	}
+
+
+	/**
+	 * 退款结果通知
+	 * 退款状态改变后,微信会把相关退款结果发送给商户。
+	 */
+	@ApiOperation("退款结果通知")
+	@PostMapping("/refunds/notify")
+	public String refundsNotify(HttpServletRequest request, HttpServletResponse response) {
+
+		log.info("退款通知执行");
+		return wxPayService.refundsNotify(request, response);
 	}
 
 
diff --git a/src/main/java/org/springblade/modules/pay/dto/OrderInfoDTO.java b/src/main/java/org/springblade/modules/pay/dto/OrderInfoDTO.java
new file mode 100644
index 0000000..de45776
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/dto/OrderInfoDTO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.dto;
+
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 订单信息 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OrderInfoDTO extends OrderInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/dto/PaymentInfoDTO.java b/src/main/java/org/springblade/modules/pay/dto/PaymentInfoDTO.java
new file mode 100644
index 0000000..0eca252
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/dto/PaymentInfoDTO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.dto;
+
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 支付信息 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PaymentInfoDTO extends PaymentInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/dto/RefundInfoDTO.java b/src/main/java/org/springblade/modules/pay/dto/RefundInfoDTO.java
new file mode 100644
index 0000000..41b82ac
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/dto/RefundInfoDTO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.dto;
+
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 退款信息 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RefundInfoDTO extends RefundInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/entity/OrderInfoEntity.java b/src/main/java/org/springblade/modules/pay/entity/OrderInfoEntity.java
new file mode 100644
index 0000000..7e6e1d1
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/entity/OrderInfoEntity.java
@@ -0,0 +1,100 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tenant.mp.TenantEntity;
+
+import java.util.Date;
+
+/**
+ * 订单信息 实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@TableName("jczz_order_info")
+@ApiModel(value = "OrderInfo对象", description = "订单信息")
+public class OrderInfoEntity {
+
+
+	/** id */
+	@ApiModelProperty(value = "主键ID", example = "")
+	@TableId(value = "id", type = IdType.ASSIGN_ID)
+	private Long id;
+
+	/** 订单标题 */
+	@ApiModelProperty(value = "订单标题", example = "")
+	@TableField("title")
+	private String title;
+
+	/** 商户订单编号 */
+	@ApiModelProperty(value = "商户订单编号", example = "")
+	@TableField("order_no")
+	private String orderNo;
+
+	/** 用户id */
+	@ApiModelProperty(value = "用户id", example = "")
+	@TableField("user_id")
+	private Long userId;
+
+	/** 支付产品id */
+	@ApiModelProperty(value = "支付产品id", example = "")
+	@TableField("proper_charge_record_id")
+	private Long properChargeRecordId;
+
+	/** 订单二维码连接 */
+	@ApiModelProperty(value = "订单二维码连接", example = "")
+	@TableField("code_url")
+	private String codeUrl;
+
+	/** 订单金额(分) */
+	@ApiModelProperty(value = "订单金额(分)", example = "")
+	@TableField("total_fee")
+	private Integer totalFee;
+
+	/** 订单状态 */
+	@ApiModelProperty(value = "订单状态", example = "")
+	@TableField("order_status")
+	private String orderStatus;
+
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("create_time")
+	private Date createTime;
+
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("update_time")
+	private Date updateTime;
+
+	/** 物业id */
+	@ApiModelProperty(value = "物业id", example = "")
+	@TableId("proper_id")
+	private Long properId;
+}
diff --git a/src/main/java/org/springblade/modules/pay/entity/PaymentInfoEntity.java b/src/main/java/org/springblade/modules/pay/entity/PaymentInfoEntity.java
new file mode 100644
index 0000000..46c08d3
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/entity/PaymentInfoEntity.java
@@ -0,0 +1,95 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tenant.mp.TenantEntity;
+
+import java.util.Date;
+
+/**
+ * 支付信息 实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@TableName("jczz_payment_info")
+@ApiModel(value = "PaymentInfo对象", description = "支付信息")
+public class PaymentInfoEntity {
+
+
+	/** id */
+	@ApiModelProperty(value = "主键ID", example = "")
+	@TableId(value = "id", type = IdType.ASSIGN_ID)
+	private Long id;
+
+	/** 订单编号 */
+	@ApiModelProperty(value = "订单编号", example = "")
+	@TableField("order_no")
+	private String orderNo;
+
+	/** 支付系统交易编号 */
+	@ApiModelProperty(value = "支付系统交易编号", example = "")
+	@TableField("transaction_id")
+	private String transactionId;
+
+	/** 支付类型 */
+	@ApiModelProperty(value = "支付类型", example = "")
+	@TableField("payment_type")
+	private String paymentType;
+
+	/** 交易类型 */
+	@ApiModelProperty(value = "交易类型", example = "")
+	@TableField("trade_type")
+	private String tradeType;
+
+	/** 交易状态 */
+	@ApiModelProperty(value = "交易状态", example = "")
+	@TableField("trade_state")
+	private String tradeState;
+
+	/** 支付金额(分) */
+	@ApiModelProperty(value = "支付金额(分)", example = "")
+	@TableField("payer_total")
+	private Integer payerTotal;
+
+	/** 通知参数 */
+	@ApiModelProperty(value = "通知参数", example = "")
+	@TableField("content")
+	private String content;
+
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("create_time")
+	private Date createTime;
+
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("update_time")
+	private Date updateTime;
+}
diff --git a/src/main/java/org/springblade/modules/pay/entity/RefundInfoEntity.java b/src/main/java/org/springblade/modules/pay/entity/RefundInfoEntity.java
new file mode 100644
index 0000000..ec28d2e
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/entity/RefundInfoEntity.java
@@ -0,0 +1,102 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tenant.mp.TenantEntity;
+
+import java.util.Date;
+
+/**
+ * 退款信息 实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@TableName("jczz_refund_info")
+@ApiModel(value = "RefundInfo对象", description = "退款信息")
+public class RefundInfoEntity  {
+
+	/** id */
+	@ApiModelProperty(value = "主键ID", example = "")
+	@TableId(value = "id", type = IdType.ASSIGN_ID)
+	private Long id;
+
+	/** 订单编号 */
+	@ApiModelProperty(value = "订单编号", example = "")
+	@TableField("order_no")
+	private String orderNo;
+
+	/** 退款单编号 */
+	@ApiModelProperty(value = "退款单编号", example = "")
+	@TableField("refund_no")
+	private String refundNo;
+
+	/** 支付系统退款单号 */
+	@ApiModelProperty(value = "支付系统退款单号", example = "")
+	@TableField("refund_id")
+	private String refundId;
+
+	/** 原订单金额(分) */
+	@ApiModelProperty(value = "原订单金额(分)", example = "")
+	@TableField("total_fee")
+	private Integer totalFee;
+
+	/** 退款金额(分) */
+	@ApiModelProperty(value = "退款金额(分)", example = "")
+	@TableField("refund")
+	private Integer refund;
+
+	/** 退款原因 */
+	@ApiModelProperty(value = "退款原因", example = "")
+	@TableField("reason")
+	private String reason;
+
+	/** 退款单状态 */
+	@ApiModelProperty(value = "退款单状态", example = "")
+	@TableField("refund_status")
+	private String refundStatus;
+
+	/** 申请退款返回参数 */
+	@ApiModelProperty(value = "申请退款返回参数", example = "")
+	@TableField("content_return")
+	private String contentReturn;
+
+	/** 退款结果通知参数 */
+	@ApiModelProperty(value = "退款结果通知参数", example = "")
+	@TableField("content_notify")
+	private String contentNotify;
+
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField(value = "create_time",fill = FieldFill.INSERT)
+	private Date createTime;
+
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField(value = "update_time",fill = FieldFill.UPDATE)
+	private Date updateTime;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/entity/WeChatMiniAuthorizeVo.java b/src/main/java/org/springblade/modules/pay/entity/WeChatMiniAuthorizeVo.java
new file mode 100644
index 0000000..13625aa
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/entity/WeChatMiniAuthorizeVo.java
@@ -0,0 +1,39 @@
+package org.springblade.modules.pay.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="WeChatMiniAuthorizeVo对象", description="微信小程序用户授权返回数据")
+public class WeChatMiniAuthorizeVo implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "会话密钥")
+    @JSONField(name = "session_key")
+    private String sessionKey;
+
+    @ApiModelProperty(value = "用户唯一标识")
+    @JSONField(name = "openid")
+    private String openId;
+
+    @ApiModelProperty(value = "用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回")
+    @JSONField(name = "unionid")
+    private String unionId;
+
+    @ApiModelProperty(value = "错误码")
+    @JSONField(name = "errcode")
+    private String errCode;
+
+    @ApiModelProperty(value = "错误信息")
+    @JSONField(name = "errmsg")
+    private String errMsg;
+}
diff --git a/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.java b/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.java
new file mode 100644
index 0000000..a6c5f59
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.java
@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.mapper;
+
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.vo.OrderInfoVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * 订单信息 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface OrderInfoMapper extends BaseMapper<OrderInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param orderInfo
+	 * @return
+	 */
+	List<OrderInfoVO> selectOrderInfoPage(IPage page, OrderInfoVO orderInfo);
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.xml b/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.xml
new file mode 100644
index 0000000..cfda60f
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/OrderInfoMapper.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.pay.mapper.OrderInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="orderInfoResultMap" type="org.springblade.modules.pay.entity.OrderInfoEntity">
+    </resultMap>
+
+
+    <select id="selectOrderInfoPage" resultMap="orderInfoResultMap">
+        select * from jczz_order_info where is_deleted = 0
+    </select>
+
+
+</mapper>
diff --git a/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.java b/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.java
new file mode 100644
index 0000000..875b7c5
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.java
@@ -0,0 +1,59 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.mapper;
+
+import org.springblade.modules.pay.dto.PaymentInfoDTO;
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import org.springblade.modules.pay.vo.PaymentInfoVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 支付信息 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface PaymentInfoMapper extends BaseMapper<PaymentInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param paymentInfo
+	 * @return
+	 */
+	List<PaymentInfoVO> selectPaymentInfoPage(IPage page, PaymentInfoVO paymentInfo);
+
+
+	/**
+	 * 查询支付信息
+	 *
+	 * @param id 支付信息ID
+	 * @return 支付信息
+	 */
+	public PaymentInfoDTO selectPaymentInfoById(Long id);
+
+	/**
+	 * 查询支付信息列表
+	 *
+	 * @param paymentInfoDTO 支付信息
+	 * @return 支付信息集合
+	 */
+	public List<PaymentInfoDTO> selectPaymentInfoList(PaymentInfoDTO paymentInfoDTO);
+}
diff --git a/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.xml b/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.xml
new file mode 100644
index 0000000..266d878
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/PaymentInfoMapper.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.pay.mapper.PaymentInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="paymentInfoResultMap" type="org.springblade.modules.pay.entity.PaymentInfoEntity">
+    </resultMap>
+
+
+    <select id="selectPaymentInfoPage" resultMap="paymentInfoResultMap">
+        select * from jczz_payment_info where is_deleted = 0
+    </select>
+
+    <resultMap type="org.springblade.modules.pay.dto.PaymentInfoDTO" id="PaymentInfoDTOResult">
+        <result property="id"    column="id"    />
+        <result property="orderNo"    column="order_no"    />
+        <result property="transactionId"    column="transaction_id"    />
+        <result property="paymentType"    column="payment_type"    />
+        <result property="tradeType"    column="trade_type"    />
+        <result property="tradeState"    column="trade_state"    />
+        <result property="payerTotal"    column="payer_total"    />
+        <result property="content"    column="content"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectPaymentInfo">
+        select
+            id,
+            order_no,
+            transaction_id,
+            payment_type,
+            trade_type,
+            trade_state,
+            payer_total,
+            content,
+            create_time,
+            update_time
+        from
+            jczz_payment_info
+    </sql>
+
+    <select id="selectPaymentInfoById" parameterType="long" resultMap="PaymentInfoDTOResult">
+        <include refid="selectPaymentInfo"/>
+        where
+        id = #{id}
+    </select>
+
+    <select id="selectPaymentInfoList" parameterType="org.springblade.modules.pay.dto.PaymentInfoDTO" resultMap="PaymentInfoDTOResult">
+        <include refid="selectPaymentInfo"/>
+        <where>
+            <if test="id != null "> and id = #{id}</if>
+            <if test="orderNo != null  and orderNo != ''"> and order_no = #{orderNo}</if>
+            <if test="transactionId != null  and transactionId != ''"> and transaction_id = #{transactionId}</if>
+            <if test="paymentType != null  and paymentType != ''"> and payment_type = #{paymentType}</if>
+            <if test="tradeType != null  and tradeType != ''"> and trade_type = #{tradeType}</if>
+            <if test="tradeState != null  and tradeState != ''"> and trade_state = #{tradeState}</if>
+            <if test="payerTotal != null  and payerTotal != ''"> and payer_total = #{payerTotal}</if>
+            <if test="content != null  and content != ''"> and content = #{content}</if>
+            <if test="createTime != null "> and create_time = #{createTime}</if>
+            <if test="updateTime != null "> and update_time = #{updateTime}</if>
+        </where>
+    </select>
+</mapper>
diff --git a/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.java b/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.java
new file mode 100644
index 0000000..f42ae01
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.java
@@ -0,0 +1,60 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.mapper;
+
+import org.springblade.modules.pay.dto.RefundInfoDTO;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import org.springblade.modules.pay.vo.RefundInfoVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 退款信息 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface RefundInfoMapper extends BaseMapper<RefundInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param refundInfo
+	 * @return
+	 */
+	List<RefundInfoVO> selectRefundInfoPage(IPage page, RefundInfoVO refundInfo);
+
+	/**
+	 * 查询退款信息
+	 *
+	 * @param id 退款信息ID
+	 * @return 退款信息
+	 */
+	public RefundInfoDTO selectRefundInfoById(Long id);
+
+	/**
+	 * 查询退款信息列表
+	 *
+	 * @param refundInfoDTO 退款信息
+	 * @return 退款信息集合
+	 */
+	public List<RefundInfoDTO> selectRefundInfoList(RefundInfoDTO refundInfoDTO);
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.xml b/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.xml
new file mode 100644
index 0000000..511768f
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/mapper/RefundInfoMapper.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.pay.mapper.RefundInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="refundInfoResultMap" type="org.springblade.modules.pay.entity.RefundInfoEntity">
+    </resultMap>
+
+
+    <select id="selectRefundInfoPage" resultMap="refundInfoResultMap">
+        select * from jczz_refund_info where is_deleted = 0
+    </select>
+    <resultMap type="org.springblade.modules.pay.dto.RefundInfoDTO" id="RefundInfoDTOResult">
+        <result property="id"    column="id"    />
+        <result property="orderNo"    column="order_no"    />
+        <result property="refundNo"    column="refund_no"    />
+        <result property="refundId"    column="refund_id"    />
+        <result property="totalFee"    column="total_fee"    />
+        <result property="refund"    column="refund"    />
+        <result property="reason"    column="reason"    />
+        <result property="refundStatus"    column="refund_status"    />
+        <result property="contentReturn"    column="content_return"    />
+        <result property="contentNotify"    column="content_notify"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRefundInfo">
+        select
+            id,
+            order_no,
+            refund_no,
+            refund_id,
+            total_fee,
+            refund,
+            reason,
+            refund_status,
+            content_return,
+            content_notify,
+            create_time,
+            update_time
+        from
+            jczz_refund_info
+    </sql>
+
+    <select id="selectRefundInfoById" parameterType="long" resultMap="RefundInfoDTOResult">
+        <include refid="selectRefundInfo"/>
+        where
+        id = #{id}
+    </select>
+
+    <select id="selectRefundInfoList" parameterType="org.springblade.modules.pay.dto.RefundInfoDTO" resultMap="RefundInfoDTOResult">
+        <include refid="selectRefundInfo"/>
+        <where>
+            <if test="id != null "> and id = #{id}</if>
+            <if test="orderNo != null "> and order_no = #{orderNo}</if>
+            <if test="refundNo != null "> and refund_no = #{refundNo}</if>
+            <if test="refundId != null "> and refund_id = #{refundId}</if>
+            <if test="totalFee != null  and totalFee != ''"> and total_fee = #{totalFee}</if>
+            <if test="refund != null  and refund != ''"> and refund = #{refund}</if>
+            <if test="reason != null  and reason != ''"> and reason = #{reason}</if>
+            <if test="refundStatus != null  and refundStatus != ''"> and refund_status = #{refundStatus}</if>
+            <if test="contentReturn != null  and contentReturn != ''"> and content_return = #{contentReturn}</if>
+            <if test="contentNotify != null  and contentNotify != ''"> and content_notify = #{contentNotify}</if>
+            <if test="createTime != null "> and create_time = #{createTime}</if>
+            <if test="updateTime != null "> and update_time = #{updateTime}</if>
+        </where>
+    </select>
+
+
+</mapper>
diff --git a/src/main/java/org/springblade/modules/pay/service/IOrderInfoService.java b/src/main/java/org/springblade/modules/pay/service/IOrderInfoService.java
new file mode 100644
index 0000000..1ded657
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/IOrderInfoService.java
@@ -0,0 +1,59 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.common.enums.OrderStatus;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.vo.OrderInfoVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * 订单信息 服务类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface IOrderInfoService extends IService<OrderInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param orderInfo
+	 * @return
+	 */
+	IPage<OrderInfoVO> selectOrderInfoPage(IPage<OrderInfoVO> page, OrderInfoVO orderInfo);
+
+
+	OrderInfoEntity createOrderByPropertyChargeRecordId(Long propertyChargeRecordId);
+
+	void saveCodeUrl(String orderNo, String codeUrl);
+
+	List<OrderInfoEntity> listOrderByCreateTimeDesc();
+
+	void updateStatusByOrderNo(String orderNo, OrderStatus orderStatus);
+
+	String getOrderStatus(String orderNo);
+
+	List<OrderInfoEntity> getNoPayOrderByDuration(int minutes);
+
+	OrderInfoEntity getOrderByOrderNo(String orderNo);
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/IPaymentInfoService.java b/src/main/java/org/springblade/modules/pay/service/IPaymentInfoService.java
new file mode 100644
index 0000000..f2501c2
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/IPaymentInfoService.java
@@ -0,0 +1,45 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import org.springblade.modules.pay.vo.PaymentInfoVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 支付信息 服务类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface IPaymentInfoService extends IService<PaymentInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param paymentInfo
+	 * @return
+	 */
+	IPage<PaymentInfoVO> selectPaymentInfoPage(IPage<PaymentInfoVO> page, PaymentInfoVO paymentInfo);
+
+	void createPaymentInfo(String plainText);
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/IRefundInfoService.java b/src/main/java/org/springblade/modules/pay/service/IRefundInfoService.java
new file mode 100644
index 0000000..a1eab06
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/IRefundInfoService.java
@@ -0,0 +1,46 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import org.springblade.modules.pay.vo.RefundInfoVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 退款信息 服务类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public interface IRefundInfoService extends IService<RefundInfoEntity> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param refundInfo
+	 * @return
+	 */
+	IPage<RefundInfoVO> selectRefundInfoPage(IPage<RefundInfoVO> page, RefundInfoVO refundInfo);
+
+
+	RefundInfoEntity createRefundByOrderNo(String orderNo, String reason);
+
+	void updateRefund(String plainText);
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/IWxPayService.java b/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
index bac42f4..dc12258 100644
--- a/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
+++ b/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
@@ -3,20 +3,35 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.modules.pay.entity.WxPayInfo;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.util.Map;
 
 public interface IWxPayService extends IService<WxPayInfo> {
 
-	/**
-	 * 获取openId
-	 * @param code
-	 * @return
-	 */
-    Object getOpenId(String code);
-
-	Map<String, String> jsapiPay(Long productId) throws IOException;
+	Object getOpenId(String code);
 
 	void processOrder(Map<String, Object> bodyMap) throws GeneralSecurityException;
+
+	void cancelOrder(String orderNo) throws Exception;
+
+	String queryOrder(String orderNo) throws Exception;
+
+	void checkOrderStatus(String orderNo) throws Exception;
+
+	void refund(String orderNo, String reason) throws Exception;
+
+	String queryRefund(String orderNo) throws Exception;
+
+	void checkRefundStatus(String refundNo) throws Exception;
+
+	void processRefund(Map<String, Object> bodyMap) throws Exception;
+
+	Map<String, String> jsapiPay(Long productId) throws IOException, Exception;
+
+	String refundsNotify(HttpServletRequest request, HttpServletResponse response);
+
+	String nativeNotify(HttpServletRequest request, HttpServletResponse response);
 }
diff --git a/src/main/java/org/springblade/modules/pay/service/impl/OrderInfoServiceImpl.java b/src/main/java/org/springblade/modules/pay/service/impl/OrderInfoServiceImpl.java
new file mode 100644
index 0000000..e3cfef6
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/impl/OrderInfoServiceImpl.java
@@ -0,0 +1,207 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.common.enums.OrderStatus;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.vo.OrderInfoVO;
+import org.springblade.modules.pay.mapper.OrderInfoMapper;
+import org.springblade.modules.pay.service.IOrderInfoService;
+import org.springblade.modules.property.entity.PropertyChargeRecord;
+import org.springblade.modules.property.service.IPropertyChargeRecordService;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 订单信息 服务实现类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Service
+public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfoEntity> implements IOrderInfoService {
+
+	private static Logger logger = LoggerFactory.getLogger(OrderInfoServiceImpl.class);
+
+
+	@Resource
+	private IPropertyChargeRecordService iPropertyChargeRecordService;
+
+	@Override
+	public IPage<OrderInfoVO> selectOrderInfoPage(IPage<OrderInfoVO> page, OrderInfoVO orderInfo) {
+		return page.setRecords(baseMapper.selectOrderInfoPage(page, orderInfo));
+	}
+
+
+	@Override
+	public OrderInfoEntity createOrderByPropertyChargeRecordId(Long propertyChargeRecordId) {
+
+		//查找已存在但未支付的订单
+		OrderInfoEntity orderInfo = this.getNoPayOrderByPropertyChargeRecordId(propertyChargeRecordId);
+		if( orderInfo != null){
+			return orderInfo;
+		}
+		//获取商品信息
+		PropertyChargeRecord propertyChargeRecord = iPropertyChargeRecordService.getById(propertyChargeRecordId);
+		//生成订单
+		orderInfo = new OrderInfoEntity();
+		orderInfo.setTitle(propertyChargeRecord.getPayContent());
+		orderInfo.setOrderNo(getOrderNoStr()); //订单号
+		orderInfo.setProperChargeRecordId(propertyChargeRecordId);
+		orderInfo.setTotalFee(propertyChargeRecord.getPayPrice().intValue()); //分
+		orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType());
+		baseMapper.insert(orderInfo);
+		return orderInfo;
+	}
+
+	/**
+	 * 存储订单二维码
+	 * @param orderNo
+	 * @param codeUrl
+	 */
+	@Override
+	public void saveCodeUrl(String orderNo, String codeUrl) {
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("order_no", orderNo);
+
+		OrderInfoEntity orderInfo = new OrderInfoEntity();
+		orderInfo.setCodeUrl(codeUrl);
+
+		baseMapper.update(orderInfo, queryWrapper);
+	}
+
+	/**
+	 * 查询订单列表,并倒序查询
+	 * @return
+	 */
+	@Override
+	public List<OrderInfoEntity> listOrderByCreateTimeDesc() {
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<OrderInfoEntity>().orderByDesc("create_time");
+		return baseMapper.selectList(queryWrapper);
+	}
+
+	/**
+	 * 根据订单号更新订单状态
+	 * @param orderNo
+	 * @param orderStatus
+	 */
+	@Override
+	public void updateStatusByOrderNo(String orderNo, OrderStatus orderStatus) {
+
+		logger.info("更新订单状态 ===> {}", orderStatus.getType());
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("order_no", orderNo);
+
+		OrderInfoEntity orderInfo = new OrderInfoEntity();
+		orderInfo.setOrderStatus(orderStatus.getType());
+
+		baseMapper.update(orderInfo, queryWrapper);
+	}
+
+	/**
+	 * 根据订单号获取订单状态
+	 * @param orderNo
+	 * @return
+	 */
+	@Override
+	public String getOrderStatus(String orderNo) {
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("order_no", orderNo);
+		OrderInfoEntity orderInfo = baseMapper.selectOne(queryWrapper);
+		if(orderInfo == null){
+			return null;
+		}
+		return orderInfo.getOrderStatus();
+	}
+
+	/**
+	 * 查询创建超过minutes分钟并且未支付的订单
+	 * @param minutes
+	 * @return
+	 */
+	@Override
+	public List<OrderInfoEntity> getNoPayOrderByDuration(int minutes) {
+
+		Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
+		queryWrapper.le("create_time", instant);
+
+		List<OrderInfoEntity> orderInfoList = baseMapper.selectList(queryWrapper);
+
+		return orderInfoList;
+	}
+
+	/**
+	 * 根据订单号获取订单
+	 * @param orderNo
+	 * @return
+	 */
+	@Override
+	public OrderInfoEntity getOrderByOrderNo(String orderNo) {
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("order_no", orderNo);
+		OrderInfoEntity orderInfo = baseMapper.selectOne(queryWrapper);
+
+		return orderInfo;
+	}
+
+
+	/**
+	 * 根据商品id查询未支付订单
+	 * 防止重复创建订单对象
+	 * @param propertyChargeRecordId
+	 * @return
+	 */
+	private OrderInfoEntity getNoPayOrderByPropertyChargeRecordId(Long propertyChargeRecordId) {
+
+		QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("product_id", propertyChargeRecordId);
+		queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
+//        queryWrapper.eq("user_id", userId);
+		OrderInfoEntity orderInfo = baseMapper.selectOne(queryWrapper);
+		return orderInfo;
+	}
+
+	//生成订单号
+	public static String getOrderNoStr() {
+		String order = "pay" + new SimpleDateFormat("yyyyMMdd").format(new Date());
+		Random r = new Random();
+		for (int i = 0; i < 10; i++) {
+			order += r.nextInt(9);
+		}
+		return order;
+	}
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/impl/PaymentInfoServiceImpl.java b/src/main/java/org/springblade/modules/pay/service/impl/PaymentInfoServiceImpl.java
new file mode 100644
index 0000000..a42515e
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/impl/PaymentInfoServiceImpl.java
@@ -0,0 +1,88 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.common.enums.PayType;
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import org.springblade.modules.pay.mapper.PaymentInfoMapper;
+import org.springblade.modules.pay.vo.PaymentInfoVO;
+import org.springblade.modules.pay.service.IPaymentInfoService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 支付信息 服务实现类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Service
+public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfoEntity> implements IPaymentInfoService {
+
+	private static Logger logger = LoggerFactory.getLogger(PaymentInfoServiceImpl.class);
+
+	@Override
+	public IPage<PaymentInfoVO> selectPaymentInfoPage(IPage<PaymentInfoVO> page, PaymentInfoVO paymentInfo) {
+		return page.setRecords(baseMapper.selectPaymentInfoPage(page, paymentInfo));
+	}
+
+	/**
+	 * 记录支付日志
+	 * @param plainText
+	 */
+	@Override
+	public void createPaymentInfo(String plainText) {
+
+		logger.info("记录支付日志");
+
+		Gson gson = new Gson();
+		HashMap plainTextMap = gson.fromJson(plainText, HashMap.class);
+
+		//订单号
+		String orderNo = (String)plainTextMap.get("out_trade_no");
+		//业务编号
+		String transactionId = (String)plainTextMap.get("transaction_id");
+		//支付类型
+		String tradeType = (String)plainTextMap.get("trade_type");
+		//交易状态
+		String tradeState = (String)plainTextMap.get("trade_state");
+		//用户实际支付金额
+		Map<String, Object> amount = (Map)plainTextMap.get("amount");
+		Integer payerTotal = ((Double) amount.get("payer_total")).intValue();
+
+		PaymentInfoEntity paymentInfo = new PaymentInfoEntity();
+		paymentInfo.setOrderNo(orderNo);
+		paymentInfo.setPaymentType(PayType.WXPAY.getType());
+		paymentInfo.setTransactionId(transactionId);
+		paymentInfo.setTradeType(tradeType);
+		paymentInfo.setTradeState(tradeState);
+		paymentInfo.setPayerTotal(payerTotal);
+		paymentInfo.setContent(plainText);
+
+		baseMapper.insert(paymentInfo);
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/impl/RefundInfoServiceImpl.java b/src/main/java/org/springblade/modules/pay/service/impl/RefundInfoServiceImpl.java
new file mode 100644
index 0000000..be4852f
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/service/impl/RefundInfoServiceImpl.java
@@ -0,0 +1,118 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import org.springblade.modules.pay.mapper.RefundInfoMapper;
+import org.springblade.modules.pay.service.IOrderInfoService;
+import org.springblade.modules.pay.service.IRefundInfoService;
+import org.springblade.modules.pay.vo.RefundInfoVO;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * 退款信息 服务实现类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Service
+public class RefundInfoServiceImpl extends ServiceImpl<RefundInfoMapper, RefundInfoEntity> implements IRefundInfoService {
+
+
+	@Resource
+	private IOrderInfoService orderInfoService;
+	@Override
+	public IPage<RefundInfoVO> selectRefundInfoPage(IPage<RefundInfoVO> page, RefundInfoVO refundInfo) {
+		return page.setRecords(baseMapper.selectRefundInfoPage(page, refundInfo));
+	}
+
+	@Override
+	public RefundInfoEntity createRefundByOrderNo(String orderNo, String reason) {
+
+		//根据订单号获取订单信息
+		OrderInfoEntity orderInfo = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery()
+			.eq(OrderInfoEntity::getOrderNo, orderNo));
+
+		//根据订单号生成退款订单
+		RefundInfoEntity refundInfo = new RefundInfoEntity();
+		refundInfo.setOrderNo(orderNo);//订单编号
+		refundInfo.setRefundNo(getOrderNoStr());//退款单编号
+		refundInfo.setTotalFee(orderInfo.getTotalFee());//原订单金额(分)
+		refundInfo.setRefund(orderInfo.getTotalFee());//退款金额(分)
+		refundInfo.setReason(reason);//退款原因
+
+		//保存退款订单
+		baseMapper.insert(refundInfo);
+
+		return refundInfo;
+	}
+
+
+	@Override
+	public void updateRefund(String content) {
+		//将json字符串转换成Map
+		Gson gson = new Gson();
+		Map<String, String> resultMap = gson.fromJson(content, HashMap.class);
+
+		//根据退款单编号修改退款单
+		QueryWrapper<RefundInfoEntity> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("refund_no", resultMap.get("out_refund_no"));
+
+		//设置要修改的字段
+		RefundInfoEntity refundInfo = new RefundInfoEntity();
+
+		refundInfo.setRefundId(resultMap.get("refund_id"));//微信支付退款单号
+
+		//查询退款和申请退款中的返回参数
+		if(resultMap.get("status") != null){
+			refundInfo.setRefundStatus(resultMap.get("status"));//退款状态
+			refundInfo.setContentReturn(content);//将全部响应结果存入数据库的content字段
+		}
+		//退款回调中的回调参数
+		if(resultMap.get("refund_status") != null){
+			refundInfo.setRefundStatus(resultMap.get("refund_status"));//退款状态
+			refundInfo.setContentNotify(content);//将全部响应结果存入数据库的content字段
+		}
+
+		//更新退款单
+		baseMapper.update(refundInfo, queryWrapper);
+	}
+
+
+	//生成订单号
+	public static String getOrderNoStr() {
+		String order = "refund" + new SimpleDateFormat("yyyyMMdd").format(new Date());
+		Random r = new Random();
+		for (int i = 0; i < 10; i++) {
+			order += r.nextInt(9);
+		}
+		return order;
+	}
+}
diff --git a/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java b/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
index 08b67fe..dfc021c 100644
--- a/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
+++ b/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
@@ -1,26 +1,48 @@
 package org.springblade.modules.pay.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.wxpay.sdk.WXPayUtil;
 import com.google.gson.Gson;
 import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
 import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
 import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.util.EntityUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springblade.common.config.WxPayConfig;
 import org.springblade.common.enums.OrderStatus;
 import org.springblade.common.enums.wxpay.WxApiType;
 import org.springblade.common.enums.wxpay.WxNotifyType;
-import org.springblade.modules.pay.controller.WxPayController;
+import org.springblade.common.enums.wxpay.WxRefundStatus;
+import org.springblade.common.enums.wxpay.WxTradeState;
+import org.springblade.common.utils.HttpUtils;
+import org.springblade.common.utils.SpringUtils;
+import org.springblade.common.utils.WechatPay2ValidatorForRequest;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
 import org.springblade.modules.pay.entity.WxPayInfo;
 import org.springblade.modules.pay.mapper.WxPayMapper;
+import org.springblade.modules.pay.service.IOrderInfoService;
+import org.springblade.modules.pay.service.IPaymentInfoService;
+import org.springblade.modules.pay.service.IRefundInfoService;
 import org.springblade.modules.pay.service.IWxPayService;
-import org.springframework.beans.factory.annotation.Value;
+import org.springblade.modules.property.entity.PropertyChargeRecord;
+import org.springblade.modules.property.service.IPropertyChargeService;
+import org.springblade.modules.system.entity.User;
+import org.springblade.modules.system.service.IUserService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
@@ -31,100 +53,37 @@
 
 @Service
 public class WxPayServiceImpl extends ServiceImpl<WxPayMapper,WxPayInfo> implements IWxPayService {
+	private static Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);
 
-	private final String  MINI_PROGRAM_APP_ID = "wx41aa8a5d2e565a05";
-	private static final Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);
+
+	@Resource
+	private WxPayConfig wxPayConfig;
+
+	@Resource
+	private IPropertyChargeService iPropertyChargeService;
+
+
+	@Resource
+	private CloseableHttpClient wxPayClient;
+
+	@Resource
+	private IOrderInfoService orderInfoService;
+
+	@Resource
+	private IPaymentInfoService paymentInfoService;
+
+	@Resource
+	private IRefundInfoService refundsInfoService;
 
 	private final ReentrantLock lock = new ReentrantLock();
+
 
 	@Override
 	public Object getOpenId(String code) {
 		return null;
 	}
 
-	@Override
-	public Map<String, String> jsapiPay(Long productId) throws IOException {
-
-		String prepayId = "";
-		//生成订单
-//		OrderInfo orderInfo = orderInfoService.createOrderByProductId(productId);
-
-
-		logger.info("调用统一下单API");
-
-//		//调用统一下单API
-//		HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.JSAPI_PAY.getType()));
-//
-//		// 请求body参数
-//
-//		Gson gson = new Gson();
-//		Map paramsMap = new HashMap();
-//		paramsMap.put("appid", wxPayConfig.getAppid());
-//		paramsMap.put("mchid", wxPayConfig.getMchId());
-//		paramsMap.put("description", orderInfo.getTitle());
-//		paramsMap.put("out_trade_no", orderInfo.getOrderNo());
-//		paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));
-//
-//		Map amountMap = new HashMap();
-//		amountMap.put("total", orderInfo.getTotalFee());
-//		amountMap.put("currency", "CNY");
-//
-//		paramsMap.put("amount", amountMap);
-//
-//		Map payerMap = new HashMap();
-//		payerMap.put("openid", "oSX3G6OUuGaKJbWzSHUpPbzgtDXo");
-//
-//		paramsMap.put("payer", payerMap);
-//
-//		//将参数转换成json字符串
-//		String jsonParams = gson.toJson(paramsMap);
-//		logger.info("请求参数 ===> {}" + jsonParams);
-//
-//		StringEntity entity = new StringEntity(jsonParams, "utf-8");
-//		entity.setContentType("application/json");
-//		httpPost.setEntity(entity);
-//		httpPost.setHeader("Accept", "application/json");
-//
-//		//完成签名并执行请求
-//		CloseableHttpResponse response = wxPayClient.execute(httpPost);
-//
-//		try {
-//			String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
-//			int statusCode = response.getStatusLine().getStatusCode();//响应状态码
-//			if (statusCode == 200) { //处理成功
-//				logger.info("成功, 返回结果 = " + bodyAsString);
-//			} else if (statusCode == 204) { //处理成功,无返回Body
-//				logger.info("成功");
-//			} else {
-//				logger.info("jszpi下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
-//				throw new IOException("request failed");
-//			}
-//			//响应结果
-//			Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
-//			//预支付交易会话标识
-//			prepayId = resultMap.get("prepay_id");
-//
-//			//返回预支付交易会话标识
-//			// 组装前端预下单参数
-//			/** 返回给前端所需要的数据 */
-//			SortedMap<String, String> payMap = new TreeMap<>();
-//			String nonceStr = WXPayUtil.generateNonceStr();
-//			String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
-//			payMap.put("appId", wxPayConfig.getAppid());
-//			payMap.put("timeStamp", timestamp);
-//			payMap.put("nonceStr", nonceStr);
-//			payMap.put("signType", "RSA");
-//			payMap.put("package", "prepay_id=" + prepayId);
-//			String paySign = getSign(wxPayConfig.getAppid(), prepayId, timestamp, nonceStr);
-//			payMap.put("paySign", paySign);
-//			logger.info("返回参数 ===> {}" + gson.toJson(payMap));
-//			return payMap;
-//		} finally {
-//			response.close();
-//		}
-		return null;
-	}
-
+	@Transactional(rollbackFor = Exception.class)
 	@Override
 	public void processOrder(Map<String, Object> bodyMap) throws GeneralSecurityException {
 		logger.info("处理订单");
@@ -143,32 +102,410 @@
         以避免函数重入造成的数据混乱*/
 		//尝试获取锁:
 		// 成功获取则立即返回true,获取失败则立即返回false。不必一直等待锁的释放
-//		if (lock.tryLock()) {
-//			try {
-//				//处理重复的通知
-//				//接口调用的幂等性:无论接口被调用多少次,产生的结果是一致的。
-//				String orderStatus = orderInfoService.getOrderStatus(orderNo);
-//				if (!OrderStatus.NOTPAY.getType().equals(orderStatus)) {
-//					return;
-//				}
-//
-//				//模拟通知并发
-//				try {
-//					TimeUnit.SECONDS.sleep(5);
-//				} catch (InterruptedException e) {
-//					e.printStackTrace();
-//				}
-//
-//				//更新订单状态
-//				orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
-//
-//				//记录支付日志
-//				paymentInfoService.createPaymentInfo(plainText);
-//			} finally {
-//				//要主动释放锁
-//				lock.unlock();
-//			}
-//		}
+		if (lock.tryLock()) {
+			try {
+				//处理重复的通知
+				//接口调用的幂等性:无论接口被调用多少次,产生的结果是一致的。
+				String orderStatus = orderInfoService.getOrderStatus(orderNo);
+				if (!OrderStatus.NOTPAY.getType().equals(orderStatus)) {
+					return;
+				}
+
+				//模拟通知并发
+				try {
+					TimeUnit.SECONDS.sleep(5);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+
+				//更新订单状态
+				orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
+
+				//记录支付日志
+				paymentInfoService.createPaymentInfo(plainText);
+			} finally {
+				//要主动释放锁
+				lock.unlock();
+			}
+		}
+	}
+
+	/**
+	 * 用户取消订单
+	 *
+	 * @param orderNo
+	 */
+	@Override
+	public void cancelOrder(String orderNo) throws Exception {
+
+		//调用微信支付的关单接口
+		this.closeOrder(orderNo);
+
+		//更新商户端的订单状态
+		orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.CANCEL);
+	}
+
+	@Override
+	public String queryOrder(String orderNo) throws Exception {
+
+		logger.info("查单接口调用 ===> {}", orderNo);
+
+		String url = String.format(WxApiType.ORDER_QUERY_BY_NO.getType(), orderNo);
+		url = wxPayConfig.getDomain().concat(url).concat("?mchid=").concat(wxPayConfig.getMchId());
+
+		HttpGet httpGet = new HttpGet(url);
+		httpGet.setHeader("Accept", "application/json");
+
+		//完成签名并执行请求
+		CloseableHttpResponse response = wxPayClient.execute(httpGet);
+
+		try {
+			String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
+			int statusCode = response.getStatusLine().getStatusCode();//响应状态码
+			if (statusCode == 200) { //处理成功
+				logger.info("成功, 返回结果 = " + bodyAsString);
+			} else if (statusCode == 204) { //处理成功,无返回Body
+				logger.info("成功");
+			} else {
+				logger.info("查单接口调用,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
+				throw new IOException("request failed");
+			}
+
+			return bodyAsString;
+
+		} finally {
+			response.close();
+		}
+
+	}
+
+	/**
+	 * 根据订单号查询微信支付查单接口,核实订单状态
+	 * 如果订单已支付,则更新商户端订单状态,并记录支付日志
+	 * 如果订单未支付,则调用关单接口关闭订单,并更新商户端订单状态
+	 *
+	 * @param orderNo
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public void checkOrderStatus(String orderNo) throws Exception {
+
+		logger.info("根据订单号核实订单状态 ===> {}", orderNo);
+
+		//调用微信支付查单接口
+		String result = this.queryOrder(orderNo);
+
+		Gson gson = new Gson();
+		Map<String, String> resultMap = gson.fromJson(result, HashMap.class);
+
+		//获取微信支付端的订单状态
+		String tradeState = resultMap.get("trade_state");
+
+		//判断订单状态
+		if (WxTradeState.SUCCESS.getType().equals(tradeState)) {
+
+			logger.info("核实订单已支付 ===> {}", orderNo);
+
+			//如果确认订单已支付则更新本地订单状态
+			orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
+			//记录支付日志
+			paymentInfoService.createPaymentInfo(result);
+		}
+
+		if (WxTradeState.NOTPAY.getType().equals(tradeState)) {
+			logger.info("核实订单未支付 ===> {}", orderNo);
+
+			//如果订单未支付,则调用关单接口
+			this.closeOrder(orderNo);
+
+			//更新本地订单状态
+			orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.CLOSED);
+		}
+
+	}
+
+	/**
+	 * 退款
+	 *
+	 * @param orderNo
+	 * @param reason
+	 * @throws IOException
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public void refund(String orderNo, String reason) throws Exception {
+
+		logger.info("创建退款单记录");
+		//根据订单编号创建退款单
+		RefundInfoEntity refundsInfo = refundsInfoService.createRefundByOrderNo(orderNo, reason);
+
+		logger.info("调用退款API");
+
+		//调用统一下单API
+		String url = wxPayConfig.getDomain().concat(WxApiType.DOMESTIC_REFUNDS.getType());
+		HttpPost httpPost = new HttpPost(url);
+
+		// 请求body参数
+		Gson gson = new Gson();
+		Map paramsMap = new HashMap();
+		paramsMap.put("out_trade_no", orderNo);//订单编号
+		paramsMap.put("out_refund_no", refundsInfo.getRefundNo());//退款单编号
+		paramsMap.put("reason", reason);//退款原因
+		paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.REFUND_NOTIFY.getType()));//退款通知地址
+
+		Map amountMap = new HashMap();
+		amountMap.put("refund", refundsInfo.getRefund());//退款金额
+		amountMap.put("total", refundsInfo.getTotalFee());//原订单金额
+		amountMap.put("currency", "CNY");//退款币种
+		paramsMap.put("amount", amountMap);
+
+		//将参数转换成json字符串
+		String jsonParams = gson.toJson(paramsMap);
+		logger.info("请求参数 ===> {}" + jsonParams);
+
+		StringEntity entity = new StringEntity(jsonParams, "utf-8");
+		entity.setContentType("application/json");//设置请求报文格式
+		httpPost.setEntity(entity);//将请求报文放入请求对象
+		httpPost.setHeader("Accept", "application/json");//设置响应报文格式
+
+		//完成签名并执行请求,并完成验签
+		CloseableHttpResponse response = wxPayClient.execute(httpPost);
+
+		try {
+
+			//解析响应结果
+			String bodyAsString = EntityUtils.toString(response.getEntity());
+			int statusCode = response.getStatusLine().getStatusCode();
+			if (statusCode == 200) {
+				logger.info("成功, 退款返回结果 = " + bodyAsString);
+			} else if (statusCode == 204) {
+				logger.info("成功");
+			} else {
+				throw new RuntimeException("退款异常, 响应码 = " + statusCode + ", 退款返回结果 = " + bodyAsString);
+			}
+
+			//更新订单状态
+			orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_PROCESSING);
+
+			//更新退款单
+			refundsInfoService.updateRefund(bodyAsString);
+
+		} finally {
+			response.close();
+		}
+	}
+
+
+	/**
+	 * 查询退款接口调用
+	 *
+	 * @param refundNo
+	 * @return
+	 */
+	@Override
+	public String queryRefund(String refundNo) throws Exception {
+
+		logger.info("查询退款接口调用 ===> {}", refundNo);
+
+		String url = String.format(WxApiType.DOMESTIC_REFUNDS_QUERY.getType(), refundNo);
+		url = wxPayConfig.getDomain().concat(url);
+
+		//创建远程Get 请求对象
+		HttpGet httpGet = new HttpGet(url);
+		httpGet.setHeader("Accept", "application/json");
+
+		//完成签名并执行请求
+		CloseableHttpResponse response = wxPayClient.execute(httpGet);
+
+		try {
+			String bodyAsString = EntityUtils.toString(response.getEntity());
+			int statusCode = response.getStatusLine().getStatusCode();
+			if (statusCode == 200) {
+				logger.info("成功, 查询退款返回结果 = " + bodyAsString);
+			} else if (statusCode == 204) {
+				logger.info("成功");
+			} else {
+				throw new RuntimeException("查询退款异常, 响应码 = " + statusCode + ", 查询退款返回结果 = " + bodyAsString);
+			}
+
+			return bodyAsString;
+
+		} finally {
+			response.close();
+		}
+	}
+
+	/**
+	 * 根据退款单号核实退款单状态
+	 *
+	 * @param refundNo
+	 * @return
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public void checkRefundStatus(String refundNo) throws Exception {
+
+		logger.info("根据退款单号核实退款单状态 ===> {}", refundNo);
+
+		//调用查询退款单接口
+		String result = this.queryRefund(refundNo);
+
+		//组装json请求体字符串
+		Gson gson = new Gson();
+		Map<String, String> resultMap = gson.fromJson(result, HashMap.class);
+
+		//获取微信支付端退款状态
+		String status = resultMap.get("status");
+
+		String orderNo = resultMap.get("out_trade_no");
+
+		if (WxRefundStatus.SUCCESS.getType().equals(status)) {
+
+			logger.info("核实订单已退款成功 ===> {}", refundNo);
+
+			//如果确认退款成功,则更新订单状态
+			orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_SUCCESS);
+
+			//更新退款单
+			refundsInfoService.updateRefund(result);
+		}
+
+		if (WxRefundStatus.ABNORMAL.getType().equals(status)) {
+
+			logger.info("核实订单退款异常  ===> {}", refundNo);
+
+			//如果确认退款成功,则更新订单状态
+			orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_ABNORMAL);
+
+			//更新退款单
+			refundsInfoService.updateRefund(result);
+		}
+	}
+
+	/**
+	 * 处理退款单
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public void processRefund(Map<String, Object> bodyMap) throws Exception {
+
+		logger.info("退款单");
+
+		//解密报文
+		String plainText = decryptFromResource(bodyMap);
+
+		//将明文转换成map
+		Gson gson = new Gson();
+		HashMap plainTextMap = gson.fromJson(plainText, HashMap.class);
+		String orderNo = (String) plainTextMap.get("out_trade_no");
+
+		if (lock.tryLock()) {
+			try {
+
+				String orderStatus = orderInfoService.getOrderStatus(orderNo);
+				if (!OrderStatus.REFUND_PROCESSING.getType().equals(orderStatus)) {
+					return;
+				}
+
+				//更新订单状态
+				orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_SUCCESS);
+
+				//更新退款单
+				refundsInfoService.updateRefund(plainText);
+
+			} finally {
+				//要主动释放锁
+				lock.unlock();
+			}
+		}
+	}
+
+
+
+	@Override
+	public Map<String, String> jsapiPay(Long properChargeRecordId) throws Exception {
+
+		String prepayId = "";
+		//生成订单
+		OrderInfoEntity orderInfo = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getProperChargeRecordId,properChargeRecordId));
+		IUserService userService = SpringUtils.getBean(IUserService.class);
+		User serviceOne = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getId, AuthUtil.getUserId()));
+
+		logger.info("调用统一下单API");
+
+		//调用统一下单API
+		HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.JSAPI_PAY.getType()));
+
+		// 请求body参数
+
+		Gson gson = new Gson();
+		Map paramsMap = new HashMap();
+		paramsMap.put("appid", wxPayConfig.getAppid());
+		paramsMap.put("mchid", wxPayConfig.getMchId());
+		paramsMap.put("description", orderInfo.getTitle());
+		paramsMap.put("out_trade_no", orderInfo.getOrderNo());
+		paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));
+
+		Map amountMap = new HashMap();
+		amountMap.put("total", orderInfo.getTotalFee());
+		amountMap.put("currency", "CNY");
+
+		paramsMap.put("amount", amountMap);
+
+		Map payerMap = new HashMap();
+		payerMap.put("openid", serviceOne.getMiniOpenId());
+
+		paramsMap.put("payer", payerMap);
+
+		// 是否指定分账,枚举值 true:是 false:否
+		paramsMap.put("profit_sharing", true);
+
+		//将参数转换成json字符串
+		String jsonParams = gson.toJson(paramsMap);
+		logger.info("请求参数 ===> {}" + jsonParams);
+
+		StringEntity entity = new StringEntity(jsonParams, "utf-8");
+		entity.setContentType("application/json");
+		httpPost.setEntity(entity);
+		httpPost.setHeader("Accept", "application/json");
+
+		//完成签名并执行请求
+		CloseableHttpResponse response = wxPayClient.execute(httpPost);
+
+		try {
+			String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
+			int statusCode = response.getStatusLine().getStatusCode();//响应状态码
+			if (statusCode == 200) { //处理成功
+				logger.info("成功, 返回结果 = " + bodyAsString);
+			} else if (statusCode == 204) { //处理成功,无返回Body
+				logger.info("成功");
+			} else {
+				logger.info("jszpi下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
+				throw new IOException("request failed");
+			}
+			//响应结果
+			Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
+			//预支付交易会话标识
+			prepayId = resultMap.get("prepay_id");
+
+			//返回预支付交易会话标识
+			// 组装前端预下单参数
+			/** 返回给前端所需要的数据 */
+			SortedMap<String, String> payMap = new TreeMap<>();
+			String nonceStr = WXPayUtil.generateNonceStr();
+			String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+			payMap.put("appId", wxPayConfig.getAppid());
+			payMap.put("timeStamp", timestamp);
+			payMap.put("nonceStr", nonceStr);
+			payMap.put("signType", "RSA");
+			payMap.put("package", "prepay_id=" + prepayId);
+			String paySign = getSign(wxPayConfig.getAppid(), prepayId, timestamp, nonceStr);
+			payMap.put("paySign", paySign);
+			logger.info("返回参数 ===> {}" + gson.toJson(payMap));
+			return payMap;
+		} finally {
+			response.close();
+		}
 	}
 
 	/**
@@ -196,7 +533,7 @@
 		//签名方式
 		Signature sign = Signature.getInstance("SHA256withRSA");
 		//私钥,通过MyPrivateKey来获取,这是个静态类可以接调用方法 ,需要的是_key.pem文件的绝对路径配上文件名
-//		sign.initSign(getPrivateKey(wxPayConfig.getPrivateKeyPath()));
+		sign.initSign(getPrivateKey(wxPayConfig.getPrivateKeyPath()));
 		sign.update(message);
 
 		return Base64.getEncoder().encodeToString(sign.sign());
@@ -227,6 +564,52 @@
 		}
 	}
 
+
+	/**
+	 * 关单接口的调用
+	 *
+	 * @param orderNo
+	 */
+	private void closeOrder(String orderNo) throws Exception {
+
+		logger.info("关单接口的调用,订单号 ===> {}", orderNo);
+		//创建远程请求对象
+		String url = String.format(WxApiType.CLOSE_ORDER_BY_NO.getType(), orderNo);
+		url = wxPayConfig.getDomain().concat(url);
+		HttpPost httpPost = new HttpPost(url);
+
+		//组装json请求体
+		Gson gson = new Gson();
+		Map<String, String> paramsMap = new HashMap<>();
+		paramsMap.put("mchid", wxPayConfig.getMchId());
+		String jsonParams = gson.toJson(paramsMap);
+		logger.info("请求参数 ===> {}", jsonParams);
+
+		//将请求参数设置到请求对象中
+		StringEntity entity = new StringEntity(jsonParams, "utf-8");
+		entity.setContentType("application/json");
+		httpPost.setEntity(entity);
+		httpPost.setHeader("Accept", "application/json");
+
+		//完成签名并执行请求
+		CloseableHttpResponse response = wxPayClient.execute(httpPost);
+
+		try {
+			int statusCode = response.getStatusLine().getStatusCode();//响应状态码
+			if (statusCode == 200) { //处理成功
+				logger.info("成功200");
+			} else if (statusCode == 204) { //处理成功,无返回Body
+				logger.info("成功204");
+			} else {
+				logger.info("Native下单失败,响应码 = " + statusCode);
+				throw new IOException("request failed");
+			}
+
+		} finally {
+			response.close();
+		}
+	}
+
 	/**
 	 * 对称解密
 	 *
@@ -247,15 +630,122 @@
 		String associatedData = resourceMap.get("associated_data");
 
 		logger.info("密文 ===> {}", ciphertext);
-//		AesUtil aesUtil = new AesUtil(wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
-//		String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
-//			nonce.getBytes(StandardCharsets.UTF_8),
-//			ciphertext);
+		AesUtil aesUtil = new AesUtil(wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
+		String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
+			nonce.getBytes(StandardCharsets.UTF_8),
+			ciphertext);
 
-//		logger.info("明文 ===> {}", plainText);
+		logger.info("明文 ===> {}", plainText);
 
-//		return plainText;
-		return null;
+		return plainText;
 	}
 
+	@Override
+	public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
+		Gson gson = new Gson();
+		Map<String, String> map = new HashMap<>();//应答对象
+
+		try {
+
+			//处理通知参数
+			String body = HttpUtils.readData(request);
+			Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
+			String requestId = (String) bodyMap.get("id");
+			logger.info("支付通知的id ===> {}", requestId);
+			logger.info("支付通知的完整数据 ===> {}", body);
+			//int a = 9 / 0;
+
+			//签名的验证
+			WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
+				= new WechatPay2ValidatorForRequest(wxPayConfig.getVerifier(), requestId, body);
+			if (!wechatPay2ValidatorForRequest.validate(request)) {
+
+				logger.error("通知验签失败");
+				//失败应答
+				response.setStatus(500);
+				map.put("code", "ERROR");
+				map.put("message", "通知验签失败");
+				return gson.toJson(map);
+			}
+			logger.info("通知验签成功");
+
+			//处理订单
+			processOrder(bodyMap);
+
+			//成功应答
+			response.setStatus(200);
+			map.put("code", "SUCCESS");
+			map.put("message", "成功");
+			return gson.toJson(map);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			//失败应答
+			response.setStatus(500);
+			map.put("code", "ERROR");
+			map.put("message", "失败");
+			return gson.toJson(map);
+		}
+	}
+
+	@Override
+	public String refundsNotify(HttpServletRequest request, HttpServletResponse response) {
+		Gson gson = new Gson();
+		Map<String, String> map = new HashMap<>();//应答对象
+
+		try {
+			//处理通知参数
+			String body = HttpUtils.readData(request);
+			Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
+			String requestId = (String) bodyMap.get("id");
+			logger.info("支付通知的id ===> {}", requestId);
+
+			//签名的验证
+			WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
+				= new WechatPay2ValidatorForRequest(wxPayConfig.getVerifier(), requestId, body);
+			if (!wechatPay2ValidatorForRequest.validate(request)) {
+
+				logger.error("通知验签失败");
+				//失败应答
+				response.setStatus(500);
+				map.put("code", "ERROR");
+				map.put("message", "通知验签失败");
+				return gson.toJson(map);
+			}
+			logger.info("通知验签成功");
+
+			//处理退款单
+			processRefund(bodyMap);
+
+			//成功应答
+			response.setStatus(200);
+			map.put("code", "SUCCESS");
+			map.put("message", "成功");
+			return gson.toJson(map);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			//失败应答
+			response.setStatus(500);
+			map.put("code", "ERROR");
+			map.put("message", "失败");
+			return gson.toJson(map);
+		}
+	}
+
+
+	//创建签名所需要的参数xml格式
+//	public static String createXML(Map<String, Object> map) {
+//		String xml = "<xml>";
+//		Set<String> set = map.keySet();
+//		Iterator<String> i = set.iterator();
+//		while (i.hasNext()) {
+//			String str = i.next();
+//			xml += "<" + str + ">" + "<![CDATA[" + map.get(str) + "]]>" + "</" + str + ">";
+//		}
+//		xml += "</xml>";
+//		return xml;
+//	}
+
+
 }
diff --git a/src/main/java/org/springblade/modules/pay/vo/OrderInfoVO.java b/src/main/java/org/springblade/modules/pay/vo/OrderInfoVO.java
new file mode 100644
index 0000000..7a1129c
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/vo/OrderInfoVO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.vo;
+
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 订单信息 视图实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OrderInfoVO extends OrderInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/vo/PaymentInfoVO.java b/src/main/java/org/springblade/modules/pay/vo/PaymentInfoVO.java
new file mode 100644
index 0000000..f137d6d
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/vo/PaymentInfoVO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.vo;
+
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 支付信息 视图实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PaymentInfoVO extends PaymentInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/vo/RefundInfoVO.java b/src/main/java/org/springblade/modules/pay/vo/RefundInfoVO.java
new file mode 100644
index 0000000..d519c32
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/vo/RefundInfoVO.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.vo;
+
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 退款信息 视图实体类
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RefundInfoVO extends RefundInfoEntity {
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/wrapper/OrderInfoWrapper.java b/src/main/java/org/springblade/modules/pay/wrapper/OrderInfoWrapper.java
new file mode 100644
index 0000000..962a6f3
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/wrapper/OrderInfoWrapper.java
@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.wrapper;
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.pay.entity.OrderInfoEntity;
+import org.springblade.modules.pay.vo.OrderInfoVO;
+
+import java.util.Objects;
+
+/**
+ * 订单信息 包装类,返回视图层所需的字段
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public class OrderInfoWrapper extends BaseEntityWrapper<OrderInfoEntity, OrderInfoVO>  {
+
+	public static OrderInfoWrapper build() {
+		return new OrderInfoWrapper();
+ 	}
+
+	@Override
+	public OrderInfoVO entityVO(OrderInfoEntity orderInfo) {
+		OrderInfoVO orderInfoVO = Objects.requireNonNull(BeanUtil.copy(orderInfo, OrderInfoVO.class));
+
+		//User createUser = UserCache.getUser(orderInfo.getCreateUser());
+		//User updateUser = UserCache.getUser(orderInfo.getUpdateUser());
+		//orderInfoVO.setCreateUserName(createUser.getName());
+		//orderInfoVO.setUpdateUserName(updateUser.getName());
+
+		return orderInfoVO;
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/wrapper/PaymentInfoWrapper.java b/src/main/java/org/springblade/modules/pay/wrapper/PaymentInfoWrapper.java
new file mode 100644
index 0000000..0cc7cfb
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/wrapper/PaymentInfoWrapper.java
@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.wrapper;
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.pay.entity.PaymentInfoEntity;
+import org.springblade.modules.pay.vo.PaymentInfoVO;
+
+import java.util.Objects;
+
+/**
+ * 支付信息 包装类,返回视图层所需的字段
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public class PaymentInfoWrapper extends BaseEntityWrapper<PaymentInfoEntity, PaymentInfoVO>  {
+
+	public static PaymentInfoWrapper build() {
+		return new PaymentInfoWrapper();
+ 	}
+
+	@Override
+	public PaymentInfoVO entityVO(PaymentInfoEntity paymentInfo) {
+		PaymentInfoVO paymentInfoVO = Objects.requireNonNull(BeanUtil.copy(paymentInfo, PaymentInfoVO.class));
+
+		//User createUser = UserCache.getUser(paymentInfo.getCreateUser());
+		//User updateUser = UserCache.getUser(paymentInfo.getUpdateUser());
+		//paymentInfoVO.setCreateUserName(createUser.getName());
+		//paymentInfoVO.setUpdateUserName(updateUser.getName());
+
+		return paymentInfoVO;
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/wrapper/RefundInfoWrapper.java b/src/main/java/org/springblade/modules/pay/wrapper/RefundInfoWrapper.java
new file mode 100644
index 0000000..2ef166e
--- /dev/null
+++ b/src/main/java/org/springblade/modules/pay/wrapper/RefundInfoWrapper.java
@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pay.wrapper;
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.pay.entity.RefundInfoEntity;
+import org.springblade.modules.pay.vo.RefundInfoVO;
+
+import java.util.Objects;
+
+/**
+ * 退款信息 包装类,返回视图层所需的字段
+ *
+ * @author BladeX
+ * @since 2024-04-07
+ */
+public class RefundInfoWrapper extends BaseEntityWrapper<RefundInfoEntity, RefundInfoVO>  {
+
+	public static RefundInfoWrapper build() {
+		return new RefundInfoWrapper();
+ 	}
+
+	@Override
+	public RefundInfoVO entityVO(RefundInfoEntity refundInfo) {
+		RefundInfoVO refundInfoVO = Objects.requireNonNull(BeanUtil.copy(refundInfo, RefundInfoVO.class));
+
+		//User createUser = UserCache.getUser(refundInfo.getCreateUser());
+		//User updateUser = UserCache.getUser(refundInfo.getUpdateUser());
+		//refundInfoVO.setCreateUserName(createUser.getName());
+		//refundInfoVO.setUpdateUserName(updateUser.getName());
+
+		return refundInfoVO;
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/modules/property/dto/PropertyChargeRecordDTO.java b/src/main/java/org/springblade/modules/property/dto/PropertyChargeRecordDTO.java
new file mode 100644
index 0000000..7762b9a
--- /dev/null
+++ b/src/main/java/org/springblade/modules/property/dto/PropertyChargeRecordDTO.java
@@ -0,0 +1,18 @@
+package org.springblade.modules.property.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import org.springblade.modules.property.entity.PropertyChargeRecord;
+
+/**
+ * 缴费记录表对象 jczz_property_charge_record
+ *
+ * @author ${context.author}
+ * @date 2024-04-07 15:44:09
+ */
+@ApiModel(value = "PropertyChargeRecordDTO对象")
+@Data
+public class PropertyChargeRecordDTO extends PropertyChargeRecord
+{
+
+}
diff --git a/src/main/java/org/springblade/modules/property/entity/PropertyChargeRecord.java b/src/main/java/org/springblade/modules/property/entity/PropertyChargeRecord.java
index 9767dc7..bb97fac 100644
--- a/src/main/java/org/springblade/modules/property/entity/PropertyChargeRecord.java
+++ b/src/main/java/org/springblade/modules/property/entity/PropertyChargeRecord.java
@@ -1,47 +1,127 @@
 package org.springblade.modules.property.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.springblade.core.mp.base.BaseEntity;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 @Data
 @TableName("jczz_property_charge_record")
 @ApiModel(value = "PropertyChargeRecord", description = "物业缴费记录")
-public class PropertyChargeRecord extends BaseEntity {
+public class PropertyChargeRecord  {
 
 
-	//物业公司的deptId
+	/** 主键 */
+	@ApiModelProperty(value = "主键ID", example = "")
+	@TableId(value = "id", type = IdType.ASSIGN_ID)
+	private Long id;
+
+	/** 物业公司id */
+	@ApiModelProperty(value = "物业公司id", example = "")
+	@TableField("property_id")
 	private String propertyId;
 
+	/** 订单号 */
+	@ApiModelProperty(value = "订单号", example = "")
+	@TableField("order_no")
+	private String orderNo;
 
-	//缴费项id
+	/** 缴费项id */
+	@ApiModelProperty(value = "缴费项id", example = "")
+	@TableField("charge_id")
 	private String chargeId;
 
-	//编号
+	/** 缴费单号 */
+	@ApiModelProperty(value = "缴费单号", example = "")
+	@TableField("no")
 	private String no;
 
-	//付款人id
+	/** 付款人id */
+	@ApiModelProperty(value = "付款人id", example = "")
+	@TableField("pay_user")
 	private String payUser;
 
-	//付款时间
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	/** 付费时间 */
+	@ApiModelProperty(value = "付费时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("pay_time")
 	private Date payTime;
 
-	//缴费方式
+	/** 付款方式 */
+	@ApiModelProperty(value = "付款方式", example = "")
+	@TableField("pay_func")
 	private String payFunc;
 
-	//付款金额
-	private String payPrice;
+	/** 付款金额 */
+	@ApiModelProperty(value = "付款金额(分)", example = "")
+	@TableField("pay_price")
+	private BigDecimal payPrice;
 
-	//付款房屋的houseCode
-	private String payHouse;
+	/** 房屋编码 */
+	@ApiModelProperty(value = "房屋编码", example = "")
+	@TableField("house_code")
+	private String houseCode;
 
-	//缴费内容
+	/** 缴费内容 */
+	@ApiModelProperty(value = "缴费内容", example = "")
+	@TableField("pay_content")
 	private String payContent;
+
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("create_time")
+	private Date createTime;
+
+	/** 创建人 */
+	@ApiModelProperty(value = "创建人", example = "")
+	@TableField("create_user")
+	private Long createUser;
+
+	/** 创建部门 */
+	@ApiModelProperty(value = "创建部门", example = "")
+	@TableField("create_dept")
+	private Long createDept;
+
+	/** 修改人 */
+	@ApiModelProperty(value = "修改人", example = "")
+	@TableField("update_user")
+	private Long updateUser;
+
+	/** 修改时间 */
+	@ApiModelProperty(value = "修改时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("update_time")
+	private Date updateTime;
+
+	/** 状态(1、待支付;2、已支付;99取消支付) */
+	@ApiModelProperty(value = "状态(1、待支付;2、已支付;99取消支付)", example = "")
+	@TableField("status")
+	private Integer status;
+
+	/** 是否已删除 */
+	@ApiModelProperty(value = "是否已删除", example = "")
+	@TableField("is_deleted")
+	private Integer isDeleted;
+
+	/** 开始时间 */
+	@ApiModelProperty(value = "开始时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("start_time")
+	private Date startTime;
+
+	/** 到期时间 */
+	@ApiModelProperty(value = "到期时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("end_time")
+	private Date endTime;
 }
diff --git a/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.java b/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.java
index 0b3cac5..bda5a80 100644
--- a/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.java
+++ b/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.java
@@ -19,6 +19,7 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
+import org.springblade.modules.property.dto.PropertyChargeRecordDTO;
 import org.springblade.modules.property.entity.PropertyCharge;
 import org.springblade.modules.property.entity.PropertyChargeRecord;
 import org.springblade.modules.property.vo.PropertyChargeRecordVO;
@@ -36,4 +37,21 @@
 
 
 	List<PropertyChargeRecordVO> getPage(IPage<PropertyChargeRecordVO> page, @Param("vo") PropertyChargeRecordVO vo);
+
+
+	/**
+	 * 查询缴费记录表
+	 *
+	 * @param id 缴费记录表ID
+	 * @return 缴费记录表
+	 */
+	public PropertyChargeRecordDTO selectPropertyChargeRecordById(Long id);
+
+	/**
+	 * 查询缴费记录表列表
+	 *
+	 * @param propertyChargeRecordDTO 缴费记录表
+	 * @return 缴费记录表集合
+	 */
+	public List<PropertyChargeRecordDTO> selectPropertyChargeRecordList(PropertyChargeRecordDTO propertyChargeRecordDTO);
 }
diff --git a/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.xml b/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.xml
index a43ab38..ae8081d 100644
--- a/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.xml
+++ b/src/main/java/org/springblade/modules/property/mapper/PropertyChargeRecordMapper.xml
@@ -6,4 +6,83 @@
     <select id="getPage" resultType="org.springblade.modules.property.vo.PropertyChargeRecordVO">
         SELECT * FROM jczz_property_charge_record where is_deleted = 0
     </select>
+
+
+    <resultMap type="org.springblade.modules.property.dto.PropertyChargeRecordDTO" id="PropertyChargeRecordDTOResult">
+        <result property="id"    column="id"    />
+        <result property="propertyId"    column="property_id"    />
+        <result property="chargeId"    column="charge_id"    />
+        <result property="no"    column="no"    />
+        <result property="payUser"    column="pay_user"    />
+        <result property="payTime"    column="pay_time"    />
+        <result property="payFunc"    column="pay_func"    />
+        <result property="payPrice"    column="pay_price"    />
+        <result property="houseCode"    column="house_code"    />
+        <result property="payContent"    column="pay_content"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="createUser"    column="create_user"    />
+        <result property="createDept"    column="create_dept"    />
+        <result property="updateUser"    column="update_user"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="status"    column="status"    />
+        <result property="isDeleted"    column="is_deleted"    />
+        <result property="startTime"    column="start_time"    />
+        <result property="endTime"    column="end_time"    />
+    </resultMap>
+
+    <sql id="selectPropertyChargeRecord">
+        select
+            id,
+            property_id,
+            charge_id,
+            no,
+            pay_user,
+            pay_time,
+            pay_func,
+            pay_price,
+            house_code,
+            pay_content,
+            create_time,
+            create_user,
+            create_dept,
+            update_user,
+            update_time,
+            status,
+            is_deleted,
+            start_time,
+            end_time
+        from
+            jczz_property_charge_record
+    </sql>
+
+    <select id="selectPropertyChargeRecordById" parameterType="long" resultMap="PropertyChargeRecordDTOResult">
+        <include refid="selectPropertyChargeRecord"/>
+        where
+        id = #{id}
+    </select>
+
+    <select id="selectPropertyChargeRecordList" parameterType="org.springblade.modules.property.dto.PropertyChargeRecordDTO" resultMap="PropertyChargeRecordDTOResult">
+        <include refid="selectPropertyChargeRecord"/>
+        <where>
+            <if test="id != null "> and id = #{id}</if>
+            <if test="propertyId != null  and propertyId != ''"> and property_id = #{propertyId}</if>
+            <if test="chargeId != null  and chargeId != ''"> and charge_id = #{chargeId}</if>
+            <if test="no != null  and no != ''"> and no = #{no}</if>
+            <if test="payUser != null  and payUser != ''"> and pay_user = #{payUser}</if>
+            <if test="payTime != null "> and pay_time = #{payTime}</if>
+            <if test="payFunc != null  and payFunc != ''"> and pay_func = #{payFunc}</if>
+            <if test="payPrice != null "> and pay_price = #{payPrice}</if>
+            <if test="houseCode != null  and houseCode != ''"> and house_code = #{houseCode}</if>
+            <if test="payContent != null  and payContent != ''"> and pay_content = #{payContent}</if>
+            <if test="createTime != null "> and create_time = #{createTime}</if>
+            <if test="createUser != null "> and create_user = #{createUser}</if>
+            <if test="createDept != null "> and create_dept = #{createDept}</if>
+            <if test="updateUser != null "> and update_user = #{updateUser}</if>
+            <if test="updateTime != null "> and update_time = #{updateTime}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="isDeleted != null "> and is_deleted = #{isDeleted}</if>
+            <if test="startTime != null "> and start_time = #{startTime}</if>
+            <if test="endTime != null "> and end_time = #{endTime}</if>
+        </where>
+    </select>
 </mapper>
diff --git a/src/main/java/org/springblade/modules/property/service/IPropertyChargeRecordService.java b/src/main/java/org/springblade/modules/property/service/IPropertyChargeRecordService.java
index 9ece75c..6dffd84 100644
--- a/src/main/java/org/springblade/modules/property/service/IPropertyChargeRecordService.java
+++ b/src/main/java/org/springblade/modules/property/service/IPropertyChargeRecordService.java
@@ -17,6 +17,7 @@
 package org.springblade.modules.property.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.modules.property.entity.PropertyCharge;
 import org.springblade.modules.property.entity.PropertyChargeRecord;
@@ -29,7 +30,7 @@
  * @author BladeX
  * @since 2023-11-23
  */
-public interface IPropertyChargeRecordService extends BaseService<PropertyChargeRecord> {
+public interface IPropertyChargeRecordService extends IService<PropertyChargeRecord> {
 
 
 	IPage<PropertyChargeRecordVO> getPage(IPage<PropertyChargeRecordVO> page, PropertyChargeRecordVO vo);
diff --git a/src/main/java/org/springblade/modules/property/service/impl/PropertyChargeRecordServiceImpl.java b/src/main/java/org/springblade/modules/property/service/impl/PropertyChargeRecordServiceImpl.java
index 28af099..5aedd34 100644
--- a/src/main/java/org/springblade/modules/property/service/impl/PropertyChargeRecordServiceImpl.java
+++ b/src/main/java/org/springblade/modules/property/service/impl/PropertyChargeRecordServiceImpl.java
@@ -1,6 +1,7 @@
 package org.springblade.modules.property.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.modules.property.entity.PropertyCharge;
 import org.springblade.modules.property.entity.PropertyChargeRecord;
@@ -13,7 +14,7 @@
 import org.springframework.stereotype.Service;
 
 @Service
-public class PropertyChargeRecordServiceImpl extends BaseServiceImpl<PropertyChargeRecordMapper, PropertyChargeRecord> implements IPropertyChargeRecordService {
+public class PropertyChargeRecordServiceImpl extends ServiceImpl<PropertyChargeRecordMapper, PropertyChargeRecord> implements IPropertyChargeRecordService {
 	@Override
 	public IPage<PropertyChargeRecordVO> getPage(IPage<PropertyChargeRecordVO> page, PropertyChargeRecordVO vo) {
 		return page.setRecords(baseMapper.getPage(page, vo));
diff --git a/src/main/java/org/springblade/modules/system/entity/User.java b/src/main/java/org/springblade/modules/system/entity/User.java
index 0984744..cb87321 100644
--- a/src/main/java/org/springblade/modules/system/entity/User.java
+++ b/src/main/java/org/springblade/modules/system/entity/User.java
@@ -104,6 +104,10 @@
 	@TableField("lat")
 	private String lat;
 
+	@ApiModelProperty(value = "小程序openid", example = "")
+	@TableField("mini_open_id")
+	private String miniOpenId;
+
 
 
 }
diff --git a/src/main/java/org/springblade/modules/wechat/controller/WechatController.java b/src/main/java/org/springblade/modules/wechat/controller/WechatController.java
new file mode 100644
index 0000000..82b571f
--- /dev/null
+++ b/src/main/java/org/springblade/modules/wechat/controller/WechatController.java
@@ -0,0 +1,33 @@
+package org.springblade.modules.wechat.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.tool.api.R;
+import org.springblade.modules.pay.entity.WeChatMiniAuthorizeVo;
+import org.springblade.modules.wechat.service.WechatService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@RestController
+@RequestMapping("blade-wechat/wechat/")
+@Api(tags = "用户 -- 登录注册")
+public class WechatController {
+	@Resource
+	private WechatService wechatService;
+
+    @ApiOperation(value = "微信小程序授权")
+    @RequestMapping(value = "/getOpenId", method = RequestMethod.GET)
+    public R<WeChatMiniAuthorizeVo> wechatRoutineLogin(String code) throws Exception {
+        return R.data(wechatService.miniAuthCode(code));
+    }
+
+
+}
+
+
+
diff --git a/src/main/java/org/springblade/modules/wechat/service/WechatService.java b/src/main/java/org/springblade/modules/wechat/service/WechatService.java
new file mode 100644
index 0000000..dcb1fb0
--- /dev/null
+++ b/src/main/java/org/springblade/modules/wechat/service/WechatService.java
@@ -0,0 +1,12 @@
+package org.springblade.modules.wechat.service;
+
+import org.springblade.modules.pay.entity.WeChatMiniAuthorizeVo;
+
+public interface WechatService {
+    /**
+     * 小程序登录凭证校验
+     *
+     * @return 小程序登录校验对象
+     */
+    WeChatMiniAuthorizeVo miniAuthCode(String code) throws Exception;
+}
diff --git a/src/main/java/org/springblade/modules/wechat/service/impl/WechatServiceImpl.java b/src/main/java/org/springblade/modules/wechat/service/impl/WechatServiceImpl.java
new file mode 100644
index 0000000..013e175
--- /dev/null
+++ b/src/main/java/org/springblade/modules/wechat/service/impl/WechatServiceImpl.java
@@ -0,0 +1,59 @@
+package org.springblade.modules.wechat.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.common.config.WxMiniConfig;
+import org.springblade.common.utils.HttpClientUtils;
+import org.springblade.common.utils.SpringUtils;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.modules.pay.entity.WeChatMiniAuthorizeVo;
+import org.springblade.modules.system.entity.User;
+import org.springblade.modules.system.service.IUserService;
+import org.springblade.modules.wechat.service.WechatService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class WechatServiceImpl implements WechatService {
+
+	private static final Logger logger = LoggerFactory.getLogger(WechatServiceImpl.class);
+
+	@Resource
+	private WxMiniConfig wxMiniConfig;
+
+	/**
+	 * 小程序登录凭证校验
+	 *
+	 * @return 小程序登录校验对象
+	 */
+	@Override
+	public WeChatMiniAuthorizeVo miniAuthCode(String code) throws Exception {
+		String url = StrUtil.format(wxMiniConfig.getJscode2sessionUrl(), wxMiniConfig.getAppid(), wxMiniConfig.getSecret(), code);
+		JSONObject data = JSON.parseObject(HttpClientUtils.doGet(url));
+		if (ObjectUtil.isNull(data)) {
+			logger.error("微信平台接口异常,没任何数据返回!");
+			throw new Exception("微信平台接口异常,没任何数据返回!");
+		}
+		if (data.containsKey("errcode") && !data.getString("errcode").equals("0")) {
+			if (data.containsKey("errmsg")) {
+				logger.error("微信接口调用失败:" + data.getString("errcode") + data.getString("errmsg"));
+				throw new Exception("微信接口调用失败:" + data.getString("errcode") + data.getString("errmsg"));
+			}
+		}
+		WeChatMiniAuthorizeVo weChatMiniAuthorizeVo = JSONObject.parseObject(data.toJSONString(), WeChatMiniAuthorizeVo.class);
+		// 绑定用户openid
+		Long userId = AuthUtil.getUserId();
+		IUserService userService = SpringUtils.getBean(IUserService.class);
+		userService.update(Wrappers.<User>lambdaUpdate().set(User::getMiniOpenId, weChatMiniAuthorizeVo.getOpenId()).eq(User::getId, userId));
+		return weChatMiniAuthorizeVo;
+	}
+
+
+}
+
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 55f16f6..a45e5b6 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -316,3 +316,18 @@
   appId: 202403288666059313538996533
   privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCCL4tz9BbUz+z3vs/eFwmUmQhsTiP3ZLwruTMJuEhsTEsT58PrdUOKGipwhKF88zj8SCk/Tn8izvDXj5IzqHEWjSEkfivYHx/6cE3VdHc6vvpvpeC06264d5NN4T6hwYH9CYz9iSmx9HFxADlg5zxj0lHqLSFf25cmEPF3F7PvAzj1cmYrKjet1HtCKaAyKADD+ojHHRjNLXZg3E5CINUqRYlLi+OKQph3VdrfokkO8efe8CR2wdiGU78mV1/UtTaiSYOEwv7pkbGECkqIXp+xYzaAVNCxikIWkc+qKmvvJXKsQVOKqv5b7/FQ/ag8trWPe8JLcQCN/Zg7DXSTc9YHAgMBAAECggEAENI73punZ5AGOmy5RyUK49xyLixakVi+x5eCdLsPAI9LFCNaOU5Jj8qZuTgp9Y8nydE5IyjtXH4IuJGgfnRBSHyrz59N4vsCksV4CSCnVzvd+Bci1b2l7MfmjKWSBiyOszdMtGXIsWm4TrWMtGysbOl8FBoIue4RtaVyzcSOR0+gDCIkn2XGqh3FhSIIApYm+eTOPDLZuSOsrgoTrppTOVUCXGN+/cSBAegWQnCES0b49F2EIRCAtSybc52N7zFPB9f8Kzzmgozilf00uS27HLZplwyLA6FMargdOi619x3T/XY52a55r4ldu/aZF2EbD1RpvMi9aGH/O77HtmLfAQKBgQC/32H0ibR5BgqfUjOWS0v+GRqG0gXr4x2R/oY9Pym16F5gEFKDYauBfEK4GYDtTEahB0Wo0n57StSZ3fX6yy9uBsPxywy0yUvzkxwe2th8fBg5czEBbLzHz4RMqo7LkfwKBatKMJLCOLdecSV2uJlDt/AIRFx5ymypiVLyYHb4IQKBgQCtsjv0ThHMM861CEfe9FZ2B4LFGfCptcek95ilARc7r3RpZpSSi+K0mF2992JVen+dkPh3FuG5NM5VSJeFyReNj5RxVz8A+4d9w3fxrqi2qfC1TFHR7IRv4JzPeZ+7wkMSc7rwkJ9UBSOdecXm2FV7BOivtnf7bGWIGLJNUb7pJwKBgCu0ZkudUk5+4cyInNePLzAh57jt/gtNIF8w6sLosEePNnALR8BFbxt/gnMM3CExTqU/Us6xo73RvbuOo4kM3zDguaFJ7wr/Dx3cVHtyvf0dByeO5Yq9igK5chlEgGI+Tnq579pmVgeHg70vaKkyQzb5nuNDLw1O3pF/hjVPY8oBAoGAFLW5nElqqdRLgx43o4eyf2Qp3WJYZYO9CBhVZOcaZA1pbd/DOy3em/XGx42lddejO6A7X8ekpjZ7m4OKPXNakZBa/KCQbIeRAhe6R2Cx0QW2I4e0AbmXmNdJGxu/Rd3FrX+K/H/h31y1gGMyi3Gjz4UoUTsKVzn3aSC4satbfeUCgYEAmpIo2ZO4hQ9THCOdgR5udXRG5s5JjGEct2QSxXntRyJm3RAkPA3/mEDVlI6X5UNIn7BKeThCFo5eM2bbFFF4sFeNV0W4uP8p9dsOnpwU7FzT++16WNiBopQpff72MNzjnt/k/KLlX/zV60zbMJ1R6McYsv0LP9Zuv9RAo8v8ZDU=
   sopCreateBy: 106575361457
+
+wxpay:
+  api-v3-key: qqwuMJcCPRhcNcmFlqb6ucxdHKqVxp9U
+  appid: wxeeab25f4f176f1fc
+  domain: https://api.mch.weixin.qq.com
+  mch-id: 1600701071
+  mch-serial-no: 4C19EAFA9E0AD598DDE3D7399B47C3D5C85EB7C9
+  notify-domain: https://wx.nkjj88.com
+  partnerKey: qqwuMJcCPRhcNcmFlqb6ucxdHKqVxp9U
+  private-key-path: /www/wwwroot/apiclient_key.pem
+  private-cert-path: /www/wwwroot/apiclient_cert.p12
+wxmini:
+  appid: wxeeab25f4f176f1fc
+  secret: 0a0e0d0a0c0b0a09080706050403020100
+  jscode2sessionUrl: https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code

--
Gitblit v1.9.3