对接邮政订单系统

master
luojian 2025-01-20 10:54:18 +08:00
parent 3b0eb0bb97
commit 8e0d8d39c1
3 changed files with 341 additions and 0 deletions

View File

@ -0,0 +1,196 @@
package com.cpxt.web.controller.biz.orderutil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.cpxt.common.annotation.Anonymous;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Security;
import java.util.*;
/**
* @Author Ly
* @Create 2024/12/4 18:57
* @Desc
*/
@RestController
@RequestMapping("/test")
@Slf4j
public class cityDelivery {
private static final char[] specialChars = {'\n', '\r', '\t', '\f','\b',' '};
// test
String clientKey ="7480617400984563";//accessKey
String clientSecret = "91wCEvn82CeyMg3k";
String sm4Key = "MJy05dcI4mPbGB61";
String appType = "wxmp";
String client_type = "other";
String version = "1.0.0";
/*static{
Security.addProvider(new BouncyCastleProvider());
}*/
/**
* post
*/
@Anonymous
public void cityDelivery_signBody2(){
Long timeStamp = System.currentTimeMillis();
String nonce = UUID.randomUUID().toString().replace("-","");
System.out.println("nonce:"+nonce );
System.out.println("timeStamp:"+timeStamp );
//签名
Map<String,Object> sortedMap = new TreeMap<>();
//下单接口
String body = "{\n" +
" \"customerCode\": \"GZHX\",\n" +
" \"payTypeFirst\": \"03\",\n" +
" \"convertFlag\": false,\n" +
" \"weight\": \"501\",\n" +
" \"expectedTime\": \"2024-11-11 12:12:00\",\n" +
" \"platformOrderNo\": \"\",\n" +
" \"channelOrderNo\": \"\",\n" +
" \"orderSource\": \"meituan\",\n" +
" \"orderSourcePlatform\": \"01\",\n" +
" \"costFee\": \"100\",\n" +
" \"packageDesc\": \"药品\",\n" +
" \"remark\": \"手机尾号1234\",\n" +
" \"expressNbr\": \"\",\n" +
" \"insuredFee\": \"1\",\n" +
" \"otherFee1\": \"2\",\n" +
" \"otherFee2\": \"3\",\n" +
" \"addressFirst\": {\n" +
" \"senderProviceCode\": \"440000\",\n" +
" \"senderProviceName\": \"广东省\",\n" +
" \"senderCityCode\": \"440100\",\n" +
" \"senderCityName\": \"广州市\",\n" +
" \"senderCountyCode\": \"440106\",\n" +
" \"senderCountyName\": \"天河区\",\n" +
" \"senderContactName\": \"中山三院\",\n" +
" \"senderContactPhone\": \"17523029470\",\n" +
" \"senderLongitude\": \"113.264000\",\n" +
" \"senderLatitude\": \"23.129101\",\n" +
" \"senderStreetCode\": \"001\",\n" +
" \"senderStreetName\": \"林和街道1\",\n" +
" \"senderAddr\": \"天河北路188号\",\n" +
" \"receiverProviceCode\": \"440000\",\n" +
" \"receiverProviceName\": \"广东省\",\n" +
" \"receiverCityCode\": \"440100\",\n" +
" \"receiverCityName\": \"广州市\",\n" +
" \"receiverCountyCode\": \"440106\",\n" +
" \"receiverCountyName\": \"天河区\",\n" +
" \"receiverContactName\": \"陈先生\",\n" +
" \"receiverContactPhone\": \"13711511111\",\n" +
" \"receiverAddr\": \"信源大厦20楼2007\",\n" +
" \"receiverLongitude\": \"113.265000\",\n" +
" \"receiverLatitude\": \"23.129101\",\n" +
" \"receiverStreetCode\": \"002\",\n" +
" \"receiverStreetName\": \"林和街道2\"\n" +
" },\n" +
" \"businessJson\": {\n" +
" \"a\": \"asd\",\n" +
" \"b\": \"asd\"\n" +
" }\n" +
"}";
//查询物流轨迹
// String body = "{\n" +
// " \"expressNbr\": \"1158114584567\",\n" +
// " \"channelOrderNo\": \"\"\n" +
// "}";
//get请求组装成 k v类型
// sortedMap.put(paramName,request.getParameter(paramName));
/**
* postdata
*/
sortedMap.put("data", JSON.toJSONString(StrUtil.removeAll(body, specialChars)));
sortedMap.put("access_id",clientKey);
sortedMap.put("nonce", nonce);
sortedMap.put("timestamp",timeStamp);
//排序
Map<String,Object> sortedParams = new TreeMap<>(sortedMap);
Set<Map.Entry<String,Object>> entrySet = sortedParams.entrySet();
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
StringBuilder stringToSign = new StringBuilder();
for (Map.Entry<String,Object> param : entrySet) {
stringToSign.append(param.getKey()).append("=").append(param.getValue()).append(",");
}
stringToSign.append("accessSecret").append("=").append(clientSecret);
String genSign = cityDelivery_SM4Util.encryptCBC(stringToSign.toString(),clientSecret,sm4Key);
System.out.println("sign:" + genSign);
}
//获取token
@Anonymous
@PostMapping("/getToken")
public void getToken(){
System.out.println("获取token");
String url = "https://wyjcs.gdwyj.cn/szelec/city-delivery-api/api/mini/app/login/token";
String nonce = UUID.randomUUID().toString().replace("-", "");
Long timestamp = System.currentTimeMillis();
//body
Map map = new HashMap();
map.put("clientKey",clientKey);
map.put("clientSecret",clientSecret);
map.put("appType",appType);
map.put("clientType",client_type);
map.put("version",version);
Map<String, Object> sortedParams1 = new TreeMap<>(map);
Set<Map.Entry<String, Object>> entrySet1 = sortedParams1.entrySet();
StringBuilder stringToSign = new StringBuilder();
for (Map.Entry<String, Object> param : entrySet1) {
stringToSign.append(param.getKey()).append("=").append(param.getValue()).append(",");
}
String encryptBase64 = cityDelivery_SM4Util.encryptCBC(stringToSign.toString(),clientSecret,sm4Key);
System.out.println("body:" + encryptBase64);
//签名
Map<String,Object> sortedMap2 = new TreeMap<>();
//get请求组装成 k v类型
// sortedMap2.put(paramName,request.getParameter(paramName));
/**
* postdata
*/
Map bodyMap = new HashMap();
bodyMap.put("body",encryptBase64);
String bodyJson = JSON.toJSONString(bodyMap);
sortedMap2.put("data", JSON.toJSONString(bodyJson));
sortedMap2.put("access_id",clientKey);
sortedMap2.put("nonce", nonce);
sortedMap2.put("timestamp",timestamp);
//排序
Map<String,Object> sortedParams2 = new TreeMap<>(sortedMap2);
Set<Map.Entry<String,Object>> entrySet2 = sortedParams2.entrySet();
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
StringBuilder stringToSign2 = new StringBuilder();
for (Map.Entry<String,Object> param : entrySet2) {
stringToSign2.append(param.getKey()).append("=").append(param.getValue()).append(",");
}
stringToSign2.append("accessSecret").append("=").append(clientSecret);
// String genSign = DigestUtils.md5Hex(stringToSign2.toString());
String genSign = cityDelivery_SM4Util.encryptCBC(stringToSign2.toString(),clientSecret,sm4Key);
System.out.println("------------");
System.out.println("sign:" + genSign);
HttpResponse response = HttpRequest.post(url)
.body(JSON.toJSONString(bodyMap))
.header("Content-Type", "application/json")
.header("client_type", client_type)
.header("app_type", appType)
.header("access_id", clientKey)
.header("nonce", nonce)
.header("timestamp", timestamp.toString())
.header("sign", genSign)
.execute();
System.out.println(response);
}
}

View File

@ -0,0 +1,131 @@
package com.cpxt.web.controller.biz.orderutil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.SM4;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Base64;
/**
* TODO
*
* @Author Mitch
* @Date 2024-12-12 16:30
*/
@Slf4j
@Component
public class cityDelivery_SM4Util {
public static String encryptCBC(String str, String secretKey, String iv) {
return encryptCBC(str, secretKey, iv, true);
}
public static String encryptCBC(String str, String secretKey, String iv, boolean checkBase64) {
String encryptBase64 = null;
if (StrUtil.isEmpty(str)) {
return "";
}
if (checkBase64 && isBase64(str)) {
return str;
}
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding,
secretKey.getBytes(CharsetUtil.CHARSET_UTF_8),
iv.getBytes(CharsetUtil.CHARSET_UTF_8));
encryptBase64 = sm4.encryptBase64(str);
return encryptBase64;
}
public static String decryptCBC(String str, String secretKey, String iv) {
return decryptCBC(str, secretKey, iv, true);
}
public static String decryptCBC(String str, String secretKey, String iv, boolean checkBase64) {
String decryptStr = null;
try {
if (checkBase64 && !isBase64(str)) {
return str;
}
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding,
secretKey.getBytes(CharsetUtil.CHARSET_UTF_8),
iv.getBytes(CharsetUtil.CHARSET_UTF_8));
decryptStr = sm4.decryptStr(str);
} catch (Exception e) {
log.error("解密参数:{}", str, "国密解密算法工具类异常--->{}", ExceptionUtil.getMessage(e));
e.printStackTrace();
}
return decryptStr;
}
public static boolean isBase64(String input) {
char specificChar = '=';
if (input == null || input.isEmpty()) {
return false;
}
if (input.length() == 20 && input.matches("[0-9]+")) {
return false;
}
if (input.length() % 4 != 0) {
return false;
}
if (input.length() < 16) {
return false;
}
if (input.length() == 16 && input.matches("[0-9]+")) {
return false;
}
try {
byte[] decodedBytes = Base64.getDecoder().decode(input);
// 判断是否以=号结尾的
if (input.endsWith(String.valueOf(specificChar))) {
int numEquals = 0;
for (int i = input.length() - 1; i >= 0; i--) {
if (input.charAt(i) == '=') {
numEquals++;
} else {
break;
}
}
return numEquals >= 0 && numEquals <= 2;
}
for (char c : input.toCharArray()) {
if (!(isBase64Character(c))) {
return false;
}
}
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
private static boolean isBase64Character(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
|| (c >= '0' && c <= '9') || c == '+' || c == '/';
}
private static String getKey(){
return RandomUtil.randomString(16);
}
public static void main(String[] args) {
// String content = "我是字符串";
//16位字符串
String key = "nCWGwBstWF3MOu8T";
String iv = "ABtjL78T7vBjhqyb";
// String s = encryptCBC(content, key, iv);
// System.out.println(s);
String m = "1lcPgvBeFGaXJKrDfpOiAw==";
String string = decryptCBC(m, key, iv);
System.out.println(string);
}
}

View File

@ -137,6 +137,20 @@
<version>5.5.7</version> <version>5.5.7</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
</dependencies> </dependencies>
</project> </project>