Browse Source

融资余额充值开放接口与验签

liyuan 7 months ago
parent
commit
b66b594cbf

+ 62 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/duoduo/controller/DuoDuoOpenApiController.java

@@ -0,0 +1,62 @@
+package org.springblade.salesPart.duoduo.controller;
+
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.salesPart.duoduo.util.MallSignUtil;
+import org.springblade.salesPart.funding.entity.PjpfBalanceReset;
+import org.springblade.salesPart.funding.service.IPjpfBalanceResetService;
+import org.springblade.system.entity.Tenant;
+import org.springblade.system.feign.ISysClient;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+
+/**
+ * @author Rain
+ */
+@RestController
+@RequestMapping("/cnAuto/mall")
+@Slf4j
+@AllArgsConstructor
+public class DuoDuoOpenApiController {
+
+	private final IPjpfBalanceResetService balanceResetService;
+
+	 private  final ISysClient sysClient;
+
+
+
+	@PostMapping("customerRechargeMsg")
+	public R<Boolean> customerRechargeMsg(@RequestHeader("sign") String sign,
+										  @RequestHeader("timestamp") Long timestamp,
+										  @RequestHeader("companyCode") String companyCode,
+										  @RequestBody @Valid PjpfBalanceReset pjpfBalanceReset) {
+		boolean verify = MallSignUtil.verify(sign, timestamp, companyCode);
+		if (!verify) {
+			return R.fail("签名验证失败");
+		}
+		R<Tenant> tenant = sysClient.getTenant(pjpfBalanceReset.getTenantId());
+		if (!tenant.isSuccess() || ObjectUtil.isEmpty(tenant.getData())) {
+			return R.fail("客户不存在");
+		}
+		pjpfBalanceReset.setDate(DateUtil.now());
+		pjpfBalanceReset.setSysNo("CZ" + DateUtil.format(pjpfBalanceReset.getDate(), DateUtil.PATTERN_DATETIME));
+		boolean saveStatus = balanceResetService.save(pjpfBalanceReset);
+		if (!saveStatus) {
+			return R.fail("接收到款数据失败");
+		}
+		return R.success("接收到款数据成功");
+	}
+
+
+	@PostMapping("sign")
+	public R<byte[]> sign(@RequestHeader("timestamp") Long timestamp, @RequestHeader("companyCode") String companyCode) {
+		return R.data(MallSignUtil.sign(timestamp, companyCode));
+	}
+
+
+}

+ 59 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/duoduo/util/MallSignUtil.java

@@ -0,0 +1,59 @@
+package org.springblade.salesPart.duoduo.util;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.RSA;
+import cn.hutool.crypto.asymmetric.Sign;
+import cn.hutool.crypto.asymmetric.SignAlgorithm;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author Rain
+ */
+@Slf4j
+public class MallSignUtil {
+
+	private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmjokR4q1XEGYGTDhASMpYaqwRSO5mXJkDqO22L6FD07FFlZf9VofieoxoYwp55fAahLIwOm7HwX1ciOwR2Z+zOLn72mBnMQxgnkJpxcIRDFCpSsBw4bLQMOY0evlCtbW1tlIA3D2ZhnrJUZE7fQkGx8cUhzvw38KPvTVBAIpfAQIDAQAB";
+
+	private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOaOiRHirVcQZgZMOEBIylhqrBFI7mZcmQOo7bYvoUPTsUWVl/1Wh+J6jGhjCnnl8BqEsjA6bsfBfVyI7BHZn7M4ufvaYGcxDGCeQmnFwhEMUKlKwHDhstAw5jR6+UK1tbW2UgDcPZmGeslRkTt9CQbHxxSHO/Dfwo+9NUEAil8BAgMBAAECgYAgPRYVlii+3+AkSUwkUQlaS7A7yoLrdU9AH8L9krNuFI/ZNw3Fsu/VT2WKwy6X1Ps5+gwgiksrS3cIFW1NIa0e0noHJzgcP3twcAA7tEX2bf/bRlmgQKgj2UChL2tZdP8eeykC0w/3V127DmTJ8Zb1hbQqHyCvsYUQ0oteLxPy8QJBAPqdHy5212/hWymTsSRC4EBp+N7+p4c0gyhOii+s54VW++kILFEokOOFVKQVYNd9f85pM3FiEAfjTT0IDGCkkAMCQQDrgw9eDI0yJcWOJA7hlwceMNmXiNZdDW2C76ZFIzX4Jd0pCt1B0D7ZkgzBJ5dsa3tyOVg4v22wEiYEeStkug+rAkBBAhDclKc9tk9XcaA5r79L9jFAZv497Dk5c2YVB9zmkbG2uRAF3Wf4HNXf2kvMmhlVCaT2fGF8KlIWyserKgTRAkEAriqEKNc7bASG7rE32BjqiKczo17suG//tr8nxSVe+h52Sa3hJpSshhX+HLH8x49NAZHq7jyTD4y8VL6PGrSGdQJAGaYcFWnc02LZw593SH4I2naA8LVwvyiGbuRPV6vJ6/e9G9ChoPM8i8+QjtcdAtzp6BBARnsNKeEBggnZV9bB7Q==";
+
+	private static final RSA RSA_SIGN = new RSA(PRIVATE_KEY, PUBLIC_KEY);
+
+
+	public static boolean verify(String signStr, Long timestamp, String companyCode) {
+		Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA);
+		sign.setPublicKey(RSA_SIGN.getPublicKey());
+		String data = companyCode + timestamp;
+		byte[] signBytes = Base64.decode(signStr);
+		return sign.verify(data.getBytes(), signBytes);
+	}
+
+	public static byte[] sign(Long timestamp, String companyCode) {
+		Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA);
+		sign.setPrivateKey(RSA_SIGN.getPrivateKey());
+		return sign.sign(companyCode + timestamp);
+	}
+
+
+	private static boolean verifySignature(String data, String sign) {
+		try {
+			// 创建RSA对象(使用Hutool封装方法)
+			RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
+			// 创建签名对象(指定SHA256withRSA算法)
+			Sign signer = new Sign(SignAlgorithm.SHA256withRSA, rsa.getPrivateKey(), rsa.getPublicKey());
+			// 将Base64编码的签名转为字节数组
+			byte[] signBytes = Base64.decode(sign);
+
+			// 执行验签操作(自动处理数据编码)
+			boolean isValid = signer.verify(data.getBytes(StandardCharsets.UTF_8), signBytes);
+			log.info("Signature verification result: {}", isValid);
+			return isValid;
+		} catch (Exception e) {
+			log.error("Signature verification failed", e);
+			return false;
+		}
+	}
+
+}