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

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java |  635 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 633 insertions(+), 2 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 18f17c5..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
@@ -1,8 +1,63 @@
 package com.ruoyi.web.controller.api;
 
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import cn.hutool.http.HttpRequest;
+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;
+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;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.SneakyThrows;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+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.*;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.servlet.http.HttpServletRequest;
+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.*;
+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>
@@ -14,7 +69,583 @@
  */
 @RestController
 @RequestMapping("/t-sys-order")
+@Api(tags = "订单管理")
 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, TErpProcurementGoodsService erpProcurementGoodsService, TCrmSupplierService crmSupplierService) {
+        this.erpProcurementService = erpProcurementService;
+        this.tokenService = tokenService;
+        this.erpProcurementGoodsService = erpProcurementGoodsService;
+        this.crmSupplierService = crmSupplierService;
+    }
+
+    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    /**
+     * API schema ,固定 LKLAPI-SHA256withRSA
+     */
+    public final static String SCHEMA = "LKLAPI-SHA256withRSA";
+
+    /**
+     * 字符集固定 utf-8
+     */
+    public static final String ENCODING = "utf-8";
+
+
+    private static final SecureRandom RANDOM = new SecureRandom();
+
+
+    @ApiOperation(value = "支付")
+    @PostMapping(value = "/payOrder")
+    @SneakyThrows
+    public R<?> payOrder(@RequestParam String id, String type, HttpServletRequest request) {
+        try {
+
+            // 查出采购单 算出价格  下单  算出应该分佣金额 应该分给谁
+            TErpProcurement erpProcurement = erpProcurementService.getById(id);
+            if (erpProcurement.getStatus()>2) {
+                return R.fail("订单已支付");
+            }
+            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\": \"" + time + "\",\n" +
+                    "\t\"version\": \"3.0\",\n" +
+                    "\t\"req_data\": {\n" +
+                    "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\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" +
+                    "\t\t},\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" +
+                    "}";
+            String authorization = getAuthorization(body);
+            org.apache.http.HttpResponse response = post(LakalaConfig.getServerUrl() + apiPath, body, 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);
+
+
+            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("A9358698");
+            erpProcurement.setAccountType(type);
+            erpProcurement.setTransType("41");
+            erpProcurementService.updateById(erpProcurement);
+
+            return R.ok(responseStr);
+        } catch (SDKException e) {
+            e.printStackTrace();
+        }
+        return R.fail(500, "调用支付宝支付预下单接口错误");
+    }
+
+
+
+    @RequestMapping("/messageHandle")
+    @ApiOperation(value = "拉卡拉支付信息回调接口")
+    public Object messageHandle(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);
+
+            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", "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");
+            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 allMoney = erpProcurement.getPayMoney();
+            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_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);
+
+            reqMap.put("req_data", map);
+
+
+            String jsonString = JSON.toJSONString(reqMap);
+            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);
+        // 先处理支付完成  修改状态 后处理分账  后走分账回调
+        JSONObject jsonObject1 = JSONObject.parseObject(body);
+        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);
+
+
+                // 响应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位数
+            String str = "";
+            for (int i = 0; i < 6; i++) {
+                str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
+            }
+            String outTradeNo = time + str;
+
+            // 操作分账
+            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<>();
+                List<TErpProcurementGoods> value = entry.getValue();
+                BigDecimal reduce = value.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
+                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);
+
+
+            String jsonString = JSON.toJSONString(reqMap);
+            post.body(jsonString);
+            HttpResponse response = post.execute();
+            String responseStr = response.body();
+
+
+            return R.ok(responseStr);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        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() {
+            public X509Certificate[] getAcceptedIssuers() {
+                return null;
+            }
+
+            public void checkClientTrusted(X509Certificate[] xcs, String str) {
+            }
+
+            public void checkServerTrusted(X509Certificate[] xcs, String str) {
+            }
+        };
+        HttpClient http = new DefaultHttpClient();
+        ClientConnectionManager ccm = http.getConnectionManager();
+        ctx.init(null, new TrustManager[]{tm}, null);
+        SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+        ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+        SchemeRegistry registry = ccm.getSchemeRegistry();
+        registry.register(new Scheme("https", ssf, 443));
+        HttpPost post = new HttpPost(url);
+        StringEntity myEntity = new StringEntity(message, ENCODING);
+        post.setEntity(myEntity);
+        post.setHeader("Authorization", SCHEMA + " " + authorization);
+        post.setHeader("Accept", "application/json");
+        post.setHeader("Content-Type", "application/json");
+        return http.execute(post);
+    }
+
+    public final String getAuthorization(String body) throws IOException {
+        String nonceStr = generateNonceStr();
+        long timestamp = generateTimestamp();
+
+        String message = LakalaConfig.getAppId() + "\n" + LakalaConfig.getMerchantNo() + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
+
+        System.out.println("getToken message :  " + message);
+
+        PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(LakalaConfig.getPriKeyStr())));
+
+        String signature = this.sign(message.getBytes(ENCODING), merchantPrivateKey);
+
+        String authorization = "appid=\"" + LakalaConfig.getAppId() + "\"," + "serial_no=\"" + LakalaConfig.getMerchantNo() + "\"," + "timestamp=\""
+                + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
+        System.out.println("authorization message :" + authorization);
+
+        return authorization;
+    }
+
+    public long generateTimestamp() {
+        return System.currentTimeMillis() / 1000;
+    }
+
+    public String generateNonceStr() {
+        char[] nonceChars = new char[32];
+        for (int index = 0; index < nonceChars.length; ++index) {
+            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
+        }
+        return new String(nonceChars);
+    }
+
+    public static PrivateKey loadPrivateKey(InputStream inputStream) {
+        try {
+            ByteArrayOutputStream array = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int length;
+            while ((length = inputStream.read(buffer)) != -1) {
+                array.write(buffer, 0, length);
+            }
+
+            String privateKey = array.toString("utf-8").replace("-----BEGIN PRIVATE KEY-----", "")
+                    .replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");
+            KeyFactory kf = KeyFactory.getInstance("RSA");
+            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("当前Java环境不支持RSA", e);
+        } catch (InvalidKeySpecException e) {
+            throw new RuntimeException("无效的密钥格式");
+        } catch (IOException e) {
+            throw new RuntimeException("无效的密钥");
+        }
+    }
+
+    public String sign(byte[] message, PrivateKey privateKey) {
+        try {
+            Signature sign = Signature.getInstance("SHA256withRSA");
+            sign.initSign(privateKey);
+            sign.update(message);
+            return new String(Base64.encodeBase64(sign.sign()));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+        } catch (SignatureException e) {
+            throw new RuntimeException("签名计算失败", e);
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("无效的私钥", e);
+        }
+    }
+
+
+    public final String getBody(HttpServletRequest request) {
+        InputStreamReader in = null;
+        try {
+            in = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8);
+            StringBuffer bf = new StringBuffer();
+            int len;
+            char[] chs = new char[1024];
+            while ((len = in.read(chs)) != -1) {
+                bf.append(new String(chs, 0, len));
+            }
+            return bf.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (null != in) {
+                try {
+                    in.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+        return null;
+    }
+
+    public static X509Certificate loadCertificate(InputStream inputStream) {
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X509");
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
+
+            cert.checkValidity();
+            return cert;
+        } catch (CertificateExpiredException e) {
+            throw new RuntimeException("证书已过期", e);
+        } catch (CertificateNotYetValidException e) {
+            throw new RuntimeException("证书尚未生效", e);
+        } catch (CertificateException e) {
+            throw new RuntimeException("无效的证书", e);
+        }
+    }
+
+    private static boolean verify(X509Certificate certificate, byte[] message, String signature) {
+        try {
+            Signature sign = Signature.getInstance("SHA256withRSA");
+            sign.initVerify(certificate);
+            sign.update(message);
+            byte[] signatureB = Base64.decodeBase64(signature);
+            return sign.verify(signatureB);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+        } catch (SignatureException e) {
+            throw new RuntimeException("签名验证过程发生了错误", e);
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("无效的证书", e);
+        }
+    }
+
+
 }
 

--
Gitblit v1.7.1