From cda724da35beb1ffd84955cc42bda5ab399ebbe1 Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期三, 09 四月 2025 18:27:38 +0800 Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/JiaDianHuiShou --- ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/Order.java | 3 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/WechatConstants.java | 6 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/entity/Order.java | 6 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/WithdrawDetailVO.java | 3 ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/vo/WithdrawOrderVO.java | 2 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/task/TaskUtil.java | 68 +++--- ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java | 203 ++++++++++++++++++ ruoyi-service/ruoyi-order/pom.xml | 5 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/TestWxPay.java | 83 +++++++ ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/WithdrawServiceImpl.java | 1 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WithdrawController.java | 1 ruoyi-service/ruoyi-order/src/main/resources/mybatis-config.xml | 2 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/WithdrawServiceImpl.java | 200 +++++++++++------ ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/QuickStart.java | 45 ++++ ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/RecoveryServeController.java | 4 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/UserDto.java | 1 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/WithdrawDetailVO.java | 2 17 files changed, 520 insertions(+), 115 deletions(-) diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/Order.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/Order.java index f34f85f..16a2b7e 100644 --- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/Order.java +++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/Order.java @@ -194,5 +194,6 @@ @ApiModelProperty("回收单凭证(多张照片 ','隔开)") @TableField("paper_pic") private String paperPic; - + @ApiModelProperty("拉起确认收款页面参数") + private String packageInfo; } diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/WithdrawDetailVO.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/WithdrawDetailVO.java index 7d7debc..df653da 100644 --- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/WithdrawDetailVO.java +++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/WithdrawDetailVO.java @@ -20,6 +20,8 @@ @ApiModelProperty("订单编号") private String orderNumber; + @ApiModelProperty("拉起确认收款参数") + private String packageInfo; @ApiModelProperty("下单用户id") private Integer userId; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/WechatConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/WechatConstants.java index a803ac7..d9d17fb 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/WechatConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/WechatConstants.java @@ -57,9 +57,13 @@ public static final String TRANSFER_DETAIL_LIST = "transfer_detail_list"; /** - * 微信商家转账到用户零钱接口地址(前缀) + * 微信商家转账到用户零钱接口地址(前缀)弃用 */ public static final String WE_CHAT_URL_PRE = "https://api.mch.weixin.qq.com/v3/transfer/batches"; + /** + * 微信发起转账(前缀) + */ + public static final String WE_CHAT_PAY_URL_PRE = "https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills"; /** * 微信商家转账到用户零钱接口地址(后缀) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/UserDto.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/UserDto.java index 9fb8c2c..5ee6696 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/UserDto.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/UserDto.java @@ -12,4 +12,5 @@ private String profilePicture; private String phone; private String userNo; + private String openId; } diff --git a/ruoyi-service/ruoyi-order/pom.xml b/ruoyi-service/ruoyi-order/pom.xml index fde9f6e..fade3f8 100644 --- a/ruoyi-service/ruoyi-order/pom.xml +++ b/ruoyi-service/ruoyi-order/pom.xml @@ -19,7 +19,10 @@ </properties> <dependencies> - + <dependency> + <groupId>com.github.wechatpay-apiv3</groupId> + <artifactId>wechatpay-java</artifactId> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WithdrawController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WithdrawController.java index 31de0b8..10f202a 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WithdrawController.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WithdrawController.java @@ -340,6 +340,7 @@ withdrawDetailVO.setWithdrawalState(withdraw.getState()); withdrawDetailVO.setWithdrawalTime(withdraw.getCreateTime()); } + withdrawDetailVO.setPackageInfo(order.getPackageInfo()); withdrawDetailVO.setAddress(order.getAddress()); if (null != serveRecord) { withdrawDetailVO.setPhoto(serveRecord.getPhoto()); diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java new file mode 100644 index 0000000..b03e338 --- /dev/null +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java @@ -0,0 +1,203 @@ +package com.ruoyi.order.controller; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.WechatConstants; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.exception.GlobalException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.vo.UserDto; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.order.entity.ChangeDispatch; +import com.ruoyi.order.entity.Order; +import com.ruoyi.order.entity.Withdraw; +import com.ruoyi.order.entity.WithdrawDetail; +import com.ruoyi.order.request.ChangeDispatchRequest; +import com.ruoyi.order.service.ChangeDispatchService; +import com.ruoyi.order.service.OrderService; +import com.ruoyi.order.service.WithdrawDetailService; +import com.ruoyi.order.service.WithdrawService; +import com.ruoyi.order.vx.HttpUtil; +import com.ruoyi.system.api.RemoteUserService; +import com.ruoyi.user.api.feignClient.UserClient; +import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * <p> + * 商家转账回调 + * </p> + * + * @author hjl + * @since 2024-05-31 + */ +@RestController +@RequestMapping("/wx") +public class WxChatPayCallBack { + + @Autowired + private WithdrawDetailService withdrawDetailService; + @Resource + private OrderService orderService; + @Autowired + private WithdrawService withdrawService; + @Autowired + private UserClient userClient; + /** + * 微信商户零线转账 - 回调通知 + * @Context注解 把HTTP请求上下文对象注入进来,HttpServletRequest、HttpServletResponse、UriInfo 等 + * @return + */ + @PostMapping("/wxChatPay") + public String wxPayCallback(HttpServletRequest request) { + Map<String, String> map = new HashMap<>(); + Map<String,String> errMap = new HashMap<>(); + try { System.err.println("请求"+request); + BufferedReader reader = request.getReader(); + String string1 = reader.toString(); + System.err.println("请求reader"+string1); + StringBuilder requestBody = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + requestBody.append(line); + } + System.err.println("全部请求体"+requestBody); + JSONObject jsonObject = JSONObject.parseObject(requestBody.toString()); + JSONObject resource = jsonObject.getJSONObject("resource"); + + AesUtil aesUtil = new AesUtil("TA2npSNWmS0GcB0tFFRWA94rm1M0iSFs".getBytes(StandardCharsets.UTF_8)); + String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8), + resource.getString("ciphertext")); + System.err.println("微信解密的字符串信息"+decryptedData); + JSONObject jsonInfo = (JSONObject) JSONObject.parse(decryptedData); + String transferBillNo = jsonInfo.getString("transfer_bill_no"); + String outBillNo = jsonInfo.getString("out_bill_no"); + String state = jsonInfo.getString("state"); + WithdrawDetail withdrawDetail = withdrawDetailService.lambdaQuery().eq(WithdrawDetail::getOutBatchNo, outBillNo).one(); + Withdraw withdraw = withdrawService.getById(withdrawDetail.getWithdrawId()); + Order order = orderService.getById(withdraw.getOrderId()); + UserDto data = userClient.getUser(order.getUserId()).getData(); + if (order.getIsWithdrawal()==3){ + return "SUCCESS"; + } + if ("SUCCESS".equals(state)){ + order.setIsWithdrawal(3); + withdrawDetail.setStatus("SUCCESS"); + withdrawDetailService.updateById(withdrawDetail); + orderService.updateById(order); + }else if ("CANCELLED".equals(state)){ + // 校验提现 + List<Withdraw> list = withdrawService.lambdaQuery().eq(Withdraw::getUserId, order.getUserId()) + .eq(Withdraw::getOrderId, order.getId()).list(); + List<Integer> stateList = list.stream().map(Withdraw::getState).collect(Collectors.toList()); + if (stateList.contains(Constants.ONE)) { + throw new GlobalException("当前订单提现申请已通过!"); + } + // 超时未收款 撤销 重新发起转账 更新packageInfo + weChatPay(order.getOrderMoney(), data.getOpenId(),list.get(0).getId(),order.getServeName()); + } + map.put("code", "SUCCESS"); + map.put("message", "成功"); + } catch (Exception e) { + errMap.put("code", "FAIL"); + errMap.put("message", "服务器内部错误"); + } + return JSON.toJSONString(map); + + } + private boolean weChatPay(BigDecimal orderMoney, String openId, String withdrawId, String serverName) { + if (StringUtils.isBlank(openId)) { + return false; + } + BigDecimal maxTransferAmount = new BigDecimal("200000"); // 单次转账限额,单位为分 + int totalTransfers = orderMoney.multiply(new BigDecimal("100")).divide(maxTransferAmount, 0, RoundingMode.UP).intValue(); + boolean allTransfersSuccessful = true; + for (int i = 0; i < totalTransfers; i++) { + BigDecimal transferAmount; + if (i < totalTransfers - 1) { + transferAmount = maxTransferAmount; + } else { + // 最后一笔转账,金额为剩余金额 + transferAmount = orderMoney.multiply(new BigDecimal("100")).subtract(maxTransferAmount.multiply(new BigDecimal(i))).setScale(0, RoundingMode.DOWN); + } + + Map<String, Object> postMap = new HashMap<>(8); + postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8"); + // 订单号 + String s = String.valueOf(UUID.randomUUID()).replaceAll("-", ""); + postMap.put("out_bill_no", s); + System.err.println("====="+postMap.get("out_bill_no")); + postMap.put(WechatConstants.OPEN_ID, openId); + // 转账金额 + postMap.put("transfer_amount", transferAmount); + // 转账备注 + postMap.put("transfer_remark", "二手回收提现确认收款"); + // 回调地址 + postMap.put("notify_url", "https://hyhsbqgc.com/api/ruoyi-order/wx/wxChatPay"); + // 转账场景报备信息 + Map<String, Object> info = new HashMap<>(); + info.put("info_type","回收商品名称"); + info.put("info_content",serverName); + postMap.put("transfer_scene_report_infos", com.alibaba.fastjson2.JSONObject.toJSONString(info)); + String result = HttpUtil.postTransBatRequest( + WechatConstants.WE_CHAT_PAY_URL_PRE, + com.alibaba.fastjson2.JSONObject.toJSONString(postMap), + "7EEA04429B006E12AAA421C002EC48BBEED5BE94", + "1665330417", + "/usr/local/vx/apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); + com.alibaba.fastjson2.JSONObject jsonObject = com.alibaba.fastjson2.JSONObject.parseObject(result); +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); + if (jsonObject.containsKey(WechatConstants.CREATE_TIME)) { + String string = jsonObject.getString("package_info"); + Withdraw withdraw = withdrawService.getById(withdrawId); + WithdrawDetail one = withdrawDetailService.lambdaQuery().eq(WithdrawDetail::getWithdrawId, withdrawId).last("limit 1").one(); + if (one!=null){ + one.setOutBatchNo(s); + one.setStatus("FAIL"); + withdrawDetailService.updateById(one); + Order order = orderService.getById(withdraw.getOrderId()); + order.setPackageInfo(string); + order.setIsWithdrawal(2); + orderService.updateById(order); + } + } else { + allTransfersSuccessful = false; + break; + } + + } + + return allTransfersSuccessful; + } + +} diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/entity/Order.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/entity/Order.java index 6f5d07f..224b8a0 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/entity/Order.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/entity/Order.java @@ -61,7 +61,9 @@ @ApiModelProperty("站点名称") @TableField("site_name") private String siteName; - + @ApiModelProperty("拉起确认收款页面参数") + @TableField("package_info") + private String packageInfo; @ApiModelProperty("回收服务id") @TableField("serve_id") private Integer serveId; @@ -145,7 +147,7 @@ @TableField("subsidy") private BigDecimal subsidy; - @ApiModelProperty("是否已提现(0:未提现,1:已提现)") + @ApiModelProperty("是否已提现(0:未提现,1:审核中 2审核通过 3:已确认收款)") @TableField("is_withdrawal") private Integer isWithdrawal; diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/WithdrawServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/WithdrawServiceImpl.java index 6e13280..db7637d 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/WithdrawServiceImpl.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/WithdrawServiceImpl.java @@ -138,7 +138,7 @@ throw new GlobalException("当前订单提现申请已通过!"); } - return weChatPay(order.getOrderMoney(), openId,list.get(0).getId()); + return weChatPay(order.getOrderMoney(), openId,list.get(0).getId(),order.getServeName()); } @Override @@ -252,7 +252,7 @@ // 已通过 withdraw.setState(Constants.ONE); // 商家微信打款至微信零钱 - boolean update = weChatPay(order.getOrderMoney(), openId,withdraw.getId()); + boolean update = weChatPay(order.getOrderMoney(), openId,withdraw.getId(),order.getServerName()); // if (!update) { // throw new GlobalException("交易提现失败,请检查是否绑定微信!"); // } @@ -272,15 +272,94 @@ @Resource private WithdrawDetailService withdrawDetailService; - private boolean weChatPay(BigDecimal orderMoney, String openId,String withdrawId) { +// private boolean weChatPay(BigDecimal orderMoney, String openId,String withdrawId) { +// if (StringUtils.isBlank(openId)) { +// return false; +// } +// +// BigDecimal maxTransferAmount = new BigDecimal("20000"); // 单次转账限额,单位为分 +// int totalTransfers = orderMoney.multiply(new BigDecimal("100")).divide(maxTransferAmount, 0, RoundingMode.UP).intValue(); +// boolean allTransfersSuccessful = true; +// +// for (int i = 0; i < totalTransfers; i++) { +// BigDecimal transferAmount; +// if (i < totalTransfers - 1) { +// transferAmount = maxTransferAmount; +// } else { +// // 最后一笔转账,金额为剩余金额 +// transferAmount = orderMoney.multiply(new BigDecimal("100")).subtract(maxTransferAmount.multiply(new BigDecimal(i))).setScale(0, RoundingMode.DOWN); +// } +// +// Map<String, Object> postMap = new HashMap<>(8); +// postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8"); +// postMap.put(WechatConstants.OUT_BATCH_NO, String.valueOf(UUID.randomUUID()).replaceAll("-", "")); +// System.err.println("====="+postMap.get(WechatConstants.OUT_BATCH_NO)); +// postMap.put(WechatConstants.BATCH_NAME, "二手回收提现"); +// postMap.put(WechatConstants.BATCH_REMARK, "二手回收提现"); +// postMap.put(WechatConstants.TOTAL_AMOUNT, transferAmount); +// postMap.put(WechatConstants.TOTAL_NUM, Constants.ONE); +// +// List<Map<String, Object>> list = new ArrayList<>(); +// Map<String, Object> subMap = new HashMap<>(4); +// subMap.put(WechatConstants.OUT_DETAIL_NO, String.valueOf(SNOW_FLAKE_ID_WORKER.nextId())); +// subMap.put(WechatConstants.TRANSFER_AMOUNT, transferAmount); +// subMap.put(WechatConstants.TRANSFER_REMARK, "二手回收提现到账"); +// subMap.put(WechatConstants.OPEN_ID, openId); +// list.add(subMap); +// postMap.put(WechatConstants.TRANSFER_DETAIL_LIST, list); +// +// // 使用类加载器获取资源 URL +//// String path = ClassLoader.getSystemResource("/usr/local/vx/apiclient_key.pem").getPath(); +// +//// String result = HttpUtil.postTransBatRequest( +//// WechatConstants.WE_CHAT_URL_PRE, +//// JSONObject.toJSONString(postMap), +//// "7EEA04429B006E12AAA421C002EC48BBEED5BE94", +//// "1665330417", +//// "/usr/local/vx/apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); +// String result = HttpUtil.postTransBatRequest( +// WechatConstants.WE_CHAT_URL_PRE, +// JSONObject.toJSONString(postMap), +// "7EEA04429B006E12AAA421C002EC48BBEED5BE94", +// "1665330417", +// "D:\\study\\JiaDianHuiShou\\ruoyi-service\\ruoyi-order\\src\\main\\java\\com\\ruoyi\\order\\vx\\apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); +// +// JSONObject jsonObject = JSONObject.parseObject(result); +// +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); +// +// if (jsonObject.containsKey(WechatConstants.CREATE_TIME)) { +// // 转账成功 +// //保存转账明细 +//// WithdrawDetail withdrawDetail = new WithdrawDetail(); +//// withdrawDetail.setWithdrawId(withdrawId); +//// withdrawDetail.setMoney(transferAmount); +//// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +//// withdrawDetailService.save(withdrawDetail); +// +// +// } else { +// allTransfersSuccessful = false; +// break; +// } +// +// } +// +// return allTransfersSuccessful; +// } + + // 上架打款到用户零钱接口已弃用 用新版商家转账接口 + private boolean weChatPay(BigDecimal orderMoney, String openId,String withdrawId,String serverName) { if (StringUtils.isBlank(openId)) { return false; } - - BigDecimal maxTransferAmount = new BigDecimal("20000"); // 单次转账限额,单位为分 + BigDecimal maxTransferAmount = new BigDecimal("200000"); // 单次转账限额,单位为分 int totalTransfers = orderMoney.multiply(new BigDecimal("100")).divide(maxTransferAmount, 0, RoundingMode.UP).intValue(); boolean allTransfersSuccessful = true; - for (int i = 0; i < totalTransfers; i++) { BigDecimal transferAmount; if (i < totalTransfers - 1) { @@ -292,54 +371,57 @@ Map<String, Object> postMap = new HashMap<>(8); postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8"); - postMap.put(WechatConstants.OUT_BATCH_NO, String.valueOf(UUID.randomUUID()).replaceAll("-", "")); - System.err.println("====="+postMap.get(WechatConstants.OUT_BATCH_NO)); - postMap.put(WechatConstants.BATCH_NAME, "二手回收提现"); - postMap.put(WechatConstants.BATCH_REMARK, "二手回收提现"); - postMap.put(WechatConstants.TOTAL_AMOUNT, transferAmount); - postMap.put(WechatConstants.TOTAL_NUM, Constants.ONE); - + // 订单号 + postMap.put("out_bill_no", String.valueOf(UUID.randomUUID()).replaceAll("-", "")); + System.err.println("====="+postMap.get("out_bill_no")); + postMap.put(WechatConstants.OPEN_ID, openId); + // 转账金额 + postMap.put("transfer_amount", transferAmount); + postMap.put("transfer_scene_id", "1010"); + // 转账备注 + postMap.put("transfer_remark", "二手回收提现确认收款"); + // 回调地址 + postMap.put("notify_url", "https://hyhsbqgc.com/api/ruoyi-order/wx/wxChatPay"); + // 转账场景报备信息 List<Map<String, Object>> list = new ArrayList<>(); - Map<String, Object> subMap = new HashMap<>(4); - subMap.put(WechatConstants.OUT_DETAIL_NO, String.valueOf(SNOW_FLAKE_ID_WORKER.nextId())); - subMap.put(WechatConstants.TRANSFER_AMOUNT, transferAmount); - subMap.put(WechatConstants.TRANSFER_REMARK, "二手回收提现到账"); - subMap.put(WechatConstants.OPEN_ID, openId); - list.add(subMap); - postMap.put(WechatConstants.TRANSFER_DETAIL_LIST, list); - - // 使用类加载器获取资源 URL -// String path = ClassLoader.getSystemResource("/usr/local/vx/apiclient_key.pem").getPath(); - -// String result = HttpUtil.postTransBatRequest( -// WechatConstants.WE_CHAT_URL_PRE, -// JSONObject.toJSONString(postMap), -// "7EEA04429B006E12AAA421C002EC48BBEED5BE94", -// "1665330417", -// "/usr/local/vx/apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); + Map<String, Object> info = new HashMap<>(); + info.put("info_type","回收商品名称"); + info.put("info_content",serverName); + list.add(info); + postMap.put("transfer_scene_report_infos", list); String result = HttpUtil.postTransBatRequest( - WechatConstants.WE_CHAT_URL_PRE, + WechatConstants.WE_CHAT_PAY_URL_PRE, JSONObject.toJSONString(postMap), "7EEA04429B006E12AAA421C002EC48BBEED5BE94", "1665330417", - "/usr/local/vx/apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); - + "/usr/local/vx/apiclient_key.pem", "/v3/fund-app/mch-transfer/transfer-bills"); JSONObject jsonObject = JSONObject.parseObject(result); - - WithdrawDetail withdrawDetail = new WithdrawDetail(); - withdrawDetail.setWithdrawId(withdrawId); - withdrawDetail.setMoney(transferAmount); - withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); - withdrawDetailService.save(withdrawDetail); - +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); + System.err.println(jsonObject); +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); if (jsonObject.containsKey(WechatConstants.CREATE_TIME)) { + String string = jsonObject.getString("package_info"); + Withdraw withdraw = this.getById(withdrawId); + + Order order = orderService.getById(withdraw.getOrderId()); + order.setIsWithdrawal(2); + order.setPackageInfo(string); + orderService.updateById(order); // 转账成功 //保存转账明细 -// WithdrawDetail withdrawDetail = new WithdrawDetail(); -// withdrawDetail.setWithdrawId(withdrawId); -// withdrawDetail.setMoney(transferAmount); -// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); -// withdrawDetailService.save(withdrawDetail); + WithdrawDetail withdrawDetail = new WithdrawDetail(); + withdrawDetail.setWithdrawId(withdrawId); + withdrawDetail.setMoney(transferAmount); + withdrawDetail.setOutBatchNo(postMap.get("out_bill_no")+""); + withdrawDetailService.save(withdrawDetail); } else { @@ -352,34 +434,6 @@ return allTransfersSuccessful; } - public static void main(String[] args) { - Map<String, Object> postMap = new HashMap<>(8); - postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8"); - postMap.put(WechatConstants.OUT_BATCH_NO, String.valueOf(UUID.randomUUID()).replaceAll("-", "")); - System.err.println("====="+postMap.get(WechatConstants.OUT_BATCH_NO)); - postMap.put(WechatConstants.BATCH_NAME, "二手回收提现"); - postMap.put(WechatConstants.BATCH_REMARK, "二手回收提现"); - postMap.put(WechatConstants.TOTAL_AMOUNT, 1); - postMap.put(WechatConstants.TOTAL_NUM, Constants.ONE); - - List<Map<String, Object>> list = new ArrayList<>(); - Map<String, Object> subMap = new HashMap<>(4); - subMap.put(WechatConstants.OUT_DETAIL_NO, String.valueOf(SNOW_FLAKE_ID_WORKER.nextId())); - subMap.put(WechatConstants.TRANSFER_AMOUNT, 1); - subMap.put(WechatConstants.TRANSFER_REMARK, "二手回收提现到账"); - subMap.put(WechatConstants.OPEN_ID, "ouqOk6-Bp6PnNnlHoQSV-6lzoVoU"); - list.add(subMap); - postMap.put(WechatConstants.TRANSFER_DETAIL_LIST, list); - String result = HttpUtil.postTransBatRequest( - WechatConstants.WE_CHAT_URL_PRE, - JSONObject.toJSONString(postMap), - "7EEA04429B006E12AAA421C002EC48BBEED5BE94", - "1665330417", - "E:\\ershoucert\\apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF); - - JSONObject jsonObject = JSONObject.parseObject(result); - System.err.println(jsonObject); - } /** * 根据当前月份获取当前季度的开始月份 diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/task/TaskUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/task/TaskUtil.java index 495fdef..c200809 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/task/TaskUtil.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/task/TaskUtil.java @@ -22,40 +22,40 @@ private WithdrawDetailService withdrawDetailService; - /** - * 每隔一分钟去处理的定时任务 - */ - @Scheduled(fixedRate = 10000 * 60) - public void taskMinute(){ - try { - - List<WithdrawDetail> list = withdrawDetailService.lambdaQuery().ne(WithdrawDetail::getStatus, "SUCCESS").ne(WithdrawDetail::getStatus, "FAIL").list(); - - for (WithdrawDetail withdrawDetail : list) { - String s = GetTransferBatchByOutNo.checkStatus(withdrawDetail.getOutBatchNo()); - if (s.equals("SUCCESS")) { - withdrawDetail.setStatus("SUCCESS"); - withdrawDetailService.updateById(withdrawDetail); - //执行订单提现成功,增加提现成功金额 - //查询订单 - - //增加已提现金额 - - - } else if (s.equals("FAIL")) { - withdrawDetail.setStatus("FAIL"); - withdrawDetailService.updateById(withdrawDetail); - }else { - withdrawDetail.setStatus(s); - withdrawDetailService.updateById(withdrawDetail); - } - - } - - } catch (Exception e) { - e.printStackTrace(); - } - } +// /** +// * 每隔一分钟去处理的定时任务 +// */ +// @Scheduled(fixedRate = 10000 * 60) +// public void taskMinute(){ +// try { +// +// List<WithdrawDetail> list = withdrawDetailService.lambdaQuery().ne(WithdrawDetail::getStatus, "SUCCESS").ne(WithdrawDetail::getStatus, "FAIL").list(); +// +// for (WithdrawDetail withdrawDetail : list) { +// String s = GetTransferBatchByOutNo.checkStatus(withdrawDetail.getOutBatchNo()); +// if (s.equals("SUCCESS")) { +// withdrawDetail.setStatus("SUCCESS"); +// withdrawDetailService.updateById(withdrawDetail); +// //执行订单提现成功,增加提现成功金额 +// //查询订单 +// +// //增加已提现金额 +// +// +// } else if (s.equals("FAIL")) { +// withdrawDetail.setStatus("FAIL"); +// withdrawDetailService.updateById(withdrawDetail); +// }else { +// withdrawDetail.setStatus(s); +// withdrawDetailService.updateById(withdrawDetail); +// } +// +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } } diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/WithdrawDetailVO.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/WithdrawDetailVO.java index ecdcdfb..4db12f5 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/WithdrawDetailVO.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/WithdrawDetailVO.java @@ -17,7 +17,8 @@ @ApiModelProperty("订单id") private String orderId; - + @ApiModelProperty("拉起确认收款参数") + private String packageInfo; @ApiModelProperty("订单编号") private String orderNumber; diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/QuickStart.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/QuickStart.java new file mode 100644 index 0000000..eb49bb9 --- /dev/null +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/QuickStart.java @@ -0,0 +1,45 @@ +package com.ruoyi.order.vx; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.service.payments.nativepay.NativePayService; +import com.wechat.pay.java.service.payments.nativepay.model.Amount; +import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest; +import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; +/** Native 支付下单为例 */ +public class QuickStart { + /** 商户号 */ + public static String merchantId = "190000****"; + /** 商户API私钥路径 */ + public static String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem"; + /** 商户证书序列号 */ + public static String merchantSerialNumber = "5157F09EFDC096DE15EBE81A47057A72********"; + /** 商户APIV3密钥 */ + public static String apiV3key = "..."; + public static void main(String[] args) { + // 使用自动更新平台证书的RSA配置 + // 建议将 config 作为单例或全局静态对象,避免重复的下载浪费系统资源 + Config config = + new RSAAutoCertificateConfig.Builder() + .merchantId(merchantId) + .privateKeyFromPath(privateKeyPath) + .merchantSerialNumber(merchantSerialNumber) + .apiV3Key(apiV3key) + .build(); + // 构建service + NativePayService service = new NativePayService.Builder().config(config).build(); + // request.setXxx(val)设置所需参数,具体参数可见Request定义 + PrepayRequest request = new PrepayRequest(); + Amount amount = new Amount(); + amount.setTotal(100); + request.setAmount(amount); + request.setAppid("wxa9d9651ae******"); + request.setMchid("190000****"); + request.setDescription("测试商品标题"); + request.setNotifyUrl("https://notify_url"); + request.setOutTradeNo("out_trade_no_001"); + // 调用下单方法,得到应答 + PrepayResponse response = service.prepay(request); + // 使用微信扫描 code_url 对应的二维码,即可体验Native支付 + System.out.println(response.getCodeUrl()); + } +} \ No newline at end of file diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/TestWxPay.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/TestWxPay.java new file mode 100644 index 0000000..cae9670 --- /dev/null +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vx/TestWxPay.java @@ -0,0 +1,83 @@ +package com.ruoyi.order.vx; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.constant.WechatConstants; +import com.ruoyi.common.core.utils.StringUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; + +public class TestWxPay { + public static void main(String[] args) { + weChatPay(BigDecimal.valueOf(0.1), "ouqOk6xtWA3JDmpd9HpZf9ijESIs", "1", "空调挂机"); + } + private static boolean weChatPay(BigDecimal orderMoney, String openId, String withdrawId, String serverName) { + if (StringUtils.isBlank(openId)) { + return false; + } + BigDecimal maxTransferAmount = new BigDecimal("200000"); // 单次转账限额,单位为分 + int totalTransfers = orderMoney.multiply(new BigDecimal("100")).divide(maxTransferAmount, 0, RoundingMode.UP).intValue(); + boolean allTransfersSuccessful = true; + for (int i = 0; i < totalTransfers; i++) { + BigDecimal transferAmount; + if (i < totalTransfers - 1) { + transferAmount = maxTransferAmount; + } else { + // 最后一笔转账,金额为剩余金额 + transferAmount = orderMoney.multiply(new BigDecimal("100")).subtract(maxTransferAmount.multiply(new BigDecimal(i))).setScale(0, RoundingMode.DOWN); + } + + Map<String, Object> postMap = new HashMap<>(8); + postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8"); + // 订单号 + postMap.put("out_bill_no", String.valueOf(UUID.randomUUID()).replaceAll("-", "")); + System.err.println("====="+postMap.get("out_bill_no")); + postMap.put(WechatConstants.OPEN_ID, openId); + // 转账金额 + postMap.put("transfer_amount", transferAmount); + postMap.put("transfer_scene_id", "1010"); + // 转账备注 + postMap.put("transfer_remark", "二手回收提现确认收款"); + // 回调地址 + postMap.put("notify_url", "https://hyhsbqgc.com/api/ruoyi-order/wx/wxChatPay"); + // 转账场景报备信息 + List<Map<String, Object>> list = new ArrayList<>(); + Map<String, Object> info = new HashMap<>(); + info.put("info_type","回收商品名称"); + info.put("info_content",serverName); + list.add(info); + postMap.put("transfer_scene_report_infos", list); + String result = HttpUtil.postTransBatRequest( + WechatConstants.WE_CHAT_PAY_URL_PRE, + JSONObject.toJSONString(postMap), + "7EEA04429B006E12AAA421C002EC48BBEED5BE94", + "1665330417", + "/usr/local/vx/apiclient_key.pem", "/v3/fund-app/mch-transfer/transfer-bills"); + JSONObject jsonObject = JSONObject.parseObject(result); +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); + System.err.println(jsonObject); + if (jsonObject.containsKey(WechatConstants.CREATE_TIME)) { + // 转账成功 + //保存转账明细 +// WithdrawDetail withdrawDetail = new WithdrawDetail(); +// withdrawDetail.setWithdrawId(withdrawId); +// withdrawDetail.setMoney(transferAmount); +// withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO)); +// withdrawDetailService.save(withdrawDetail); + + + } else { + allTransfersSuccessful = false; + break; + } + + } + + return allTransfersSuccessful; + } +} diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mybatis-config.xml b/ruoyi-service/ruoyi-order/src/main/resources/mybatis-config.xml index d744366..30a0aa0 100644 --- a/ruoyi-service/ruoyi-order/src/main/resources/mybatis-config.xml +++ b/ruoyi-service/ruoyi-order/src/main/resources/mybatis-config.xml @@ -5,7 +5,7 @@ <settings> <!-- 打印查询语句 不会写入到日志文件中--> <setting name="logImpl" value="STDOUT_LOGGING"/> - <!--<setting name="logImpl" value="LOG4J" />--> +<!-- <setting name="logImpl" value="LOG4J" />--> <!-- 控制全局缓存(二级缓存),按美团技术团队的说法,尽量别用缓存机制 emmmm.... --> <setting name="cacheEnabled" value="true"/> <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false --> diff --git a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/RecoveryServeController.java b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/RecoveryServeController.java index ed75d56..a2420f0 100644 --- a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/RecoveryServeController.java +++ b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/RecoveryServeController.java @@ -161,7 +161,9 @@ UserRecipient userRecipient = userRecipientService.lambdaQuery() .eq(UserRecipient::getIsDefault, Constants.ONE) .eq(UserRecipient::getUserId, loginUser.getUserid()) - .eq(UserRecipient::getIsDelete, Constants.ZERO).one(); + .eq(UserRecipient::getIsDelete, Constants.ZERO) + .last("limit 1") + .one(); return R.ok(new ServeDetailVO(recoveryServe, userRecipient)); } diff --git a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/WithdrawServiceImpl.java b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/WithdrawServiceImpl.java index 8aacf0b..5e28ae5 100644 --- a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/WithdrawServiceImpl.java +++ b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/WithdrawServiceImpl.java @@ -82,6 +82,7 @@ withdrawOrder.setCompleteTime(order.getCreateTime()); withdrawOrder.setIsWithdrawal(order.getIsWithdrawal()); withdrawOrder.setMoney(order.getOrderMoney()); + withdrawOrder.setPackageInfo(order.getPackageInfo()); if (order.getAddress()!=null) { withdrawOrder.setAddress(order.getReservationAddress() + order.getAddress()); }else { diff --git a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/vo/WithdrawOrderVO.java b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/vo/WithdrawOrderVO.java index 57b6517..ad44d1c 100644 --- a/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/vo/WithdrawOrderVO.java +++ b/ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/vo/WithdrawOrderVO.java @@ -44,5 +44,7 @@ @ApiModelProperty("订单金额") private BigDecimal money; + @ApiModelProperty("拉起确认收款页面参数") + private String packageInfo; } -- Gitblit v1.7.1