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.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>
|
* 订单管理 前端控制器
|
* </p>
|
*
|
* @author xiaochen
|
* @since 2025-08-20
|
*/
|
@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\": \"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\": \"" + 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("D9261078");
|
erpProcurement.setAccountType(type);
|
erpProcurement.setTransType("41");
|
erpProcurementService.updateById(erpProcurement);
|
|
return R.ok(responseStr);
|
} catch (SDKException e) {
|
e.printStackTrace();
|
}
|
return R.fail(500, "调用支付宝支付预下单接口错误");
|
}
|
|
|
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 = "拉卡拉支付信息回调接口")
|
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", "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 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_merchant_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()));
|
for (Object object : jsonArray) {
|
JSONObject jsonObject = JSONObject.parseObject(object.toString());
|
String recvMerchantNo = jsonObject.getString("recv_merchant_no");
|
String recvNo = jsonObject.getString("recv_no");
|
List<TErpProcurementGoods> collect1 = list1.stream().filter(e -> e.getRecvMerchantNo().equals(recvMerchantNo)).collect(Collectors.toList());
|
collect1.stream().forEach(e->e.setRecvNo(recvNo));
|
erpProcurementGoodsService.updateBatchById(collect1);
|
}
|
// 响应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\": \"822290059430BFA\",\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", "822290059430BFA");
|
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);
|
}
|
}
|
|
|
}
|