From 551f464b563572850267cd1f2300941943084891 Mon Sep 17 00:00:00 2001 From: Aug <17674666882@163.com> Date: Wed, 21 May 2025 14:33:32 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E9=80=80=E6=AC=BE=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ithub_wechatpay_apiv3_wechatpay_java_0_2_15.xml | 13 + ..._wechatpay_apiv3_wechatpay_java_core_0_2_15.xml | 13 + .idea/workspace.xml | 230 ++++++++--- .../controller/MassageOrderController.java | 2 +- .../modules/massageOrder/entity/MassageOrder.java | 6 +- .../massageOrder/mapper/MassageOrderMapper.java | 2 +- .../massageOrder/service/IMassageOrderService.java | 2 +- .../service/impl/MassageOrderServiceImpl.java | 2 +- .../modules/massageOrder/vue/MassageOrderList.vue | 6 + .../massageOrder/vue/modules/MassageOrderForm.vue | 5 + .../modules/massageOrder/vue3/MassageOrder.data.ts | 10 + .../controller/MassageRefoundLogController.java | 171 +++++++++ .../entity/MassageRefoundLog.java | 71 ++++ .../mapper/MassageRefoundLogMapper.java | 17 + .../mapper/xml/MassageRefoundLogMapper.xml | 5 + .../service/IMassageRefoundLogService.java | 14 + .../service/impl/MassageRefoundLogServiceImpl.java | 19 + .../vue/MassageRefoundLogList.vue | 196 ++++++++++ .../vue/modules/MassageRefoundLogForm.vue | 124 ++++++ .../MassageRefoundLogModal.Style#Drawer.vue | 84 ++++ .../vue/modules/MassageRefoundLogModal.vue | 60 +++ .../vue3/MassageRefoundLog.api.ts | 61 +++ .../vue3/MassageRefoundLog.data.ts | 69 ++++ .../vue3/MassageRefoundLogList.vue | 162 ++++++++ .../vue3/components/MassageRefoundLogModal.vue | 58 +++ .../jeecg-boot-module-system.iml | 2 + jeecg-boot-module-system/pom.xml | 7 + .../api/massageController/RefoundController.java | 61 +++ .../modules/apiService/WxMiniappPayService.java | 29 ++ .../apiService/impl/WxMiniappPayServiceImpl.java | 422 +++++++++++++++++++++ .../org/jeecg/modules/wxUtils/CreateOrderReq.java | 8 + .../jeecg/modules/wxUtils/HttpServletUtils.java | 47 +++ .../org/jeecg/modules/wxUtils/PayOrderInfo.java | 31 ++ .../org/jeecg/modules/wxUtils/QueryOrderReq.java | 23 ++ .../org/jeecg/modules/wxUtils/RefundOrderReq.java | 36 ++ .../java/org/jeecg/modules/wxUtils/Response.java | 164 ++++++++ .../wxUtils/WxPayAutoCertificateConfig.java | 113 ++++++ .../org/jeecg/modules/wxUtils/WxPayConfig.java | 13 + .../src/main/resources/apiclient_key.pem | 28 ++ .../src/main/resources/application-dev.yml | 28 ++ .../src/main/resources/pub_key.pem | 9 + 41 files changed, 2373 insertions(+), 50 deletions(-) create mode 100644 .idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_0_2_15.xml create mode 100644 .idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_core_0_2_15.xml create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/controller/MassageRefoundLogController.java create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/entity/MassageRefoundLog.java create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/MassageRefoundLogMapper.java create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/xml/MassageRefoundLogMapper.xml create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/IMassageRefoundLogService.java create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/impl/MassageRefoundLogServiceImpl.java create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/MassageRefoundLogList.vue create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogForm.vue create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.Style#Drawer.vue create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.vue create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.api.ts create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.data.ts create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLogList.vue create mode 100644 jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/components/MassageRefoundLogModal.vue create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/massageController/RefoundController.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/WxMiniappPayService.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/WxMiniappPayServiceImpl.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/CreateOrderReq.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/HttpServletUtils.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/PayOrderInfo.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/QueryOrderReq.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/RefundOrderReq.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/Response.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayAutoCertificateConfig.java create mode 100644 jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayConfig.java create mode 100644 jeecg-boot-module-system/src/main/resources/apiclient_key.pem create mode 100644 jeecg-boot-module-system/src/main/resources/pub_key.pem diff --git a/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_0_2_15.xml b/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_0_2_15.xml new file mode 100644 index 0000000..783b541 --- /dev/null +++ b/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_0_2_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_core_0_2_15.xml b/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_core_0_2_15.xml new file mode 100644 index 0000000..fbc3769 --- /dev/null +++ b/.idea/libraries/Maven__com_github_wechatpay_apiv3_wechatpay_java_core_0_2_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index eb2f72c..9e69024 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,9 +1,51 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - + @@ -318,17 +433,28 @@ - - + - + + + + + @@ -337,74 +463,78 @@ - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + @@ -413,20 +543,30 @@ - + - + file://$PROJECT_DIR$/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/OrderServiceImpl.java - 265 - + + file://$PROJECT_DIR$/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/WxMiniappPayServiceImpl.java + 249 + + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/controller/MassageOrderController.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/controller/MassageOrderController.java index c67ee1f..ca20ae8 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/controller/MassageOrderController.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/controller/MassageOrderController.java @@ -39,7 +39,7 @@ import org.jeecg.common.aspect.annotation.AutoLog; /** * @Description: 订单信息表 * @Author: jeecg-boot - * @Date: 2025-05-18 + * @Date: 2025-05-20 * @Version: V1.0 */ @Api(tags="订单信息表") diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/entity/MassageOrder.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/entity/MassageOrder.java index 99927f3..53f7c5a 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/entity/MassageOrder.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/entity/MassageOrder.java @@ -22,7 +22,7 @@ import lombok.experimental.Accessors; /** * @Description: 订单信息表 * @Author: jeecg-boot - * @Date: 2025-05-18 + * @Date: 2025-05-20 * @Version: V1.0 */ @Data @@ -98,6 +98,10 @@ public class MassageOrder implements Serializable { @Dict(dicCode = "is_del") @ApiModelProperty(value = "是否删除") private java.lang.String isDel; + /**是否已退款*/ + @Excel(name = "是否已退款", width = 15) + @ApiModelProperty(value = "是否已退款") + private java.lang.String isRefound; //项目信息 @TableField(exist = false) diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/mapper/MassageOrderMapper.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/mapper/MassageOrderMapper.java index 99d767c..ba5b59d 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/mapper/MassageOrderMapper.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/mapper/MassageOrderMapper.java @@ -9,7 +9,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @Description: 订单信息表 * @Author: jeecg-boot - * @Date: 2025-05-18 + * @Date: 2025-05-20 * @Version: V1.0 */ public interface MassageOrderMapper extends BaseMapper { diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/IMassageOrderService.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/IMassageOrderService.java index 04b5577..fa1dcd5 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/IMassageOrderService.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/IMassageOrderService.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService; /** * @Description: 订单信息表 * @Author: jeecg-boot - * @Date: 2025-05-18 + * @Date: 2025-05-20 * @Version: V1.0 */ public interface IMassageOrderService extends IService { diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/impl/MassageOrderServiceImpl.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/impl/MassageOrderServiceImpl.java index 1ddcaaa..2e9a00e 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/impl/MassageOrderServiceImpl.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/service/impl/MassageOrderServiceImpl.java @@ -10,7 +10,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; /** * @Description: 订单信息表 * @Author: jeecg-boot - * @Date: 2025-05-18 + * @Date: 2025-05-20 * @Version: V1.0 */ @Service diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/MassageOrderList.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/MassageOrderList.vue index b93b82d..71dfed4 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/MassageOrderList.vue +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/MassageOrderList.vue @@ -177,6 +177,11 @@ align:"center", dataIndex: 'isDel_dictText' }, + { + title:'是否已退款', + align:"center", + dataIndex: 'isRefound' + }, { title: '操作', dataIndex: 'action', @@ -222,6 +227,7 @@ fieldList.push({type:'string',value:'itemId',text:'关联项目id',dictCode:"massage_item,title,id"}) fieldList.push({type:'string',value:'userId',text:'关联用户id',dictCode:"han_hai_member,nick_name,id"}) fieldList.push({type:'string',value:'isDel',text:'是否删除',dictCode:'is_del'}) + fieldList.push({type:'string',value:'isRefound',text:'是否已退款',dictCode:''}) this.superFieldList = fieldList } } diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/modules/MassageOrderForm.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/modules/MassageOrderForm.vue index d666913..c55a35f 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/modules/MassageOrderForm.vue +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue/modules/MassageOrderForm.vue @@ -58,6 +58,11 @@ + + + + + diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue3/MassageOrder.data.ts b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue3/MassageOrder.data.ts index 9321abc..9daffa1 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue3/MassageOrder.data.ts +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageOrder/vue3/MassageOrder.data.ts @@ -59,6 +59,11 @@ export const columns: BasicColumn[] = [ align:"center", dataIndex: 'isDel_dictText' }, + { + title: '是否已退款', + align:"center", + dataIndex: 'isRefound' + }, ]; //查询数据 export const searchFormSchema: FormSchema[] = [ @@ -135,4 +140,9 @@ export const formSchema: FormSchema[] = [ dictCode:"is_del" }, }, + { + label: '是否已退款', + field: 'isRefound', + component: 'Input', + }, ]; diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/controller/MassageRefoundLogController.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/controller/MassageRefoundLogController.java new file mode 100644 index 0000000..5cfa676 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/controller/MassageRefoundLogController.java @@ -0,0 +1,171 @@ +package org.jeecg.modules.massageRefoundLog.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.massageRefoundLog.entity.MassageRefoundLog; +import org.jeecg.modules.massageRefoundLog.service.IMassageRefoundLogService; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.jeecg.common.aspect.annotation.AutoLog; + + /** + * @Description: 退款记录表 + * @Author: jeecg-boot + * @Date: 2025-05-20 + * @Version: V1.0 + */ +@Api(tags="退款记录表") +@RestController +@RequestMapping("/massageRefoundLog/massageRefoundLog") +@Slf4j +public class MassageRefoundLogController extends JeecgController { + @Autowired + private IMassageRefoundLogService massageRefoundLogService; + + /** + * 分页列表查询 + * + * @param massageRefoundLog + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "退款记录表-分页列表查询") + @ApiOperation(value="退款记录表-分页列表查询", notes="退款记录表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(MassageRefoundLog massageRefoundLog, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(massageRefoundLog, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = massageRefoundLogService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param massageRefoundLog + * @return + */ + @AutoLog(value = "退款记录表-添加") + @ApiOperation(value="退款记录表-添加", notes="退款记录表-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody MassageRefoundLog massageRefoundLog) { + massageRefoundLogService.save(massageRefoundLog); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param massageRefoundLog + * @return + */ + @AutoLog(value = "退款记录表-编辑") + @ApiOperation(value="退款记录表-编辑", notes="退款记录表-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody MassageRefoundLog massageRefoundLog) { + massageRefoundLogService.updateById(massageRefoundLog); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "退款记录表-通过id删除") + @ApiOperation(value="退款记录表-通过id删除", notes="退款记录表-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + massageRefoundLogService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "退款记录表-批量删除") + @ApiOperation(value="退款记录表-批量删除", notes="退款记录表-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.massageRefoundLogService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "退款记录表-通过id查询") + @ApiOperation(value="退款记录表-通过id查询", notes="退款记录表-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + MassageRefoundLog massageRefoundLog = massageRefoundLogService.getById(id); + if(massageRefoundLog==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(massageRefoundLog); + } + + /** + * 导出excel + * + * @param request + * @param massageRefoundLog + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, MassageRefoundLog massageRefoundLog) { + return super.exportXls(request, massageRefoundLog, MassageRefoundLog.class, "退款记录表"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, MassageRefoundLog.class); + } + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/entity/MassageRefoundLog.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/entity/MassageRefoundLog.java new file mode 100644 index 0000000..ad9e697 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/entity/MassageRefoundLog.java @@ -0,0 +1,71 @@ +package org.jeecg.modules.massageRefoundLog.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 退款记录表 + * @Author: jeecg-boot + * @Date: 2025-05-20 + * @Version: V1.0 + */ +@Data +@TableName("massage_refound_log") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="massage_refound_log对象", description="退款记录表") +public class MassageRefoundLog implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private java.lang.String id; + /**创建人*/ + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @ApiModelProperty(value = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @ApiModelProperty(value = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @ApiModelProperty(value = "更新日期") + private java.util.Date updateTime; + /**关联订单id*/ + @Excel(name = "关联订单id", width = 15) + @ApiModelProperty(value = "关联订单id") + private java.lang.String orderId; + /**退款时间*/ + @Excel(name = "退款时间", width = 15) + @ApiModelProperty(value = "退款时间") + private java.util.Date refoundTime; + /**退款金额*/ + @Excel(name = "退款金额", width = 15) + @ApiModelProperty(value = "退款金额") + private java.math.BigDecimal refoundAmount; + /**退款状态*/ + @Excel(name = "退款状态", width = 15) + @ApiModelProperty(value = "退款状态") + private java.lang.String status; + /**关联用户id*/ + @Excel(name = "关联用户id", width = 15, dictTable = "han_hai_member", dicText = "nick_name", dicCode = "id") + @Dict(dictTable = "han_hai_member", dicText = "nick_name", dicCode = "id") + @ApiModelProperty(value = "关联用户id") + private java.lang.String userId; +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/MassageRefoundLogMapper.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/MassageRefoundLogMapper.java new file mode 100644 index 0000000..870734c --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/MassageRefoundLogMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.massageRefoundLog.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.massageRefoundLog.entity.MassageRefoundLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 退款记录表 + * @Author: jeecg-boot + * @Date: 2025-05-20 + * @Version: V1.0 + */ +public interface MassageRefoundLogMapper extends BaseMapper { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/xml/MassageRefoundLogMapper.xml b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/xml/MassageRefoundLogMapper.xml new file mode 100644 index 0000000..ec29024 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/mapper/xml/MassageRefoundLogMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/IMassageRefoundLogService.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/IMassageRefoundLogService.java new file mode 100644 index 0000000..704b54d --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/IMassageRefoundLogService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.massageRefoundLog.service; + +import org.jeecg.modules.massageRefoundLog.entity.MassageRefoundLog; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 退款记录表 + * @Author: jeecg-boot + * @Date: 2025-05-20 + * @Version: V1.0 + */ +public interface IMassageRefoundLogService extends IService { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/impl/MassageRefoundLogServiceImpl.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/impl/MassageRefoundLogServiceImpl.java new file mode 100644 index 0000000..47dd982 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/service/impl/MassageRefoundLogServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.massageRefoundLog.service.impl; + +import org.jeecg.modules.massageRefoundLog.entity.MassageRefoundLog; +import org.jeecg.modules.massageRefoundLog.mapper.MassageRefoundLogMapper; +import org.jeecg.modules.massageRefoundLog.service.IMassageRefoundLogService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 退款记录表 + * @Author: jeecg-boot + * @Date: 2025-05-20 + * @Version: V1.0 + */ +@Service +public class MassageRefoundLogServiceImpl extends ServiceImpl implements IMassageRefoundLogService { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/MassageRefoundLogList.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/MassageRefoundLogList.vue new file mode 100644 index 0000000..fa845f7 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/MassageRefoundLogList.vue @@ -0,0 +1,196 @@ + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogForm.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogForm.vue new file mode 100644 index 0000000..7998552 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogForm.vue @@ -0,0 +1,124 @@ + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.Style#Drawer.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.Style#Drawer.vue new file mode 100644 index 0000000..c83b529 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.Style#Drawer.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.vue new file mode 100644 index 0000000..065cd64 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue/modules/MassageRefoundLogModal.vue @@ -0,0 +1,60 @@ + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.api.ts b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.api.ts new file mode 100644 index 0000000..4cfd1da --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.api.ts @@ -0,0 +1,61 @@ +import {defHttp} from '/@/utils/http/axios'; +import {Modal} from 'ant-design-vue'; + +enum Api { + list = '/massageRefoundLog/massageRefoundLog/list', + save='/massageRefoundLog/massageRefoundLog/add', + edit='/massageRefoundLog/massageRefoundLog/edit', + deleteOne = '/massageRefoundLog/massageRefoundLog/delete', + deleteBatch = '/massageRefoundLog/massageRefoundLog/deleteBatch', + importExcel = '/massageRefoundLog/massageRefoundLog/importExcel', + exportXls = '/massageRefoundLog/massageRefoundLog/exportXls', +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +/** + * 列表接口 + * @param params + */ +export const list = (params) => + defHttp.get({url: Api.list, params}); + +/** + * 删除单个 + */ +export const deleteOne = (params,handleSuccess) => { + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} +/** + * 批量删除 + * @param params + */ +export const batchDelete = (params, handleSuccess) => { + Modal.confirm({ + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.data.ts b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.data.ts new file mode 100644 index 0000000..a23a653 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLog.data.ts @@ -0,0 +1,69 @@ +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +//列表数据 +export const columns: BasicColumn[] = [ + { + title: '关联订单id', + align:"center", + dataIndex: 'orderId' + }, + { + title: '退款时间', + align:"center", + dataIndex: 'refoundTime' + }, + { + title: '退款金额', + align:"center", + dataIndex: 'refoundAmount' + }, + { + title: '退款状态', + align:"center", + dataIndex: 'status_dictText' + }, + { + title: '关联用户id', + align:"center", + dataIndex: 'userId_dictText' + }, +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +]; +//表单数据 +export const formSchema: FormSchema[] = [ + { + label: '关联订单id', + field: 'orderId', + component: 'Input', + }, + { + label: '退款时间', + field: 'refoundTime', + component: 'Input', + }, + { + label: '退款金额', + field: 'refoundAmount', + component: 'InputNumber', + }, + { + label: '退款状态', + field: 'status', + component: 'JDictSelectTag', + componentProps:{ + dictCode:"" + }, + }, + { + label: '关联用户id', + field: 'userId', + component: 'JDictSelectTag', + componentProps:{ + dictCode:"han_hai_member,nick_name,id" + }, + }, +]; diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLogList.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLogList.vue new file mode 100644 index 0000000..7e25183 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/MassageRefoundLogList.vue @@ -0,0 +1,162 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/components/MassageRefoundLogModal.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/components/MassageRefoundLogModal.vue new file mode 100644 index 0000000..c6d2611 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/massageRefoundLog/vue3/components/MassageRefoundLogModal.vue @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-module-system/jeecg-boot-module-system.iml b/jeecg-boot-module-system/jeecg-boot-module-system.iml index 4a1bf6f..be7f453 100644 --- a/jeecg-boot-module-system/jeecg-boot-module-system.iml +++ b/jeecg-boot-module-system/jeecg-boot-module-system.iml @@ -289,6 +289,8 @@ + + diff --git a/jeecg-boot-module-system/pom.xml b/jeecg-boot-module-system/pom.xml index f9aedc0..08966d3 100644 --- a/jeecg-boot-module-system/pom.xml +++ b/jeecg-boot-module-system/pom.xml @@ -74,6 +74,13 @@ compile + + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.15 + + diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/massageController/RefoundController.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/massageController/RefoundController.java new file mode 100644 index 0000000..a372739 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/massageController/RefoundController.java @@ -0,0 +1,61 @@ +package org.jeecg.modules.api.massageController; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.modules.apiService.WxMiniappPayService; +import org.jeecg.modules.wxUtils.RefundOrderReq; +import org.jeecg.modules.wxUtils.Response; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +@Api(tags="退款-退款相关接口") +@RestController +@RequestMapping("/massage/refound") +@Slf4j +public class RefoundController { + @Resource + private WxMiniappPayService wxMiniappPayService; + + /** + * 退款申请 + * @param orderId + * @return + */ + @ApiOperation( + value="退款", + notes="退款") + @PostMapping("/refund") + public Response refund(@RequestHeader("X-Access-Token") String token, String orderId) { + log.info("------微信支付退款------"); + return wxMiniappPayService.refund(token, orderId); + } + +// /** +// * 查询单笔退款(通过商户退款单号) +// * @param outRefundNo 商户退款单号 +// * @return +// */ +// @ApiOperation( +// value="查询单笔退款(通过商户退款单号)", +// notes="查询单笔退款(通过商户退款单号)") +// @GetMapping("/queryByOutRefundNo") +// public Response queryByOutRefundNo(String outRefundNo) { +// log.info("------微信支付查询单笔退款------"); +// return wxMiniappPayService.queryByOutRefundNo(outRefundNo); +// } + + /** + * 微信小程序退款回调 + * @param request + * @return + * @throws Exception + */ + @PostMapping("/refundNotify") + public String refundNotify(HttpServletRequest request) throws Exception { + log.info("------微信支付微信小程序退款回调------"); + return wxMiniappPayService.refundNotify(request); + } +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/WxMiniappPayService.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/WxMiniappPayService.java new file mode 100644 index 0000000..39ab7dd --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/WxMiniappPayService.java @@ -0,0 +1,29 @@ +package org.jeecg.modules.apiService; + +import org.jeecg.modules.wxUtils.RefundOrderReq; +import org.jeecg.modules.wxUtils.Response; + +import javax.servlet.http.HttpServletRequest; + +public interface WxMiniappPayService { + /** + * 退款 + * @param orderId + * @return + */ + Response refund(String token, String orderId); + + /** + * 查询单笔退款(通过商户退款单号) + * @param outRefundNo 商户退款单号 + * @return + */ + Response queryByOutRefundNo(String outRefundNo); + + /** + * 微信小程序退款回调 + * @param request + * @return + */ + String refundNotify(HttpServletRequest request); +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/WxMiniappPayServiceImpl.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/WxMiniappPayServiceImpl.java new file mode 100644 index 0000000..6d7d0d3 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/WxMiniappPayServiceImpl.java @@ -0,0 +1,422 @@ +package org.jeecg.modules.apiService.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.exception.HttpException; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.*; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.config.shiro.ShiroRealm; +import org.jeecg.modules.apiService.WxMiniappPayService; +import org.jeecg.modules.apiUtils.CommonUtils; +import org.jeecg.modules.hanHaiMember.entity.HanHaiMember; +import org.jeecg.modules.hanHaiMember.service.IHanHaiMemberService; +import org.jeecg.modules.massageOrder.entity.MassageOrder; +import org.jeecg.modules.massageOrder.service.IMassageOrderService; +import org.jeecg.modules.massageRefoundLog.entity.MassageRefoundLog; +import org.jeecg.modules.massageRefoundLog.service.IMassageRefoundLogService; +import org.jeecg.modules.wxUtils.HttpServletUtils; +import org.jeecg.modules.wxUtils.RefundOrderReq; +import org.jeecg.modules.wxUtils.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Service +public class WxMiniappPayServiceImpl implements WxMiniappPayService { + + /** + * 微信小程序的 AppID + */ + @Value("${wx.miniapp.appid}") + private String appid; + + /** + * 微信小程序的密钥 + */ + @Value("${wx.miniapp.secret}") + private String secret; + + /** + * 商户号 + */ + @Value("${wx.miniapp.merchantId}") + private String merchantId; + + /** + * 商户API私钥路径 + */ + @Value("${wx.miniapp.privateKeyPath}") + private String privateKeyPath; + + /** + * 商户证书序列号 + */ + @Value("${wx.miniapp.merchantSerialNumber}") + private String merchantSerialNumber; + + /** + * 商户APIV3密钥 + */ + @Value("${wx.miniapp.apiV3Key}") + private String apiV3Key; + + /** + * 支付通知地址 + */ + @Value("${wx.miniapp.payNotifyUrl}") + private String payNotifyUrl; + + /** + * 退款通知地址 + */ + @Value("${wx.miniapp.refundNotifyUrl}") + private String refundNotifyUrl; + + + @Autowired + @Qualifier("rsaAutoCertificateConfig") + private Config config; + @Autowired + @Qualifier("rsaAutoCertificateConfig") + private Config notificationConfig; + + +// @Autowired +// private IPopularizeOrderService popularizeOrderService; +// +// @Autowired +// private IPopularizeOrderTuiLogService popularizeOrderTuiLogService; + + //权限验证 + @Resource + private ShiroRealm shiroRealm; + + //退款记录 + @Autowired + private IHanHaiMemberService hanHaiMemberService; + + //订单信息 + @Autowired + private IMassageOrderService massageOrderService; + + //退款记录 + @Autowired + private IMassageRefoundLogService massageRefoundLogService; + + + /** + * 退款 + *
+     * 交易时间超过一年的订单无法提交退款(按支付成功时间+365天计算)
+     * 微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
+     * 请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次
+     * 每个支付订单的部分退款次数不能超过50次
+     * 如果同一个用户有多笔退款,建议分不同批次进行退款,避免并发退款导致退款失败
+     * 申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过退款查询接口获取结果
+     * 错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次
+     * 一个月之前的订单申请退款频率限制为:5000/min
+     * 同一笔订单多次退款的请求需相隔1分钟
+     * 
+ * + * @param orderId + * @return + */ + @Override + public Response refund(String token, String orderId) { + //权限验证 + HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token); + //HanHaiMember hanHaiMember = hanHaiMemberService.getById("1919297392365035521"); + + // 初始化服务 + RefundService service = new RefundService.Builder().config(config).build(); + + //根据订单标识查询订单 + MassageOrder payOrder = massageOrderService.lambdaQuery() + .eq(MassageOrder::getId, orderId) + .eq(MassageOrder::getUserId, hanHaiMember.getId()) + .one(); + if (payOrder == null) { + return Response.error("订单不存在"); + } + + //查询订单是否已经退款过 + MassageRefoundLog check = massageRefoundLogService + .lambdaQuery() + .eq(MassageRefoundLog::getOrderId, orderId) + .eq(MassageRefoundLog::getUserId, hanHaiMember.getId()) + .one(); + if(null != check){ + return Response.error("该订单已经退款过:"+orderId); + } + //添加退款记录 + MassageRefoundLog massageRefoundLog = new MassageRefoundLog(); + massageRefoundLog.setStatus("0");//退款状态 + massageRefoundLog.setOrderId(orderId);//退款订单号 + massageRefoundLog.setRefoundAmount(payOrder.getAmount());//退款金额 + massageRefoundLog.setUserId(hanHaiMember.getId());//退款用户 + massageRefoundLogService.save(massageRefoundLog); +// if (payOrder.getAmount().compareTo(req.getRefundAmount()) < 0) { +// return Response.error("退款金额不能大于支付金额"); +// } + + CreateRequest request = new CreateRequest(); + // 调用request.setXxx(val)设置所需参数,具体参数可见Request定义 + request.setOutTradeNo(orderId); + request.setOutRefundNo("REFUND_" + orderId); + AmountReq amount = new AmountReq(); + // 订单总金额,单位为分,只能为整数,详见支付金额 + amount.setTotal(decimalToLong(payOrder.getAmount())); + // 退款金额,单位为分,只能为整数,不能超过支付总额 + amount.setRefund(decimalToLong(payOrder.getAmount())); + amount.setCurrency("CNY"); + + request.setAmount(amount); + request.setNotifyUrl(refundNotifyUrl); + // 调用接口 + Refund refund = null; + try { + refund = service.create(request); + } catch (HttpException e) { + log.error("退款申请失败,发送HTTP请求失败:", e); + return Response.error("退款失败"); + } catch (MalformedMessageException e) { + log.error("退款申请失败,解析微信支付应答或回调报文异常,返回信息:", e); + return Response.error("退款失败"); + } catch (ValidationException e) { + log.error("退款申请失败,验证签名失败,返回信息:", e); + return Response.error("验证签名失败"); + } catch (ServiceException e) { + log.error("退款申请失败,发送HTTP请求成功,返回异常,返回码:{},返回信息:", e.getErrorCode(), e); + return Response.error("退款失败:" + e.getErrorMessage()); + } catch (Exception e) { + log.error("退款申请失败,异常:", e); + return Response.error("退款失败"); + } + if (Status.SUCCESS.equals(refund.getStatus())) { + log.info("退款成功!-订单号:{}", payOrder.getId()); + + //修改退款记录订单状态 + MassageRefoundLog refoundLog = massageRefoundLogService.lambdaQuery() + .eq(MassageRefoundLog::getOrderId, payOrder.getId()) + .one(); + + refoundLog.setRefoundTime(CommonUtils.getCurrentTime()); + refoundLog.setStatus("1"); + massageRefoundLogService.updateById(refoundLog); + + return Response.success("退款成功"); + } else if (Status.CLOSED.equals(refund.getStatus())) { + log.info("退款关闭!-订单号:{}", payOrder.getId()); + return Response.error("退款关闭"); + } else if (Status.PROCESSING.equals(refund.getStatus())) { + log.info("退款处理中!-订单号:{}", payOrder.getId()); + return Response.error("退款处理中"); + } else if (Status.ABNORMAL.equals(refund.getStatus())) { + log.info("退款异常!-订单号:{}", payOrder.getId()); + return Response.error("退款异常"); + } + return Response.error("退款失败"); + } + + /** + * 查询单笔退款(通过商户退款单号) + *
+     * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,建议查询退款状态在提交退款申请后1分钟发起,一般来说零钱支付的退款5分钟内到账,银行卡支付的退款1-3个工作日到账。
+     * 
+ * + * @param outRefundNo 商户退款单号 + * @return + */ + @Override + public Response queryByOutRefundNo(String outRefundNo) { + // 初始化服务 + RefundService service = new RefundService.Builder().config(config).build(); + QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest(); + // 调用request.setXxx(val)设置所需参数,具体参数可见Request定义 + request.setOutRefundNo(outRefundNo.trim()); + // 调用接口 + Refund refund = null; + try { + refund = service.queryByOutRefundNo(request); + log.info("退款查询结果:{}", JSONObject.toJSONString(refund)); + //【退款状态】退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。可选取值:SUCCESS:退款成功CLOSED:退款关闭PROCESSING:退款处理中ABNORMAL:退款异常【退款状态】退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。可选取值:SUCCESS:退款成功CLOSED:退款关闭PROCESSING:退款处理中ABNORMAL:退款异常 + if (Status.SUCCESS.equals(refund.getStatus())) { + log.info("退款成功!-订单号:{}", outRefundNo); + return Response.success("退款成功"); + } else if (Status.CLOSED.equals(refund.getStatus())) { + log.info("退款关闭!-订单号:{}", outRefundNo); + return Response.error("退款关闭"); + } else if (Status.PROCESSING.equals(refund.getStatus())) { + log.info("退款处理中!-订单号:{}", outRefundNo); + return Response.success("退款处理中"); + } else if (Status.ABNORMAL.equals(refund.getStatus())) { + log.info("退款异常!-订单号:{}", outRefundNo); + return Response.error("退款异常"); + } + } catch (HttpException e) { + log.error("退款查询失败,发送HTTP请求失败:", e); + return Response.error("退款查询失败"); + } catch (MalformedMessageException e) { + log.error("退款查询失败,解析微信支付应答或回调报文异常,返回信息:", e); + return Response.error("退款查询失败"); + } catch (ValidationException e) { + log.error("退款查询失败,验证签名失败,返回信息:", e); + return Response.error("退款查询失败"); + } catch (ServiceException e) { + log.error("退款查询失败,发送HTTP请求成功,返回异常,返回码:{},返回信息:", e.getErrorCode(), e); + return Response.error("退款查询失败"); + } catch (Exception e) { + log.error("退款查询失败,异常:", e); + return Response.error("退款查询失败"); + } + + return Response.success(refund); + } + + /** + * 微信小程序退款回调 + *
+     * 注意:
+     * 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功
+     *
+     * 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
+     * 如果在所有通知频率后没有收到微信侧回调。商户应调用查询订单接口确认订单状态。
+     * 
+ * + * @param request + * @return + */ + @Override + public String refundNotify(HttpServletRequest request) { + Map returnMap = new HashMap<>(2); + returnMap.put("code", "FAIL"); + returnMap.put("message", "失败"); + try { + // 请求头Wechatpay-Signature + String signature = request.getHeader("Wechatpay-Signature"); + // 请求头Wechatpay-nonce + String nonce = request.getHeader("Wechatpay-Nonce"); + // 请求头Wechatpay-Timestamp + String timestamp = request.getHeader("Wechatpay-Timestamp"); + // 微信支付证书序列号 + String serial = request.getHeader("Wechatpay-Serial"); + // 签名方式 + String signType = request.getHeader("Wechatpay-Signature-Type"); + // 构造解析器和请求参数 + NotificationParser parser = new NotificationParser((NotificationConfig) notificationConfig); + RequestParam requestParam = new RequestParam.Builder() + .serialNumber(serial) + .nonce(nonce) + .signature(signature) + .timestamp(timestamp) + .signType(signType) + .body(HttpServletUtils.getRequestBody(request)) + .build(); + log.info("微信小程序支付退款回调验签参数: {}", JSON.toJSONString(requestParam)); + // 解析通知 + RefundNotification notification = null; + try { + notification = parser.parse(requestParam, RefundNotification.class); + } catch (MalformedMessageException e) { + log.error("微信小程序支付退款回调:回调通知参数不正确、解析通知数据失败:", e); + returnMap.put("message", "回调通知参数不正确"); + return JSONObject.toJSONString(returnMap); + } catch (ValidationException e) { + log.error("微信小程序支付退款回调:签名验证失败 ", e); + returnMap.put("message", "签名验证失败"); + return JSONObject.toJSONString(returnMap); + } catch (Exception e) { + log.error("微信小程序支付退款回调:未知异常 ", e); + returnMap.put("message", "未知异常"); + return JSONObject.toJSONString(returnMap); + } + log.info("微信小程序支付退款回调解析成功: {}", JSON.toJSONString(notification)); + // 根据退款状态处理 + Status refundStatus = notification.getRefundStatus(); + switch (refundStatus) { + case SUCCESS: + // TODO 退款成功逻辑 + + returnMap.put("code", "SUCCESS"); + returnMap.put("message", "退款成功"); + + //修改订单退款状态 + MassageOrder order = massageOrderService + .lambdaQuery() + .eq(MassageOrder::getId, notification.getOutTradeNo()) + .eq(MassageOrder::getIsRefound, "0") + .one(); + if(null != order){ + order.setStatus("3"); + order.setIsRefound("1"); + massageOrderService.updateById(order); + } + + //修改退款记录状态 + MassageRefoundLog refoundLog = massageRefoundLogService + .lambdaQuery() + .eq(MassageRefoundLog::getOrderId, notification.getOutTradeNo()) + .eq(MassageRefoundLog::getStatus, "0") + .one(); + if(null != refoundLog){ + refoundLog.setStatus("1"); + refoundLog.setRefoundTime(CommonUtils.getCurrentTime()); + massageRefoundLogService.updateById(refoundLog); + } + + + return JSONObject.toJSONString(returnMap); + case PROCESSING: + log.warn("退款处理中: {}", notification); + returnMap.put("message", "退款处理中,请稍后查询"); + return JSONObject.toJSONString(returnMap); + case ABNORMAL: + log.error("退款异常: {}", notification); + returnMap.put("message", "退款异常,请联系客服"); + return JSONObject.toJSONString(returnMap); + case CLOSED: + log.warn("退款已关闭: {}", notification); + returnMap.put("message", "退款已关闭,操作失败"); + return JSONObject.toJSONString(returnMap); + default: + log.error("未知退款状态: {}", refundStatus); + returnMap.put("message", "未知退款状态"); + return JSONObject.toJSONString(returnMap); + } + } catch (Exception e) { + log.error("退款回调处理异常", e); + returnMap.put("message", "退款处理异常"); + return JSONObject.toJSONString(returnMap); + } + } + + + /** + * 金额转换 + * + * @param money + * @return + */ + private static long decimalToLong(BigDecimal money) { + return money.multiply(BigDecimal.valueOf(100)).longValue(); + } + + +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/CreateOrderReq.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/CreateOrderReq.java new file mode 100644 index 0000000..8cfe775 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/CreateOrderReq.java @@ -0,0 +1,8 @@ +package org.jeecg.modules.wxUtils; + +public class CreateOrderReq { + /** + * 微信用户openid(前端不用传参) + */ + private String wxOpenId; +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/HttpServletUtils.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/HttpServletUtils.java new file mode 100644 index 0000000..ab49815 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/HttpServletUtils.java @@ -0,0 +1,47 @@ +package org.jeecg.modules.wxUtils; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + *

+ * HttpServletRequest 获取请求体 + *

+ * + * @author songfayuan + * @date 2024/9/30 19:11 + */ +public class HttpServletUtils { + + /** + * 获取请求体 + * + * @param request + * @return + * @throws IOException + */ + public static String getRequestBody(HttpServletRequest request) throws IOException { + ServletInputStream stream = null; + BufferedReader reader = null; + StringBuffer sb = new StringBuffer(); + try { + stream = request.getInputStream(); + // 获取响应 + reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + throw new IOException("读取返回支付接口数据流出现异常!"); + } finally { + reader.close(); + } + return sb.toString(); + } + +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/PayOrderInfo.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/PayOrderInfo.java new file mode 100644 index 0000000..6936a91 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/PayOrderInfo.java @@ -0,0 +1,31 @@ +package org.jeecg.modules.wxUtils; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * 支付订单信息 + *

+ * + * @author songfayuan + * @date 2024/9/30 17:46 + */ +@Data +public class PayOrderInfo { + /** + * 订单标题 + */ + private String description; + /** + * 商户订单号 + * 只能是数字、大小写字母_-*且在同一个商户号下唯一。 + */ + private String outTradeNo; + /** + * 支付金额,单位:元 + */ + private BigDecimal amount; +} + diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/QueryOrderReq.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/QueryOrderReq.java new file mode 100644 index 0000000..686b26b --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/QueryOrderReq.java @@ -0,0 +1,23 @@ +package org.jeecg.modules.wxUtils; + +import lombok.Data; + +/** + *

+ * 订单查询请求 + *

+ * + * @author songfayuan + * @date 2024/9/30 19:19 + */ +@Data +public class QueryOrderReq { + /** + * 订单号:业务侧的订单号 + */ + private String transactionId; + /** + * 商户订单号 + */ + private String outTradeNo; +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/RefundOrderReq.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/RefundOrderReq.java new file mode 100644 index 0000000..bf0ceca --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/RefundOrderReq.java @@ -0,0 +1,36 @@ +package org.jeecg.modules.wxUtils; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * 退款订单请求参数 + *

+ * + * @author songfayuan + * @date 2024/9/30 19:19 + */ +@Data +public class RefundOrderReq { + /** + * 订单号:业务侧的订单号 + */ + private String transactionId; + /** + * 商户订单号 + */ + private String outTradeNo; + + /** + * 原订单金额 说明:原支付交易的订单总金额,这里单位为元。 + */ + private BigDecimal totalAmount; + + /** + * 退款金额 说明:退款金额,这里单位为元,不能超过原订单支付金额。 + */ + private BigDecimal refundAmount; +} + diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/Response.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/Response.java new file mode 100644 index 0000000..92b12cb --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/Response.java @@ -0,0 +1,164 @@ +package org.jeecg.modules.wxUtils; + +import lombok.Data; + +/** + * 返回参数封装类 + * + * @param + * @author songfayuan + */ + +@Data +public class Response { + /** + * 状态码 + */ + protected int code; + + /** + * 提示信息 + */ + protected String msg; + + /** + * 数据 + */ + protected T data; + + /** + * 成功时状态码 + */ + private static final int SUCCESS_CODE = 200; + + /** + * 成功时提示信息 + */ + private static final String SUCCESS_MSG = "success"; + + /** + * 异常、错误信息状态码 + */ + private static final int ERROR_CODE = 500; + + /** + * 异常、错误提示信息 + */ + private static final String ERROR_MSG = "服务器内部异常,请联系技术人员!"; + + /** + * 返回成功消息 + * + * @param + * @return + */ + public static Response success() { + Response resp = new Response(); + resp.code = (SUCCESS_CODE); + resp.msg = (SUCCESS_MSG); + return resp; + } + + /** + * 返回成功消息 + * + * @param + * @param msg + * @return + */ + public static Response successResponse(String msg) { + Response resp = new Response(); + resp.code = SUCCESS_CODE; + resp.msg = msg; + return resp; + } + + /** + * 返回错误消息 + * + * @param + * @return + */ + public static Response error() { + Response resp = new Response(); + resp.code = (ERROR_CODE); + resp.msg = (ERROR_MSG); + return resp; + } + + /** + * 返回错误消息 + * + * @param + * @param msg + * @return + */ + public static Response errorResponse(String msg) { + Response resp = new Response(); + resp.code = ERROR_CODE; + resp.msg = msg; + return resp; + } + + /** + * 自定义状态码、提示信息 + * + * @param + * @param code 状态码 + * @param msg 提示信息 + * @return + */ + public static Response response(int code, String msg) { + Response resp = new Response(); + resp.code = (code); + resp.msg = (msg); + return resp; + } + + /** + * 自定义状态码、提示信息、业务数据 + * + * @param + * @param code 状态码 + * @param msg 提示信息 + * @param data 业务数据 + * @return + */ + public static Response response(int code, String msg, T data) { + Response resp = new Response<>(); + resp.code = (code); + resp.msg = (msg); + resp.data = data; + return resp; + } + + /** + * 返回成功数据 + * + * @param + * @param data 业务数据 + * @return + */ + public static Response success(T data) { + Response resp = new Response<>(); + resp.code = (SUCCESS_CODE); + resp.msg = (SUCCESS_MSG); + resp.data = data; + return resp; + } + + /** + * 返回错误消息 + * + * @param + * @param data 业务数据 + * @return + */ + public static Response error(T data) { + Response resp = new Response<>(); + resp.code = (ERROR_CODE); + resp.msg = (ERROR_MSG); + resp.data = data; + return resp; + } +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayAutoCertificateConfig.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayAutoCertificateConfig.java new file mode 100644 index 0000000..0a7df7d --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayAutoCertificateConfig.java @@ -0,0 +1,113 @@ +package org.jeecg.modules.wxUtils; + + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Configuration +public class WxPayAutoCertificateConfig { + + /** + * 微信小程序的 AppID + */ + @Value("${wx.miniapp.appid}") + private String appid; + + /** + * 微信小程序的密钥 + */ + @Value("${wx.miniapp.secret}") + private String secret; + + /** + * 商户号 + */ + @Value("${wx.miniapp.merchantId}") + private String merchantId; + + /** + * 商户API私钥路径 + */ + @Value("${wx.miniapp.privateKeyPath}") + private String privateKeyPath; + + /** + * 商户API公钥路径 + */ + @Value("${wx.miniapp.publicKeyPath}") + private String publicKeyPath; + + /** + * 公钥 + */ + @Value("${wx.miniapp.publicKeyId}") + private String publicKeyId; + + /** + * 商户证书序列号 + */ + @Value("${wx.miniapp.merchantSerialNumber}") + private String merchantSerialNumber; + + /** + * 商户APIV3密钥 + */ + @Value("${wx.miniapp.apiV3Key}") + private String apiV3Key; + + /** + * 支付通知地址 + */ + @Value("${wx.miniapp.payNotifyUrl}") + private String payNotifyUrl; + + /** + * 退款通知地址 + */ + @Value("${wx.miniapp.refundNotifyUrl}") + private String refundNotifyUrl; + + /** + * 初始化商户配置 + * @return + */ + @Bean + public Config rsaAutoCertificateConfig() { + // 这里把Config作为配置Bean是为了避免多次创建资源,一般项目运行的时候这些东西都确定了 + // 具体的参数改为申请的数据,可以通过读配置文件的形式获取 +// Config config = new RSAAutoCertificateConfig.Builder() +// .merchantId("1659066870") +// .privateKeyFromPath("E:\\git_java\\api_java\\popularize-admin\\popularize-admin\\popularize-admin\\module-pay\\src\\main\\resources\\apiclient_key.pem") +// .merchantSerialNumber("7BE56DC695B2B612BD1C6C710A7FBFA1AC46B10F") +// .apiV3Key("vtribevtribevtribevtribevtribe12") +// .build(); + + Config config = new RSAPublicKeyConfig.Builder() + .merchantId(merchantId) + .privateKeyFromPath(privateKeyPath) + .publicKeyFromPath(publicKeyPath) + .publicKeyId(publicKeyId) + .merchantSerialNumber(merchantSerialNumber) + .apiV3Key(apiV3Key) + .build(); + + +// Config config = new RSAAutoCertificateConfig.Builder() +// .merchantId(merchantId) +// .privateKeyFromPath(privateKeyPath) +// .merchantSerialNumber(merchantSerialNumber) +// .apiV3Key(apiV3Key) +// .build(); + + log.info("初始化微信支付商户配置完成..."); + return config; + } + + +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayConfig.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayConfig.java new file mode 100644 index 0000000..e5393b7 --- /dev/null +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wxUtils/WxPayConfig.java @@ -0,0 +1,13 @@ +package org.jeecg.modules.wxUtils; +import lombok.Data; +import org.springframework.stereotype.Component; + + +@Data +@Component +public class WxPayConfig { + + + +} + diff --git a/jeecg-boot-module-system/src/main/resources/apiclient_key.pem b/jeecg-boot-module-system/src/main/resources/apiclient_key.pem new file mode 100644 index 0000000..ca53b76 --- /dev/null +++ b/jeecg-boot-module-system/src/main/resources/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8an3vcCIsBgcy +wG+H5tZZ0/qZJIEeqFHYDvKxqs69slnT4pUxG7wir66o+SQP7bPBpHDh7OGghuhP +8KTSYMnG100k44Rfm7Ch+P2/mdexfgu4aC2CBFf6ziOjopBzBfc3TEOuwCdPTcFL +4G3yZ65xldiO+stiDdeXa5EQrD9LFWL4YADOkd8RPxUGFQaWWWnUR+7VdWCHsYZ7 +J1qrwmyVsNXsbcWAdQKwiXy7fws6IOyRUj4p8tUc/GDqz1vwCTZQJ6Km3b+nCLqb +SDbZ82XhSJJzZRzGzcY/IqdeQT9Lrb0SYWs3HDmN5/NngU2cihiUqw4LrzWy/ui0 ++Fvt46AVAgMBAAECggEBAJbphO0fF3/DZEiWMb7ceZuBWhsHThRMJSG091auxODT +1XcM6QpoeIwfwvm8c9H+Rhg3qeKLZTy6UaCV0q5er77/+94sDX62qQdS84tfoY+c +sa6GYszcxcsxCQKr1p8KjDRSdXOmnNW8JbKsk+Owf9yidM4wum5TP/ccRRjhneB4 +YmN+cw93bl+5yqebvaRwC1S7WcUspj2lmaSLE/IvFOBU91Wnn6XvjkAU7QnuUxlV +0NVWgJqhykng6E/lsXkEB6Akk5fZXHDvJCgP6zCDHZs0LC8MTl984fDtr1CB1lnw +n/B6gQEYhVnqlvGxLhjGwZbfYzFuPZqgnDkVbBWflYECgYEA99s7k74edmVkOriI +KYuYctDkU22HsoKHaB+VhKfeaZWWr25RPpWk0yQWNr1SxkdEJopzxVMuCoxrGy6F +MUpgM0By6QBoU3WFZONSzDalqFJANIVj+o3/RCnI5w4na6MAaw4t/hMd2avxSje/ +k1A2CeBYm7eN7bYaFXe+hwFGyz0CgYEAwptLctRG3R35beRBXMccuvvxjXmSNfpW +qIBCnNn0KzBu7r8JyxHVI8mIdA5jD8C0G91wFnm0hG+fcZ+9eFpLZCaHbfVI55GS +NsOBwkO5WrOj2LcWd9yi4cKPxFceOLrEBKmxTXFGnoeVoA4468ec8kEQywG96dvb +QKFZ4JM11bkCgYEAhRA9u+Ollwp39M58y1EWVw2uhtuWrk9FQrEyJDW7QhP9AdHH +7EGKa5BEHL8nYSuBeu95l8ZAQYmBNuaSuxOi8eD3z/9YAvZk1vTzzo7IAMWnkorK +UglJsd587Q68Ox0XbGIAbxb0P5f/wkiLoRq+6C55Y5/3olbRShUvRGt7BkECgYBw +zuCvkcn6R3PddeFFzM4kvgNKBVzyGUm+p4r1rYpStuK3Vtpwcsfg1ORakjRuX0CI +npZpEOfJlYMRtI16hK0LQyJiZTt7sPDW+gHwAJ4jq9qgt5E4rhdlUwlPwUhtjiYu +pcd3ouBS6Tmc7GGmm7Go5Hq9kybpt16jWmTlP7CHUQKBgGaJwRKkIjJsvpGEkxcx +ReFyK5avL+ky/q/Q/TyCmEr8uVZGe1kEXdDk53+VR1YzwX/K+7Bjx0vlH3T57Z9J +vv1fiJZimmLy17mkRQurREvWfICTH/WJxzMF5ALJLpqGzr451fzaupMNhI04Ln/e +dTDkCyho1MMaRP+2a12AIEex +-----END PRIVATE KEY----- diff --git a/jeecg-boot-module-system/src/main/resources/application-dev.yml b/jeecg-boot-module-system/src/main/resources/application-dev.yml index e31fff9..5b5a2c3 100644 --- a/jeecg-boot-module-system/src/main/resources/application-dev.yml +++ b/jeecg-boot-module-system/src/main/resources/application-dev.yml @@ -329,3 +329,31 @@ third-app: client-secret: ?? agent-id: ?? +## 微信商户 +wx: + miniapp: + appid: wx77ba4c7131677a74 # 微信小程序appid + secret: fb915d623f92d455f2e70934f75fb96c # 微信小程序密钥 + merchantId: 1712378227 # 商户号 + privateKeyPath: jeecg-boot-module-system/src/main/resources/apiclient_key.pem #本地私钥路径 + publicKeyPath: jeecg-boot-module-system/src/main/resources/pub_key.pem #本地公钥路径 +# privateKeyPath: /root/massage/cerFile/apiclient_key.pem #线上私钥路径 +# publicKeyPath: /root/massage/cerFile/pub_key.pem #线上公钥路径 + publicKeyId: PUB_KEY_ID_0117123782272025033100396400002931 #公钥 + merchantSerialNumber: 33E9FE8076531A7C7AD401DC34E053DBD7C28E22 # 商户API证书序列号 + apiV3Key: 0fdb77429ffdf206c151af76a663041c # 商户APIV3密钥 + payNotifyUrl: https://www.yurangongfang.com/massage-admin/massage/order/payOrderNotify/ # 支付通知地址(测试环境) + refundNotifyUrl: https://www.yurangongfang.com/massage-admin/massage/refound/refundNotify/ # 退款通知地址(正式环境) +# refundNotifyUrl: http://augcl.natapp1.cc/massage-admin/massage/refound/refundNotify/ # 退款通知地址(测试环境) + +### 微信商户 +#wx: +# miniapp: +# appid: wx797abcfb479c75ec # 微信小程序appid +# secret: c4565acc18698a7000be1b2bb748be81 # 微信小程序密钥 +# merchantId: 1659066870 # 商户号 +# privateKeyPath: jeecg-boot-module-system/src/main/resources/apiclient_key.pem +# merchantSerialNumber: 7BE56DC695B2B612BD1C6C710A7FBFA1AC46B10F # 商户API证书序列号 +# apiV3Key: vtribevtribevtribevtribevtribe12 # 商户APIV3密钥 +# payNotifyUrl: http://h5.xzaiyp.top/popularize-admin/order_pay/refundNotify # 支付通知地址(测试环境) +# refundNotifyUrl: http://h5.xzaiyp.top/popularize-admin/order_pay/refundNotify # 退款通知地址(测试环境) \ No newline at end of file diff --git a/jeecg-boot-module-system/src/main/resources/pub_key.pem b/jeecg-boot-module-system/src/main/resources/pub_key.pem new file mode 100644 index 0000000..bd7b4f5 --- /dev/null +++ b/jeecg-boot-module-system/src/main/resources/pub_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6xCzq1CjrZYTqtE52f7t +4AU9rgRZYKNn94tmkIuYa1wGX13gWNIlo1muExV/Ejg4H9Xe0RCQwNNJieeyfhU7 +Vl/qms4Ukj8sqIrvKqw9j81AVHK2BSk87aRs0ha+gvV1tDDmcCLHrY8SeGcJ2U2z +I9iu5X1kLdkXNiojWrMngGslki2FSfJelftoZUDk30mf18AoG5iBzIPJ4/Gy5Rh0 +U+FDwpWzERR7XjMoAZ7YiRYUdV/SpQkx6CrM4Em3AKxmpxvwSVg7NiMDoTljfgq+ +6ZHB9DMQPbeqkQ9qkCMg0sVjpB/aI9tObE0mtU8zP/mBg7TDTs0qa2SXFem5ZTDg +JQIDAQAB +-----END PUBLIC KEY-----