From e1b1f32ad968da303fbd4827ace995704743cdda Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期三, 17 九月 2025 09:41:32 +0800
Subject: [PATCH] 拉卡拉支付

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java |  227 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 211 insertions(+), 16 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 43c9faa..9680c68 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
@@ -1,11 +1,21 @@
 package com.ruoyi.web.controller.api;
 
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.lkl.laop.sdk.exception.SDKException;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.framework.web.service.TokenService;
+import com.ruoyi.system.model.TCrmSupplier;
+import com.ruoyi.system.model.TErpProcurement;
+import com.ruoyi.system.model.TErpProcurementGoods;
 import com.ruoyi.system.query.TErpGoodsWarehouseQuery;
 import com.ruoyi.system.service.*;
 import com.ruoyi.web.core.config.LakalaConfig;
@@ -22,11 +32,9 @@
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.poi.ss.formula.functions.T;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
@@ -34,11 +42,20 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.io.*;
+import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.security.*;
 import java.security.cert.*;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -54,12 +71,18 @@
 public class TSysOrderController {
 
     private final TErpProcurementService erpProcurementService;
+    private final TErpProcurementGoodsService erpProcurementGoodsService;
+    private final TCrmSupplierService crmSupplierService;
+
     private final TokenService tokenService;
 
+
     @Autowired
-    public TSysOrderController(TErpProcurementService erpProcurementService, TokenService tokenService) {
+    public TSysOrderController(TErpProcurementService erpProcurementService, TokenService tokenService, TErpProcurementGoodsService erpProcurementGoodsService, TCrmSupplierService crmSupplierService) {
         this.erpProcurementService = erpProcurementService;
         this.tokenService = tokenService;
+        this.erpProcurementGoodsService = erpProcurementGoodsService;
+        this.crmSupplierService = crmSupplierService;
     }
 
     private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
@@ -81,27 +104,41 @@
     @ApiOperation(value = "支付")
     @PostMapping(value = "/payOrder")
     @SneakyThrows
-    public R<?> payOrder(@RequestBody @Valid TErpGoodsWarehouseQuery query, HttpServletRequest request) {
+    public R<?> payOrder(@RequestParam String id, String type, HttpServletRequest request) {
         SysUser user = tokenService.getLoginUser().getUser();
         try {
 
             // 查出采购单 算出价格  下单  算出应该分佣金额 应该分给谁
+            TErpProcurement erpProcurement = erpProcurementService.getById(id);
 
-            String apiPath = "/api/v3/labs/trans/preorder";
+            String ipAddr = IpUtils.getIpAddr(request);
+            String time = DateUtils.dateTimeNow();
+
+            // SYMBOLS 随机取4位数
+            String nonce = "";
+            for (int i = 0; i < 6; i++) {
+                nonce += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
+            }
+            String outTradeNo = time + nonce;
+            String amount = String.valueOf(erpProcurement.getPayMoney().multiply(new BigDecimal("100")).intValue());
+
+
+            String apiPath = "sit/api/v3/labs/trans/preorder";
             String body = "{\n" +
-                    "\t\"req_time\": \"20250915115329\",\n" +
+                    "\t\"req_time\": \"" + time + "\",\n" +
                     "\t\"version\": \"3.0\",\n" +
                     "\t\"req_data\": {\n" +
-                    "\t\t\"out_trade_no\": \"c13c493182e1ee84\",\n" +
+                    "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\n" +
                     "\t\t\"merchant_no\": \"822290059430BFA\",\n" +
                     "\t\t\"term_no\": \"D9261078\",\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\": \"180.157.249.160\"\n" +
+                    "\t\t\t\"request_ip\": \"" + ipAddr + "\"\n" +
                     "\t\t},\n" +
-                    "\t\t\"subject\": \"cc测试\",\n" +
-                    "\t\t\"total_amount\": 1,\n" +
-                    "\t\t\"account_type\": \"ALIPAY\",\n" +
+                    "\t\t\"subject\": \"商品采购\",\n" +
+                    "\t\t\"settle_type\": \"1\",\n" +
+                    "\t\t\"total_amount\": " + amount + ",\n" +
+                    "\t\t\"account_type\": \"" + type + "\",\n" +
                     "\t\t\"trans_type\": \"41\"\n" +
                     "\t}\n" +
                     "}";
@@ -112,6 +149,19 @@
                         + IOUtils.toString(response.getEntity().getContent(), ENCODING));
             }
             String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING);
+
+
+            erpProcurement.setPayNumber(outTradeNo);
+            JSONObject jsonObject = JSONObject.parseObject(responseStr);
+            JSONObject jsonObject1 = jsonObject.getJSONObject("resp_data");
+            String code = jsonObject1.getString("log_no");
+            erpProcurement.setPayTransactionId(code);
+            erpProcurement.setStatus(2);
+            erpProcurement.setTermNo("D9261078");
+            erpProcurement.setAccountType(type);
+            erpProcurement.setTransType("41");
+            erpProcurementService.updateById(erpProcurement);
+
             return R.ok(responseStr);
         } catch (SDKException e) {
             e.printStackTrace();
@@ -120,6 +170,10 @@
     }
 
 
+    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 = "拉卡拉支付信息回调接口")
@@ -146,9 +200,151 @@
         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);
+            List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId()));
 
-        if (verify) {
-            // 先处理支付完成  修改状态 后处理分账  后走分账回调
+
+            // 操作分账
+            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", "http://221.182.45.100:8089/t-sys-order/messageSeparateHandle");
+            String time = DateUtils.dateTimeNow();
+
+            // SYMBOLS 随机取4位数
+            String str = "";
+            for (int i = 0; i < 6; i++) {
+                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<>();
+            // 根据供应商id分组
+            Map<String, List<TErpProcurementGoods>> collect = list.stream().collect(Collectors.groupingBy(TErpProcurementGoods::getSupplierId));
+            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() + "");
+                objects.add(map1);
+            }
+
+            // 添加平台的
+            map.put("recv_datas", objects);
+            String jsonString = JSON.toJSONString(map);
+            post.body(jsonString);
+            HttpResponse response = post.execute();
+            String responseStr = response.body();
+            JSONObject jsonObject = JSONObject.parseObject(responseStr);
+            if ("成功".equals(jsonObject.getString("msg"))) {
+                Object o1 = jsonObject.get("resp_data");
+                JSONObject jsonObject2 = JSONObject.parseObject(o1.toString());
+                String separate_no = jsonObject2.getString("separate_no");
+                erpProcurement.setSeparateNo(separate_no);
+                erpProcurementService.updateById(erpProcurement);
+            }
+
+            // 响应success
+            JSONObject responseJsonObject = new JSONObject();
+            responseJsonObject.put("code", "SUCCESS");
+            responseJsonObject.put("message", "执行成功");
+            return responseJsonObject;
+        }
+        return null;
+    }
+
+    @RequestMapping("/messageSeparateHandle")
+    @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);
+
+            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());
+            String time = DateUtils.dateTimeNow();
+
+            // SYMBOLS 随机取4位数
+            String str = "";
+            for (int i = 0; i < 6; i++) {
+                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<>();
+            // 根据供应商id分组
+            Map<String, List<TErpProcurementGoods>> collect = list.stream().collect(Collectors.groupingBy(TErpProcurementGoods::getSupplierId));
+            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() + "");
+                objects.add(map1);
+            }
+
+            // 添加平台的
+            map.put("recv_datas", objects);
+            String jsonString = JSON.toJSONString(map);
+            post.body(jsonString);
+            HttpResponse response = post.execute();
+            String responseStr = response.body();
+
 
             // 响应success
             JSONObject jsonObject = new JSONObject();
@@ -256,7 +452,6 @@
             throw new RuntimeException("无效的私钥", e);
         }
     }
-
 
 
     public final String getBody(HttpServletRequest request) {

--
Gitblit v1.7.1