package com.nuvole.util.pay.allinPay.syb; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.nuvole.common.domain.emnu.CommonResultEmnu; import com.nuvole.common.domain.result.CommonResult; import com.nuvole.constants.PropertiesConstants; import com.nuvole.constants.ServiceConstants; import com.nuvole.util.IdGenerator; import com.nuvole.util.pay.allinPay.syb.param.MerchantAddParam; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.jcajce.spec.SM2ParameterSpec; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigInteger; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; /** * 通联支付工具类(收银宝) * * @Author: lc * @Date: 2019/8/27 14:57 */ public class SybPayUtil { //版本号 private static final String version = "11"; //支付信息 private static final String k = PropertiesConstants.TL_PAY_K; private static final String appId = PropertiesConstants.TL_PAY_APPID; private static final String orgCode = PropertiesConstants.TL_PAY_ORGCODE; //测试用下列参数 //快捷支付测试环境参数 private static final String tlk = "allinpay888"; private static final String tlappId = "00000051"; private static final String tlCusId = "990581007426001"; //快捷支付正式环境所用测试参数 /* private static final String tlk = "a0ea3fa20dbd7bb4d5abf1d59d63bae8"; private static final String tlappId = "00000003"; private static final String tlCusId = "990440148166000";*/ /**算法常量:SM3withSM2*/ private static final String ALGORITHM_SM3SM2_BCPROV = "SM3withSM2"; /** 算法常量:SM3加密长度 */ private final static int SM3withSM2_RS_LEN=32; /** * 统一支付 * * @param orgid:通联机构号 * @param cusid:通联商户号 * @param appid:通联appid * @param sub_appid:微信支付APPID, * @param acct:用户标识(微信openid) * @param trxamt:交易金额(分) * @param reqsn:商户交易单号 * @param paytype:交易方式(W01:微信 A01:支付宝) * @param notify_url:交易结果通知地址 * @param key:商户对应的key * @param asinfo:分账信息,可以为空 * @param body:标题 * @param remark:备注 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String unifiedOrder(String orgid, String cusid, String appid, String sub_appid, String acct, Integer trxamt, String reqsn, String paytype, String notify_url, String key, String asinfo, String body, String remark) { //组装数据 Map paramMap = new HashMap(); if (StrUtil.isNotEmpty(orgid)) { paramMap.put("orgid", orgid); } paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("trxamt", Convert.toStr(trxamt)); paramMap.put("reqsn", reqsn); paramMap.put("paytype", paytype); paramMap.put("randomstr", IdGenerator.getUUID()); if (StrUtil.isNotEmpty(body)) { paramMap.put("body", body); } if (StrUtil.isNotEmpty(remark)) { paramMap.put("remark", remark); } if (StrUtil.isNotEmpty(acct)) { paramMap.put("acct", acct); } paramMap.put("notify_url", notify_url); paramMap.put("signtype", "RSA"); if (StrUtil.isNotEmpty(asinfo)) { paramMap.put("asinfo", asinfo); } if (StrUtil.isNotEmpty(sub_appid)) { paramMap.put("sub_appid", sub_appid); } paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); // String sign = DigestUtil.md5Hex(signStr).toUpperCase(Locale.ENGLISH); // paramMap.put("sign", sign); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); // System.out.println("is param:" + JSONUtil.parseObj(paramMap)); String result = ""; if (ServiceConstants.SERVICE_TYPE) { //走服务调用 String url = ServiceConstants.SERVICE_UNIFIED_URL; result = HttpUtil.post(url, paramMap); } else { result = HttpUtil.post(SybPayUrl.UNIFIED_ORDER_URL, paramMap); } System.out.println("is result:" + result); return result; } /** * 根据授权码(付款码)获取用户ID * 使用场景: * 通过微信付款码换取openid * 通过银联userAuth的code(非付款码)换取userid * * @param orgid:集团/代理商商户号 * @param cusid:通联商户号 * @param appid:通联appid * @param key:商户对应的key * @param authCode:支付授权码(微信、支付宝的授权码) * @param authType:授权码类型 01-微信付款码 02-银联userAuth * @param identify:云闪付UA标识 当authtype=02时选送 * @param subAppid:微信支付appid 针对01有效 */ public static String authCode2Userid(String orgid, String cusid, String appid, String key, String authCode, String authType, String identify, String subAppid) { Map paramMap = new HashMap(); if (StrUtil.isNotEmpty(orgid)) { paramMap.put("orgid", orgid); } paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("authcode", authCode); paramMap.put("authtype", authType); if (StringUtils.isNotBlank(identify)) { paramMap.put("identify", identify); } if (StringUtils.isNotBlank(subAppid)) { paramMap.put("sub_appid", subAppid); } paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("根据授权码(付款码)获取用户ID -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; //走服务调用 if (ServiceConstants.SERVICE_TYPE) { String url = ServiceConstants.SERVICE_AUTHCODE2USERID_URL; result = HttpUtil.post(url, paramMap); } else { result = HttpUtil.post(SybPayUrl.SERVICE_AUTHCODE2USERID_URL, paramMap); } return result; } /** * B扫C支付(商户扫用户) * * @param orgid:通联机构号 * @param cusid:通联商户号 * @param appid:通联appid * @param key:商户对应的key * @param trxamt:交易金额(分) * @param reqsn:商户交易单号 * @param body:订单标题, * @param remark:订单备注 * @param authcode:支付授权码(微信、支付宝的授权码) * @param limit_pay:支付限额 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String orderBsweepC(String orgid, String cusid, String appid, String key, Integer trxamt, String reqsn, String body, String remark, String authcode, String limit_pay) { Map paramMap = new HashMap(); if (StrUtil.isNotEmpty(orgid)) { paramMap.put("orgid", orgid); } paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("trxamt", Convert.toStr(trxamt)); paramMap.put("reqsn", reqsn); if (StrUtil.isNotEmpty(body)) { paramMap.put("body", body); } if (StrUtil.isNotEmpty(remark)) { paramMap.put("remark", remark); } paramMap.put("authcode", authcode); if (StrUtil.isNotEmpty(body)) { paramMap.put("body", body); } if (StrUtil.isNotEmpty(remark)) { paramMap.put("remark", remark); } if (StrUtil.isNotEmpty(limit_pay)) { paramMap.put("limit_pay", limit_pay); } paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("is tl b sweep c param -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; //走服务调用 if (ServiceConstants.SERVICE_TYPE) { String url = ServiceConstants.SERVICE_B_SWEEP_C_URL; result = HttpUtil.post(url, paramMap); } else { result = HttpUtil.post(SybPayUrl.ORDER_B_SWEEP_C_URL, paramMap); } Map resultMap = JSON.parseObject(result); if (null != resultMap && resultMap.size() > 0) { //返回码2000等待结果确认每隔10秒执行结果查询,最多4次 if ("2000".equals(resultMap.get("trxstatus") + "")) { int index = 0; final int count = 4; do { index++; try { result = getPayResult(orgid, cusid, appid, key, reqsn); resultMap = JSON.parseObject(result); Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } while (index < count && "2000".equals(resultMap.get("trxstatus") + "")); } } return result; } /** * 查询交易支付结果 * * @param orgid 通联机构号 * @param cusid 通联商户号 * @param appid 通联appid * @param key 商户对应的key * @param reqsn 商户交易单号 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String getPayResult(String orgid, String cusid, String appid, String key, String reqsn) { //组装数据 Map paramMap = new HashMap(); if (StrUtil.isNotEmpty(orgid)) { paramMap.put("orgid", orgid); } paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("reqsn", reqsn); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); String result = ""; //走服务调用 if (ServiceConstants.SERVICE_TYPE) { String url = ServiceConstants.SERVICE_PAY_RESULT_URL; result = HttpUtil.post(url, paramMap); } else { result = HttpUtil.post(SybPayUrl.PAY__RESULT_B_SWEEP_C_URL, paramMap); } System.out.println("is tl b sweep c 查询交易结果 param -->" + JSONUtil.toJsonStr(paramMap)); return result; } private static String checkCardUrl = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo="; /** * 签约申请 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param meruserid 商户用户号(会员id) * @param accttype 00:借记卡02:准贷记卡/贷记卡 * @param acctno 银行卡号 * @param idno 证件号 * @param acctname 户名 * @param mobile 手机号码 * @param validdate 有效期MMyy信用卡不能为空 * @param cvv2 Cvv2 信用卡不能为空 * @param signtype 加密方式 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String agreeapply(String key, String cusid, String appid, String meruserid, String accttype, String acctno, String idno, String acctname, String mobile, String validdate, String cvv2 , String signtype) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); // 商户用户号 paramMap.put("meruserid", meruserid); //商户用户号 00:借记卡 02:准贷记卡/贷记卡 paramMap.put("accttype", accttype); // 银行卡号 paramMap.put("acctno", acctno); // 证件类型 0:身份证 2:护照 5:港澳通行证 6:台湾通行证 paramMap.put("idtype", 0); //证件号 paramMap.put("idno", idno); // 户名 paramMap.put("acctname", acctname); // 手机号码 paramMap.put("mobile", mobile); if ("02".equals(accttype)) { paramMap.put("validdate", validdate); paramMap.put("cvv2", cvv2); } paramMap.put("signtype", "RSA"); String signStr = null; String sign = null; try { signStr = coverMap2String(paramMap); System.out.println("signStr==>" + signStr); sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("is agreeapply url:" + SybPayUrl.AGREEAPPLY_URL); System.out.println("is agreeapply param:" + JSONUtil.toJsonStr(paramMap)); System.out.println("is agreeapply sign:" + sign); String result = HttpUtil.post(SybPayUrl.AGREEAPPLY_URL, paramMap); System.out.println("is agreeapply result:" + result); return result; } /** * 重发签约短信 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param meruserid 商户用户号(会员id) * @param accttype 00:借记卡02:准贷记卡/贷记卡 * @param acctno 银行卡号 * @param idno 证件号 * @param acctname 户名 * @param mobile 手机号码 * @param validdate 有效期MMyy信用卡不能为空 * @param cvv2 Cvv2 信用卡不能为空 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String agreems(String key, String cusid, String appid, String meruserid, String accttype, String acctno, String idno, String acctname, String mobile, String validdate, String cvv2, String signtype) { Map paramMap = new HashMap(); if (PropertiesConstants.PAY_TYPE == 1) { paramMap.put("appid", tlappId); // paramMap.put("key", tlk); key = tlk; } else { paramMap.put("appid", appid); // paramMap.put("key", key); } paramMap.put("cusid", tlCusId); // paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("meruserid", meruserid); paramMap.put("accttype", accttype); paramMap.put("acctno", acctno); paramMap.put("idno", idno); paramMap.put("mobile", mobile); paramMap.put("acctname", acctname); if ("02".equals(accttype)) { paramMap.put("validdate", validdate); paramMap.put("cvv2", cvv2); } String signStr = coverMap2String(paramMap); String sign = null; if ("RSA".equals(signtype)) { try { sign = SybPayUtil.rsaSign(key, sign, "utf-8"); } catch (Exception e) { e.printStackTrace(); } } else { paramMap.put("key", key); sign = DigestUtil.md5Hex(signStr).toUpperCase(Locale.ENGLISH); paramMap.remove("key"); } paramMap.put("sign", sign); System.out.println("is agreeapply url:" + SybPayUrl.AGREEMS_URL); System.out.println("is agreeapply param:" + JSONUtil.toJsonStr(paramMap)); String result = HttpUtil.post(SybPayUrl.AGREEMS_URL, paramMap); System.out.println("is agreeapply result:" + result); return result; } /** * 解除绑定 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param agreeid 协议id * @Author: lc * @Date: 2019/8/27 15:25 */ public static String unbind(String key, String cusid, String appid, String agreeid) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("agreeid", agreeid); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("is unbind url:" + SybPayUrl.UNBIND_URL); System.out.println("is unbind param:" + JSONUtil.toJsonStr(paramMap)); String result = HttpUtil.post(SybPayUrl.UNBIND_URL, paramMap); System.out.println("is unbind result:" + result); return result; } /** * 签约申请确认 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param meruserid 商户用户号(会员id) * @param accttype 00:借记卡02:准贷记卡/贷记卡 * @param acctno 银行卡号 * @param idno 证件号 * @param acctname 户名 * @param mobile 手机号码 * @param validdate 有效期MMyy信用卡不能为空 * @param cvv2 Cvv2 信用卡不能为空 * @param code 短信验证码 * @param thpinfo 透传信息(签约申请接口返回) * @Author: lc * @Date: 2019/8/27 15:25 */ public static String agreeconfirm(String key, String cusid, String appid, String meruserid, String accttype, String acctno, String idno, String acctname, String mobile, String validdate, String cvv2, String code, String thpinfo, String signtype) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("meruserid", meruserid); paramMap.put("accttype", accttype); paramMap.put("acctno", acctno); paramMap.put("idtype", "0"); paramMap.put("idno", idno); paramMap.put("acctname", acctname); paramMap.put("mobile", mobile); paramMap.put("smscode", code); if (StrUtil.isNotEmpty(thpinfo)) { paramMap.put("thpinfo", thpinfo); } if ("02".equals(accttype)) { paramMap.put("validdate", validdate); paramMap.put("cvv2", cvv2); } paramMap.put("signtype", "RSA"); String signStr = null; String sign = null; if ("RSA".equals(signtype)) { try { signStr = coverMap2String(paramMap); System.out.println("signStr==>" + signStr); sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } } else { paramMap.put("key", key); signStr = coverMap2String(paramMap); sign = DigestUtil.md5Hex(signStr).toUpperCase(Locale.ENGLISH); paramMap.remove("key"); } paramMap.put("sign", sign); System.out.println("is agreeconfirm url:" + SybPayUrl.AGREEAPPLY_URL); System.out.println("is agreeconfirm param:" + JSONUtil.toJsonStr(paramMap)); System.out.println("is agreeconfirm sign:" + sign); String result = HttpUtil.post(SybPayUrl.AGREECONFIRM_URL, paramMap); System.out.println("is agreeconfirm result:" + result); return result; } /** * 支付申请 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param orderid 订单id * @param agreeid 协议id * @param amount 金额(单位分) * @param subject 订单的展示标题 * @param notifyurl 交易结果通知地址 * @Author: lc * @Date: 2019/8/27 15:25 */ public static String payapplyagree(String key, String cusid, String appid, String orderid, String agreeid, String amount, String subject, String notifyurl) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("reqsn", orderid); paramMap.put("agreeid", agreeid); paramMap.put("amount", amount); paramMap.put("currency", "CNY"); paramMap.put("subject", subject); paramMap.put("notifyurl", notifyurl); String signStr = null; String sign = null; try { signStr = coverMap2String(paramMap); System.out.println("signStr==>" + signStr); sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("is payapplyagree url:" + SybPayUrl.PAYAPPLYAGREE_URL); System.out.println("is payapplyagree param:" + JSONUtil.toJsonStr(paramMap)); String result = HttpUtil.post(SybPayUrl.PAYAPPLYAGREE_URL, paramMap); System.out.println("is payapplyagree result:" + result); return result; } /** * 支付确认 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param orderid 订单id * @param agreeid 协议id * @param smscode 短信支付验证码 * @param thpinfo 透传信息(支付申请接口返回) * @Author: lc * @Date: 2019/8/27 15:25 */ public static String payagreeconfirm(String key, String cusid, String appid, String orderid, String agreeid, String smscode, String thpinfo) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("reqsn", orderid); paramMap.put("agreeid", agreeid); paramMap.put("smscode", smscode); if (StrUtil.isNotEmpty(thpinfo)) { paramMap.put("thpinfo", thpinfo); } String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("is payagreeconfirm url:" + SybPayUrl.PAYAGREECONFIRM_URL); System.out.println("is payagreeconfirm param:" + JSONUtil.toJsonStr(paramMap)); String result = HttpUtil.post(SybPayUrl.PAYAGREECONFIRM_URL, paramMap); System.out.println("is payagreeconfirm result:" + result); return result; } /** * 重发支付短信 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param orderid 订单id * @param agreeid 协议id * @param thpinfo 交易透传信息(支付申请接口返回) * @Author: lc * @Date: 2019/8/27 15:25 */ public static String paysmsagree(String key, String cusid, String appid, String orderid, String agreeid, String thpinfo) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("signtype", "RSA"); paramMap.put("orderid", orderid); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("agreeid", agreeid); if (StrUtil.isNotEmpty(thpinfo)) { paramMap.put("thpinfo", thpinfo); } String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("is paysmsagree url:" + SybPayUrl.PAYSMSAGREE_URL); System.out.println("is paysmsagree param:" + JSONUtil.toJsonStr(paramMap)); String result = HttpUtil.post(SybPayUrl.PAYSMSAGREE_URL, paramMap); System.out.println("is paysmsagree result:" + result); return result; } /** * 查询交易结果 * * @param key 秘钥 * @param cusid 通联分配的商户号 * @param appid 通联分配的appid * @param orderid 订单id * @param transactionId 平台订单 */ public static String query(String key, String cusid, String appid, String orderid, String transactionId) { Map paramMap = new HashMap(); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("reqsn", orderid); //收银宝交易单号 paramMap.put("trxid", transactionId); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(key, signStr, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); String result = HttpUtil.post(SybPayUrl.QUERY_URL, paramMap); System.out.println("is query result:" + result); return result; } /** * 将Map中的数据转换成按照Key的ascii码排序后的key1=value1&key2=value2的形式 * * @param data * @return */ private static String coverMap2String(Map data) { TreeMap tree = new TreeMap(); Iterator> it = data.entrySet().iterator(); while (it.hasNext()) { Map.Entry en = it.next(); tree.put(en.getKey(), en.getValue()); } it = tree.entrySet().iterator(); StringBuffer sf = new StringBuffer(512); while (it.hasNext()) { Map.Entry en = it.next(); String value = en.getValue(); if (StringUtils.isBlank(value)) { continue; } sf.append(en.getKey() + "=" + Convert.toStr(value) + "&"); } return sf.substring(0, sf.length() - 1); } public static String getMerchantPayResult(String appId, String cusId, String key, String id, Date createTime, String orgId) { //组装数据 Map paramMap = new HashMap(); if (PropertiesConstants.PAY_TYPE == 1) { paramMap.put("appid", tlappId); } else { paramMap.put("appid", appId); } paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("cusid", cusId); paramMap.put("resendnotify", "0"); paramMap.put("signtype", "MD5"); paramMap.put("orderid", id); paramMap.put("orgid", orgId); DateFormat format = new SimpleDateFormat("MMdd"); paramMap.put("trxdate", format.format(createTime)); paramMap.put("key", key); String signStr = coverMap2String(paramMap); String sign = DigestUtil.md5Hex(signStr).toUpperCase(Locale.ENGLISH); paramMap.put("sign", sign); paramMap.remove("key"); String result = ""; System.out.println(paramMap.toString()); //走服务调用 if (ServiceConstants.SERVICE_TYPE) { String url = ServiceConstants.MERCHANT_PAY_RESULT; result = HttpUtil.post(url, paramMap); } else { result = HttpUtil.post(SybPayUrl.MERCHANT_PAY_RESULT, paramMap); } System.out.println(result); return result; } /** * 商城支付手动回调 * * @param cusorderid * @param trxid * @param trxstatus */ public static void callBack(String cusorderid, String trxid, String trxstatus) { String url = SybPayUrl.SHOP_CALL_BACK; HashMap paramMap = new HashMap(); paramMap.put("cusorderid", cusorderid); paramMap.put("trxid", trxid); paramMap.put("trxstatus", trxstatus); HttpUtil.get(url, paramMap); } public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, byte[] encodedKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance(algorithm); return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey)); } public static String rsaSign(String content, String privateKey, String charset) throws Exception { PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", org.apache.commons.codec.binary.Base64.decodeBase64(privateKey.getBytes())); return rsaSign(content, priKey, charset); } public static String rsaSign(String content, byte[] privateKey, String charset) throws Exception { PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", privateKey); return rsaSign(content, priKey, charset); } public static String rsaSign(String content, PrivateKey priKey, String charset) throws Exception { Signature signature = Signature .getInstance("SHA1WithRSA"); signature.initSign(priKey); if (charset == null || "".equals(charset)) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); } byte[] signed = signature.sign(); String signStr = new String(Base64.encodeBase64(signed)); System.out.println("明文:" + content); System.out.println("密文:" + signStr); return signStr; } /** * 判断是否位信用卡 * * @param cardNo * @return true 信用卡 false 储蓄卡 null 卡号不正确 */ public static Boolean checkCardType(String cardNo) { String resp = HttpUtil.get(checkCardUrl + cardNo, 30000); System.out.println(resp); try { JSONObject jsonObject = JSONObject.parseObject(resp); if (jsonObject.getBooleanValue("validated")) { return "CC".equals(jsonObject.getString("cardType")); } return null; } catch (Exception e) { return null; } } /** * 商户进件 * * @param merchantAddParam * @param key 商户对应的key * @return */ public static CommonResult merchantAdd(MerchantAddParam merchantAddParam, String key) { CommonResult validResult = validMerchantAddParam(merchantAddParam); if (validResult.getStatus() == CommonResult.STATUS_ERR) { return validResult; } Map paramMap = new HashMap(); Field[] merchantAddFields = MerchantAddParam.class.getDeclaredFields(); try { for (Field field : merchantAddFields) { String fieldName = field.getName(); field.setAccessible(true); Object o = field.get(merchantAddParam); if (o != null) { paramMap.put(fieldName, o); } } } catch (IllegalAccessException e) { e.printStackTrace(); } paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("version", version); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("商户进件参数 -->" + JSONUtil.toJsonStr(paramMap)); System.out.println("商户进件参数 signStr -->" + signStr); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_URL, paramMap); System.out.println("商户进件返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(result); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /*** * 商户审核状态查询 * @param * @param merchantid 业务系统的id * @return */ public static CommonResult> merchantAddStatusQuery(String orgid, String cusid, String appid, String key, String merchantid) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("merchantid", merchantid); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("商户进件 商户审核状态 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_QUERYSTATUS_URL, paramMap); System.out.println("商户进件 商户审核状态 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /** * 2.20 微信/支付宝认证状态查询 * * @param orgid * @param cusid * @param appid * @param key * @param chnltype 渠道类型 使用中文大写缩写 微信:WXP 支付宝:ALP * @param pid 产品类型 P0001、P0002、P0003 ==> 收银宝、当面付、网上收银 * @return */ public static CommonResult> merchantAddQueryWxVerifyState(String orgid, String cusid, String appid, String key, String chnltype, String pid) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("chnltype", chnltype); if (StringUtils.isNotBlank(pid)) { paramMap.put("pid", pid); } String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("微信/支付宝认证状态查询 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_QUERYWXVERIFYSTATE_URL, paramMap); System.out.println("微信/支付宝认证状态查询 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /*** * 用于对参数签名,生成可访问的收银包url * 合规性审核补录统一h5接口 、 认证统一H5 共用 * @param * @return */ public static String merchantAddUrlSign(String orgid, String cusid, String appid, String key, String urlPrefix, String userid, String notifyurl, String pagetype) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); if (StringUtils.isNotBlank(userid)) { paramMap.put("userid", userid); } if (StringUtils.isNotBlank(notifyurl)) { paramMap.put("notifyurl", notifyurl); } if (StringUtils.isNotBlank(pagetype)) { paramMap.put("pagetype", pagetype); } String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("url签名 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = urlPrefix + "?" + signStr + "&sign=" + sign; return result; } /*** * 无纸化进件协议签约状态查询 * @param electsigntype 01/03 01表示收银宝业务协议 03表示结算委托协议(商户性质是企业且结算账户对私) * @return */ public static CommonResult> merchantElectSignQuery(String orgid, String cusid, String appid, String key, String electsigntype) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("electsigntype", electsigntype); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("无纸化进件协议签约状态查询 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_QUERYELECTSIGN_URL, paramMap); System.out.println("无纸化进件协议签约状态查询 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /** * 合规性状态查询接口 * 商户合规性状态查询,根据通联商户号查询商户对应合规性状态 * * @param orgid * @param cusid * @param appid * @param key * @return */ public static CommonResult> merchantAddQueryCusrGc(String orgid, String cusid, String appid, String key) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("合规性状态查询接口 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_QUERYCUSRGC_URL, paramMap); System.out.println("合规性状态查询接口 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /*** * 无纸化进件协议重发接口 * @return */ public static CommonResult> merchantElectSign(String orgid, String cusid, String appid, String key) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("无纸化进件协议重发接口 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_ELECTSIGN_URL, paramMap); System.out.println("无纸化进件协议重发接口 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } /** * 无纸化进件电子协议URL接口查询 * * @param orgid * @param cusid * @param appid * @param key * @return */ public static CommonResult merchantQueryElecturl(String orgid, String cusid, String appid, String key, String redirecturl) { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("redirecturl", redirecturl); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(signStr, key, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); paramMap.remove("key"); System.out.println("无纸化进件电子协议URL接口查询 查询参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = ""; result = HttpUtil.post(SybPayUrl.SYB_MERCHANT_ADD_QUERYELECTURL_URL, paramMap); System.out.println("无纸化进件电子协议URL接口查询 返回值 -->" + result); Map resultMap = JSON.parseObject(result); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(result); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } private static CommonResult validMerchantAddParam(MerchantAddParam merchantAddParam) { if (merchantAddParam == null) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS); } if (StringUtils.isBlank(merchantAddParam.getRandomstr())) { merchantAddParam.setRandomstr(IdGenerator.getUUID()); } if (StringUtils.isBlank(merchantAddParam.getSigntype())) { merchantAddParam.setSigntype("RSA"); } // *商户性质 //1.企业 3.个体户 4.个人 6.事业单位 String comproperty = merchantAddParam.getComproperty(); if (StringUtils.isBlank(comproperty)) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质需要填写"); } //商户性质为企业 // if ("1".equals(comproperty)) { // if (StringUtils.isBlank(merchantAddParam.getPubacctinfo())) { // return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业时需要填写对公账户信息"); // } // } //商户性质为个人时必填 if ("4".equals(comproperty)) { if (StringUtils.isBlank(merchantAddParam.getLegalpic())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要上传经营者手持身份证照片"); } } if (!"4".equals(comproperty)) { if (StringUtils.isBlank(merchantAddParam.getCorpbusname())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写营业执照名称"); } if (StringUtils.isBlank(merchantAddParam.getCreditcode())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写统一社会信用代码证"); } if (StringUtils.isBlank(merchantAddParam.getCreditcodeexpire())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写社会信用代码证有效期"); } if (StringUtils.isBlank(merchantAddParam.getCorpbuspic())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写营业执照照片"); } if (StringUtils.isBlank(merchantAddParam.getBusconactperson())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写业务联系人姓名"); } if (StringUtils.isBlank(merchantAddParam.getBusconacttel())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质非个人时需要填写业务联系人电话"); } } //商户性质为企业、个体户时必填 if ("1".equals(comproperty) || "3".equals(comproperty)) { if (StringUtils.isBlank(merchantAddParam.getHoldername())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写控股股东姓名"); } if (StringUtils.isBlank(merchantAddParam.getHolderidno())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写控股股东身份证"); } if (StringUtils.isBlank(merchantAddParam.getHolderexpire())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写控股股东有效期"); } if (StringUtils.isBlank(merchantAddParam.getRegisterfund())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写注册资本"); } if (StringUtils.isBlank(merchantAddParam.getStafftotal())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写员工人数"); } if (StringUtils.isBlank(merchantAddParam.getOperatelimit())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写经营区域"); } if (StringUtils.isBlank(merchantAddParam.getInspect())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "商户性质为企业、个体户时需要填写经营地段"); } } // if (StringUtils.isBlank(merchantAddParam.getAddfacusid())) { // return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "所在机构资金归集时,该字段不能为空"); // } // 结算账户 0-对私 1-对公 String accttype = merchantAddParam.getAccttype(); if (StringUtils.isBlank(accttype)) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "结算账户类型不能为空"); } if ("0".equals(accttype)) { if (StringUtils.isBlank(merchantAddParam.getSettidno())) { return new CommonResult(CommonResultEmnu.INVALID_PARAMS, "结算账户对私时,结算人身份证号不能为空"); } } return new CommonResult(); } public static CommonResult uploadfile(String orgid, String cusid, String appid, String key, String ftpFilePath) throws Exception { Map paramMap = new HashMap(); paramMap.put("orgid", orgid); paramMap.put("cusid", cusid); paramMap.put("appid", appid); paramMap.put("version", version); paramMap.put("randomstr", IdGenerator.getUUID()); paramMap.put("signtype", "RSA"); paramMap.put("filetype", "jpg"); String signStr = coverMap2String(paramMap); String sign = null; try { sign = SybPayUtil.rsaSign(key, signStr, "utf-8"); } catch (Exception e) { e.printStackTrace(); } paramMap.put("sign", sign); System.out.println("上传文件参数 -->" + JSONUtil.toJsonStr(paramMap)); String result = dorequest(SybPayUrl.SYB_FILE_UPLOAD_URL, paramMap, ftpFilePath); System.out.println("上传文件 返回值 -->" + result); CommonResult mapCommonResult = handleResult(result); return mapCommonResult; } /** * 只做retcode 判断 不做业务状态判断 * * @param result * @return */ private static CommonResult handleResult(String result) { Map resultMap = JSONObject.parseObject(result, Map.class); String retcode = Convert.toStr(resultMap.get("retcode")); if ("success".equalsIgnoreCase(retcode)) { return new CommonResult(resultMap); } else { return new CommonResult(CommonResultEmnu.ERROR, Convert.toStr(resultMap.get("retmsg"))); } } private static String dorequest(String url, Map params, String path) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; try { httpClient = HttpClients.createDefault(); // 把一个普通参数和文件上传给下面这个地址 是一个servlet HttpPost httpPost = new HttpPost(url); // 把文件转换成流对象FileBody FileBody bin = new FileBody(new File(path)); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.addPart("filecontent", bin); for (Map.Entry entry : params.entrySet()) { builder.addTextBody(entry.getKey(), entry.getValue()); } httpPost.setEntity(builder.build()); // 发起请求 并返回请求的响应 response = httpClient.execute(httpPost); // 获取响应对象 HttpEntity resEntity = response.getEntity(); if (resEntity != null) { String result = EntityUtils.toString(resEntity, Charset.forName("UTF-8")); return result; } // 销毁 EntityUtils.consume(resEntity); } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (httpClient != null) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } /** * 验签 * @param param 参数 * @param appKey appKey * @param signType 加密类型 * @return 结果 */ public static boolean validSign(TreeMap param, String appKey, String signType) { if (param == null || param.isEmpty()) { return false; } if (!param.containsKey("sign")) { return false; } String sign = param.remove("sign"); if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序 param.put("key", appKey); } String paramStr = content(param); byte[] paramByteArr = getByteUtf8(paramStr); if ("MD5".equals(signType)) { return sign.equalsIgnoreCase( md5(paramByteArr)); } else if("SM2".equals(signType)){ PublicKey publicKey; try { publicKey = pubKeySM2FromBase64Str(appKey); } catch (GeneralSecurityException e) { return false; } return verifySM3SM2(publicKey, decodeBase64(sign), paramByteArr); }else { return rsaVerifyPublicKey(paramStr, sign, appKey); } } /** * 公钥验签 * @param content 内容 * @param sign 签名 * @param publicKey 公钥key * @return 结果 */ private static boolean rsaVerifyPublicKey(String content, String sign, String publicKey) { PublicKey pubKey; try { pubKey = getPublicKeyFromX509("RSA", Base64.decodeBase64(publicKey.getBytes())); } catch (GeneralSecurityException e) { e.printStackTrace(); return false; } return rsaVerifyPublicKey(content, sign, pubKey); } /** * 公钥验签 * @param content 内容 * @param sign 签名 * @param pubKey 公钥 * @return 结果 */ public static boolean rsaVerifyPublicKey(String content, String sign, PublicKey pubKey) { Signature signature; try { signature = Signature .getInstance("SHA1WithRSA"); } catch (NoSuchAlgorithmException e) { return false; } try { signature.initVerify(pubKey); } catch (InvalidKeyException e) { return false; } try { signature.update(getByteUtf8(content)); } catch (SignatureException e) { return false; } try { return signature.verify(decodeBase64(sign)); } catch (SignatureException e) { return false; } } /** * 拼接验签/加签内容 * @param param 参数 * @return 验签/加签字符串 */ private static String content(TreeMap param) { //noinspection DuplicatedCode StringBuilder sb = new StringBuilder(); for (Map.Entry entry : param.entrySet()) { if (entry.getValue() != null && entry.getValue().length() > 0) { sb.append(entry.getKey()).append("=") .append(entry.getValue()).append("&"); } } if (sb.length() > 0) { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } /** * md5 * * @param b 加密字符集 * @return 加密字符串 */ public static String md5(byte[] b) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(b); byte[] hash = md.digest(); StringBuilder outStrBuf = new StringBuilder(32); for (byte value : hash) { int v = value & 0xFF; if (v < 16) { outStrBuf.append('0'); } outStrBuf.append(Integer.toString(v, 16).toLowerCase()); } return outStrBuf.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new String(b); } } /** * 初始化公钥 * @param algorithm 指定公钥算法 * @return 公钥 * @throws GeneralSecurityException 初始化异常 */ public static PublicKey getPublicKeyFromX509(String algorithm, byte[] encodedKey) throws GeneralSecurityException { KeyFactory keyFactory = KeyFactory.getInstance(algorithm); return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); } /** * 初始化公钥 * @param keyStr 公钥字符串 * @return 公钥 * @throws GeneralSecurityException 初始化异常 */ public static PublicKey pubKeySM2FromBase64Str(String keyStr) throws GeneralSecurityException { // KeyFactory keyFactory = KeyFactory.getInstance("EC"); // return keyFactory.generatePublic(new X509EncodedKeySpec(decodeBase64(keyStr))); return getPublicKeyFromX509("EC", decodeBase64(keyStr)); } /** * base64字节数组 * @param str 字符串 * @return 字节数组 */ private static byte[] decodeBase64(String str) { return Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); } /** * 转byte * @param str 字符串 * @return 字节数组 */ private static byte[] getByteUtf8(String str) { if (str == null) { return new byte[0]; } return str.getBytes(StandardCharsets.UTF_8); } /** 验证签名-SM3WithSM2*/ private static boolean verifySM3SM2(final PublicKey publicKey,final byte[] signData, final byte[] srcData) { SM2ParameterSpec parameterSpec = new SM2ParameterSpec(getByteUtf8("Allinpay")); Signature verifier; try { verifier = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC"); } catch (NoSuchAlgorithmException | NoSuchProviderException e) { return false; } try { verifier.setParameter(parameterSpec); verifier.initVerify(publicKey); verifier.update(srcData); return verifier.verify(bytePlain2ByteAsn1(signData)); } catch (GeneralSecurityException e) { return false; } } /** * 将普通字节数组转换为ASN1字节数组 适用于SM3withSM2验签时验签明文转换 */ private static byte[] bytePlain2ByteAsn1(byte[] data) { if (data.length != SM3withSM2_RS_LEN * 2) { throw new RuntimeException("err data. "); } BigInteger r = new BigInteger(1, Arrays.copyOfRange(data, 0, SM3withSM2_RS_LEN)); BigInteger s = new BigInteger(1, Arrays.copyOfRange(data, SM3withSM2_RS_LEN, SM3withSM2_RS_LEN * 2)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(r)); v.add(new ASN1Integer(s)); try { return new DERSequence(v).getEncoded("DER"); } catch (IOException e) { throw new RuntimeException(e); } } }