新增退款接口
新增接口等注释
#修改#
更新新的支付接口
This commit is contained in:
Actinia-517
2017-12-05 16:24:55 +08:00
parent bcda184f94
commit dfd2cc68c5
31 changed files with 4472 additions and 61 deletions

View File

@@ -0,0 +1,822 @@
/**
*
* Licensed Property to China UnionPay Co., Ltd.
*
* (C) Copyright of China UnionPay Co., Ltd. 2010
* All Rights Reserved.
*
*
* Modification History:
* =============================================================================
* Author Date Description
* ------------ ---------- ---------------------------------------------------
* xshu 2014-05-28 证书工具类.
* =============================================================================
*/
package com.egzosn.pay.union.SDK;
import com.egzosn.pay.common.util.str.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.*;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @ClassName: CertUtil
* @Description: acpsdk证书工具类主要用于对证书的加载和使用
* @date 2016-7-22 下午2:46:20
*
*/
public class CertUtil {
//日志
protected static final Log log = LogFactory.getLog(CertUtil.class);
public static final String UNIONPAY_CNNAME = "中国银联股份有限公司";
/** 证书容器,存储对商户请求报文签名私钥证书. */
private static KeyStore keyStore = null;
/** 敏感信息加密公钥证书 */
private static X509Certificate encryptCert = null;
/** 磁道加密公钥 */
private static PublicKey encryptTrackKey = null;
/** 验证银联返回报文签名证书. */
private static X509Certificate validateCert = null;
/** 验签中级证书 */
private static X509Certificate middleCert = null;
/** 验签根证书 */
private static X509Certificate rootCert = null;
/** 验证银联返回报文签名的公钥证书存储Map. */
private static Map<String, X509Certificate> certMap = new HashMap<String, X509Certificate>();
/** 商户私钥存储Map */
private final static Map<String, KeyStore> keyStoreMap = new ConcurrentHashMap<String, KeyStore>();
/**
* 请求报文签名(使用配置文件中配置的私钥证书或者对称密钥签名)<br>
* 功能:对请求报文进行签名,并计算赋值certid,signature字段并返回<br>
* @param reqData 请求报文map<br>
* @param encoding 上送请求报文域encoding字段的值<br>
* @return 签名后的map对象<br>
*/
public static Map<String, String> sign(Map<String, String> reqData,String encoding) {
reqData = filterBlank(reqData);
SDKUtils.signParams(reqData, encoding);
return reqData;
}
/**
* 过滤请求报文中的空字符串或者空字符串
* @param contentData
* @return
*/
public static Map<String, String> filterBlank(Map<String, String> contentData){
Map<String, String> submitFromData = new HashMap<String, String>();
Set<String> keyset = contentData.keySet();
for(String key:keyset){
String value = contentData.get(key);
if (StringUtils.isNotBlank(value)) {
// 对value值进行去除前后空处理
submitFromData.put(key, value.trim());
}
}
return submitFromData;
}
static {
init();
}
/**
* 初始化所有证书.
*/
private static void init() {
try {
addProvider();//向系统添加BC provider
initSignCert();//初始化签名私钥证书
initMiddleCert();//初始化验签证书的中级证书
initRootCert();//初始化验签证书的根证书
initEncryptCert();//初始化加密公钥
initTrackKey();//构建磁道加密公钥
initValidateCertFromDir();//初始化所有的验签证书
} catch (Exception e) {
e.printStackTrace();
log.error("init失败。如果是用对称密钥签名的可无视此异常。", e);
}
}
/**
* 添加签名,验签,加密算法提供者
*/
private static void addProvider(){
if (Security.getProvider("BC") == null) {
log.info("add BC provider");
Security.addProvider(new BouncyCastleProvider());
} else {
Security.removeProvider("BC"); //解决eclipse调试时tomcat自动重新加载时BC存在不明原因异常的问题。
Security.addProvider(new BouncyCastleProvider());
log.info("re-add BC provider");
}
// printSysInfo();
}
/**
* 用配置文件acp_sdk.properties中配置的私钥路径和密码 加载签名证书
*/
private static void initSignCert() {
if(!"01".equals(SDKConfig.getConfig().getSignMethod())){
log.info("非rsa签名方式不加载签名证书。");
return;
}
if (SDKConfig.getConfig().getSignCertPath() == null
|| SDKConfig.getConfig().getSignCertPwd() == null
|| SDKConfig.getConfig().getSignCertType() == null) {
log.error("WARN: " + SDKConfig.SDK_SIGNCERT_PATH + "" + SDKConfig.SDK_SIGNCERT_PWD
+ "" + SDKConfig.SDK_SIGNCERT_TYPE + "为空。 停止加载签名证书。");
return;
}
if (null != keyStore) {
keyStore = null;
}
try {
keyStore = getKeyInfo(SDKConfig.getConfig().getSignCertPath(),
SDKConfig.getConfig().getSignCertPwd(), SDKConfig
.getConfig().getSignCertType());
log.info("InitSignCert Successful. CertId=["
+ getSignCertId() + "]");
} catch (IOException e) {
e.printStackTrace();
log.error("InitSignCert Error", e);
}
}
/**
* 用配置文件acp_sdk.properties配置路径 加载敏感信息加密证书
*/
private static void initMiddleCert() {
// log.info("加载中级证书==>"+SDKConfig.getConfig().getMiddleCertPath());
if (!StringUtils.isEmpty(SDKConfig.getConfig().getMiddleCertPath())) {
middleCert = initCert(SDKConfig.getConfig().getMiddleCertPath());
log.info("Load MiddleCert Successful");
} else {
log.info("WARN: acpsdk.middle.path is empty");
}
}
/**
* 用配置文件acp_sdk.properties配置路径 加载敏感信息加密证书
*/
private static void initRootCert() {
// log.info("加载根证书==>"+SDKConfig.getConfig().getRootCertPath());
if (!StringUtils.isEmpty(SDKConfig.getConfig().getRootCertPath())) {
rootCert = initCert(SDKConfig.getConfig().getRootCertPath());
log.info("Load RootCert Successful");
} else {
log.info("WARN: acpsdk.rootCert.path is empty");
}
}
/**
* 用配置文件acp_sdk.properties配置路径 加载银联公钥上级证书(中级证书)
*/
private static void initEncryptCert() {
// log.info("加载敏感信息加密证书==>"+SDKConfig.getConfig().getEncryptCertPath());
if (!StringUtils.isEmpty(SDKConfig.getConfig().getEncryptCertPath())) {
encryptCert = initCert(SDKConfig.getConfig().getEncryptCertPath());
log.info("Load EncryptCert Successful");
} else {
log.info("WARN: acpsdk.encryptCert.path is empty");
}
}
/**
* 用配置文件acp_sdk.properties配置路径 加载磁道公钥
*/
private static void initTrackKey() {
if (!StringUtils.isEmpty(SDKConfig.getConfig().getEncryptTrackKeyModulus())
&& !StringUtils.isEmpty(SDKConfig.getConfig().getEncryptTrackKeyExponent())) {
encryptTrackKey = getPublicKey(SDKConfig.getConfig().getEncryptTrackKeyModulus(),
SDKConfig.getConfig().getEncryptTrackKeyExponent());
log.info("LoadEncryptTrackKey Successful");
} else {
log.info("WARN: acpsdk.encryptTrackKey.modulus or acpsdk.encryptTrackKey.exponent is empty");
}
}
/**
* 用配置文件acp_sdk.properties配置路径 加载验证签名证书
*/
private static void initValidateCertFromDir() {
if(!"01".equals(SDKConfig.getConfig().getSignMethod())){
log.info("非rsa签名方式不加载验签证书。");
return;
}
certMap.clear();
String dir = SDKConfig.getConfig().getValidateCertDir();
log.info("加载验证签名证书目录==>" + dir +"如果请求报文中version=5.1.0那么此验签证书目录使用不到可以不需要设置version=5.0.0必须设置)。");
if (StringUtils.isEmpty(dir)) {
log.error("WARN: acpsdk.validateCert.dir is empty");
return;
}
CertificateFactory cf = null;
FileInputStream in = null;
try {
cf = CertificateFactory.getInstance("X.509", "BC");
}catch (NoSuchProviderException e) {
log.error("LoadVerifyCert Error: No BC Provider", e);
return ;
} catch (CertificateException e) {
log.error("LoadVerifyCert Error", e);
return ;
}
File fileDir = new File(dir);
File[] files = fileDir.listFiles(new CerFilter());
for (int i = 0; i < files.length; i++) {
File file = files[i];
try {
in = new FileInputStream(file.getAbsolutePath());
validateCert = (X509Certificate) cf.generateCertificate(in);
if(validateCert == null) {
log.error("Load verify cert error, " + file.getAbsolutePath() + " has error cert content.");
continue;
}
certMap.put(validateCert.getSerialNumber().toString(),
validateCert);
// 打印证书加载信息,供测试阶段调试
log.info("[" + file.getAbsolutePath() + "][CertId="
+ validateCert.getSerialNumber().toString() + "]");
} catch (CertificateException e) {
log.error("LoadVerifyCert Error", e);
e.printStackTrace();
}catch (FileNotFoundException e) {
log.error("LoadVerifyCert Error File Not Found", e);
e.printStackTrace();
}finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.error(e.toString());
e.printStackTrace();
}
}
}
}
log.info("LoadVerifyCert Finish");
}
/**
* 用给定的路径和密码 加载签名证书并保存到certKeyStoreMap
*
* @param certFilePath
* @param certPwd
*/
private static void loadSignCert(String certFilePath, String certPwd) {
KeyStore keyStore = null;
try {
keyStore = getKeyInfo(certFilePath, certPwd, "PKCS12");
keyStoreMap.put(certFilePath, keyStore);
log.info("LoadRsaCert Successful");
} catch (IOException e) {
log.error("LoadRsaCert Error", e);
e.printStackTrace();
}
}
/**
* 通过证书路径初始化为公钥证书
* @param path
* @return
*/
private static X509Certificate initCert(String path) {
X509Certificate encryptCertTemp = null;
CertificateFactory cf = null;
FileInputStream in = null;
try {
cf = CertificateFactory.getInstance("X.509", "BC");
in = new FileInputStream(path);
encryptCertTemp = (X509Certificate) cf.generateCertificate(in);
// 打印证书加载信息,供测试阶段调试
log.info("[" + path + "][CertId="
+ encryptCertTemp.getSerialNumber().toString() + "]");
} catch (CertificateException e) {
log.error("InitCert Error", e);
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
log.error("InitCert Error File Not Found", e);
} catch (NoSuchProviderException e) {
e.printStackTrace();
log.error("LoadVerifyCert Error No BC Provider", e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
log.error(e.toString());
}
}
}
return encryptCertTemp;
}
/**
* 通过keyStore 获取私钥签名证书PrivateKey对象
*
* @return
*/
public static PrivateKey getSignCertPrivateKey() {
try {
Enumeration<String> aliasenum = keyStore.aliases();
String keyAlias = null;
if (aliasenum.hasMoreElements()) {
keyAlias = aliasenum.nextElement();
}
PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias,
SDKConfig.getConfig().getSignCertPwd().toCharArray());
return privateKey;
} catch (KeyStoreException e) {
e.printStackTrace();
log.error("getSignCertPrivateKey Error", e);
return null;
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
log.error("getSignCertPrivateKey Error", e);
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error("getSignCertPrivateKey Error", e);
return null;
}
}
/**
* 通过指定路径的私钥证书 获取PrivateKey对象
*
* @return
*/
public static PrivateKey getSignCertPrivateKeyByStoreMap(String certPath,
String certPwd) {
if (!keyStoreMap.containsKey(certPath)) {
loadSignCert(certPath, certPwd);
}
try {
Enumeration<String> aliasenum = keyStoreMap.get(certPath)
.aliases();
String keyAlias = null;
if (aliasenum.hasMoreElements()) {
keyAlias = aliasenum.nextElement();
}
PrivateKey privateKey = (PrivateKey) keyStoreMap.get(certPath)
.getKey(keyAlias, certPwd.toCharArray());
return privateKey;
} catch (KeyStoreException e) {
e.printStackTrace();
log.error("getSignCertPrivateKeyByStoreMap Error", e);
return null;
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
log.error("getSignCertPrivateKeyByStoreMap Error", e);
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error("getSignCertPrivateKeyByStoreMap Error", e);
return null;
}
}
/**
* 获取敏感信息加密证书PublicKey
*
* @return
*/
public static PublicKey getEncryptCertPublicKey() {
if (null == encryptCert) {
String path = SDKConfig.getConfig().getEncryptCertPath();
if (!StringUtils.isEmpty(path)) {
encryptCert = initCert(path);
return encryptCert.getPublicKey();
} else {
log.error("acpsdk.encryptCert.path is empty");
return null;
}
} else {
return encryptCert.getPublicKey();
}
}
/**
* 重置敏感信息加密证书公钥
*/
public static void resetEncryptCertPublicKey() {
encryptCert = null;
}
/**
* 获取磁道加密证书PublicKey
*
* @return
*/
public static PublicKey getEncryptTrackPublicKey() {
if (null == encryptTrackKey) {
initTrackKey();
}
return encryptTrackKey;
}
/**
* 通过certId获取验签证书Map中对应证书PublicKey
*
* @param certId 证书物理序号
* @return 通过证书编号获取到的公钥
*/
public static PublicKey getValidatePublicKey(String certId) {
X509Certificate cf = null;
if (certMap.containsKey(certId)) {
// 存在certId对应的证书对象
cf = certMap.get(certId);
return cf.getPublicKey();
} else {
// 不存在则重新Load证书文件目录
initValidateCertFromDir();
if (certMap.containsKey(certId)) {
// 存在certId对应的证书对象
cf = certMap.get(certId);
return cf.getPublicKey();
} else {
log.error("缺少certId=[" + certId + "]对应的验签证书.");
return null;
}
}
}
/**
* 获取配置文件acp_sdk.properties中配置的签名私钥证书certId
*
* @return 证书的物理编号
*/
public static String getSignCertId() {
try {
Enumeration<String> aliasenum = keyStore.aliases();
String keyAlias = null;
if (aliasenum.hasMoreElements()) {
keyAlias = aliasenum.nextElement();
}
X509Certificate cert = (X509Certificate) keyStore
.getCertificate(keyAlias);
return cert.getSerialNumber().toString();
} catch (Exception e) {
log.error("getSignCertId Error", e);
return null;
}
}
/**
* 获取敏感信息加密证书的certId
*
* @return
*/
public static String getEncryptCertId() {
if (null == encryptCert) {
String path = SDKConfig.getConfig().getEncryptCertPath();
if (!StringUtils.isEmpty(path)) {
encryptCert = initCert(path);
return encryptCert.getSerialNumber().toString();
} else {
log.error("acpsdk.encryptCert.path is empty");
return null;
}
} else {
return encryptCert.getSerialNumber().toString();
}
}
/**
* 将签名私钥证书文件读取为证书存储对象
*
* @param pfxkeyfile
* 证书文件名
* @param keypwd
* 证书密码
* @param type
* 证书类型
* @return 证书对象
* @throws IOException
*/
private static KeyStore getKeyInfo(String pfxkeyfile, String keypwd,
String type) throws IOException {
log.info("加载签名证书==>" + pfxkeyfile);
FileInputStream fis = null;
try {
KeyStore ks = KeyStore.getInstance(type, "BC");
log.info("Load RSA CertPath=[" + pfxkeyfile + "],Pwd=["+ keypwd + "],type=["+type+"]");
fis = new FileInputStream(pfxkeyfile);
char[] nPassword = null;
nPassword = null == keypwd || "".equals(keypwd.trim()) ? null: keypwd.toCharArray();
if (null != ks) {
ks.load(fis, nPassword);
}
return ks;
} catch (Exception e) {
log.error("getKeyInfo Error", e);
e.printStackTrace();
return null;
} finally {
if(null!=fis)
fis.close();
}
}
/**
* 通过签名私钥证书路径密码获取私钥证书certId
* @param certPath
* @param certPwd
* @return
*/
public static String getCertIdByKeyStoreMap(String certPath, String certPwd) {
if (!keyStoreMap.containsKey(certPath)) {
// 缓存中未查询到,则加载RSA证书
loadSignCert(certPath, certPwd);
}
return getCertIdIdByStore(keyStoreMap.get(certPath));
}
/**
* 通过keystore获取私钥证书的certId值
* @param keyStore
* @return
*/
private static String getCertIdIdByStore(KeyStore keyStore) {
Enumeration<String> aliasenum = null;
try {
aliasenum = keyStore.aliases();
String keyAlias = null;
if (aliasenum.hasMoreElements()) {
keyAlias = aliasenum.nextElement();
}
X509Certificate cert = (X509Certificate) keyStore
.getCertificate(keyAlias);
return cert.getSerialNumber().toString();
} catch (KeyStoreException e) {
log.error("getCertIdIdByStore Error", e);
return null;
}
}
/**
* 使用模和指数生成RSA公钥 注意此代码用了默认补位方式为RSA/None/PKCS1Padding不同JDK默认的补位方式可能不同
*
* @param modulus
* 模
* @param exponent
* 指数
* @return
*/
private static PublicKey getPublicKey(String modulus, String exponent) {
try {
BigInteger b1 = new BigInteger(modulus);
BigInteger b2 = new BigInteger(exponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return keyFactory.generatePublic(keySpec);
} catch (Exception e) {
log.error("构造RSA公钥失败" + e);
return null;
}
}
/**
* 将字符串转换为X509Certificate对象.
*
* @param x509CertString
* @return
*/
public static X509Certificate genCertificateByStr(String x509CertString) {
X509Certificate x509Cert = null;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
InputStream tIn = new ByteArrayInputStream(
x509CertString.getBytes("ISO-8859-1"));
x509Cert = (X509Certificate) cf.generateCertificate(tIn);
} catch (Exception e) {
log.error("gen certificate error", e);
}
return x509Cert;
}
/**
* 从配置文件acp_sdk.properties中获取验签公钥使用的中级证书
* @return
*/
public static X509Certificate getMiddleCert() {
if (null == middleCert) {
String path = SDKConfig.getConfig().getMiddleCertPath();
if (!StringUtils.isEmpty(path)) {
initMiddleCert();
} else {
log.error(SDKConfig.SDK_MIDDLECERT_PATH + " not set in " + SDKConfig.FILE_NAME);
return null;
}
}
return middleCert;
}
/**
* 从配置文件acp_sdk.properties中获取验签公钥使用的根证书
* @return
*/
public static X509Certificate getRootCert() {
if (null == rootCert) {
String path = SDKConfig.getConfig().getRootCertPath();
if (!StringUtils.isEmpty(path)) {
initRootCert();
} else {
log.error(SDKConfig.SDK_ROOTCERT_PATH + " not set in " + SDKConfig.FILE_NAME);
return null;
}
}
return rootCert;
}
/**
* 获取证书的CN
* @param aCert
* @return
*/
private static String getIdentitiesFromCertficate(X509Certificate aCert) {
String tDN = aCert.getSubjectDN().toString();
String tPart = "";
if ((tDN != null)) {
String tSplitStr[] = tDN.substring(tDN.indexOf("CN=")).split("@");
if (tSplitStr != null && tSplitStr.length > 2
&& tSplitStr[2] != null)
tPart = tSplitStr[2];
}
return tPart;
}
/**
* 验证书链。
* @param cert
* @return
*/
private static boolean verifyCertificateChain(X509Certificate cert){
if ( null == cert) {
log.error("cert must Not null");
return false;
}
X509Certificate middleCert = CertUtil.getMiddleCert();
if (null == middleCert) {
log.error("middleCert must Not null");
return false;
}
X509Certificate rootCert = CertUtil.getRootCert();
if (null == rootCert) {
log.error("rootCert or cert must Not null");
return false;
}
try {
X509CertSelector selector = new X509CertSelector();
selector.setCertificate(cert);
Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>();
trustAnchors.add(new TrustAnchor(rootCert, null));
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(
trustAnchors, selector);
Set<X509Certificate> intermediateCerts = new HashSet<X509Certificate>();
intermediateCerts.add(rootCert);
intermediateCerts.add(middleCert);
intermediateCerts.add(cert);
pkixParams.setRevocationEnabled(false);
CertStore intermediateCertStore = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(intermediateCerts), "BC");
pkixParams.addCertStore(intermediateCertStore);
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
@SuppressWarnings("unused")
PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder
.build(pkixParams);
log.info("verify certificate chain succeed.");
return true;
} catch (CertPathBuilderException e){
log.error("verify certificate chain fail.", e);
} catch (Exception e) {
log.error("verify certificate chain exception: ", e);
}
return false;
}
/**
* 检查证书链
*
* @param cert
* 待验证的证书
* @return
*/
public static boolean verifyCertificate(X509Certificate cert) {
if ( null == cert) {
log.error("cert must Not null");
return false;
}
try {
cert.checkValidity();//验证有效期
// cert.verify(middleCert.getPublicKey());
if(!verifyCertificateChain(cert)){
return false;
}
} catch (Exception e) {
log.error("verifyCertificate fail", e);
return false;
}
if(SDKConfig.getConfig().isIfValidateCNName()){
// 验证公钥是否属于银联
if(!UNIONPAY_CNNAME.equals(CertUtil.getIdentitiesFromCertficate(cert))) {
log.error("cer owner is not CUP:" + CertUtil.getIdentitiesFromCertficate(cert));
return false;
}
} else {
// 验证公钥是否属于银联
if(!UNIONPAY_CNNAME.equals(CertUtil.getIdentitiesFromCertficate(cert))
&& !"00040000:SIGN".equals(CertUtil.getIdentitiesFromCertficate(cert))) {
log.error("cer owner is not CUP:" + CertUtil.getIdentitiesFromCertficate(cert));
return false;
}
}
return true;
}
/**
* 打印系统环境信息
*/
private static void printSysInfo() {
log.info("================= SYS INFO begin====================");
log.info("os_name:" + System.getProperty("os.name"));
log.info("os_arch:" + System.getProperty("os.arch"));
log.info("os_version:" + System.getProperty("os.version"));
log.info("java_vm_specification_version:"
+ System.getProperty("java.vm.specification.version"));
log.info("java_vm_specification_vendor:"
+ System.getProperty("java.vm.specification.vendor"));
log.info("java_vm_specification_name:"
+ System.getProperty("java.vm.specification.name"));
log.info("java_vm_version:"
+ System.getProperty("java.vm.version"));
log.info("java_vm_name:" + System.getProperty("java.vm.name"));
log.info("java.version:" + System.getProperty("java.version"));
log.info("java.vm.vendor=[" + System.getProperty("java.vm.vendor") + "]");
log.info("java.version=[" + System.getProperty("java.version") + "]");
// printProviders();
log.info("================= SYS INFO end=====================");
}
/**
* 打jre中印算法提供者列表
*/
private static void printProviders() {
log.info("Providers List:");
Provider[] providers = Security.getProviders();
for (int i = 0; i < providers.length; i++) {
log.info(i + 1 + "." + providers[i].getName());
}
}
/**
* 证书文件过滤器
*
*/
static class CerFilter implements FilenameFilter {
public boolean isCer(String name) {
if (name.toLowerCase().endsWith(".cer")) {
return true;
} else {
return false;
}
}
@Override
public boolean accept(File dir, String name) {
return isCer(name);
}
}
}

View File

@@ -0,0 +1,690 @@
package com.egzosn.pay.union.SDK;
import com.egzosn.pay.common.util.str.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.util.Properties;
/**
*
* @ClassName SDKConfig
* @Description acpsdk配置文件acp_sdk.properties配置信息类
* @date 2016-7-22 下午4:04:55
* @lastUpdate Actinia Date:2017/11/7 0007 21:55
*
*/
public class SDKConfig {
protected final Log log = LogFactory.getLog(SDKConfig.class);
public static final String FILE_NAME = "acp_sdk.properties";
/** 前台请求URL. */
private String frontRequestUrl;
/** 后台请求URL. */
private String backRequestUrl;
/** 单笔查询 */
private String singleQueryUrl;
/** 批量查询 */
private String batchQueryUrl;
/** 批量交易 */
private String batchTransUrl;
/** 文件传输 */
private String fileTransUrl;
/** 签名证书路径. */
private String signCertPath;
/** 签名证书密码. */
private String signCertPwd;
/** 签名证书类型. */
private String signCertType;
/** 加密公钥证书路径. */
private String encryptCertPath;
/** 验证签名公钥证书目录. */
private String validateCertDir;
/** 按照商户代码读取指定签名证书目录. */
private String signCertDir;
/** 磁道加密证书路径. */
private String encryptTrackCertPath;
/** 磁道加密公钥模数. */
private String encryptTrackKeyModulus;
/** 磁道加密公钥指数. */
private String encryptTrackKeyExponent;
/** 有卡交易. */
private String cardRequestUrl;
/** app交易 */
private String appRequestUrl;
/** 证书使用模式(单证书/多证书) */
private String singleMode;
/** 安全密钥(SHA256和SM3计算时使用) */
private String secureKey;
/** 中级证书路径 */
private String middleCertPath;
/** 根证书路径 */
private String rootCertPath;
/** 是否验证验签证书CN除了false都验 */
private boolean ifValidateCNName = true;
/** 是否验证https证书默认都不验 */
private boolean ifValidateRemoteCert = false;
/** signMethod没配按01吧 */
private String signMethod = "01";
/** version没配按5.0.0 */
private String version = "5.0.0";
/** frontUrl */
private String frontUrl;
/** backUrl */
private String backUrl;
/*缴费相关地址*/
private String jfFrontRequestUrl;
private String jfBackRequestUrl;
private String jfSingleQueryUrl;
private String jfCardRequestUrl;
private String jfAppRequestUrl;
private String qrcBackTransUrl;
private String qrcB2cIssBackTransUrl;
private String qrcB2cMerBackTransUrl;
/** 配置文件中的前台URL常量. */
public static final String SDK_FRONT_URL = "acpsdk.frontTransUrl";
/** 配置文件中的后台URL常量. */
public static final String SDK_BACK_URL = "acpsdk.backTransUrl";
/** 配置文件中的单笔交易查询URL常量. */
public static final String SDK_SIGNQ_URL = "acpsdk.singleQueryUrl";
/** 配置文件中的批量交易查询URL常量. */
public static final String SDK_BATQ_URL = "acpsdk.batchQueryUrl";
/** 配置文件中的批量交易URL常量. */
public static final String SDK_BATTRANS_URL = "acpsdk.batchTransUrl";
/** 配置文件中的文件类交易URL常量. */
public static final String SDK_FILETRANS_URL = "acpsdk.fileTransUrl";
/** 配置文件中的有卡交易URL常量. */
public static final String SDK_CARD_URL = "acpsdk.cardTransUrl";
/** 配置文件中的app交易URL常量. */
public static final String SDK_APP_URL = "acpsdk.appTransUrl";
/** 以下缴费产品使用,其余产品用不到,无视即可 */
// 前台请求地址
public static final String JF_SDK_FRONT_TRANS_URL= "acpsdk.jfFrontTransUrl";
// 后台请求地址
public static final String JF_SDK_BACK_TRANS_URL="acpsdk.jfBackTransUrl";
// 单笔查询请求地址
public static final String JF_SDK_SINGLE_QUERY_URL="acpsdk.jfSingleQueryUrl";
// 有卡交易地址
public static final String JF_SDK_CARD_TRANS_URL="acpsdk.jfCardTransUrl";
// App交易地址
public static final String JF_SDK_APP_TRANS_URL="acpsdk.jfAppTransUrl";
// 人到人
public static final String QRC_BACK_TRANS_URL="acpsdk.qrcBackTransUrl";
// 人到人
public static final String QRC_B2C_ISS_BACK_TRANS_URL="acpsdk.qrcB2cIssBackTransUrl";
// 人到人
public static final String QRC_B2C_MER_BACK_TRANS_URL="acpsdk.qrcB2cMerBackTransUrl";
/** 配置文件中签名证书路径常量. */
public static final String SDK_SIGNCERT_PATH = "acpsdk.signCert.path";
/** 配置文件中签名证书密码常量. */
public static final String SDK_SIGNCERT_PWD = "acpsdk.signCert.pwd";
/** 配置文件中签名证书类型常量. */
public static final String SDK_SIGNCERT_TYPE = "acpsdk.signCert.type";
/** 配置文件中密码加密证书路径常量. */
public static final String SDK_ENCRYPTCERT_PATH = "acpsdk.encryptCert.path";
/** 配置文件中磁道加密证书路径常量. */
public static final String SDK_ENCRYPTTRACKCERT_PATH = "acpsdk.encryptTrackCert.path";
/** 配置文件中磁道加密公钥模数常量. */
public static final String SDK_ENCRYPTTRACKKEY_MODULUS = "acpsdk.encryptTrackKey.modulus";
/** 配置文件中磁道加密公钥指数常量. */
public static final String SDK_ENCRYPTTRACKKEY_EXPONENT = "acpsdk.encryptTrackKey.exponent";
/** 配置文件中验证签名证书目录常量. */
public static final String SDK_VALIDATECERT_DIR = "acpsdk.validateCert.dir";
/** 配置文件中是否加密cvn2常量. */
public static final String SDK_CVN_ENC = "acpsdk.cvn2.enc";
/** 配置文件中是否加密cvn2有效期常量. */
public static final String SDK_DATE_ENC = "acpsdk.date.enc";
/** 配置文件中是否加密卡号常量. */
public static final String SDK_PAN_ENC = "acpsdk.pan.enc";
/** 配置文件中证书使用模式 */
public static final String SDK_SINGLEMODE = "acpsdk.singleMode";
/** 配置文件中安全密钥 */
public static final String SDK_SECURITYKEY = "acpsdk.secureKey";
/** 配置文件中根证书路径常量 */
public static final String SDK_ROOTCERT_PATH = "acpsdk.rootCert.path";
/** 配置文件中根证书路径常量 */
public static final String SDK_MIDDLECERT_PATH = "acpsdk.middleCert.path";
/** 配置是否需要验证验签证书CN除了false之外的值都当true处理 */
public static final String SDK_IF_VALIDATE_CN_NAME = "acpsdk.ifValidateCNName";
/** 配置是否需要验证https证书除了true之外的值都当false处理 */
public static final String SDK_IF_VALIDATE_REMOTE_CERT = "acpsdk.ifValidateRemoteCert";
/** signmethod */
public static final String SDK_SIGN_METHOD ="acpsdk.signMethod";
/** version */
public static final String SDK_VERSION = "acpsdk.version";
/** 后台通知地址 */
public static final String SDK_BACKURL = "acpsdk.backUrl";
/** 前台通知地址 */
public static final String SDK_FRONTURL = "acpsdk.frontUrl";
/** 操作对象. */
private static SDKConfig config = new SDKConfig();
/** 属性文件对象. */
private Properties properties;
private SDKConfig () {
super();
}
/**
* 获取config对象.
* @return
*/
public static SDKConfig getConfig() {
return config;
}
/**
* 从classpath路径下加载配置参数
*/
public void loadPropertiesFromSrc() {
InputStream in = null;
try {
log.info("从classpath: " +SDKConfig.class.getClassLoader().getResource("").getPath()+" 获取属性文件"+FILE_NAME);
in = SDKConfig.class.getClassLoader().getResourceAsStream(FILE_NAME);
if (null != in) {
properties = new Properties();
try {
properties.load(in);
} catch (IOException e) {
throw e;
}
} else {
log.info(FILE_NAME + "属性文件未能在classpath指定的目录下 "+SDKConfig.class.getClassLoader().getResource("").getPath()+" 找到!");
return;
}
loadProperties(properties);
} catch (IOException e) {
log.info(e.getMessage(), e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.info(e.getMessage(), e);
}
}
}
}
/**
* 根据传入的 {@link #load(java.util.Properties)}对象设置配置参数
*
* @param pro
*/
public void loadProperties(Properties pro) {
log.info("开始从属性文件中加载配置项");
String value = null;
value = pro.getProperty(SDK_SIGNCERT_PATH);
if (!StringUtils.isEmpty(value)) {
this.signCertPath = value.trim();
}
value = pro.getProperty(SDK_SIGNCERT_PWD);
if (!StringUtils.isEmpty(value)) {
this.signCertPwd = value.trim();
}
value = pro.getProperty(SDK_SIGNCERT_TYPE);
if (!StringUtils.isEmpty(value)) {
this.signCertType = value.trim();
}
value = pro.getProperty(SDK_ENCRYPTCERT_PATH);
if (!StringUtils.isEmpty(value)) {
this.encryptCertPath = value.trim();
}
value = pro.getProperty(SDK_VALIDATECERT_DIR);
if (!StringUtils.isEmpty(value)) {
this.validateCertDir = value.trim();
}
value = pro.getProperty(SDK_FRONT_URL);
if (!StringUtils.isEmpty(value)) {
this.frontRequestUrl = value.trim();
}
value = pro.getProperty(SDK_BACK_URL);
if (!StringUtils.isEmpty(value)) {
this.backRequestUrl = value.trim();
}
value = pro.getProperty(SDK_BATQ_URL);
if (!StringUtils.isEmpty(value)) {
this.batchQueryUrl = value.trim();
}
value = pro.getProperty(SDK_BATTRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.batchTransUrl = value.trim();
}
value = pro.getProperty(SDK_FILETRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.fileTransUrl = value.trim();
}
value = pro.getProperty(SDK_SIGNQ_URL);
if (!StringUtils.isEmpty(value)) {
this.singleQueryUrl = value.trim();
}
value = pro.getProperty(SDK_CARD_URL);
if (!StringUtils.isEmpty(value)) {
this.cardRequestUrl = value.trim();
}
value = pro.getProperty(SDK_APP_URL);
if (!StringUtils.isEmpty(value)) {
this.appRequestUrl = value.trim();
}
value = pro.getProperty(SDK_ENCRYPTTRACKCERT_PATH);
if (!StringUtils.isEmpty(value)) {
this.encryptTrackCertPath = value.trim();
}
value = pro.getProperty(SDK_SECURITYKEY);
if (!StringUtils.isEmpty(value)) {
this.secureKey = value.trim();
}
value = pro.getProperty(SDK_ROOTCERT_PATH);
if (!StringUtils.isEmpty(value)) {
this.rootCertPath = value.trim();
}
value = pro.getProperty(SDK_MIDDLECERT_PATH);
if (!StringUtils.isEmpty(value)) {
this.middleCertPath = value.trim();
}
/**缴费部分**/
value = pro.getProperty(JF_SDK_FRONT_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.jfFrontRequestUrl = value.trim();
}
value = pro.getProperty(JF_SDK_BACK_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.jfBackRequestUrl = value.trim();
}
value = pro.getProperty(JF_SDK_SINGLE_QUERY_URL);
if (!StringUtils.isEmpty(value)) {
this.jfSingleQueryUrl = value.trim();
}
value = pro.getProperty(JF_SDK_CARD_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.jfCardRequestUrl = value.trim();
}
value = pro.getProperty(JF_SDK_APP_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.jfAppRequestUrl = value.trim();
}
value = pro.getProperty(QRC_BACK_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.qrcBackTransUrl = value.trim();
}
value = pro.getProperty(QRC_B2C_ISS_BACK_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.qrcB2cIssBackTransUrl = value.trim();
}
value = pro.getProperty(QRC_B2C_MER_BACK_TRANS_URL);
if (!StringUtils.isEmpty(value)) {
this.qrcB2cMerBackTransUrl = value.trim();
}
value = pro.getProperty(SDK_ENCRYPTTRACKKEY_EXPONENT);
if (!StringUtils.isEmpty(value)) {
this.encryptTrackKeyExponent = value.trim();
}
value = pro.getProperty(SDK_ENCRYPTTRACKKEY_MODULUS);
if (!StringUtils.isEmpty(value)) {
this.encryptTrackKeyModulus = value.trim();
}
value = pro.getProperty(SDK_IF_VALIDATE_CN_NAME);
if (!StringUtils.isEmpty(value)) {
if( "false".equals(value.trim())) {
this.ifValidateCNName = false;
}
}
value = pro.getProperty(SDK_IF_VALIDATE_REMOTE_CERT);
if (!StringUtils.isEmpty(value)) {
if( "true".equals(value.trim())) {
this.ifValidateRemoteCert = true;
}
}
value = pro.getProperty(SDK_SIGN_METHOD);
if (!StringUtils.isEmpty(value)) {
this.signMethod = value.trim();
}
value = pro.getProperty(SDK_SIGN_METHOD);
if (!StringUtils.isEmpty(value)) {
this.signMethod = value.trim();
}
value = pro.getProperty(SDK_VERSION);
if (!StringUtils.isEmpty(value)) {
this.version = value.trim();
}
value = pro.getProperty(SDK_FRONTURL);
if (!StringUtils.isEmpty(value)) {
this.frontUrl = value.trim();
}
value = pro.getProperty(SDK_BACKURL);
if (!StringUtils.isEmpty(value)) {
this.backUrl = value.trim();
}
}
public String getSignMethod () {
return signMethod;
}
public void setSignMethod (String signMethod) {
this.signMethod = signMethod;
}
public String getSignMethodByStr(String signStr) {
if(StringUtils.isBlank(signStr)){
return SDKConstants.SIGNMETHOD_RSA;
}
signStr = signStr.toUpperCase();
switch (signStr) {
case "RSA":
return SDKConstants.SIGNMETHOD_RSA;
case "SHA256":
return SDKConstants.SIGNMETHOD_SHA256;
case "SM3":
return SDKConstants.SIGNMETHOD_SM3;
default:
return SDKConstants.SIGNMETHOD_RSA;
}
}
public String getFrontRequestUrl() {
return frontRequestUrl;
}
public void setFrontRequestUrl(String frontRequestUrl) {
this.frontRequestUrl = frontRequestUrl;
}
public String getBackRequestUrl() {
return backRequestUrl;
}
public void setBackRequestUrl(String backRequestUrl) {
this.backRequestUrl = backRequestUrl;
}
public String getSignCertPath() {
return signCertPath;
}
public void setSignCertPath(String signCertPath) {
this.signCertPath = signCertPath;
}
public String getSignCertPwd() {
return signCertPwd;
}
public void setSignCertPwd(String signCertPwd) {
this.signCertPwd = signCertPwd;
}
public String getSignCertType() {
return signCertType;
}
public void setSignCertType(String signCertType) {
this.signCertType = signCertType;
}
public String getEncryptCertPath() {
return encryptCertPath;
}
public void setEncryptCertPath(String encryptCertPath) {
this.encryptCertPath = encryptCertPath;
}
public String getValidateCertDir() {
return validateCertDir;
}
public void setValidateCertDir(String validateCertDir) {
this.validateCertDir = validateCertDir;
}
public String getSingleQueryUrl() {
return singleQueryUrl;
}
public void setSingleQueryUrl(String singleQueryUrl) {
this.singleQueryUrl = singleQueryUrl;
}
public String getBatchQueryUrl() {
return batchQueryUrl;
}
public void setBatchQueryUrl(String batchQueryUrl) {
this.batchQueryUrl = batchQueryUrl;
}
public String getBatchTransUrl() {
return batchTransUrl;
}
public void setBatchTransUrl(String batchTransUrl) {
this.batchTransUrl = batchTransUrl;
}
public String getFileTransUrl() {
return fileTransUrl;
}
public void setFileTransUrl(String fileTransUrl) {
this.fileTransUrl = fileTransUrl;
}
public String getSignCertDir() {
return signCertDir;
}
public void setSignCertDir(String signCertDir) {
this.signCertDir = signCertDir;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public String getCardRequestUrl() {
return cardRequestUrl;
}
public void setCardRequestUrl(String cardRequestUrl) {
this.cardRequestUrl = cardRequestUrl;
}
public String getAppRequestUrl() {
return appRequestUrl;
}
public void setAppRequestUrl(String appRequestUrl) {
this.appRequestUrl = appRequestUrl;
}
public String getEncryptTrackCertPath() {
return encryptTrackCertPath;
}
public void setEncryptTrackCertPath(String encryptTrackCertPath) {
this.encryptTrackCertPath = encryptTrackCertPath;
}
public String getJfFrontRequestUrl() {
return jfFrontRequestUrl;
}
public void setJfFrontRequestUrl(String jfFrontRequestUrl) {
this.jfFrontRequestUrl = jfFrontRequestUrl;
}
public String getJfBackRequestUrl() {
return jfBackRequestUrl;
}
public void setJfBackRequestUrl(String jfBackRequestUrl) {
this.jfBackRequestUrl = jfBackRequestUrl;
}
public String getJfSingleQueryUrl() {
return jfSingleQueryUrl;
}
public void setJfSingleQueryUrl(String jfSingleQueryUrl) {
this.jfSingleQueryUrl = jfSingleQueryUrl;
}
public String getJfCardRequestUrl() {
return jfCardRequestUrl;
}
public void setJfCardRequestUrl(String jfCardRequestUrl) {
this.jfCardRequestUrl = jfCardRequestUrl;
}
public String getJfAppRequestUrl() {
return jfAppRequestUrl;
}
public void setJfAppRequestUrl(String jfAppRequestUrl) {
this.jfAppRequestUrl = jfAppRequestUrl;
}
public String getSingleMode() {
return singleMode;
}
public void setSingleMode(String singleMode) {
this.singleMode = singleMode;
}
public String getEncryptTrackKeyExponent() {
return encryptTrackKeyExponent;
}
public void setEncryptTrackKeyExponent(String encryptTrackKeyExponent) {
this.encryptTrackKeyExponent = encryptTrackKeyExponent;
}
public String getEncryptTrackKeyModulus() {
return encryptTrackKeyModulus;
}
public void setEncryptTrackKeyModulus(String encryptTrackKeyModulus) {
this.encryptTrackKeyModulus = encryptTrackKeyModulus;
}
public String getSecureKey() {
return secureKey;
}
public void setSecureKey(String securityKey) {
this.secureKey = securityKey;
}
public String getMiddleCertPath() {
return middleCertPath;
}
public void setMiddleCertPath(String middleCertPath) {
this.middleCertPath = middleCertPath;
}
public boolean isIfValidateCNName() {
return ifValidateCNName;
}
public void setIfValidateCNName(boolean ifValidateCNName) {
this.ifValidateCNName = ifValidateCNName;
}
public boolean isIfValidateRemoteCert() {
return ifValidateRemoteCert;
}
public void setIfValidateRemoteCert(boolean ifValidateRemoteCert) {
this.ifValidateRemoteCert = ifValidateRemoteCert;
}
public String getQrcBackTransUrl() {
return qrcBackTransUrl;
}
public void setQrcBackTransUrl(String qrcBackTransUrl) {
this.qrcBackTransUrl = qrcBackTransUrl;
}
public String getQrcB2cIssBackTransUrl() {
return qrcB2cIssBackTransUrl;
}
public void setQrcB2cIssBackTransUrl(String qrcB2cIssBackTransUrl) {
this.qrcB2cIssBackTransUrl = qrcB2cIssBackTransUrl;
}
public String getQrcB2cMerBackTransUrl() {
return qrcB2cMerBackTransUrl;
}
public void setQrcB2cMerBackTransUrl(String qrcB2cMerBackTransUrl) {
this.qrcB2cMerBackTransUrl = qrcB2cMerBackTransUrl;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getFrontUrl() {
return frontUrl;
}
public void setFrontUrl(String frontUrl) {
this.frontUrl = frontUrl;
}
public String getBackUrl() {
return backUrl;
}
public void setBackUrl(String backUrl) {
this.backUrl = backUrl;
}
public String getRootCertPath() {
return rootCertPath;
}
public void setRootCertPath(String rootCertPath) {
this.rootCertPath = rootCertPath;
}
}

View File

@@ -0,0 +1,402 @@
/**
* Licensed Property to China UnionPay Co., Ltd.
* <p>
* (C) Copyright of China UnionPay Co., Ltd. 2010
* All Rights Reserved.
* <p>
* <p>
* Modification History:
* =============================================================================
* Author Date Description
* ------------ ---------- ---------------------------------------------------
* xshu 2014-05-28 MPI插件包常量定义
* =============================================================================
*/
package com.egzosn.pay.union.SDK;
/**
*
* @ClassName SDKConstants
* @Description acpsdk常量类
* @date 2016-7-22 下午4:05:54
*
*/
public class SDKConstants {
public final static String COLUMN_DEFAULT = "-";
public final static String KEY_DELIMITER = "#";
/** memeber variable: blank. */
public static final String BLANK = "";
/** member variabel: space. */
public static final String SPACE = " ";
/** memeber variable: unline. */
public static final String UNLINE = "_";
/** memeber varibale: star. */
public static final String STAR = "*";
/** memeber variable: line. */
public static final String LINE = "-";
/** memeber variable: add. */
public static final String ADD = "+";
/** memeber variable: colon. */
public final static String COLON = "|";
/** memeber variable: point. */
public final static String POINT = ".";
/** memeber variable: comma. */
public final static String COMMA = ",";
/** memeber variable: slash. */
public final static String SLASH = "/";
/** memeber variable: div. */
public final static String DIV = "/";
/** memeber variable: left . */
public final static String LB = "(";
/** memeber variable: right. */
public final static String RB = ")";
/** memeber variable: rmb. */
public final static String CUR_RMB = "RMB";
/** memeber variable: .page size */
public static final int PAGE_SIZE = 10;
/** memeber variable: String ONE. */
public static final String ONE = "1";
/** memeber variable: String ZERO. */
public static final String ZERO = "0";
/** memeber variable: number six. */
public static final int NUM_SIX = 6;
/** memeber variable: equal mark. */
public static final String EQUAL = "=";
/** memeber variable: operation ne. */
public static final String NE = "!=";
/** memeber variable: operation le. */
public static final String LE = "<=";
/** memeber variable: operation ge. */
public static final String GE = ">=";
/** memeber variable: operation lt. */
public static final String LT = "<";
/** memeber variable: operation gt. */
public static final String GT = ">";
/** memeber variable: list separator. */
public static final String SEP = "./";
/** memeber variable: Y. */
public static final String Y = "Y";
/** memeber variable: AMPERSAND. */
public static final String AMPERSAND = "&";
/** memeber variable: SQL_LIKE_TAG. */
public static final String SQL_LIKE_TAG = "%";
/** memeber variable: @. */
public static final String MAIL = "@";
/** memeber variable: number zero. */
public static final int NZERO = 0;
public static final String LEFT_BRACE = "{";
public static final String RIGHT_BRACE = "}";
/** memeber variable: string true. */
public static final String TRUE_STRING = "true";
/** memeber variable: string false. */
public static final String FALSE_STRING = "false";
/** memeber variable: forward success. */
public static final String SUCCESS = "success";
/** memeber variable: forward fail. */
public static final String FAIL = "fail";
/** memeber variable: global forward success. */
public static final String GLOBAL_SUCCESS = "$success";
/** memeber variable: global forward fail. */
public static final String GLOBAL_FAIL = "$fail";
public static final String UTF_8_ENCODING = "UTF-8";
public static final String GBK_ENCODING = "GBK";
public static final String CONTENT_TYPE = "Content-type";
public static final String APP_XML_TYPE = "application/xml;charset=utf-8";
public static final String APP_FORM_TYPE = "application/x-www-form-urlencoded;charset=";
public static final String VERSION_1_0_0 = "1.0.0";
public static final String VERSION_5_0_0 = "5.0.0";
public static final String VERSION_5_0_1 = "5.0.1";
public static final String VERSION_5_1_0 = "5.1.0";
public static final String SIGNMETHOD_RSA = "01";
public static final String SIGNMETHOD_SHA256 = "11";
public static final String SIGNMETHOD_SM3 = "12";
public static final String UNIONPAY_CNNAME = "中国银联股份有限公司";
public static final String CERTTYPE_01 = "01";// 敏感信息加密公钥
public static final String CERTTYPE_02 = "02";// 磁道加密公钥
/******************************************** 5.0报文接口定义 ********************************************/
/** 版本号. */
public static final String param_version = "version";
/** 证书ID. */
public static final String param_certId = "certId";
/** 签名. */
public static final String param_signature = "signature";
/** 签名方法. */
public static final String param_signMethod = "signMethod";
/** 编码方式. */
public static final String param_encoding = "encoding";
/** 交易类型. */
public static final String param_txnType = "txnType";
/** 交易子类. */
public static final String param_txnSubType = "txnSubType";
/** 业务类型. */
public static final String param_bizType = "bizType";
/** 前台通知地址 . */
public static final String param_frontUrl = "frontUrl";
/** 后台通知地址. */
public static final String param_backUrl = "backUrl";
/** 接入类型. */
public static final String param_accessType = "accessType";
/** 收单机构代码. */
public static final String param_acqInsCode = "acqInsCode";
/** 商户类别. */
public static final String param_merCatCode = "merCatCode";
/** 商户类型. */
public static final String param_merType = "merType";
/** 商户代码. */
public static final String param_merId = "merId";
/** 商户名称. */
public static final String param_merName = "merName";
/** 商户简称. */
public static final String param_merAbbr = "merAbbr";
/** 二级商户代码. */
public static final String param_subMerId = "subMerId";
/** 二级商户名称. */
public static final String param_subMerName = "subMerName";
/** 二级商户简称. */
public static final String param_subMerAbbr = "subMerAbbr";
/** Cupsecure 商户代码. */
public static final String param_csMerId = "csMerId";
/** 商户订单号. */
public static final String param_orderId = "orderId";
/** 交易时间. */
public static final String param_txnTime = "txnTime";
/** 发送时间. */
public static final String param_txnSendTime = "txnSendTime";
/** 订单超时时间间隔. */
public static final String param_orderTimeoutInterval = "orderTimeoutInterval";
/** 支付超时时间. */
public static final String param_payTimeoutTime = "payTimeoutTime";
/** 默认支付方式. */
public static final String param_defaultPayType = "defaultPayType";
/** 支持支付方式. */
public static final String param_supPayType = "supPayType";
/** 支付方式. */
public static final String param_payType = "payType";
/** 自定义支付方式. */
public static final String param_customPayType = "customPayType";
/** 物流标识. */
public static final String param_shippingFlag = "shippingFlag";
/** 收货地址-国家. */
public static final String param_shippingCountryCode = "shippingCountryCode";
/** 收货地址-省. */
public static final String param_shippingProvinceCode = "shippingProvinceCode";
/** 收货地址-市. */
public static final String param_shippingCityCode = "shippingCityCode";
/** 收货地址-地区. */
public static final String param_shippingDistrictCode = "shippingDistrictCode";
/** 收货地址-详细. */
public static final String param_shippingStreet = "shippingStreet";
/** 商品总类. */
public static final String param_commodityCategory = "commodityCategory";
/** 商品名称. */
public static final String param_commodityName = "commodityName";
/** 商品URL. */
public static final String param_commodityUrl = "commodityUrl";
/** 商品单价. */
public static final String param_commodityUnitPrice = "commodityUnitPrice";
/** 商品数量. */
public static final String param_commodityQty = "commodityQty";
/** 是否预授权. */
public static final String param_isPreAuth = "isPreAuth";
/** 币种. */
public static final String param_currencyCode = "currencyCode";
/** 账户类型. */
public static final String param_accType = "accType";
/** 账号. */
public static final String param_accNo = "accNo";
/** 支付卡类型. */
public static final String param_payCardType = "payCardType";
/** 发卡机构代码. */
public static final String param_issInsCode = "issInsCode";
/** 持卡人信息. */
public static final String param_customerInfo = "customerInfo";
/** 交易金额. */
public static final String param_txnAmt = "txnAmt";
/** 余额. */
public static final String param_balance = "balance";
/** 地区代码. */
public static final String param_districtCode = "districtCode";
/** 附加地区代码. */
public static final String param_additionalDistrictCode = "additionalDistrictCode";
/** 账单类型. */
public static final String param_billType = "billType";
/** 账单号码. */
public static final String param_billNo = "billNo";
/** 账单月份. */
public static final String param_billMonth = "billMonth";
/** 账单查询要素. */
public static final String param_billQueryInfo = "billQueryInfo";
/** 账单详情. */
public static final String param_billDetailInfo = "billDetailInfo";
/** 账单金额. */
public static final String param_billAmt = "billAmt";
/** 账单金额符号. */
public static final String param_billAmtSign = "billAmtSign";
/** 绑定标识号. */
public static final String param_bindId = "bindId";
/** 风险级别. */
public static final String param_riskLevel = "riskLevel";
/** 绑定信息条数. */
public static final String param_bindInfoQty = "bindInfoQty";
/** 绑定信息集. */
public static final String param_bindInfoList = "bindInfoList";
/** 批次号. */
public static final String param_batchNo = "batchNo";
/** 总笔数. */
public static final String param_totalQty = "totalQty";
/** 总金额. */
public static final String param_totalAmt = "totalAmt";
/** 文件类型. */
public static final String param_fileType = "fileType";
/** 文件名称. */
public static final String param_fileName = "fileName";
/** 批量文件内容. */
public static final String param_fileContent = "fileContent";
/** 商户摘要. */
public static final String param_merNote = "merNote";
/** 商户自定义域. */
// public static final String param_merReserved = "merReserved";//接口变更删除
/** 请求方保留域. */
public static final String param_reqReserved = "reqReserved";// 新增接口
/** 保留域. */
public static final String param_reserved = "reserved";
/** 终端号. */
public static final String param_termId = "termId";
/** 终端类型. */
public static final String param_termType = "termType";
/** 交互模式. */
public static final String param_interactMode = "interactMode";
/** 发卡机构识别模式. */
// public static final String param_recognitionMode = "recognitionMode";
public static final String param_issuerIdentifyMode = "issuerIdentifyMode";// 接口名称变更
/** 商户端用户号. */
public static final String param_merUserId = "merUserId";
/** 持卡人IP. */
public static final String param_customerIp = "customerIp";
/** 查询流水号. */
public static final String param_queryId = "queryId";
/** 原交易查询流水号. */
public static final String param_origQryId = "origQryId";
/** 系统跟踪号. */
public static final String param_traceNo = "traceNo";
/** 交易传输时间. */
public static final String param_traceTime = "traceTime";
/** 清算日期. */
public static final String param_settleDate = "settleDate";
/** 清算币种. */
public static final String param_settleCurrencyCode = "settleCurrencyCode";
/** 清算金额. */
public static final String param_settleAmt = "settleAmt";
/** 清算汇率. */
public static final String param_exchangeRate = "exchangeRate";
/** 兑换日期. */
public static final String param_exchangeDate = "exchangeDate";
/** 响应时间. */
public static final String param_respTime = "respTime";
/** 原交易应答码. */
public static final String param_origRespCode = "origRespCode";
/** 原交易应答信息. */
public static final String param_origRespMsg = "origRespMsg";
/** 应答码. */
public static final String param_respCode = "respCode";
/** 应答码信息. */
public static final String param_respMsg = "respMsg";
// 新增四个报文字段merUserRegDt merUserEmail checkFlag activateStatus
/** 商户端用户注册时间. */
public static final String param_merUserRegDt = "merUserRegDt";
/** 商户端用户注册邮箱. */
public static final String param_merUserEmail = "merUserEmail";
/** 验证标识. */
public static final String param_checkFlag = "checkFlag";
/** 开通状态. */
public static final String param_activateStatus = "activateStatus";
/** 加密证书ID. */
public static final String param_encryptCertId = "encryptCertId";
/** 用户MAC、IMEI串号、SSID. */
public static final String param_userMac = "userMac";
/** 关联交易. */
// public static final String param_relationTxnType = "relationTxnType";
/** 短信类型 */
public static final String param_smsType = "smsType";
/** 风控信息域 */
public static final String param_riskCtrlInfo = "riskCtrlInfo";
/** IC卡交易信息域 */
public static final String param_ICTransData = "ICTransData";
/** VPC交易信息域 */
public static final String param_VPCTransData = "VPCTransData";
/** 安全类型 */
public static final String param_securityType = "securityType";
/** 银联订单号 */
public static final String param_tn = "tn";
/** 分期付款手续费率 */
public static final String param_instalRate = "instalRate";
/** 分期付款手续费率 */
public static final String param_mchntFeeSubsidy = "mchntFeeSubsidy";
/** 签名公钥证书 */
public static final String param_signPubKeyCert = "signPubKeyCert";
/** 加密公钥证书 */
public static final String param_encryptPubKeyCert = "encryptPubKeyCert";
/** 证书类型 */
public static final String param_certType = "certType";
/** 渠道类型*/
public static final String param_channelType = "channelType";
/** C2B码,1-20位数字*/
public static final String param_qrNo = "qrNo";
/*原交易商户订单号*/
public static final String param_origOrderId = "origOrderId";
/*原交易商户发送交易时间*/
public static final String param_origTxnTime = "origTxnTime";
}

View File

@@ -0,0 +1,204 @@
package com.egzosn.pay.union.SDK;/**
* Description
* author: Fuzx
* date: 2017/11/27 0027
*/
import com.egzosn.pay.common.util.sign.SecureUtil;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.sign.encrypt.Base64;
import com.egzosn.pay.common.util.sign.encrypt.RSA;
import com.egzosn.pay.common.util.sign.encrypt.SHA256;
import com.egzosn.pay.common.util.str.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static com.egzosn.pay.union.SDK.SDKConstants.*;
/**
* @author Actinia
* @email hayesfu@qq.com
* @create 2017 2017/11/27 0027
*/
public class SDKUtils {
//日志
protected static final Log log = LogFactory.getLog(SDKUtils.class);
/**
* 验证签名
*
* @param resData
* 返回报文数据
* @param encoding
* 编码格式
* @return
*/
public static boolean validate(Map<String, Object> resData, String encoding) {
log.info("验签处理开始");
if (StringUtils.isEmpty(encoding)) {
encoding = "UTF-8";
}
String signMethod = resData.get(SDKConstants.param_signMethod).toString();
String version = resData.get(SDKConstants.param_version).toString();
if (SIGNMETHOD_RSA.equals(signMethod) || VERSION_1_0_0.equals(version) || VERSION_5_0_1.equals(version)) {
// 获取返回报文的版本号
if (VERSION_5_0_0.equals(version) || VERSION_1_0_0.equals(version) || VERSION_5_0_1.equals(version)) {
String stringSign = resData.get(SDKConstants.param_signature).toString();
log.info("签名原文:["+stringSign+"]");
// 从返回报文中获取certId 然后去证书静态Map中查询对应验签证书对象
String certId = resData.get(SDKConstants.param_certId).toString();
log.info("对返回报文串验签使用的验签公钥序列号:["+certId+"]");
// 将Map信息转换成key1=value1&key2=value2的形式
String stringData = SignUtils.parameterText(resData);
log.info("待验签返回报文串:["+stringData+"]");
try {
// 验证签名需要用银联发给商户的公钥证书.
return SecureUtil.validateSignBySoft(CertUtil.getValidatePublicKey(certId), Base64.decode(stringSign),
SecureUtil.sha1X16(stringData, encoding));
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
} else if (VERSION_5_1_0.equals(version)) {
// 1.从返回报文中获取公钥信息转换成公钥对象
String strCert = resData.get(SDKConstants.param_signPubKeyCert).toString();
log.info("验签公钥证书:["+strCert+"]");
X509Certificate x509Cert = CertUtil.genCertificateByStr(strCert);
if(x509Cert == null) {
log.error("convert signPubKeyCert failed");
return false;
}
// 2.验证证书链
if (!CertUtil.verifyCertificate(x509Cert)) {
log.error("验证公钥证书失败,证书信息:["+strCert+"]");
return false;
}
// 3.验签
String stringSign = resData.get(SDKConstants.param_signature).toString();
log.info("签名原文:["+stringSign+"]");
// 将Map信息转换成key1=value1&key2=value2的形式
String stringData = SignUtils.parameterText(resData);
log.info("待验签返回报文串:["+stringData+"]");
try {
// 验证签名需要用银联发给商户的公钥证书.
boolean result = SecureUtil.validateSignBySoft256(x509Cert
.getPublicKey(), Base64.decode(stringSign
), SHA256.sha256X16(
stringData, encoding));
log.info("验证签名" + (result? "成功":"失败"));
return result;
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
} else if (SIGNMETHOD_SHA256.equals(signMethod)) {
// 1.进行SHA256验证
String stringSign = resData.get(SDKConstants.param_signature).toString();
log.info("签名原文:["+stringSign+"]");
// 将Map信息转换成key1=value1&key2=value2的形式
String stringData = SignUtils.parameterText(resData);
log.info("待验签返回报文串:["+stringData+"]");
String strBeforeSha256 = stringData
+ SDKConstants.AMPERSAND
+ SecureUtil.sha256X16Str(SDKConfig.getConfig()
.getSecureKey(), encoding);
String strAfterSha256 = SecureUtil.sha256X16Str(strBeforeSha256,
encoding);
boolean result = stringSign.equals(strAfterSha256);
log.info("验证签名" + (result? "成功":"失败"));
return result;
} else if (SIGNMETHOD_SM3.equals(signMethod)) {
// 1.进行SM3验证
String stringSign = resData.get(SDKConstants.param_signature).toString();
log.info("签名原文:["+stringSign+"]");
// 将Map信息转换成key1=value1&key2=value2的形式
String stringData = SignUtils.parameterText(resData);
log.info("待验签返回报文串:["+stringData+"]");
String strBeforeSM3 = stringData
+ SDKConstants.AMPERSAND
+ SecureUtil.sm3X16Str(SDKConfig.getConfig()
.getSecureKey(), encoding);
String strAfterSM3 = SecureUtil
.sm3X16Str(strBeforeSM3, encoding);
boolean result = stringSign.equals(strAfterSM3);
log.info("验证签名" + (result? "成功":"失败"));
return result;
}
return false;
}
/**
* 对参数加密
* @param data
* @param encoding
* @return
*/
public static boolean signParams(Map<String, String> data,String encoding){
if (StringUtils.isBlank(encoding)) {
encoding = "UTF-8";
}
String signMethod = data.get(SDKConstants.param_signMethod);
String version = data.get(SDKConstants.param_version);
if(StringUtils.isBlank(signMethod)){
log.info("银联签名方式不能为空");
return false;
}
if(StringUtils.isBlank(version)){
log.info("版本号不能为空");
return false;
}
if (SIGNMETHOD_RSA.equals(signMethod)|| VERSION_1_0_0.equals(version) || SDKConstants.VERSION_5_0_1.equals(version)) {
if (SDKConstants.VERSION_5_0_0.equals(version) || VERSION_1_0_0.equals(version) || SDKConstants.VERSION_5_0_1.equals(version)) {
data.put(SDKConstants.param_certId, CertUtil.getSignCertId());
String stringData = SignUtils.parameterText(data);
String stringSign = null;
try {
// 通过SHA1进行摘要并转16进制
byte[] signDigest = SecureUtil
.sha1X16(stringData, encoding);
stringSign = RSA.sign(signDigest, CertUtil.getSignCertPrivateKey());
// 设置签名域值
data.put(SDKConstants.param_signature, stringSign);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}else if (SDKConstants.SIGNMETHOD_SHA256.equals(signMethod)) {
String stringData = SignUtils.parameterText(data);
String strBeforeSha256 = stringData
+ SDKConstants.AMPERSAND
+ SecureUtil.sha256X16Str(SDKConfig.getConfig().getSecureKey(), encoding);
String strAfterSha256 = SecureUtil.sha256X16Str(strBeforeSha256,
encoding);
data.put(SDKConstants.param_signature, strAfterSha256);
} else if (SDKConstants.SIGNMETHOD_SM3.equals(signMethod)) {
String stringData = SignUtils.parameterText(data);
String strBeforeSM3 = stringData
+ SDKConstants.AMPERSAND
+ SecureUtil.sm3X16Str(SDKConfig.getConfig().getSecureKey(), encoding);
String strAfterSM3 = SecureUtil.sm3X16Str(strBeforeSM3, encoding);
// 设置签名域值
data.put(SDKConstants.param_signature, strAfterSM3);
}
return false;
}
}

View File

@@ -3,83 +3,88 @@ package com.egzosn.pay.union.api;
import com.egzosn.pay.common.api.BasePayConfigStorage;
/**
* 支付客户端配置存储
* author egan
*
* email egzosn@gmail.com
* date 2016-5-18 14:09:01
* @author Actinia
* @email hayesfu@qq.com
* <pre>
create 2017 2017/11/4 0004
* </pre>
*/
public class UnionPayConfigStorage extends BasePayConfigStorage {
// 商户PID
public volatile String merId ;
// 商户签约拿到的pid,partner_id的简称合作伙伴身份等同于 partner
public volatile String pid ;
//partner_id的简称合作伙伴身份
// public volatile String partner ;
/**
* 商户号
*/
public volatile String merId;
// 商户收款账号
public volatile String seller;
/**
* 商户收款账号
*/
public volatile String seller;
//公钥
private volatile String aliPublicKey;
//全渠道固定值
public static String version = "5.0.0";
public String getAliPublicKey() {
public String getAliPublicKey () {
return aliPublicKey;
}
public void setAliPublicKey(String aliPublicKey) {
public void setAliPublicKey (String aliPublicKey) {
setKeyPublic(aliPublicKey);
this.aliPublicKey = aliPublicKey;
}
@Override
public String getAppid() {
public String getAppid () {
return null;
}
/**
* @see #getPid()
* @return 合作者id
* @see #getPid()
*/
@Deprecated
@Override
public String getPartner() {
return pid;
public String getPartner () {
return merId;
}
/**
* 设置合作者id
* @see #setPid(String)
*
* @param partner 合作者id
* @see #setPid(String)
*/
@Deprecated
public void setPartner(String partner) {
this.pid = partner;
public void setPartner (String partner) {
this.merId = partner;
}
@Override
public String getPid() {
return pid;
public String getPid () {
return merId;
}
public void setPid(String pid) {
this.pid = pid;
public void setPid (String pid) {
this.merId = pid;
}
public String getSeller() {
@Override
public String getSeller () {
return seller;
}
public void setSeller(String seller) {
public void setSeller (String seller) {
this.seller = seller;
}
public String getMerId () {
return merId;
}
public void setMerId (String merId) {
this.merId = merId;
}
}

View File

@@ -0,0 +1,464 @@
package com.egzosn.pay.union.api;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.api.BasePayService;
import com.egzosn.pay.common.api.Callback;
import com.egzosn.pay.common.api.PayConfigStorage;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.result.PayException;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.union.SDK.CertUtil;
import com.egzosn.pay.union.SDK.SDKConfig;
import com.egzosn.pay.union.SDK.SDKConstants;
import com.egzosn.pay.union.SDK.SDKUtils;
import com.egzosn.pay.union.enums.UnionTransactionType;
import com.egzosn.pay.union.request.UnionQueryOrder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author Actinia
* @email hayesfu@qq.com
* @create 2017 2017/11/5 0005
*/
public class UnionPayService extends BasePayService {
//日志
protected static final Log log = LogFactory.getLog(UnionPayService.class);
public UnionPayService (PayConfigStorage payConfigStorage) {
super(payConfigStorage);
}
public UnionPayService (PayConfigStorage payConfigStorage, HttpConfigStorage configStorage) {
super(payConfigStorage, configStorage);
SDKConfig.getConfig().loadPropertiesFromSrc();
}
/**
* 银联全渠道系统产品参数除了encoding自行选择外其他不需修改
* @return 返回参数集合
*/
private Map<String ,String> getCommonParam(){
Map<String ,String> params = new HashMap<>();
params.put(SDKConstants.param_version, SDKConfig.getConfig().getVersion());
params.put(SDKConstants.param_encoding, payConfigStorage.getInputCharset().toUpperCase());
params.put(SDKConstants.param_signMethod, SDKConfig.getConfig().getSignMethodByStr(payConfigStorage.getSignType()));
params.put(SDKConstants.param_merId, payConfigStorage.getPid());
//接入类型商户接入填0 不需修改0直连商户 1 收单机构 2平台商户
params.put(SDKConstants.param_accessType, "0");
DateFormat df = new SimpleDateFormat("YYYYMMDDhhmmss");
params.put(SDKConstants.param_txnTime, df.format(new Date()));
params.put(SDKConstants.param_backUrl, SDKConfig.getConfig().getBackUrl());
return params;
}
/**
* 回调校验
*
* @param result 回调回来的参数集
* @return 签名校验 true通过
*/
@Override
public boolean verify (Map<String, Object> result) {
if(result != null){
if(SDKUtils.validate(result, payConfigStorage.getInputCharset())){
String respCode = result.get("respCode").toString();
if(("00").equals(respCode)){
//成功,获取tn号
//String tn = resmap.get("tn");
//TODO
return true;
}else{
//其他应答码为失败请排查原因或做失败处理
//TODO
}
}else{
// 校验失败
}
}else{
}
return false;
}
/**
* 签名校验
*
* @param params 参数集
* @param sign 签名
* @return 签名校验 true通过
*/
@Override
public boolean signVerify (Map<String, Object> params, String sign) {
return false;
}
/**
* 支付宝需要,微信是否也需要再次校验来源,进行订单查询
* 校验数据来源
*
* @param id 业务id, 数据的真实性.
* @return true通过
*/
@Override
public boolean verifySource (String id) {
return false;
}
/**
* 返回创建的订单信息
*
* @param order 支付订单
* @return 订单信息
* @see PayOrder 支付订单信息
*/
@Override
public Map orderInfo (PayOrder order) {
Map<String, String> params = this.getCommonParam();
UnionTransactionType type = (UnionTransactionType)order.getTransactionType();
type.convertMap(params);
switch (type){
case APPLY_QR_CODE:
params.put(SDKConstants.param_orderId, order.getOutTradeNo());
params.put(SDKConstants.param_txnAmt, order.getPrice().toString());
params.put(SDKConstants.param_currencyCode, "156");
break;
case CONSUME:
params.put(SDKConstants.param_orderId, order.getOutTradeNo());
params.put(SDKConstants.param_txnAmt, order.getPrice().toString());
params.put(SDKConstants.param_currencyCode, "156");
params.put(SDKConstants.param_qrNo, order.getAuthCode());
params.put(SDKConstants.param_termId, order.getDeviceInfo());
break;
default:
}
return params;
}
/**
* 获取输出二维码,用户返回给支付端,
*
* @param order 发起支付的订单信息
* @return 返回图片信息,支付时需要的
*/
@Override
public BufferedImage genQrPay (PayOrder order) {
Map<String ,String > params = orderInfo(order);
CertUtil.sign(params,payConfigStorage.getInputCharset().toUpperCase());
JSONObject response = getHttpRequestTemplate().postForObject(SDKConfig.getConfig().getBackRequestUrl(),params,JSONObject.class);
if(SDKUtils.validate(response,payConfigStorage.getInputCharset().toUpperCase())){
if("00".equals(response.getString(SDKConstants.param_respCode))){
//成功,获取tn号
return MatrixToImageWriter.writeInfoToJpgBuff( response.getString(SDKConstants.param_respCode));
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException("1000", "验证签名失败", response.toJSONString()));
}
}
/**
* 刷卡付,pos主动扫码付款(条码付)
*
* @param order 发起支付的订单信息
* @return 返回支付结果
*/
@Override
public Map<String, Object> microPay (PayOrder order) {
Map<String ,String > params = orderInfo(order);
CertUtil.sign(params,payConfigStorage.getInputCharset().toUpperCase());
return getHttpRequestTemplate().postForObject(SDKConfig.getConfig().getBackRequestUrl(),params,JSONObject.class);
}
/**
* 交易查询接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回查询回来的结果集,支付方原值返回
*/
@Override
public Map<String, Object> query (String tradeNo, String outTradeNo) {
Map<String ,String > params = this.getCommonParam();
UnionTransactionType.QUERY.convertMap(params);
params.put(SDKConstants.param_orderId,outTradeNo);
CertUtil.sign(params,payConfigStorage.getInputCharset().toUpperCase());
JSONObject response = getHttpRequestTemplate().postForObject(SDKConfig.getConfig().getBackRequestUrl(),params,JSONObject.class);
if(SDKUtils.validate(response,payConfigStorage.getInputCharset().toUpperCase())){
if("00".equals(response.getString(SDKConstants.param_respCode))){
String origRespCode = response.getString(SDKConstants.param_origRespCode);
if(("00").equals(origRespCode)){
//交易成功,更新商户订单状态
//TODO
return response;
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException("1000", "验证签名失败", response.toJSONString()));
}
}
/**
* 消费撤销/退货接口
*
* @return 返回支付方申请退款后的结果
*/
public Map<String, Object> unionRefundOrConsumeUndo (UnionQueryOrder queryOrder,UnionTransactionType type) {
Map<String ,String> params = this.getCommonParam();
type.convertMap(params);
params.put(SDKConstants.param_orderId,queryOrder.getOrderId());
params.put(SDKConstants.param_txnAmt,queryOrder.getTxnAmt());
if(StringUtils.isNotBlank(queryOrder.getOrigQryId())) {
params.put(SDKConstants.param_origQryId, queryOrder.getOrigQryId());
}
if(StringUtils.isNotBlank(queryOrder.getOrigOrderId())){
params.put(SDKConstants.param_origOrderId,queryOrder.getOrigOrderId());
}
if(StringUtils.isNotBlank(queryOrder.getOrigTxnTime())) {
params.put(SDKConstants.param_origTxnTime, queryOrder.getOrigOrderId());
}
CertUtil.sign(params,payConfigStorage.getInputCharset().toUpperCase());
JSONObject response = getHttpRequestTemplate().postForObject(SDKConfig.getConfig().getBackRequestUrl(),params,JSONObject.class);
if(SDKUtils.validate(response,payConfigStorage.getInputCharset().toUpperCase())){
if("00".equals(response.getString(SDKConstants.param_respCode))){
String origRespCode = response.getString(SDKConstants.param_origRespCode);
//交易成功,更新商户订单状态
//TODO
return response;
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException("1000", "验证签名失败", response.toJSONString()));
}
}
/**
* 将请求参数或者请求流转化为 Map
*
* @param parameterMap 请求参数
* @param is 请求流
* @return 获得回调的请求参数
*/
@Override
public Map<String, Object> getParameter2Map (Map<String, String[]> parameterMap, InputStream is) {
return null;
}
/**
* 获取输出消息,用户返回给支付端
*
* @param code 状态
* @param message 消息
* @return 返回输出消息
*/
@Override
public PayOutMessage getPayOutMessage (String code, String message) {
return null;
}
/**
* 获取成功输出消息,用户返回给支付端
* 主要用于拦截器中返回
*
* @param payMessage 支付回调消息
* @return 返回输出消息
*/
@Override
public PayOutMessage successPayOutMessage (PayMessage payMessage) {
return null;
}
/**
* 获取输出消息,用户返回给支付端, 针对于web端
*
* @param orderInfo 发起支付的订单信息
* @param method 请求方式 "post" "get",
* @return 获取输出消息,用户返回给支付端, 针对于web端
* @see MethodType 请求类型
*/
@Override
public String buildRequest (Map<String, Object> orderInfo, MethodType method) {
return null;
}
/**
* 交易查询接口,带处理器
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @return 返回查询回来的结果集
*/
@Override
public <T> T query (String tradeNo, String outTradeNo, Callback<T> callback) {
return null;
}
/**
* 交易关闭接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方交易关闭后的结果
*/
@Override
public Map<String, Object> close (String tradeNo, String outTradeNo) {
return null;
}
/**
* 交易关闭接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @return 返回支付方交易关闭后的结果
*/
@Override
public <T> T close (String tradeNo, String outTradeNo, Callback<T> callback) {
return null;
}
/**
* 申请退款接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
*/
@Override
public Map<String, Object> refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return null;
}
/**
* 申请退款接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @param callback 处理器
* @return 返回支付方申请退款后的结果
*/
@Override
public <T> T refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback) {
return null;
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery (String tradeNo, String outTradeNo) {
return null;
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @return 返回支付方查询退款后的结果
*/
@Override
public <T> T refundquery (String tradeNo, String outTradeNo, Callback<T> callback) {
return null;
}
/**
* 下载对账单
*
* @param billDate 账单时间
* @param billType 账单类型
* @return 返回fileContent 请自行将数据落地
*/
@Override
public Object downloadbill (Date billDate, String billType) {
Map<String ,String > params = this.getCommonParam();
UnionTransactionType.File_Transfer.convertMap(params);
DateFormat df = new SimpleDateFormat("MMDD");
params.put(SDKConstants.param_settleDate,df.format(new Date()));
params.put(SDKConstants.param_fileType,billType);
CertUtil.sign(params,payConfigStorage.getInputCharset().toUpperCase());
Map<String ,Object > response = getHttpRequestTemplate().postForObject(SDKConfig.getConfig().getBackRequestUrl(),params,Map.class);
if(SDKUtils.validate(response,payConfigStorage.getInputCharset().toUpperCase())){
if("00".equals(response.get(SDKConstants.param_respCode))){
return response.get(SDKConstants.param_fileContent).toString();
}else{
throw new PayErrorException(new PayException(response.get(SDKConstants.param_respCode).toString(), response.get(SDKConstants.param_respMsg).toString(), response.toString()));
}
}else{
throw new PayErrorException(new PayException("1000", "验证签名失败", response.toString()));
}
}
/**
* 下载对账单
*
* @param billDate 账单时间:具体请查看对应支付平台
* @param billType 账单类型,具体请查看对应支付平台
* @param callback 处理器
* @return 返回支付方下载对账单的结果
*/
@Override
public <T> T downloadbill (Date billDate, String billType, Callback<T> callback) {
return null;
}
/**
* 通用查询接口
*
* @param tradeNoOrBillDate 支付平台订单号或者账单日期, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @param callback 处理器
* @return 返回支付方对应接口的结果
*/
@Override
public <T> T secondaryInterface (Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback) {
return null;
}
}

View File

@@ -0,0 +1,98 @@
package com.egzosn.pay.union.enums;
import com.egzosn.pay.common.bean.TransactionType;
import com.egzosn.pay.union.SDK.SDKConstants;
import java.util.Map;
/**
* @author Actinia
* @email hayesfu@qq.com
* <pre>
create 2017 2017/11/4 0004
* </pre>
*/
public enum UnionTransactionType implements TransactionType{
//申码(主扫场景)
APPLY_QR_CODE("01","07","000000","08"),
//消费(被扫场景)
CONSUME("01","06","000000","08"),
//消费撤销
CONSUME_UNDO("31","00","000000","08"),
//查询
QUERY("00","00","000201",""),
//退款
REFUND("04","00","000000","08"),
//对账文件下载
File_Transfer("00","00","000201","")
;
/**
* 交易类型
*/
private String txnType;
/**
* 交易子类
*/
private String txnSubType;
/**
* 业务类型
*/
private String bizType;
/**
* 渠道类型
*/
private String channelType;
UnionTransactionType (String txnType, String txnSubType, String bizType, String channelType) {
this.txnType = txnType;
this.txnSubType = txnSubType;
this.bizType = bizType;
this.channelType = channelType;
}
public void convertMap(Map<String ,String> contentData){
contentData.put(SDKConstants.param_txnType, this.getTxnType());
contentData.put(SDKConstants.param_txnSubType,this.getTxnSubType());
contentData.put(SDKConstants.param_bizType,this.getBizType());
contentData.put(SDKConstants.param_channelType,this.getChannelType());
}
public String getTxnType () {
return txnType;
}
public String getTxnSubType () {
return txnSubType;
}
public String getBizType () {
return bizType;
}
public String getChannelType () {
return channelType;
}
/**
*获取交易对类型枚举
*
* @return 交易类型
*/
@Override
public String getType () {
return this.name();
}
/**
*
*/
@Override
public String getMethod () {
return null;
}
}

View File

@@ -0,0 +1,82 @@
package com.egzosn.pay.union.request;
/**
* @author Actinia
* @email hayesfu@qq.com
* <pre>
create 2017 2017/11/4 0004
* </pre>
*/
public class UnionQueryOrder {
private Integer payId;
/**
* 支付平台订单号
*/
private String orderId;
/**
* 金额
*/
private String txnAmt;
/**
* 原交易查询流水号
*/
private String origQryId;
/**
* 原交易商户订单号
*/
private String origOrderId;
/**
* 原交易商户发送交易时间:
*/
private String origTxnTime;
public Integer getPayId() {
return payId;
}
public void setPayId(Integer payId) {
this.payId = payId;
}
public String getOrderId () {
return orderId;
}
public void setOrderId (String orderId) {
this.orderId = orderId;
}
public String getTxnAmt () {
return txnAmt;
}
public void setTxnAmt (String txnAmt) {
this.txnAmt = txnAmt;
}
public String getOrigQryId () {
return origQryId;
}
public void setOrigQryId (String origQryId) {
this.origQryId = origQryId;
}
public String getOrigOrderId () {
return origOrderId;
}
public void setOrigOrderId (String origOrderId) {
this.origOrderId = origOrderId;
}
public String getOrigTxnTime () {
return origTxnTime;
}
public void setOrigTxnTime (String origTxnTime) {
this.origTxnTime = origTxnTime;
}
}