支付对接

This commit is contained in:
周现广
2026-04-08 19:01:16 +08:00
parent 2cdda23545
commit cce99a9ec6
47 changed files with 3351 additions and 4 deletions
@@ -0,0 +1,28 @@
package io.v.nutz.pay.util;
import io.v.nutz.pay.pojo.LoginUser;
import io.v.nutz.sys.models.Sys_user;
import io.v.nutz.web.commons.utils.ShiroUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
public class AuthUtil {
public static AuthUtil instance() {
return new AuthUtil();
}
public LoginUser getLoginUser() {
return new LoginUser().setId(ShiroUtil.getUserId())
.setUsername(ShiroUtil.getPlatformUsername());
}
public String getUserId() {
return getLoginUser().getId();
}
public String getUsername() {
return getLoginUser().getUsername();
}
}
@@ -0,0 +1,41 @@
package io.v.nutz.pay.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import java.util.Date;
import java.util.Random;
public class BillNoUtil {
/**
* 雪花算法获取订单ID
* @param pre 单号ID前缀,自定义即可
* @return
*/
public static String getSimpleNo(String pre) {
return pre + IdUtil.getSnowflake().nextId();
}
public static String getDateNo(String pre, Integer length) {
String no = "000000000" + RandomUtil.randomNumbers(length);
no = no.substring(no.length() - length, no.length());
return pre + DateUtil.format(new Date(), "yyMMddHH") + no;
}
public static String getTimeNo(Integer length) {
String dateStart = DateUtil.format(new Date(), "yyyyMMddHHmmss");
Integer roundLength = length - dateStart.length();
String roundStr = generate24Digit(roundLength);
return dateStart + roundStr;
}
public static String generate24Digit(Integer length) {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(random.nextInt(10)); // 生成0-9的随机数字
}
return sb.toString();
}
}
@@ -0,0 +1,139 @@
package io.v.nutz.pay.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.util.Base64;
import java.util.Enumeration;
@Slf4j
public class PKCS7Tool {
// 加密算法
private static String KEY_ALGORITHM = "SHA256withRSA";
public static PKCS7Tool instance() {
return new PKCS7Tool();
}
/**
* Pkcs7Detach 签名
* @param signFilePath 签名证书
* @param password 证书秘钥
* @param content 内容
* @return
*/
public String signature(String signFilePath, String password, byte[] content){
if (StringUtils.isEmpty(signFilePath)) {
throw new RuntimeException("缺少证书");
}
if (StringUtils.isEmpty(password)) {
throw new RuntimeException("缺少证书密码");
}
log.info("生成签名信息:signFilePath-->{}, password-->{}", signFilePath, password);
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//创建密钥对
KeyStore keyStore = KeyStore.getInstance("PKCS12");
File file = new File(signFilePath);
if(!file.exists()) {
throw new RuntimeException("证书路径不存在");
}
FileInputStream fis = new FileInputStream(file);
keyStore.load(fis, password.toCharArray());
fis.close();
//获取别名
Enumeration enumas = keyStore.aliases();
String alias = null;
while (enumas.hasMoreElements()) {
alias = (String) enumas.nextElement();
}
//准备密钥对
Key key = keyStore.getKey(alias, password.toCharArray());
Signature sig = Signature.getInstance(KEY_ALGORITHM);
// 使用私钥初始化 Signature 对象
sig.initSign((PrivateKey) key);
sig.update(content);
// 生成签名
byte[] sign = sig.sign();
log.info("Pkcs7Detach 签名成功,加密后的密文为:{}", Base64.getEncoder().encodeToString(sign));
return Base64.getEncoder().encodeToString(sign);
} catch (Exception e) {
e.printStackTrace();
log.error("Pkcs7Detach 签名异常:"+e.getMessage());
}
return null;
}
/**
* 签名验证
* @param verifySignFilePath 验证签名证书
* @param password 证书秘钥
* @param data data是你的原始数据
* @param signature signature是之前生成的PKCS#7格式的签名
* @return boolean
*/
public boolean verifySignature(String verifySignFilePath, String password, byte[] data, byte[] signature) {
if (StringUtils.isEmpty(verifySignFilePath)) {
throw new RuntimeException("缺少证书");
}
if (StringUtils.isEmpty(password)) {
throw new RuntimeException("缺少证书密码");
}
log.info("验证签名信息:verifySignFilePath-->{}, password-->{}", verifySignFilePath, password);
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//创建密钥对
KeyStore keyStore = KeyStore.getInstance("PKCS12");
File file = new File(verifySignFilePath);
FileInputStream fis = new FileInputStream(file);
keyStore.load(fis, password.toCharArray());
fis.close();
//获取别名
Enumeration enumas = keyStore.aliases();
String alias = null;
while (enumas.hasMoreElements()) {
alias = (String) enumas.nextElement();
}
//准备密钥对
Key key = keyStore.getKey(alias, password.toCharArray());
PublicKey publicKey=null;
if (key instanceof PrivateKey) {
//获取用户证书
Certificate cert = keyStore.getCertificate(alias);
publicKey = cert.getPublicKey();
}
Signature sig = Signature.getInstance(KEY_ALGORITHM);
// 使用私钥初始化 Signature 对象
sig.initSign((PrivateKey) key);
sig.update(data);
// 使用公钥验证签名
sig.initVerify(publicKey);
sig.update(data);
boolean isVerified = sig.verify(signature);
log.info("Pkcs7Detach 验签结果:",isVerified);
if (isVerified) {
log.info("Pkcs7Detach 验签成功,返回为:",isVerified);
}
return isVerified;
} catch (Exception e) {
e.printStackTrace();
log.error("Pkcs7Detach 验证失败:{}",e.getMessage());
}
return false;
}
}
@@ -0,0 +1,43 @@
package io.v.nutz.pay.util;
import javax.servlet.http.HttpServletRequest;
public class ServletUtil {
public static String getIp(HttpServletRequest request) {
if (request == null) {
return null;
} else {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("http_client_ip");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip != null && ip.indexOf(",") != -1) {
ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
}
return ip;
}
}
}
@@ -0,0 +1,206 @@
package io.v.nutz.pay.util;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
public class XmlUtil
{
public XmlUtil()
{
}
public static Schema createSchema(File file)
throws Exception
{
SchemaFactory schemafactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
return schemafactory.newSchema(file);
}
public static void validateViaDOM(Document document, Schema schema)
throws Exception
{
DOMSource domsource = new DOMSource(document);
Validator validator = schema.newValidator();
validator.validate(domsource);
}
public static void validateViaDOM(String s, Schema schema)
throws Exception
{
DOMSource domsource = new DOMSource(createDocument(s));
Validator validator = schema.newValidator();
validator.validate(domsource);
}
public static void validateViaSAX(String s, Schema schema)
throws Exception
{
SAXSource saxsource = new SAXSource(new InputSource(new InputStreamReader(new ByteArrayInputStream(s.getBytes("UTF-8")))));
Validator validator = schema.newValidator();
validator.validate(saxsource);
}
public static void validateViaStreamSource(String s, Schema schema)
throws Exception
{
StreamSource streamsource = new StreamSource(new ByteArrayInputStream(s.getBytes("UTF-8")));
Validator validator = schema.newValidator();
validator.validate(streamsource);
}
public static Document createDocument(String s)
throws Exception
{
DocumentBuilder documentbuilder = createDocumentBuilder();
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes("UTF-8")));
}
public static Document createDocument(String s, String s1)
throws Exception
{
DocumentBuilder documentbuilder = createDocumentBuilder();
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes(s1)));
}
public static Document createDocument(File file)
throws Exception
{
DocumentBuilder documentbuilder = createDocumentBuilder();
return documentbuilder.parse(file);
}
public static DocumentBuilder createDocumentBuilder()
throws Exception
{
DocumentBuilderFactory documentbuilderfactory = DocumentBuilderFactory.newInstance();
return documentbuilderfactory.newDocumentBuilder();
}
public static String getNodeText(Document document, String s)
throws Exception
{
return getNodeText(document, s, 0);
}
public static String getNodeText(Document document, String s, String defaultValue)
throws Exception
{
return getNodeText(document, s, 0) == null? defaultValue : getNodeText(document, s, 0);
}
public static String getNodeText(Document document, String s, int i)
throws Exception
{
NodeList nodelist = document.getElementsByTagName(s);
if(nodelist == null || i >= nodelist.getLength())
return null;
else
return nodelist.item(i).getTextContent();
}
public static String getChildNodeText(Node node, String s)
{
NodeList nodelist = node.getChildNodes();
int i = nodelist.getLength();
for(int j = 0; j < i; j++)
{
Node node1 = nodelist.item(j);
if(node1.getNodeType() == 1 && node1.getNodeName() == s)
return node1.getTextContent();
}
return null;
}
public static List getNodeList(Document document, String s)
throws Exception
{
NodeList nodelist = document.getElementsByTagName(s);
ArrayList arraylist = new ArrayList();
if(nodelist == null)
return null;
for(int i = 0; i < nodelist.getLength(); i++)
arraylist.add(nodelist.item(i).getTextContent());
return arraylist;
}
public static String getNodeAttributeValue(Document document, String s, String s1)
throws Exception
{
NodeList nodelist = document.getElementsByTagName(s);
if(nodelist != null && nodelist.getLength() > 0)
{
Element element = (Element)nodelist.item(0);
return element.getAttribute(s1);
} else
{
return null;
}
}
public static String getNodeText(Node node, String s)
throws Exception
{
NodeList nodelist = node.getChildNodes();
int i = nodelist.getLength();
for(int j = 0; j < i; j++)
{
Node node1 = nodelist.item(j);
if(node1.getNodeType() == 1 && node1.getNodeName().equals(s))
return node1.getTextContent();
}
return null;
}
public static String createPrettyFormat(Document document)
throws Exception
{
return createPrettyFormat(document, "UTF-8");
}
public static String createPrettyFormat(Document document, String s)
throws Exception
{
DOMSource domsource = new DOMSource(document);
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer transformer = transformerfactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
transformer.setOutputProperty("encoding", s);
StringWriter stringwriter = new StringWriter();
transformer.transform(domsource, new StreamResult(stringwriter));
return stringwriter.toString();
}
public static String createCompactFormat(Document document)
throws Exception
{
return createCompactFormat(document, "UTF-8");
}
public static String createCompactFormat(Document document, String s)
throws Exception
{
DOMSource domsource = new DOMSource(document);
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer transformer = transformerfactory.newTransformer();
transformer.setOutputProperty("encoding", s);
StringWriter stringwriter = new StringWriter();
transformer.transform(domsource, new StreamResult(stringwriter));
return stringwriter.toString();
}
}