|
@@ -6,8 +6,9 @@ import com.ydtech.exception.SystemException;
|
|
|
import com.ydtech.modules.admin.components.request.UnionPayRequest;
|
|
import com.ydtech.modules.admin.components.request.UnionPayRequest;
|
|
|
import com.ydtech.modules.admin.components.response.UnionPayResponse;
|
|
import com.ydtech.modules.admin.components.response.UnionPayResponse;
|
|
|
import com.ydtech.modules.admin.utils.UnionPayUtils;
|
|
import com.ydtech.modules.admin.utils.UnionPayUtils;
|
|
|
-import com.ydtech.utils.SM2Utils;
|
|
|
|
|
|
|
+import com.ydtech.utils.SM2;
|
|
|
import com.ydtech.utils.StringUtils;
|
|
import com.ydtech.utils.StringUtils;
|
|
|
|
|
+import com.ydtech.utils.idgen.IdGenerate;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import org.redisson.api.RLock;
|
|
import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
import org.redisson.api.RedissonClient;
|
|
@@ -58,35 +59,24 @@ public class UnionPayRequestApiComponent {
|
|
|
|
|
|
|
|
private final static int UNION_PAY_SLEEP_TIME = 5000;
|
|
private final static int UNION_PAY_SLEEP_TIME = 5000;
|
|
|
|
|
|
|
|
- private final static int RANDOM_MAX = 999999999;
|
|
|
|
|
-
|
|
|
|
|
- private final static int RANDOM_MIN = 100000000;
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 运营商二要素验证接口
|
|
* 运营商二要素验证接口
|
|
|
*
|
|
*
|
|
|
* @param request
|
|
* @param request
|
|
|
*/
|
|
*/
|
|
|
- public UnionPayResponse twoFactorVerifyRequest(UnionPayRequest request) {
|
|
|
|
|
- String url = unionPayApiConfigurationProperties.getFactorVerifyUrl();
|
|
|
|
|
|
|
+ public UnionPayResponse threeFactorVerifyRequest(UnionPayRequest request) {
|
|
|
|
|
+ String url = unionPayApiConfigurationProperties.getThreeFactorVerifyUrl();
|
|
|
|
|
|
|
|
JSONObject params = new JSONObject();
|
|
JSONObject params = new JSONObject();
|
|
|
- if (StringUtils.isBlank(request.getPhoneNo())) {
|
|
|
|
|
- throw new InvalidParameterException("手机号不允许为空!");
|
|
|
|
|
|
|
+ if (StringUtils.isBlank(request.getPhoneNo()) || StringUtils.isBlank(request.getCertNo()) ||
|
|
|
|
|
+ StringUtils.isBlank(request.getName())) {
|
|
|
|
|
+ throw new InvalidParameterException("手机号、身份证、用户姓名不允许为空!");
|
|
|
}
|
|
}
|
|
|
params.put("phoneNo", request.getPhoneNo());
|
|
params.put("phoneNo", request.getPhoneNo());
|
|
|
-
|
|
|
|
|
- //01:验证姓名+手机号,此时用户姓名必输 02:身份证+手机号,此时证件类型、证件
|
|
|
|
|
- if (StringUtils.isNotBlank(request.getCertNo())) {
|
|
|
|
|
- params.put("verifyType", "02");
|
|
|
|
|
- params.put("certType", "01");//证件类型 01:身份证
|
|
|
|
|
- params.put("certNo", request.getCertNo());
|
|
|
|
|
- } else if (StringUtils.isNotBlank(request.getName())) {
|
|
|
|
|
- params.put("verifyType", "01");
|
|
|
|
|
- params.put("name", request.getName());
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new InvalidParameterException("身份证、用户姓名至少传值一个!");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ params.put("certType", "01");//证件类型 01:身份证
|
|
|
|
|
+ params.put("certNo", request.getCertNo());
|
|
|
|
|
+ params.put("name", request.getName());
|
|
|
return commonRequest(url, params);
|
|
return commonRequest(url, params);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -96,7 +86,7 @@ public class UnionPayRequestApiComponent {
|
|
|
* @param request
|
|
* @param request
|
|
|
*/
|
|
*/
|
|
|
public UnionPayResponse bankCardVerifyRequest(UnionPayRequest request) {
|
|
public UnionPayResponse bankCardVerifyRequest(UnionPayRequest request) {
|
|
|
- String url = unionPayApiConfigurationProperties.getFactorVerifyUrl();
|
|
|
|
|
|
|
+ String url = unionPayApiConfigurationProperties.getBankCardVerifyUrl();
|
|
|
|
|
|
|
|
JSONObject params = new JSONObject();
|
|
JSONObject params = new JSONObject();
|
|
|
if (StringUtils.isBlank(request.getCardNo())) {
|
|
if (StringUtils.isBlank(request.getCardNo())) {
|
|
@@ -108,7 +98,7 @@ public class UnionPayRequestApiComponent {
|
|
|
}
|
|
}
|
|
|
params.put("cardNo", request.getCardNo());
|
|
params.put("cardNo", request.getCardNo());
|
|
|
params.put("personalMandate", "1");//是否取得个人授权,字段取值0或1。1:是 0:否
|
|
params.put("personalMandate", "1");//是否取得个人授权,字段取值0或1。1:是 0:否
|
|
|
- params.put("sceneId", "13"); //TODO 业务场景 13:车险
|
|
|
|
|
|
|
+ params.put("sceneId", "13"); // 业务场景 13:车险
|
|
|
if (StringUtils.isNotBlank(request.getCertNo())) {
|
|
if (StringUtils.isNotBlank(request.getCertNo())) {
|
|
|
params.put("certType", "01");//证件类型 01:身份证
|
|
params.put("certType", "01");//证件类型 01:身份证
|
|
|
params.put("certNo", request.getCertNo());
|
|
params.put("certNo", request.getCertNo());
|
|
@@ -119,20 +109,32 @@ public class UnionPayRequestApiComponent {
|
|
|
if (StringUtils.isNotBlank(request.getPhoneNo())) {
|
|
if (StringUtils.isNotBlank(request.getPhoneNo())) {
|
|
|
params.put("phoneNo", request.getPhoneNo());
|
|
params.put("phoneNo", request.getPhoneNo());
|
|
|
}
|
|
}
|
|
|
- params.put("appName", "01晋掌柜");//TODO 交易发起应用名称
|
|
|
|
|
|
|
+ params.put("appName", "01晋掌柜");// 交易发起应用名称
|
|
|
params.put("ipType", "04");//IP版本号 04:IPV4 06:IPV6
|
|
params.put("ipType", "04");//IP版本号 04:IPV4 06:IPV6
|
|
|
try {
|
|
try {
|
|
|
- params.put("sourceIp", InetAddress.getLocalHost().getHostAddress()); // ip
|
|
|
|
|
|
|
+ params.put("sourceIp", ipFormat(InetAddress.getLocalHost().getHostAddress())); // ip
|
|
|
} catch (UnknownHostException e) {
|
|
} catch (UnknownHostException e) {
|
|
|
LOGGER.error("获取ipv4地址异常", e);
|
|
LOGGER.error("获取ipv4地址异常", e);
|
|
|
throw new RuntimeException("获取ipv4地址异常:", e);
|
|
throw new RuntimeException("获取ipv4地址异常:", e);
|
|
|
}
|
|
}
|
|
|
- params.put("protocolVersion", ""); // 用户授权协议版本号 //TODO
|
|
|
|
|
- params.put("protocolNo", ""); // 用户授权协议流水号
|
|
|
|
|
|
|
+ params.put("protocolVersion", "V1.0"); // 用户授权协议版本号
|
|
|
|
|
+ params.put("protocolNo", IdGenerate.nextId());
|
|
|
return commonRequest(url, params);
|
|
return commonRequest(url, params);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ private String ipFormat(String ip) {
|
|
|
|
|
+ String[] ips = ip.split("\\.");
|
|
|
|
|
+ StringBuffer br = new StringBuffer();
|
|
|
|
|
+ for (int i = 0; i < ips.length; i++) {
|
|
|
|
|
+ br.append(StringUtils.leftPad(ips[i], 3, "0"));
|
|
|
|
|
+ if (i < ips.length - 1) {
|
|
|
|
|
+ br.append(".");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return br.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 调用银联接口
|
|
* 调用银联接口
|
|
|
*
|
|
*
|
|
@@ -145,8 +147,7 @@ public class UnionPayRequestApiComponent {
|
|
|
String publicKey = unionPayApiConfigurationProperties.getPublicKey();
|
|
String publicKey = unionPayApiConfigurationProperties.getPublicKey();
|
|
|
|
|
|
|
|
JSONObject data = new JSONObject();
|
|
JSONObject data = new JSONObject();
|
|
|
- String dataValue = Base64.getEncoder().encodeToString(SM2Utils.encrypt(params.toString(),
|
|
|
|
|
- publicKey).getBytes());
|
|
|
|
|
|
|
+ String dataValue = SM2.sm2Encrypt(params.toString(), publicKey);
|
|
|
data.put("data", dataValue);
|
|
data.put("data", dataValue);
|
|
|
|
|
|
|
|
HttpHeaders httpHeaders = new HttpHeaders();
|
|
HttpHeaders httpHeaders = new HttpHeaders();
|
|
@@ -154,15 +155,17 @@ public class UnionPayRequestApiComponent {
|
|
|
httpHeaders.set("Accept", "application/json");
|
|
httpHeaders.set("Accept", "application/json");
|
|
|
httpHeaders.set("Authorization", getAccessToken());
|
|
httpHeaders.set("Authorization", getAccessToken());
|
|
|
// 请求
|
|
// 请求
|
|
|
- HttpEntity<String> httpEntity = new HttpEntity<>(params.toString(), httpHeaders);
|
|
|
|
|
|
|
+ LOGGER.error("银联接口url:"+url);
|
|
|
|
|
+ LOGGER.error("银联接口入参:"+params);
|
|
|
|
|
+ HttpEntity<String> httpEntity = new HttpEntity<>(data.toString(), httpHeaders);
|
|
|
ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
|
|
ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
|
|
|
JSONObject resp = JSONObject.parseObject(response.getBody());
|
|
JSONObject resp = JSONObject.parseObject(response.getBody());
|
|
|
|
|
|
|
|
if ("20000000".equals(resp.getString("errCode"))) {
|
|
if ("20000000".equals(resp.getString("errCode"))) {
|
|
|
String privateKey = unionPayApiConfigurationProperties.getPrivateKey();
|
|
String privateKey = unionPayApiConfigurationProperties.getPrivateKey();
|
|
|
-
|
|
|
|
|
- String respData = SM2Utils.decrypt(new String(Base64.getDecoder().decode(resp.getString("data"))),
|
|
|
|
|
|
|
+ String respData = SM2.sm2Decrypt(resp.getString("data"),
|
|
|
privateKey);
|
|
privateKey);
|
|
|
|
|
+ LOGGER.error("银联接口返参:"+respData);
|
|
|
return JSONObject.parseObject(respData, UnionPayResponse.class);
|
|
return JSONObject.parseObject(respData, UnionPayResponse.class);
|
|
|
} else {
|
|
} else {
|
|
|
throw new SystemException("银联信息验证异常[" + resp.getString("errCode") + ":" +
|
|
throw new SystemException("银联信息验证异常[" + resp.getString("errCode") + ":" +
|
|
@@ -245,16 +248,18 @@ public class UnionPayRequestApiComponent {
|
|
|
httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
|
|
httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
|
|
|
httpHeaders.set("Accept", "application/json");
|
|
httpHeaders.set("Accept", "application/json");
|
|
|
// 请求
|
|
// 请求
|
|
|
|
|
+ LOGGER.error("银联获取token-url:"+accessTokenUrl);
|
|
|
|
|
+ LOGGER.error("银联获取token-入参:"+params);
|
|
|
HttpEntity<JSONObject> httpEntity = new HttpEntity<>(params, httpHeaders);
|
|
HttpEntity<JSONObject> httpEntity = new HttpEntity<>(params, httpHeaders);
|
|
|
ResponseEntity<String> response = restTemplate.postForEntity(accessTokenUrl, httpEntity, String.class);
|
|
ResponseEntity<String> response = restTemplate.postForEntity(accessTokenUrl, httpEntity, String.class);
|
|
|
JSONObject resp = JSONObject.parseObject(response.getBody());
|
|
JSONObject resp = JSONObject.parseObject(response.getBody());
|
|
|
-
|
|
|
|
|
|
|
+ LOGGER.error("银联获取token-返参:"+resp);
|
|
|
if ("0000".equals(resp.getString("errCode"))) {
|
|
if ("0000".equals(resp.getString("errCode"))) {
|
|
|
String token = resp.getString("accessToken");
|
|
String token = resp.getString("accessToken");
|
|
|
int expiresIn = resp.getIntValue("expiresIn"); //失效时间
|
|
int expiresIn = resp.getIntValue("expiresIn"); //失效时间
|
|
|
Map<String, String> map = new HashMap<>();
|
|
Map<String, String> map = new HashMap<>();
|
|
|
- map.put(UNION_PAY_MAP, "OPEN-ACCESS-TOKEN AccessToken=\"" + token + "\", appId=\"" + appId + "\"");
|
|
|
|
|
- redisTemplate.opsForHash().putAll(UNION_PAY_ACCESS_TOKEN_KEY, map);
|
|
|
|
|
|
|
+ map.put(UNION_PAY_ACCESS_TOKEN_KEY, "OPEN-ACCESS-TOKEN AccessToken=" + token + ", AppId=" + appId );
|
|
|
|
|
+ redisTemplate.opsForHash().putAll(UNION_PAY_MAP, map);
|
|
|
redisTemplate.expire(UNION_PAY_ACCESS_TOKEN_KEY, expiresIn - 30, TimeUnit.SECONDS);
|
|
redisTemplate.expire(UNION_PAY_ACCESS_TOKEN_KEY, expiresIn - 30, TimeUnit.SECONDS);
|
|
|
return token;
|
|
return token;
|
|
|
} else {
|
|
} else {
|