parent
922d9c3d9c
commit
44e44af0bb
@ -0,0 +1,9 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.advice;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface Gtw2Ctrl {
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.advice;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.InvalidGatewayShortIdException;
|
||||||
|
import au.com.royalpay.payment.core.exceptions.InvalidShortIdException;
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import au.com.royalpay.payment.core.exceptions.SignInvalidException;
|
||||||
|
import au.com.royalpay.payment.manage.mappers.system.OrgSignInfoMapper;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.context.request.*;
|
||||||
|
import org.springframework.web.servlet.View;
|
||||||
|
import org.springframework.web.util.UriComponents;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.*;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static au.com.royalpay.payment.tools.codec.RSACrypt.loadPrivateKey;
|
||||||
|
import static au.com.royalpay.payment.tools.codec.RSACrypt.loadPublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author taylor
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class Gtw2SignAspect {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private static final String V2_SIGN_TYPE = "RSA2";
|
||||||
|
@Resource
|
||||||
|
private OrgSignInfoMapper orgSignRsaMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Pointcut("within(au.com.royalpay.payment.manage.gateway.web..*) && " +
|
||||||
|
"!execution(* au.com.royalpay.payment.manage.gateway.web.*.handlePartner*(..))")
|
||||||
|
private void anyMethod() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Around(value = "anyMethod()")
|
||||||
|
public JSONObject aroundHandleRequest(ProceedingJoinPoint pjp) throws Throwable {
|
||||||
|
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||||
|
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||||
|
UriComponents components = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(sra.getRequest())).build();
|
||||||
|
String requestUrl = UriComponentsBuilder.fromHttpUrl(components.toUriString()).replaceQuery(null).toUriString();
|
||||||
|
MultiValueMap<String, String> requireParams = components.getQueryParams();
|
||||||
|
if (!requireParams.containsKey("nonce_str")) {
|
||||||
|
throw new ParamInvalidException("nonce_str", "error.payment.valid.param_missing");
|
||||||
|
}
|
||||||
|
if (!requireParams.containsKey("sign")) {
|
||||||
|
throw new ParamInvalidException("sign", "error.payment.valid.param_missing");
|
||||||
|
}
|
||||||
|
if (!requireParams.containsKey("sign_type")) {
|
||||||
|
throw new ParamInvalidException("sign_type", "error.payment.valid.param_missing");
|
||||||
|
}
|
||||||
|
if (!StringUtils.equals(V2_SIGN_TYPE, requireParams.getFirst("sign_type"))) {
|
||||||
|
throw new ParamInvalidException("sign_type", "error.payment.valid.invalid_param");
|
||||||
|
}
|
||||||
|
NativeWebRequest webRequest = new ServletWebRequest(sra.getRequest());
|
||||||
|
Map<String, String> pathVariables = (Map<String, String>) webRequest.getAttribute(View.PATH_VARIABLES, RequestAttributes.SCOPE_REQUEST);
|
||||||
|
if (!pathVariables.containsKey("shortId")) {
|
||||||
|
throw new InvalidShortIdException();
|
||||||
|
}
|
||||||
|
Object[] requestArgs = pjp.getArgs();
|
||||||
|
JSONObject requestBody = null;
|
||||||
|
for (Object arg : requestArgs) {
|
||||||
|
try {
|
||||||
|
if (arg instanceof JSONObject) {
|
||||||
|
requestBody = JSONObject.parseObject(arg.toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ParamInvalidException("Request Body", "error.payment.valid.invalid_param");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!StringUtils.equals("GET", sra.getRequest().getMethod()) && requestBody == null
|
||||||
|
&& !requestUrl.contains("/attachment/files")) {
|
||||||
|
throw new ParamInvalidException("Request Body", "error.payment.valid.invalid_param");
|
||||||
|
}
|
||||||
|
AtomicBoolean isTrueSign = new AtomicBoolean(buildSign(pathVariables.get("shortId"),
|
||||||
|
requestBody == null ? new JSONObject() : requestBody,
|
||||||
|
requestUrl,
|
||||||
|
requireParams.getFirst("nonce_str"),
|
||||||
|
requireParams.getFirst("sign")));
|
||||||
|
if (!isTrueSign.get()) {
|
||||||
|
throw new SignInvalidException();
|
||||||
|
}
|
||||||
|
Object result = pjp.proceed();
|
||||||
|
JSONObject data = JSONObject.parseObject(result.toString());
|
||||||
|
return buildResponseData(pathVariables.get("shortId"), requestUrl, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject buildResponseData(String clientMoniker, String requestUrl, JSONObject data) {
|
||||||
|
data.put("nonce_str", RandomStringUtils.random(15, true, true));
|
||||||
|
data.put("sign_type", V2_SIGN_TYPE);
|
||||||
|
data.put("url", requestUrl);
|
||||||
|
JSONObject signInfo = orgSignRsaMapper.findOrgSignInfo(clientMoniker);
|
||||||
|
String signStr = sign(JSONObject.toJSONBytes(data, SerializerFeature.MapSortField), signInfo.getString("platform_private_key"));
|
||||||
|
JSONObject respJson = new JSONObject();
|
||||||
|
respJson.put("data", data);
|
||||||
|
respJson.put("sign", signStr);
|
||||||
|
logger.info("ApiV2 Response : {}", JSONObject.toJSONString(respJson, SerializerFeature.MapSortField));
|
||||||
|
return respJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean buildSign(String clientMoniker, JSONObject requestData, String url, String nonceStr, String requestSign) {
|
||||||
|
requestData.put("url", url);
|
||||||
|
requestData.put("sign_type", V2_SIGN_TYPE);
|
||||||
|
requestData.put("nonce_str", nonceStr);
|
||||||
|
logger.info("ApiV2 Request : {}, RequestSign : {}", JSONObject.toJSONString(requestData, SerializerFeature.MapSortField), requestSign);
|
||||||
|
JSONObject signInfo = orgSignRsaMapper.findOrgSignInfo(clientMoniker);
|
||||||
|
if (signInfo == null) {
|
||||||
|
throw new InvalidGatewayShortIdException();
|
||||||
|
}
|
||||||
|
if (!signInfo.containsKey("mch_public_key")) {
|
||||||
|
throw new ServerErrorException("error.payment.valid.invalid.mch_public_key");
|
||||||
|
}
|
||||||
|
// return checkSign(JSONObject.toJSONBytes(requestData, SerializerFeature.MapSortField), requestSign, signInfo.getString("mch_public_key"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sign(byte[] source, String privateKey) {
|
||||||
|
try {
|
||||||
|
PrivateKey priKey = loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8)));
|
||||||
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||||
|
signature.initSign(priKey);
|
||||||
|
signature.update(source);
|
||||||
|
byte[] signed = signature.sign();
|
||||||
|
return Base64.encodeBase64URLSafeString(signed);
|
||||||
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
|
//shall never happen
|
||||||
|
throw new ServerErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkSign(byte[] source, String sign, String publicKey) {
|
||||||
|
try {
|
||||||
|
PublicKey pubKey = loadPublicKey(new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8)));
|
||||||
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||||
|
signature.initVerify(pubKey);
|
||||||
|
signature.update(source);
|
||||||
|
return signature.verify(Base64.decodeBase64(sign));
|
||||||
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
|
//shall never happen
|
||||||
|
throw new ServerErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientCompanyConfig {
|
||||||
|
|
||||||
|
@JSONField(name = "company_name")
|
||||||
|
private String companyName;
|
||||||
|
@JSONField(name = "short_name")
|
||||||
|
private String shortName;
|
||||||
|
@JSONField(name = "store_name")
|
||||||
|
private String storeName;
|
||||||
|
@JSONField(name = "business_name")
|
||||||
|
private String businessName;
|
||||||
|
@JSONField(name = "business_structure")
|
||||||
|
private String businessStructure;
|
||||||
|
private String abn;
|
||||||
|
private String acn;
|
||||||
|
@JSONField(name = "company_phone")
|
||||||
|
private String companyPhone;
|
||||||
|
@JSONField(name = "logo_url")
|
||||||
|
private String logoId;
|
||||||
|
|
||||||
|
private static String[] WHITE_LIST = {"businessName","abn", "acn"};
|
||||||
|
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null && !Arrays.asList(WHITE_LIST).contains(field.getName())) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsIgnoreCase(businessStructure, "Company")) {
|
||||||
|
if (StringUtils.isBlank(acn) || acn.length() != 9) {
|
||||||
|
throw new ParamInvalidException("acn", "Required Param acn not found");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if (StringUtils.isBlank(abn)) {
|
||||||
|
throw new ParamInvalidException("abn", "Required Param abn not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JSONObject basicInfo() {
|
||||||
|
return (JSONObject) JSON.toJSON(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientComplianceFileConfig {
|
||||||
|
@JSONField(name = "id_type")
|
||||||
|
private String idType;
|
||||||
|
@JSONField(name = "id_title")
|
||||||
|
private String idTitle;
|
||||||
|
@JSONField(name = "id_title_description")
|
||||||
|
private String idTitleDesc;
|
||||||
|
@JSONField(name = "bank_statement")
|
||||||
|
private String bankStatement;
|
||||||
|
@JSONField(name = "certificate_of_registration")
|
||||||
|
private String certOfRegistration;
|
||||||
|
@JSONField(name = "id_file")
|
||||||
|
private String id;
|
||||||
|
@JSONField(name = "utility_bill")
|
||||||
|
private String utilityBill;
|
||||||
|
|
||||||
|
private static String[] WHITE_LIST = {"utility_bill","id_title_description"};
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null && !Arrays.asList(WHITE_LIST).contains(field.getName())) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!StringUtils.equalsIgnoreCase(idTitle, "Ultimate beneficiary owner")) {
|
||||||
|
if (StringUtils.isBlank(idTitleDesc)) {
|
||||||
|
throw new ParamInvalidException("id_title_description", "error.payment.valid.param_missing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientContactConfig {
|
||||||
|
@JSONField(name = "contact_person")
|
||||||
|
private String contactPerson;
|
||||||
|
@JSONField(name = "contact_phone")
|
||||||
|
private String contactPhone;
|
||||||
|
@JSONField(name = "contact_email")
|
||||||
|
private String contactEmail;
|
||||||
|
@JSONField(name = "contact_job")
|
||||||
|
private String contactJob;
|
||||||
|
private String address;
|
||||||
|
private String suburb;
|
||||||
|
private String postcode;
|
||||||
|
private String state;
|
||||||
|
private String country;
|
||||||
|
@JSONField(name = "registered_address")
|
||||||
|
private String registeredAddress;
|
||||||
|
@JSONField(name = "registered_suburb")
|
||||||
|
private String registeredSuburb;
|
||||||
|
@JSONField(name = "registered_postcode")
|
||||||
|
private String registeredPostcode;
|
||||||
|
@JSONField(name = "registered_state")
|
||||||
|
private String registeredState;
|
||||||
|
private String timezone;
|
||||||
|
|
||||||
|
private static java.util.regex.Pattern TIMEZONE_PATTERN = java.util.regex.Pattern.compile("^((Australia/West)|(Australia/Eucla)|(Australia/North)|(Australia/South)|(Australia/Brisbane)|(Australia/Melbourne)|(Australia/LHI))$");
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Matcher matcher = TIMEZONE_PATTERN.matcher(timezone);
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Timezone not acceptable!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject contractInfo() {
|
||||||
|
JSONObject contract = (JSONObject) JSON.toJSON(this);
|
||||||
|
if (StringUtils.equalsIgnoreCase(state, "OTHER")) {
|
||||||
|
contract.put("state", "其他(Other)");
|
||||||
|
}
|
||||||
|
return contract;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject legalAddressInfo() {
|
||||||
|
JSONObject address = new JSONObject();
|
||||||
|
address.put("address", registeredAddress);
|
||||||
|
address.put("suburb", registeredSuburb);
|
||||||
|
address.put("postcode", registeredPostcode);
|
||||||
|
if (StringUtils.equalsIgnoreCase(registeredState, "OTHER")) {
|
||||||
|
address.put("state", "其他(Other)");
|
||||||
|
}
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientLegalConfig {
|
||||||
|
|
||||||
|
@JSONField(name = "legal_representative_person")
|
||||||
|
private String representativePerson ;
|
||||||
|
@JSONField(name = "legal_representative_phone")
|
||||||
|
private String representativePhone;
|
||||||
|
@JSONField(name = "legal_representative_email")
|
||||||
|
private String representativeEmail;
|
||||||
|
@JSONField(name = "legal_representative_job")
|
||||||
|
private String representativeJobTitle;
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject clientLegalInfo() {
|
||||||
|
JSONObject legal = new JSONObject();
|
||||||
|
legal.put("representative_person", representativePerson);
|
||||||
|
legal.put("job_title", representativeJobTitle);
|
||||||
|
legal.put("phone", representativePhone);
|
||||||
|
legal.put("email", representativeEmail);
|
||||||
|
return legal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientPayConfig {
|
||||||
|
@JSONField(name = "client_pay_type")
|
||||||
|
private String clientPayType;
|
||||||
|
@JSONField(name = "client_pay_desc")
|
||||||
|
private String clientPayDesc;
|
||||||
|
@JSONField(name = "royalpay_industry")
|
||||||
|
private String royalpayindustry;
|
||||||
|
@JSONField(name = "wechat_industry")
|
||||||
|
private String wechatindustry;
|
||||||
|
@JSONField(name = "alipay_industry")
|
||||||
|
private String alipayindustry;
|
||||||
|
@JSONField(name = "company_photo")
|
||||||
|
private String companyPhoto;
|
||||||
|
@JSONField(name = "store_photo")
|
||||||
|
private String storePhoto;
|
||||||
|
@JSONField(name = "company_website")
|
||||||
|
private String companyWebsite;
|
||||||
|
|
||||||
|
private static String[] WHITE_LIST = {"companyWebsite","store_photo", "company_photo"};
|
||||||
|
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null && !Arrays.asList(WHITE_LIST).contains(field.getName())) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (clientPayType.indexOf("1") != -1) {
|
||||||
|
if (StringUtils.isBlank(companyWebsite)) {
|
||||||
|
throw new ParamInvalidException("company_website", "Required Param company_website not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (clientPayType.indexOf("2") != -1) {
|
||||||
|
if (StringUtils.isBlank(companyPhoto)) {
|
||||||
|
throw new ParamInvalidException("company_photo", "Required Param company_photo not found");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(storePhoto)) {
|
||||||
|
throw new ParamInvalidException("store_photo", "Required Param store_photo not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject payConfig() {
|
||||||
|
JSONObject config = (JSONObject) JSON.toJSON(this);
|
||||||
|
config.put("alipayindustry", alipayindustry);
|
||||||
|
config.put("industry", wechatindustry);
|
||||||
|
config.put("royalpayindustry", royalpayindustry);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by yixian on 2016-06-29.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ClientRegisterInfo {
|
||||||
|
private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
@JSONField(name = "apply_id")
|
||||||
|
private String applyId;
|
||||||
|
@JSONField(name = "parent_partner_code")
|
||||||
|
private String parentPartnerCode;
|
||||||
|
@JSONField(name = "notify_url")
|
||||||
|
private String notifyUrl;
|
||||||
|
@JSONField(name = "company_info")
|
||||||
|
private ClientCompanyConfig companyConfig;
|
||||||
|
@JSONField(name = "contact_info")
|
||||||
|
private ClientContactConfig contactConfig;
|
||||||
|
@JSONField(name = "legal_info")
|
||||||
|
private ClientLegalConfig legalConfig;
|
||||||
|
@JSONField(name = "pay_info")
|
||||||
|
private ClientPayConfig payConfig;
|
||||||
|
@JSONField(name = "settle_info")
|
||||||
|
private ClientSettleConfig settleConfig;
|
||||||
|
@JSONField(name = "compliance_file_info")
|
||||||
|
private ClientComplianceFileConfig complianceFileConfig;
|
||||||
|
|
||||||
|
private static String[] WHITE_LIST = {"parentPartnerCode", "notifyUrl"};
|
||||||
|
|
||||||
|
public void checkParamsInvalid() {
|
||||||
|
try {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null && !Arrays.asList(WHITE_LIST).contains(field.getName())) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
companyConfig.checkParamsInvalid();
|
||||||
|
contactConfig.checkParamsInvalid();
|
||||||
|
legalConfig.checkParamsInvalid();
|
||||||
|
payConfig.checkParamsInvalid();
|
||||||
|
settleConfig.checkParamsInvalid();
|
||||||
|
complianceFileConfig.checkParamsInvalid();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.error("gateway api register client error : {}", e.getMessage());
|
||||||
|
throw new BadRequestException("Params Format Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertClientInfo(String clientMoniker, String bdUserName, boolean hasParentBoolean, int parentClientId) {
|
||||||
|
JSONObject client = new JSONObject();
|
||||||
|
client.putAll(companyConfig.basicInfo());
|
||||||
|
client.put("logo_thumbnail", companyConfig.getLogoId());
|
||||||
|
client.putAll(contactConfig.contractInfo());
|
||||||
|
client.putAll(payConfig.payConfig());
|
||||||
|
client.put("create_time", new Date());
|
||||||
|
client.put("ali_sub_merchant_id", clientMoniker);
|
||||||
|
client.put("credential_code", RandomStringUtils.random(32, true, true));
|
||||||
|
client.put("creator", applyId);
|
||||||
|
client.put("bd_user", applyId);
|
||||||
|
client.put("bd_user_name", bdUserName);
|
||||||
|
client.put("client_moniker", clientMoniker);
|
||||||
|
if (hasParentBoolean && parentClientId != 0) {
|
||||||
|
client.put("parent_client_id", parentClientId);
|
||||||
|
}
|
||||||
|
client.put("source", 5);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertClientConfigInfo(int clientId, String clientMoniker) {
|
||||||
|
JSONObject clientConfig = new JSONObject();
|
||||||
|
clientConfig.putAll(payConfig.payConfig());
|
||||||
|
clientConfig.put("notify_url", notifyUrl);
|
||||||
|
clientConfig.put("client_id", clientId);
|
||||||
|
clientConfig.put("client_moniker", clientMoniker);
|
||||||
|
return clientConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertClientLegalInfo(int clientId) {
|
||||||
|
JSONObject clientLegalInfo = new JSONObject();
|
||||||
|
clientLegalInfo.putAll(legalConfig.clientLegalInfo());
|
||||||
|
clientLegalInfo.putAll(contactConfig.legalAddressInfo());
|
||||||
|
clientLegalInfo.put("client_id", clientId);
|
||||||
|
return clientLegalInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertBankInfo(int clientId) {
|
||||||
|
JSONObject bankInfo = settleConfig.insertBankInfo();
|
||||||
|
bankInfo.put("client_id", clientId);
|
||||||
|
return bankInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientAuthFilesInfo insertClientComplianceInfo() {
|
||||||
|
ClientAuthFilesInfo file = new ClientAuthFilesInfo();
|
||||||
|
file.setFile_bank_info(complianceFileConfig.getBankStatement());
|
||||||
|
file.setFile_id_info(complianceFileConfig.getId());
|
||||||
|
file.setFile_company_info(complianceFileConfig.getCertOfRegistration());
|
||||||
|
file.setUtility_bill_info(complianceFileConfig.getUtilityBill());
|
||||||
|
file.setId_type(complianceFileConfig.getIdType());
|
||||||
|
file.setBeneficiary_id_title(complianceFileConfig.getIdTitle());
|
||||||
|
file.setOther_id_title_desc(complianceFileConfig.getIdTitleDesc());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertClientRateInfo(JSONObject defaultRateConfig) {
|
||||||
|
JSONObject rate = new JSONObject();
|
||||||
|
rate.put("clean_days", settleConfig.getCleanDays());
|
||||||
|
rate.put("active_time", settleConfig.getActiveTime());
|
||||||
|
rate.put("expiry_time", settleConfig.getExpireTime());
|
||||||
|
rate.put("wechat_rate_value", settleConfig.getWechatRate());
|
||||||
|
rate.put("alipay_rate_value", settleConfig.getAlipayRate());
|
||||||
|
rate.put("alipayonline_rate_value", settleConfig.getAlipayOnlineRate());
|
||||||
|
rate.put("bestpay_rate_value", getDefaultRate(defaultRateConfig, String.valueOf(settleConfig.getCleanDays()),"Bestpay"));
|
||||||
|
rate.put("jd_rate_value", getDefaultRate(defaultRateConfig, String.valueOf(settleConfig.getCleanDays()),"JDpay"));
|
||||||
|
rate.put("Rpay_rate_value", getDefaultRate(defaultRateConfig, String.valueOf(settleConfig.getCleanDays()),"Rpay"));
|
||||||
|
rate.put("cb_bankpay_rate_value", getDefaultRate(defaultRateConfig, String.valueOf(settleConfig.getCleanDays()),"CB_Bankpay"));
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDefaultRate(JSONObject defaultRateConfig, String cleanDays, String rateKey) {
|
||||||
|
JSONObject config = defaultRateConfig.getJSONObject("t" + cleanDays);
|
||||||
|
return config.getString(rateKey);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.beans;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClientSettleConfig {
|
||||||
|
@JSONField(name = "swift_code")
|
||||||
|
private String swiftCode;
|
||||||
|
@JSONField(name = "bsb_no")
|
||||||
|
private String bsbNo;
|
||||||
|
private String bank;
|
||||||
|
private String city;
|
||||||
|
private String address;
|
||||||
|
private String system;
|
||||||
|
private String postcode;
|
||||||
|
private String state;
|
||||||
|
private String branch;
|
||||||
|
@JSONField(name = "account_no")
|
||||||
|
private String accountNo;
|
||||||
|
@JSONField(name = "account_name")
|
||||||
|
private String accountName;
|
||||||
|
@JSONField(name = "clean_days")
|
||||||
|
private int cleanDays;
|
||||||
|
@JSONField(name = "wechat_rate")
|
||||||
|
private String wechatRate;
|
||||||
|
@JSONField(name = "alipay_rate")
|
||||||
|
private String alipayRate;
|
||||||
|
@JSONField(name = "alipay_online_rate")
|
||||||
|
private String alipayOnlineRate;
|
||||||
|
@JSONField(name = "transaction_fee")
|
||||||
|
private String transactionFee;
|
||||||
|
@JSONField(name = "active_time")
|
||||||
|
private String activeTime;
|
||||||
|
@JSONField(name = "expire_time")
|
||||||
|
private String expireTime;
|
||||||
|
|
||||||
|
|
||||||
|
private static Pattern ACCOUNT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9 &]+$");
|
||||||
|
|
||||||
|
public void checkParamsInvalid() throws IllegalAccessException {
|
||||||
|
for (Field field : getClass().getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
if (field.get(this) == null) {
|
||||||
|
throw new ParamInvalidException(field.getName(), "Required Param " + field.getName() +" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject insertBankInfo() {
|
||||||
|
JSONObject bankInfo = new JSONObject();
|
||||||
|
if (swiftCode.length() > 12) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Switft code must be less than 12 characters");
|
||||||
|
}
|
||||||
|
if (bsbNo.length() > 6) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:BSB No must be less than 6 characters");
|
||||||
|
}
|
||||||
|
if (accountNo.length() > 20) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Account No must be less than 20 characters");
|
||||||
|
}
|
||||||
|
if (accountName.length() > 50) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Account Name must be less than 50 characters");
|
||||||
|
}
|
||||||
|
Matcher matcher = ACCOUNT_NAME_PATTERN.matcher(accountName);
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Invalid Account Name format");
|
||||||
|
}
|
||||||
|
bankInfo.put("swift_code", swiftCode);
|
||||||
|
bankInfo.put("bsb_no", bsbNo);
|
||||||
|
bankInfo.put("account_no", accountNo);
|
||||||
|
bankInfo.put("account_name", accountName);
|
||||||
|
bankInfo.put("bank", bank);
|
||||||
|
bankInfo.put("city", city);
|
||||||
|
bankInfo.put("address", address);
|
||||||
|
bankInfo.put("system", system);
|
||||||
|
bankInfo.put("postcode", postcode);
|
||||||
|
bankInfo.put("state", state);
|
||||||
|
bankInfo.put("branch", branch);
|
||||||
|
return bankInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.core;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
public interface GatewayMerchantApply {
|
||||||
|
|
||||||
|
JSONObject validOrgV200(String shortId);
|
||||||
|
|
||||||
|
JSONObject applicationMerchant(JSONObject org, JSONObject registerInfo);
|
||||||
|
|
||||||
|
JSONObject getMerchantStatus(JSONObject org, String clientMoniker);
|
||||||
|
|
||||||
|
void notifyOrgMerchantStatus(JSONObject client);
|
||||||
|
}
|
@ -0,0 +1,255 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.core.impls;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.InvalidShortIdException;
|
||||||
|
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
|
||||||
|
import au.com.royalpay.payment.manage.gateway.beans.ClientRegisterInfo;
|
||||||
|
import au.com.royalpay.payment.manage.gateway.core.GatewayMerchantApply;
|
||||||
|
import au.com.royalpay.payment.manage.management.sysconfig.core.impls.PermissionPartnerManagerImpl;
|
||||||
|
import au.com.royalpay.payment.manage.mappers.log.GatewayClientApplyNotifyLogMapper;
|
||||||
|
import au.com.royalpay.payment.manage.mappers.system.*;
|
||||||
|
import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo;
|
||||||
|
import au.com.royalpay.payment.manage.merchants.core.ClientManager;
|
||||||
|
import au.com.royalpay.payment.manage.system.core.impl.ClientContractServiceImpl;
|
||||||
|
import au.com.royalpay.payment.tools.env.SysConfigManager;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
|
||||||
|
import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor;
|
||||||
|
import cn.yixblog.platform.http.HttpRequestGenerator;
|
||||||
|
import cn.yixblog.platform.http.HttpRequestResult;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.*;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static au.com.royalpay.payment.tools.codec.RSACrypt.loadPrivateKey;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GatewayMerchantApplyImpl implements GatewayMerchantApply {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(ClientContractServiceImpl.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrgMapper orgMapper;
|
||||||
|
@Resource
|
||||||
|
private OrgSignInfoMapper orgSignRsaMapper;
|
||||||
|
@Resource
|
||||||
|
private ClientMapper clientMapper;
|
||||||
|
@Resource
|
||||||
|
private ManagerMapper managerMapper;
|
||||||
|
@Resource
|
||||||
|
private ClientConfigMapper clientConfigMapper;
|
||||||
|
@Resource
|
||||||
|
private SysClientLegalPersonMapper sysClientLegalPersonMapper;
|
||||||
|
@Resource
|
||||||
|
private PermissionPartnerManagerImpl permissionPartnerManagerImpl;
|
||||||
|
@Resource
|
||||||
|
private ClientBDMapper clientBDMapper;
|
||||||
|
@Resource
|
||||||
|
private ClientBankAccountMapper clientBankAccountMapper;
|
||||||
|
@Resource
|
||||||
|
private ClientManager clientManager;
|
||||||
|
@Resource
|
||||||
|
private SysConfigManager sysConfigManager;
|
||||||
|
@Resource
|
||||||
|
private RoyalThreadPoolExecutor royalThreadPoolExecutor;
|
||||||
|
@Resource
|
||||||
|
private GatewayClientApplyNotifyLogMapper gatewayClientApplyNotifyLogMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject validOrgV200(String shortId) {
|
||||||
|
JSONObject orgSignJson = orgSignRsaMapper.findOrgSignInfo(shortId);
|
||||||
|
JSONObject org = orgMapper.findOne(orgSignJson.getInteger("org_id"));
|
||||||
|
if (org == null) {
|
||||||
|
throw new InvalidShortIdException();
|
||||||
|
}
|
||||||
|
return org;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public JSONObject applicationMerchant(JSONObject org, JSONObject registerInfo) {
|
||||||
|
ClientRegisterInfo registerBean = JSONObject.toJavaObject(registerInfo, ClientRegisterInfo.class);
|
||||||
|
registerBean.checkParamsInvalid();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject manager = managerMapper.findAvailableByLoginId(registerBean.getApplyId());
|
||||||
|
if (manager == null) {
|
||||||
|
throw new ParamInvalidException("applyId","applyId is invalid");
|
||||||
|
}
|
||||||
|
boolean hasParentBoolean = StringUtils.isNotBlank(registerBean.getParentPartnerCode());
|
||||||
|
int parentClientId = 0;
|
||||||
|
if (hasParentBoolean) {
|
||||||
|
JSONObject parentClient = clientMapper.findClientByMoniker(registerBean.getParentPartnerCode());
|
||||||
|
if (parentClient == null) {
|
||||||
|
throw new ParamInvalidException("parentPartnerCode","parentPartnerCode is invalid");
|
||||||
|
}
|
||||||
|
parentClientId = parentClient.getIntValue("client_id");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
JSONObject client = registerBean.insertClientInfo(clientManager.initMerchantCode(), manager.getString("display_name"), hasParentBoolean, parentClientId);
|
||||||
|
client.put("org_id", org.getString("org_id"));
|
||||||
|
clientMapper.save(client);
|
||||||
|
clientConfigMapper.save(registerBean.insertClientConfigInfo(client.getIntValue("client_id"),client.getString("client_moniker")));
|
||||||
|
sysClientLegalPersonMapper.save(registerBean.insertClientLegalInfo(client.getIntValue("client_id")));
|
||||||
|
permissionPartnerManagerImpl.permissionClientModuleSave(client.getIntValue("client_id"), client.getString("client_moniker"));
|
||||||
|
JSONObject clientBd = new JSONObject();
|
||||||
|
clientBd.put("client_id", client.getIntValue("client_id"));
|
||||||
|
clientBd.put("bd_id", manager.getString("manager_id"));
|
||||||
|
clientBd.put("bd_name", manager.getString("display_name"));
|
||||||
|
clientBd.put("create_time", new Date());
|
||||||
|
clientBd.put("create_id", manager.getString("manager_id"));
|
||||||
|
clientBd.put("start_date", new Date());
|
||||||
|
clientBd.put("proportion", 1);
|
||||||
|
clientBDMapper.saveBD(clientBd);
|
||||||
|
clientBankAccountMapper.save(registerBean.insertBankInfo(client.getIntValue("client_id")));
|
||||||
|
//todo 合规文件待增加source_agree_file
|
||||||
|
ClientAuthFilesInfo clientAuthFilesInfo = registerBean.insertClientComplianceInfo();
|
||||||
|
clientManager.uploadAuthFiles(manager, client.getString("client_moniker"), clientAuthFilesInfo);
|
||||||
|
JSONObject rateConfig = registerBean.insertClientRateInfo(JSONObject.parseObject(sysConfigManager.getSysConfig().getString("sys_rates")));
|
||||||
|
clientManager.newConfigRate(manager, client.getString("client_moniker"), rateConfig);
|
||||||
|
clientManager.commitToCompliance(client.getString("client_moniker"), manager);
|
||||||
|
result.put("parnter_code", client.getString("client_moniker"));
|
||||||
|
result.put("credential_code", client.getString("credential_code"));
|
||||||
|
result.put("company_name", client.getString("company_name"));
|
||||||
|
result.put("short_name", client.getString("short_name"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("gateway api register fail :{}", e.getMessage());
|
||||||
|
throw new BadRequestException("PARAM_ERROR:Params length too long");
|
||||||
|
}
|
||||||
|
result.put("partner_status", "PROCESSING");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getMerchantStatus(JSONObject org, String clientMoniker) {
|
||||||
|
JSONObject client = clientMapper.findClientByMoniker(clientMoniker);
|
||||||
|
if (client == null) {
|
||||||
|
throw new InvalidShortIdException();
|
||||||
|
}
|
||||||
|
if (client.getIntValue("org_id") != org.getIntValue("org_id")) {
|
||||||
|
logger.error("This client was not belong to your organization,queryClient:{},orgID:{}", clientMoniker, org.getIntValue("org_id"));
|
||||||
|
throw new InvalidShortIdException();
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("partner_code", clientMoniker);
|
||||||
|
result.put("credential_code", client.getString("credential_code"));
|
||||||
|
result.put("company_name", client.getString("company_name"));
|
||||||
|
result.put("short_name", client.getString("short_name"));
|
||||||
|
result.put("apply_time", DateFormatUtils.format(client.getDate("create_time"), "yyyy-MM-dd HH:mm:ss"));
|
||||||
|
result.put("apply_id", client.getString("creator"));
|
||||||
|
int approveResult = client.getIntValue("approve_result");
|
||||||
|
String clientStatus = "";
|
||||||
|
switch (approveResult) {
|
||||||
|
case 1:
|
||||||
|
clientStatus = "PASS";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
clientStatus = "PROCESSING";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
clientStatus = "REFUSED";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
clientStatus = "PROCESSING";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.put("partner_status", clientStatus);
|
||||||
|
if ( approveResult == 1 || approveResult == 5) {
|
||||||
|
result.put("approve_time", DateFormatUtils.format(client.getDate("approve_time"), "yyyy-MM-dd HH:mm:ss"));
|
||||||
|
if (approveResult == 5) {
|
||||||
|
result.put("refuse_description", client.getString("refuse_remark"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyOrgMerchantStatus(JSONObject client) {
|
||||||
|
String clientMoniker = client.getString("client_moniker");
|
||||||
|
if (client.getIntValue("source") != 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject clientConfig = clientConfigMapper.find(client.getIntValue("client_id"));
|
||||||
|
if (StringUtils.isBlank(clientConfig.getString("notify_url"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String notifyUrl = clientConfig.getString("notify_url");
|
||||||
|
|
||||||
|
JSONObject org = orgMapper.findOne(client.getInteger("org_id"));
|
||||||
|
JSONObject merchantStatus = getMerchantStatus(org, clientMoniker);
|
||||||
|
merchantStatus.put("nonce_str", RandomStringUtils.random(15, true, true));
|
||||||
|
merchantStatus.put("sign_type", "RSA2");
|
||||||
|
merchantStatus.put("url", notifyUrl);
|
||||||
|
JSONObject signInfo = orgSignRsaMapper.findByOrgId(org.getInteger("org_id"));
|
||||||
|
String signStr = sign(JSONObject.toJSONBytes(merchantStatus, SerializerFeature.MapSortField), signInfo.getString("platform_private_key"));
|
||||||
|
JSONObject respJson = new JSONObject();
|
||||||
|
respJson.put("data", merchantStatus);
|
||||||
|
respJson.put("sign", signStr);
|
||||||
|
logger.info("ApiV2 Response : {}", JSONObject.toJSONString(respJson, SerializerFeature.MapSortField));
|
||||||
|
JSONObject log = preInsertServerNotifyLog(client, notifyUrl);
|
||||||
|
royalThreadPoolExecutor.execute(() -> {
|
||||||
|
logger.debug("开始推送商户状态[{}]异步通知[{}]:", clientMoniker, notifyUrl);
|
||||||
|
HttpRequestGenerator gen = new HttpRequestGenerator(notifyUrl, RequestMethod.POST);
|
||||||
|
gen.setJSONEntity(respJson);
|
||||||
|
HttpRequestResult result = gen.execute();
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
log.put("success", true);
|
||||||
|
log.put("http_code", result.getStatusCode());
|
||||||
|
log.put("updatetime", new Date());
|
||||||
|
gatewayClientApplyNotifyLogMapper.update(log);
|
||||||
|
logger.debug("商户状态[{}]异步通知[{}]推送完成:[{}]", clientMoniker, notifyUrl, result.getStatusCode());
|
||||||
|
}else {
|
||||||
|
Throwable exp = result.getException();
|
||||||
|
log.put("success", false);
|
||||||
|
log.put("http_code", result.getStatusCode());
|
||||||
|
log.put("err_msg", exp == null ? null : exp.getMessage());
|
||||||
|
log.put("updatetime", new Date());
|
||||||
|
gatewayClientApplyNotifyLogMapper.update(log);
|
||||||
|
logger.debug("商户状态[{}]异步通知[{}]推送失败:[{}]-[{}]", clientMoniker, notifyUrl, result.getStatusCode(), exp.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject preInsertServerNotifyLog(JSONObject client,String notifyUrl) {
|
||||||
|
int clientId = client.getIntValue("client_id");
|
||||||
|
JSONObject log = gatewayClientApplyNotifyLogMapper.findHistoryByClientId(clientId);
|
||||||
|
if (log == null) {
|
||||||
|
log = new JSONObject();
|
||||||
|
log.put("org_id", client.getString("org_id"));
|
||||||
|
log.put("client_id", clientId);
|
||||||
|
log.put("notify_url", notifyUrl);
|
||||||
|
log.put("addtime", new Date());
|
||||||
|
log.put("success", 0);
|
||||||
|
log.put("http_code", 0);
|
||||||
|
gatewayClientApplyNotifyLogMapper.saveLog(log);
|
||||||
|
}
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sign(byte[] source, String privateKey) {
|
||||||
|
try {
|
||||||
|
PrivateKey priKey = loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8)));
|
||||||
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||||
|
signature.initSign(priKey);
|
||||||
|
signature.update(source);
|
||||||
|
byte[] signed = signature.sign();
|
||||||
|
return Base64.encodeBase64URLSafeString(signed);
|
||||||
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
|
//shall never happen
|
||||||
|
throw new ServerErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package au.com.royalpay.payment.manage.gateway.web;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.core.exceptions.InvalidShortIdException;
|
||||||
|
import au.com.royalpay.payment.core.utils.PaymentValidUtils;
|
||||||
|
import au.com.royalpay.payment.manage.gateway.advice.Gtw2Ctrl;
|
||||||
|
import au.com.royalpay.payment.manage.gateway.core.GatewayMerchantApply;
|
||||||
|
import au.com.royalpay.payment.tools.connections.attachment.core.AttachmentClient;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.springframework.validation.Errors;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author taylor
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1.0/gateway/partners/{shortId}")
|
||||||
|
@Gtw2Ctrl
|
||||||
|
public class GtwPayController {
|
||||||
|
@Resource
|
||||||
|
private GatewayMerchantApply gatewayMerchantApply;
|
||||||
|
@Resource
|
||||||
|
private AttachmentClient attachmentClient;
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping(value = "/merchant/application")
|
||||||
|
public JSONObject applicationMerchant(@RequestBody JSONObject registerInfo, Errors errors,
|
||||||
|
@PathVariable String shortId) {
|
||||||
|
JSONObject org = gatewayMerchantApply.validOrgV200(shortId);
|
||||||
|
PaymentValidUtils.handleValidErrors(errors);
|
||||||
|
return gatewayMerchantApply.applicationMerchant(org, registerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/merchant/{partner_code}/status")
|
||||||
|
public JSONObject getMerchantStatus(@PathVariable String shortId,
|
||||||
|
@PathVariable String partner_code) {
|
||||||
|
JSONObject org = gatewayMerchantApply.validOrgV200(shortId);
|
||||||
|
return gatewayMerchantApply.getMerchantStatus(org, partner_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/attachment/files")
|
||||||
|
public JSONObject uploadFile(@PathVariable String shortId,@RequestParam MultipartFile file) throws Exception {
|
||||||
|
JSONObject org = gatewayMerchantApply.validOrgV200(shortId);
|
||||||
|
if (org == null) {
|
||||||
|
throw new InvalidShortIdException();
|
||||||
|
}
|
||||||
|
JSONObject fileInfo = attachmentClient.uploadFile(file, false);
|
||||||
|
fileInfo.put("file_type", fileInfo.getString("filetype"));
|
||||||
|
fileInfo.remove("filepath");
|
||||||
|
fileInfo.remove("length");
|
||||||
|
fileInfo.remove("fileid");
|
||||||
|
fileInfo.remove("filetype");
|
||||||
|
fileInfo.put("file_url", fileInfo.getString("url"));
|
||||||
|
return fileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package au.com.royalpay.payment.manage.mappers.log;
|
||||||
|
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.AdvanceSelect;
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper;
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.AutoSql;
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.SqlType;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by davep on 2016-07-22.
|
||||||
|
*/
|
||||||
|
@AutoMapper(tablename = "gateway_clientApply_notify_log", pkName = "id")
|
||||||
|
public interface GatewayClientApplyNotifyLogMapper {
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.INSERT)
|
||||||
|
void saveLog(JSONObject log);
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.UPDATE)
|
||||||
|
void update(JSONObject notice);
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.SELECT)
|
||||||
|
@AdvanceSelect(addonWhereClause = "success=0 and addtime(`addtime`,'24:00:00')>now()")
|
||||||
|
List<JSONObject> listErrorLogsIn24Hour();
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.SELECT)
|
||||||
|
JSONObject findHistoryByClientId(@Param("client_id") int clientId);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package au.com.royalpay.payment.manage.mappers.system;
|
||||||
|
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper;
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.AutoSql;
|
||||||
|
import cn.yixblog.support.mybatis.autosql.annotations.SqlType;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
||||||
|
|
||||||
|
@AutoMapper(tablename = "org_sign_info", pkName = "org_id", keyGenerator = Jdbc3KeyGenerator.class)
|
||||||
|
public interface OrgSignInfoMapper {
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.SELECT)
|
||||||
|
JSONObject findByOrgId(@Param("org_id") int orgId);
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.SELECT)
|
||||||
|
JSONObject findOrgSignInfo(@Param("gateway_short_id") String orgId);
|
||||||
|
|
||||||
|
int getPartnercode(@Param("codes") String codes);
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.UPDATE)
|
||||||
|
void update(JSONObject signInfo);
|
||||||
|
|
||||||
|
@AutoSql(type = SqlType.INSERT)
|
||||||
|
void insert(JSONObject signInfo);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="au.com.royalpay.payment.manage.mappers.system.OrgSignInfoMapper">
|
||||||
|
<select id="getPartnercode" resultType="int">
|
||||||
|
SELECT count(1)
|
||||||
|
FROM org_sign_info
|
||||||
|
where gateway_short_id = #{codes};
|
||||||
|
</select>
|
||||||
|
</mapper>
|
Loading…
Reference in new issue