From 3cc8093733d705ed5415e37eb82d909509590c4b Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期四, 18 九月 2025 09:01:33 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java | 270 ++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 203 insertions(+), 67 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java index 9680c68..eef2033 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java @@ -5,6 +5,7 @@ import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.lkl.laop.sdk.exception.SDKException; @@ -43,6 +44,7 @@ import javax.validation.Valid; import java.io.*; import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.cert.*; @@ -105,12 +107,13 @@ @PostMapping(value = "/payOrder") @SneakyThrows public R<?> payOrder(@RequestParam String id, String type, HttpServletRequest request) { - SysUser user = tokenService.getLoginUser().getUser(); try { // 查出采购单 算出价格 下单 算出应该分佣金额 应该分给谁 TErpProcurement erpProcurement = erpProcurementService.getById(id); - + if (erpProcurement.getStatus()>2) { + return R.fail("订单已支付"); + } String ipAddr = IpUtils.getIpAddr(request); String time = DateUtils.dateTimeNow(); @@ -129,8 +132,8 @@ "\t\"version\": \"3.0\",\n" + "\t\"req_data\": {\n" + "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\n" + - "\t\t\"merchant_no\": \"822290059430BFA\",\n" + - "\t\t\"term_no\": \"D9261078\",\n" + + "\t\t\"merchant_no\": \"822290059430BF9\",\n" + + "\t\t\"term_no\": \"A9358698\",\n" + "\t\t\"notify_url\": \"http://221.182.45.100:8089/t-sys-order/messageHandle\",\n" + "\t\t\"location_info\": {\n" + "\t\t\t\"request_ip\": \"" + ipAddr + "\"\n" + @@ -157,7 +160,7 @@ String code = jsonObject1.getString("log_no"); erpProcurement.setPayTransactionId(code); erpProcurement.setStatus(2); - erpProcurement.setTermNo("D9261078"); + erpProcurement.setTermNo("A9358698"); erpProcurement.setAccountType(type); erpProcurement.setTransType("41"); erpProcurementService.updateById(erpProcurement); @@ -170,10 +173,6 @@ } - public static void main(String[] args) { - String a = "{\"code\":\"BBS00000\",\"msg\":\"成功\",\"resp_time\":\"20250916114506\",\"resp_data\":{\"merchant_no\":\"822290059430BFA\",\"out_trade_no\":\"202509161144582Kck\",\"trade_no\":\"2025091666200821320234\",\"log_no\":\"66200821320234\",\"settle_merchant_no\":\"\",\"settle_term_no\":\"\",\"trade_req_date\":\"20250916\",\"acc_resp_fields\":{\"code\":\"https://qr.alipay.com/bax01747cbtdjneesjaz0044\",\"code_image\":\"\",\"prepay_id\":\"\",\"app_id\":\"\",\"pay_sign\":\"\",\"time_stamp\":\"\",\"nonce_str\":\"\",\"package\":\"\",\"sign_type\":\"\",\"form_data\":\"\",\"redirect_url\":\"\",\"best_pay_info\":\"\",\"partner_id\":\"\",\"sub_mch_id\":\"2088240727800097\"}}}"; - - } @RequestMapping("/messageHandle") @ApiOperation(value = "拉卡拉支付信息回调接口") @@ -207,14 +206,20 @@ if (verify && erpProcurement.getStatus()==2) { erpProcurement.setPayTime(LocalDateTime.now()); erpProcurement.setStatus(3); - erpProcurementService.updateById(erpProcurement); + List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); // 操作分账 HttpRequest post = HttpUtil.createPost(LakalaConfig.getServerUrl() + "sit/api/v3/sacs/separate"); + + HashMap<String, Object> reqMap = new HashMap<>(); + reqMap.put("version", "3.0"); + reqMap.put("req_time", DateUtils.dateTimeNow()); + + HashMap<String, Object> map = new HashMap<>(); - map.put("merchant_no", "822290059430BFA"); + map.put("merchant_no", "822290059430BF9"); map.put("log_no", erpProcurement.getPayTransactionId()); map.put("log_date", DateUtils.dateTime()); map.put("notify_url", "http://221.182.45.100:8089/t-sys-order/messageSeparateHandle"); @@ -229,6 +234,7 @@ map.put("out_separate_no", outTradeNo); map.put("total_amt", erpProcurement.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue() + ""); // 平台应得分账 + BigDecimal allMoney = erpProcurement.getPayMoney(); BigDecimal payMoney = erpProcurement.getPayMoney(); ArrayList<HashMap<String, Object>> objects = new ArrayList<>(); // 根据供应商id分组 @@ -240,14 +246,30 @@ List<TErpProcurementGoods> value = entry.getValue(); BigDecimal reduce = value.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); payMoney = payMoney.subtract(reduce); - map1.put("recv_merchant_no", supplier.getRecvMerchantNo()); + map1.put("recv_no", supplier.getRecvMerchantNo()); map1.put("separate_value", reduce.multiply(BigDecimal.valueOf(100)).intValue() + ""); objects.add(map1); } + HashMap<String, Object> map1 = new HashMap<>(); + map1.put("recv_merchant_no", "822641048160MMJ"); + // 手续费 + BigDecimal bigDecimal = allMoney.multiply(new BigDecimal("0.038")).setScale(2, RoundingMode.HALF_UP); + payMoney = payMoney.subtract(bigDecimal); + map1.put("separate_value", payMoney.multiply(BigDecimal.valueOf(100)).intValue() + ""); + if(payMoney.doubleValue()>0){ + objects.add(map1); + } + erpProcurement.setMoney(payMoney); + erpProcurement.setOutSeparateNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); // 添加平台的 map.put("recv_datas", objects); - String jsonString = JSON.toJSONString(map); + + reqMap.put("req_data", map); + + + String jsonString = JSON.toJSONString(reqMap); post.body(jsonString); HttpResponse response = post.execute(); String responseStr = response.body(); @@ -273,44 +295,137 @@ @ApiOperation(value = "拉卡拉分账信息回调接口") public Object messageSeparateHandle(HttpServletRequest request) throws Exception { String body = this.getBody(request); - String authorization = request.getHeader("Authorization"); - String timestamp = null; - String nonce = null; - String signature = null; - authorization = authorization.replaceAll("LKLAPI-SHA256withRSA ", ""); - String[] split = authorization.split(","); - for (String s : split) { - if (s.startsWith("timestamp")) { - timestamp = s.split("=")[1].replaceAll("\"", ""); - } - if (s.startsWith("nonce")) { - nonce = s.split("=")[1].replaceAll("\"", ""); - } - if (s.startsWith("signature")) { - // 取出签名 - signature = s.split("signature=")[1].replaceAll("\"", ""); - } - } - X509Certificate lklCertificate = loadCertificate(new FileInputStream(new File(LakalaConfig.getLklNotifyCerStr()))); - String preSignData = timestamp + "\n" + nonce + "\n" + body + "\n"; - boolean verify = verify(lklCertificate, preSignData.getBytes(ENCODING), signature); // 先处理支付完成 修改状态 后处理分账 后走分账回调 JSONObject jsonObject1 = JSONObject.parseObject(body); - Object o = jsonObject1.get("out_trade_no"); - TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getPayNumber, o)); - if (verify && erpProcurement.getStatus()==2) { - erpProcurement.setPayTime(LocalDateTime.now()); - erpProcurement.setStatus(3); - erpProcurementService.updateById(erpProcurement); + Object o = jsonObject1.get("out_separate_no"); + Object status = jsonObject1.get("status"); + Object cmd_type = jsonObject1.get("cmd_type"); + Object detail_datas = jsonObject1.get("detail_datas"); + JSONArray jsonArray = JSONArray.parseArray(detail_datas.toString()); + if("SEPARATE".equals(cmd_type.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getOutSeparateNo, o.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status)) { + erpProcurement.setRefundStatus(1); + erpProcurementService.updateById(erpProcurement); + // 修改分账状态 + List<TErpProcurementGoods> list1 = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + list1.stream().forEach(e->e.setStatus(1)); + erpProcurementGoodsService.updateBatchById(list1); - List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); - // 操作分账 - HttpRequest post = HttpUtil.createPost(LakalaConfig.getServerUrl() + "sit/api/v3/sacs/separate"); - HashMap<String, Object> map = new HashMap<>(); - map.put("merchant_no", "822290059430BFA"); - map.put("log_no", erpProcurement.getPayTransactionId()); - map.put("log_date", DateUtils.dateTime()); - map.put("notify_url", DateUtils.dateTime()); + + // 响应success + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "执行成功"); + return jsonObject; + } + }else if("FALLBACK".equals(cmd_type.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getRefundOutSeparateNo, o.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status) && erpProcurement.getRefundStatus()==1) { + erpProcurement.setRefundStatus(2); + erpProcurementService.updateById(erpProcurement); + List<TErpProcurementGoods> list1 = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + list1.stream().forEach(e->e.setStatus(2)); + erpProcurementGoodsService.updateBatchById(list1); + + + // 发起退款 + String time = DateUtils.dateTimeNow(); + String ipAddr = IpUtils.getIpAddr(request); + // SYMBOLS 随机取4位数 + String str = ""; + for (int i = 0; i < 6; i++) { + str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + String outTradeNo = time + str; + String refund_amount = erpProcurement.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue() + ""; + + String apiPath = "sit/api/v3/rfd/refund_front/refund"; + String body1 = "{\n" + + "\t\"req_time\": \"" + time + "\",\n" + + "\t\"version\": \"3.0\",\n" + + "\t\"req_data\": {\n" + + "\t\t\"merchant_no\": \"822290059430BF9\",\n" + + "\t\t\"term_no\": \""+erpProcurement.getTermNo()+"\",\n" + + "\t\t\"refund_amount\": " + refund_amount + ",\n" + + "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\n" + + "\t\t\"notify_url\": \"" + "http://221.182.45.100:8089/t-sys-order/messageRefundHandle" + "\",\n" + + "\t\t\"origin_log_no\": \"" + erpProcurement.getPayTransactionId() + "\",\n" + + "\t\t\"location_info\": {\n" + + "\t\t\t\"request_ip\": \"" + ipAddr + "\"\n" + + "\t\t},\n" + + "\t}\n" + + "}"; + String authorization = getAuthorization(body1); + org.apache.http.HttpResponse response = post(LakalaConfig.getServerUrl() + apiPath, body1, authorization); + if (response.getStatusLine().getStatusCode() != 200) { + return R.fail(500, "请求失败,statusCode " + response.getStatusLine() + + IOUtils.toString(response.getEntity().getContent(), ENCODING)); + } + String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING); + JSONObject jsonObject = JSONObject.parseObject(responseStr); + JSONObject jsonObject2 = jsonObject.getJSONObject("resp_data"); + String code = jsonObject2.getString("log_no"); + erpProcurement.setRefundLogNo(code); + erpProcurement.setRefundNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); + + + + + // 响应success + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("code", "SUCCESS"); + jsonObject3.put("message", "执行成功"); + return jsonObject3; + } + } + + return null; + } + @RequestMapping("/messageRefundHandle") + @ApiOperation(value = "拉卡拉退款信息回调接口") + public Object messageRefundHandle(HttpServletRequest request) throws Exception { + String body = this.getBody(request); + // 先处理支付完成 修改状态 后处理分账 后走分账回调 + JSONObject jsonObject1 = JSONObject.parseObject(body); + Object status = jsonObject1.get("trade_status"); + Object out_trade_no = jsonObject1.get("out_trade_no"); + if(status !=null && "SUCCESS".equals(status.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getRefundNo, out_trade_no.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status)) { + erpProcurement.setStatus(6); + erpProcurementService.updateById(erpProcurement); + // 响应success + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "执行成功"); + return jsonObject; + } + } + + return null; + } + + + + + @ApiOperation(value = "退款") + @PostMapping(value = "/refundOrder") + @SneakyThrows + public R<?> refundOrder(@RequestParam String id, String type, HttpServletRequest request) { + SysUser user = tokenService.getLoginUser().getUser(); + try { + // 先退分账 在退订单 + // 查出采购单 算出价格 下单 算出应该分佣金额 应该分给谁 + TErpProcurement erpProcurement = erpProcurementService.getById(id); + // 还未分账成功不能退款 + + if(erpProcurement.getStatus()==null || erpProcurement.getStatus()!=1){ + return R.fail("订单处理中,请稍后操作"); + } + + String time = DateUtils.dateTimeNow(); // SYMBOLS 随机取4位数 @@ -319,43 +434,64 @@ str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); } String outTradeNo = time + str; - map.put("out_separate_no", outTradeNo); - map.put("total_amt", erpProcurement.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue() + ""); - // 平台应得分账 - BigDecimal payMoney = erpProcurement.getPayMoney(); - ArrayList<HashMap<String, Object>> objects = new ArrayList<>(); + + // 操作分账 + HttpRequest post = HttpUtil.createPost(LakalaConfig.getServerUrl() + "sit/api/v3/sacs/fallback"); + HashMap<String, Object> reqMap = new HashMap<>(); + reqMap.put("version", "3.0"); + reqMap.put("req_time", DateUtils.dateTimeNow()); + + + + HashMap<String, Object> map = new HashMap<>(); + map.put("merchant_no", "822290059430BF9"); + map.put("origin_separate_no", erpProcurement.getSeparateNo()); + map.put("out_separate_no",outTradeNo); + erpProcurement.setRefundOutSeparateNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); + + + List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + // 根据供应商id分组 Map<String, List<TErpProcurementGoods>> collect = list.stream().collect(Collectors.groupingBy(TErpProcurementGoods::getSupplierId)); + ArrayList<HashMap<String, Object>> objects = new ArrayList<>(); + BigDecimal allMoney = list.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); for (Map.Entry<String, List<TErpProcurementGoods>> entry : collect.entrySet()) { HashMap<String, Object> map1 = new HashMap<>(); - String supplierId = entry.getKey(); - TCrmSupplier supplier = crmSupplierService.getById(supplierId); List<TErpProcurementGoods> value = entry.getValue(); BigDecimal reduce = value.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); - payMoney = payMoney.subtract(reduce); - map1.put("recv_merchant_no", supplier.getRecvMerchantNo()); - map1.put("separate_value", reduce.multiply(BigDecimal.valueOf(100)).intValue() + ""); + String recv_no = value.stream().map(TErpProcurementGoods::getRecvNo).collect(Collectors.toList()).get(0); + map1.put("recv_no", recv_no); + map1.put("amt", reduce.multiply(BigDecimal.valueOf(100)).intValue() + ""); objects.add(map1); } + BigDecimal add = allMoney.add(erpProcurement.getMoney()).multiply(BigDecimal.valueOf(100)); + map.put("total_amt",add); + map.put("origin_recv_datas",objects); + reqMap.put("req_data", map); - // 添加平台的 - map.put("recv_datas", objects); - String jsonString = JSON.toJSONString(map); + + String jsonString = JSON.toJSONString(reqMap); post.body(jsonString); HttpResponse response = post.execute(); String responseStr = response.body(); - // 响应success - JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "SUCCESS"); - jsonObject.put("message", "执行成功"); - return jsonObject; + return R.ok(responseStr); + } catch (Exception e) { + e.printStackTrace(); } - return null; + return R.fail(500, "调用支付宝支付预下单接口错误"); } + + + + + + public org.apache.http.HttpResponse post(String url, String message, String authorization) throws Exception { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { -- Gitblit v1.7.1