Merge branch 'master' of gitee.com:super-shopkeeper/chaozhanggui

This commit is contained in:
zhujunshuai 2023-04-12 14:05:07 +08:00
commit 17ec8176fc
31 changed files with 2954 additions and 64 deletions

View File

@ -28,6 +28,7 @@ import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.util.TokenUtil;
import cn.pluss.platform.vo.MemberScanVO;
import cn.pluss.platform.vo.MerchantOrderPosVO;
import cn.pluss.platform.vo.MerchantOrderVO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -49,6 +50,8 @@ import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.*;
import static cn.hutool.poi.excel.sax.AttributeName.s;
@Slf4j
@RestController
@RequiredArgsConstructor
@ -436,10 +439,7 @@ public class MerchantOrderController {
@PostMapping("/posScanPay")
public Result<Object> posScanPay(@RequestBody MerChantOrderDTO merchantOrderDTO) {
//首先验签
Map<String, String> token = TokenUtil.getToken(merchantOrderDTO.getTimestamp(), merchantOrderDTO.getRequestId());
boolean sign = token.get("TOKEN").equals(merchantOrderDTO.getToken());
System.out.println(token);
MsgException.check(!sign,"签名错误");
verify(merchantOrderDTO.getTimestamp(), merchantOrderDTO.getRequestId(), merchantOrderDTO.getAppId(), merchantOrderDTO.getToken());
//通过后查询商户信息
DeviceStock deviceStock = deviceStockService.checkBind(merchantOrderDTO.getSn());
MerchantBaseInfo merchantBaseInfoById = merchantBaseInfoService.getMerchantBaseInfoById(Integer.valueOf(deviceStock.getActMercId()));
@ -451,14 +451,19 @@ public class MerchantOrderController {
}
//进行支付操作
try {
return merchantOrderService.toActivePay(merchantOrderDTO);
Result<Object> activePay = merchantOrderService.toActivePay(merchantOrderDTO);
String result = activePay.toString();
JSONObject jsonData = JSONObject.parseObject(result);
Object orderNumber = jsonData.getJSONObject("data").get("orderNumber");
HashMap<String, Object> map = new HashMap<>();
map.put("orderNumber", orderNumber);
return ResultGenerator.genSuccessResult(map);
} catch (Exception e){
e.printStackTrace();
return ResultGenerator.genFailResult(e.getMessage());
}
}
/**
* 主扫会员支付
* @param memberScanPayDTO
@ -775,6 +780,69 @@ public class MerchantOrderController {
}
return ResultGenerator.genSuccessResult("获取成功",order);
}
@GetMapping("/pos/tradeQuery/{orderNumber}")
@ApiOperation(value = "pos交易订单支付结果查询", notes = "交易订单支付结果查询", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "orderNumber", value = "查询的orderNumber", paramType = "orderNumber", required = true, dataType = "String")})
public Result<Object> posTradeQuery(@PathVariable String orderNumber, String timestamp,
String requestId, String token, String appId) throws Exception {
//首先验签
verify(timestamp, requestId, appId, token);
// 校验参数是否完整
if (StringUtil.isEmpty(orderNumber)) {
return ResultGenerator.genFailResult("无订单号");
}
QueryWrapper<MerchantOrder> queryWrapper = new QueryWrapper<MerchantOrder>()
.eq("orderNumber",orderNumber);
MerchantOrder order = merchantOrderService.getOne(queryWrapper);
if(order == null){
return ResultGenerator.genFailResult("订单数据异常");
}
MerchantOrderPosVO orderPosVO = new MerchantOrderPosVO();
//支付成功
if("1".equals(order.getStatus())){
orderPosVO.setConsumeFee(order.getConsumeFee());
orderPosVO.setStatus(order.getStatus());
orderPosVO.setPayTypeCode(order.getPayTypeCode());
return ResultGenerator.genSuccessResult("获取成功",orderPosVO);
}
String aisleSwitch = order.getAisleSwitch();
MerchantChannelStatus channel = null;
switch (aisleSwitch){
case "2":
channel = merchantChannelStatusMapper.getByMerchantCode(order.getMerchantCode(),1);
break;
default:
channel = merchantChannelStatusMapper.getByMerchantCode(order.getMerchantCode(),Integer.valueOf(aisleSwitch));
break;
}
if(channel != null){
JSONObject result = null;
switch (channel.getChannel()){
case 1:
result = sxfPayService.tradeQuery(order,channel.getMerchantId());
break;
case 3:
result = ryxPayService.tradeQuery(order,channel.getMerchantId());
break;
case 4:
result = ysPayOldService.tradeQuery(order,channel.getMerchantId());
break;
}
if(result != null){
merchantOrderService.updateOrderStatus(result,order);
String status = result.getString("payStatus");
if("1".equals(status)){
order.setStatus("1");
}
}
orderPosVO.setConsumeFee(order.getConsumeFee());
orderPosVO.setStatus(order.getStatus());
orderPosVO.setPayTypeCode(order.getPayTypeCode());
}
return ResultGenerator.genSuccessResult("获取成功", orderPosVO);
}
@GetMapping("/closeOrder")
@ApiOperation(value = "订单关闭", notes = "订单关闭", httpMethod = "POST")
@ -1233,4 +1301,13 @@ public class MerchantOrderController {
List<Map<String, Object>> couponList = merchantOrderService.getCouponList(orderNumber);
return ResultGenerator.genSuccessResult(couponList);
}
public void verify(String timestamp, String requestId, String appId,
String token){
//首先验证签
Map<String, String> tokenMap = TokenUtil.getToken(timestamp, requestId, appId);
boolean sign = tokenMap.get("TOKEN").equals(token);
System.out.println(token);
MsgException.check(!sign,"签名错误");
}
}

View File

@ -2,6 +2,7 @@ package cn.pluss.platform.controller.merchant.callback;
import cn.hutool.crypto.symmetric.DES;
import cn.pluss.platform.channel.MerchantAuditService;
import cn.pluss.platform.channel.ys.YSAuditServiceV3;
import cn.pluss.platform.entity.RyxAccessModel;
import cn.pluss.platform.ryx.RyxService;
import cn.pluss.platform.ys.impl.v20210929.YsConfigV2;
@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ExecutorService;
/**
* @author DJH
@ -45,6 +47,10 @@ public class AuditCallbackController {
@Autowired
private YsConfigV2 ysConfig;
@Autowired
private YSAuditServiceV3 ysAuditServiceV3;
@Autowired
private ExecutorService executorService;
@PostMapping("sxf")
// TODO 后续需要接sxf的回调
@ -75,6 +81,30 @@ public class AuditCallbackController {
ysAuditServiceV2.merchantAuditCallback(respJson);
return "success";
}
@PostMapping("/ysV3")
public String ysAuditCallbackV3(@RequestBody JSONObject result) throws Exception {
log.info("云商服V3进件接口回调参数{}",result.toJSONString());
executorService.execute(() -> {
try {
ysAuditServiceV3.callback(result);
} catch (Exception e) {
e.printStackTrace();
}
});
return "success";
}
@PostMapping("/ysSignV3")
public String ysSignV3(@RequestBody JSONObject result) throws Exception {
log.info("云商服V3签约接口回调参数{}",result.toJSONString());
executorService.execute(() -> {
try {
ysAuditServiceV3.callback(result);
} catch (Exception e) {
e.printStackTrace();
}
});
return "success";
}
/**
* 审核不通过的解密data数据

View File

@ -56,6 +56,7 @@ public class TokenRegistryInterceptor extends HandlerInterceptorAdapter {
limitUri.add("/api/open/login");
limitUri.add("/api/index.html");
limitUri.add("/api/merchantOrder/posScanPay");
limitUri.add("/api/merchantOrder/pos/tradeQuery");
boolean passFlag = limitUri.stream().anyMatch(s -> s.equals(requestUri) || requestUri.startsWith(s));
if (passFlag) {
return true;

View File

@ -34,11 +34,11 @@ public class TokenUtil {
* @param requestId 请求ID自定义
* @return
*/
public static Map<String, String> getToken(String timestamp, String requestId) {
public static Map<String, String> getToken(String timestamp, String requestId,String appId) {
String token = "";
String encode = "";
SortedMap<String, Object> map = new TreeMap();
map.put("appId", APP_ID);
map.put("appId", appId);
map.put("timestamp", timestamp);
map.put("requestId", requestId);
Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
@ -62,7 +62,7 @@ public class TokenUtil {
System.out.println(s);
String s1 = UUID.randomUUID().toString();
System.out.println(s1);
Map<String, String> token = getToken(s, s1);
Map<String, String> token = getToken(s, s1,APP_SECRET);
System.out.println(token);
}

View File

@ -12,14 +12,14 @@ ys:
## 代理商编号
agentNo:
## 交易发起方编号 武汉融商创赢科技有限公司
srcMerchantNo:
srcMerchantNo: 826521673920090
## 私钥用于签名,对应的公钥给到银盛
priKey:
priKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD2J82Gg79Tk8HZ9Zl7EOeLwvUn41c4ktUg6jveIhYLhT/PW5hpPAtgKXd9BvhtpfXhzbK6U9UURKhBgFIkQ+oIJQNfbB/F2jdVK9ke3IYi0/TXHMnY63x43qxciLeAOt+LxdhHn6ZImV4MsRkPjF/zLsaJrPOPWbc2m4T1yvinfzkrxhZaWn1dj4+IdyO3tA/juXCjydQqKR2kSqJlo6gdT9N3RIJ+ETda2UUahZyYXBfjyxFQEaOXthm6krZH1zBHs510Og6bQJQHjMmTskkslWvj38qPDfsuC4tq0Hgbu3LcyiX9vGYzQoGOaGhDEiNPObdDlOuh5gn0slRmg+PxAgMBAAECggEAJRvrCBRki50C5HD6Kmtp/M/vVYwYYhcAum2ViO9qk2ILNJ+CYpsCvASEVvzuBtm2L8xq3Vw2C1AubXGC8KSsa33o/EG4qIM1REnP+a8VKbr6dlOIuoMFyNMI+QpDX7mAafnxmRqgXuGAJDmupYFsFaU/mRHRxhKoZDsd2FA5HEbuDI9SJp86keE72NHsxyqfDIZyIk3Z8k7HZY2wg3FW+YaOKQBHVA9JYvhfZMeaQ1ymrA0IAqWpUqjLkqAa2Qa6xUsbj+QhvrkBCE48i8duamXKDSOaLfkqTb8IyxOM9eTsFwLVGEuZQrkhrLxdrg5aBPvu81pIJME6SgrquJJ84QKBgQD/MAFLiWU0wDJ4Hqf2jKa5vgrBmCqOsANBc079s8gDXM4zbsG/TjMHPDmiOGZxtDG8937twjYzRv9XpnqyITMArlhWWMhTOJ3r3CTVr/OISgeZKPGjfp+MbeDsOK4OggTVKZmNLx3nKiuc94IlTDOcz5qArVBTxKadWg56f1UGswKBgQD28G+haXxneMhRZozoHPjcfdgtDoZJaVa8XTXw8nvQala5ioU9yesbIAdtD/VR/eWwuMtO4rK1IFxtNZQ/MtSXwqlnKLf1xDJQPuj3kY5mC7H7sn4HGeFDP50VFnPgIaUnB5VwgyYFm8l19AW06OBjlnoBv0dnl1s5u+DgpzQcywKBgQCfeWSVzBtPR/1CTAYzcdqPoVAfg/S0jxK5yFHJAp0wXMMQKVszLq99CgoKcqyyyiV7LkBIXWJ50RipsgRjZZP2DP5vl7Q5LdyjFUR/tiG/PmRZNtkrj2ot3Ez/0rwTnPVgMUsgjB1n5Va0FYljvadTi/nGCIl2kCJ/m1QJAaIlOQKBgGV8TwRxS9ViiEEb+lDyhzxm488wpvPIvQLQ8/hAT65J5bZ/PV81etA9C5BA/Ltjs2A7siKLfJJ/6DxhxrlqdICiWeixjVkN9vePw0LrqTA7IjylELJuamuu2yntflXgvfUaYspIu/mWGufFEAtXodCL6TyKlhf21mEV28e4L+ydAoGAItgCUGbot95QNT1z+9QFN+18AvMnWCNvqanrC4qsk0phjYX9FFwfSCqWVeVm0Q0+2tUrRNcUEcbmlbQToBZq/hSu0nPcZIPvnNxLfW/NY7eVCXIcI5eNPjUIgbRCVMc6w5ukYMxPidOBuRXIt1iq2+iV20/FMbA58sY7AgOiaMw=
## 签名公钥,由银盛提供
pubKey:
## 付款验签公钥,由银盛提供
oldPubKey:
oldPubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7SPkmIUf2auwkgbVchMyfeCDgICuA1GKrSwRbDI24UMVhzDgcIxCUmFG5/DfcPJz0d3oV9Ggkd4/7NmteRvmNnOOGNOnmR6AGEKafDpL1mAdpndmpkAZ0f6OVo3Py5JDg2wt8d+u3dF0AFWwd2rrrqscWvxJVB55DnuZfXl2CyQIDAQAB
## 进件URL前缀v2
auditDomainV2: https://ouser.ysepay.com:6443/

View File

@ -28,8 +28,10 @@ public interface MerchantBaseInfoMapper extends BaseMapper<MerchantBaseInfo> {
@Select("SELECT * FROM tb_pluss_merchant_base_info WHERE userId = #{userId}")
List<MerchantBaseInfo> selectListByUserId(@Param("userId") Serializable userId);
MerchantBaseInfo getByUserId(@Param("userId") String userId);
default MerchantBaseInfo queryMerchantBaseInfo(MerchantBaseInfo merchantBaseInfo) {
default MerchantBaseInfo queryMerchantBaseInfo(MerchantBaseInfo merchantBaseInfo) {
return selectOne(new QueryWrapper<>(merchantBaseInfo));
}

View File

@ -263,7 +263,12 @@
</if>
</where>
</select>
<select id="getByUserId" parameterType="java.lang.String" resultType="cn.pluss.platform.entity.MerchantBaseInfo">
SELECT * from tb_pluss_merchant_base_info
<where>
userId=#{userId}
</where>
</select>
<!-- 根据签约时间查询当前用户的推广商户 -->
<select id="queryMerchantBaseInfoPageCountBySignDt" parameterType="java.util.Map" resultType="java.lang.Integer">

View File

@ -3,6 +3,7 @@ package cn.pluss.platform.controller.merchant;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.channel.MerchantAuditService;
import cn.pluss.platform.channel.ys.YSAuditServiceV3;
import cn.pluss.platform.entity.MerchantChannelStatus;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
@ -28,6 +29,8 @@ public class MerchantChannelStatusController {
@Autowired
private MerchantAuditService ysAuditServiceV2;
@Autowired
private YSAuditServiceV3 ysAuditServiceV3;
/**
* 清理进件驳回信息中的通道数据
@ -59,7 +62,7 @@ public class MerchantChannelStatusController {
@ResponseBody
public Result<Object> openOnlinePay(String merchantCode) {
MerchantChannelStatus mcs = mcsService.getByMerchantCode(merchantCode, 4);
((YsAuditServiceImpl) ysAuditServiceV2).openOnlinePay(mcs);
ysAuditServiceV3.openOnlinePay(mcs);
return ResultGenerator.genSuccessResult("操作成功", null);
}

View File

@ -0,0 +1,278 @@
package cn.pluss.platform.entity;
import cn.pluss.platform.exception.MsgException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.Objects;
@Setter
@Getter
@TableName(value = "tb_pluss_merc_change_record", autoResultMap = true)
public class MercChangeRecord {
@TableId
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 商户基本信息
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private MerchantBaseInfo baseInfo;
@TableField(typeHandler = FastjsonTypeHandler.class)
private MerchantBaseInfo preBaseInfo;
/**
* 法人身份证信息
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private IdCard legalCardInfo;
@TableField(typeHandler = FastjsonTypeHandler.class)
private IdCard preLegalCardInfo;
/**
* 结算身份证信息
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private IdCard idCardInfo;
@TableField(typeHandler = FastjsonTypeHandler.class)
private IdCard preIdCardInfo;
/**
* 结算银行卡信息
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private BankCard bankCardInfo;
@TableField(typeHandler = FastjsonTypeHandler.class)
private BankCard preBankCardInfo;
/**
* 费率信息
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private MerchantRateNew rateInfo;
@TableField(typeHandler = FastjsonTypeHandler.class)
private MerchantRateNew preRateInfo;
private JSONObject ext;
@TableField("changeForm")
private String changeForm;
/**
* 状态0: 待审核1审核中2审核驳回3审核通过
*/
private String status;
public void setStatus(String status) {
this.status = status;
}
public void setStatus(MercChangeRecord.Status status) {
this.setStatus(status.getValue());
}
/**
* 备注信息驳回理由
*/
private String remark;
/**
* 通道业务id
*/
private String applicationId;
/**
* 通道id
*/
private String channelId;
public String getChannelType() {
if ("1".equals(channelId) || "3".equals(channelId)) {
return "D1";
}
if ("4".equals(channelId)) {
return "D0";
}
return null;
}
public String getChannelName() {
if ("1".equals(channelId)) {
return "随行付";
}
if ("3".equals(channelId)) {
return "瑞银信";
}
if ("4".equals(channelId)) {
return "银盛";
}
return null;
}
public String getTitle() {
if ("1".equals(channelId)) {
return "D1次日到账-随行付通道";
}
if ("3".equals(channelId)) {
return "D1次日到账-瑞银信通道";
}
if ("4".equals(channelId)) {
return "D0实时到账-银盛通道";
}
return null;
}
public String getChannelTypeDesc() {
if ("1".equals(channelId) || "3".equals(channelId)) {
return "次日到账";
}
if ("4".equals(channelId)) {
return "实时到账";
}
return null;
}
@TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private String virMerchantId;
/**
* 变更类型
* 1基本信息变更法人信息变更(补充)
* 2结算信息变更
* 3费率变更
* 5结算人信息变更(补充)
*/
private String changeType;
public void setChangeType(String changeType) {
this.changeType = changeType;
}
public void setChangeType(MercChangeRecord.Type changeType) {
this.changeType = changeType.getValue();
}
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 审核出结果时间
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date resultTime;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@Getter
@AllArgsConstructor
public enum Status {
EDIT("0", "编辑中"),
AUDITING("1", "审核中"),
REFUSE("2", "已驳回"),
SUCCESS("3", "通过已生效"),
/**
* 审核通过未生效该状态主要用于随行付变更费率第二天生效的情况
*/
SUCCESS_INVALID("4", "通过未生效"),
/**
* 已过期
*/
EXPIRED("5", "已过期"),
NO_DATA("-1", "未开通");
public static Status getByStatus(String value) {
for (Status status : Status.values()) {
if (status.getValue().equals(value)) {
return status;
}
}
return null;
}
public static Status getAppStatus(String value) {
Status byStatus = getByStatus(value);
if (byStatus == Status.EDIT) {
return Status.AUDITING;
}
return byStatus;
}
private final String value;
private final String desc;
}
@Getter
@AllArgsConstructor
public enum Type {
BASE("1"),
/**
* 结算信息
*/
ACCOUNT("2"),
RATE("3"),
/**
* 营业执照
*/
BLL("4"),
CARD("5"),
ACCOUNT_CARD("52"),
ADDRESS("6"),
/** 交易提额 */
AMOUNT_LIMIT("7"),
/** 远程交易 */
BOUNDARY("8"),
/** 分时结算 */
TIME_OF_USE("9"),
/** 重置报备 */
RESET("10"),
CANCELLATION("11"),
;
private final String value;
public static Type getByValue(String value) {
for (Type type : Type.values()) {
if (Objects.equals(value, type.value)) {
return type;
}
}
throw new MsgException("未知的操作类型");
}
}
}

View File

@ -2,10 +2,14 @@ package cn.pluss.platform.entity;
import cn.pluss.platform.exception.MsgException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.experimental.Accessors;
import java.util.Date;
@ -18,10 +22,60 @@ import java.util.Objects;
@Accessors(chain = true)
public class MerchantChannelStatus {
@Getter
@AllArgsConstructor
public enum AuditStatus {
RESET("0", null, "未开通"),
EXAMINING("1", "-100", "待审核"),
CHANNEL_REQ("1", "-999","进件请求中"),
CHANNEL_EXAMINING("1", null,"通道审核中"),
REJECT("2", null, "已驳回"),
SUCCESS("3", null, "进件通过"),
SIGNING("8", null, "待签约"),
CHANNEL_ARTIFICIAL_EXAMINING("11", null, "通道人工审核中"),
;
public static AuditStatus get(String code, String thirdCode) {
AuditStatus result = null;
for (AuditStatus item : AuditStatus.values()) {
if (Objects.equals(code, item.getCode()) && item.getThirdCode() == null) {
result = item;
}
if (Objects.equals(code, item.getCode()) && Objects.equals(thirdCode, item.getThirdCode())) {
return item;
}
}
if (result == null) {
throw new MsgException("未知的进件状态");
}
return result;
}
public static AuditStatus get(MerchantChannelStatus mcs) {
String mcsStatus = mcs.getStatus();
String mcsThirdStatus = mcs.getThirdStatus();
return get(mcsStatus, mcsThirdStatus);
}
private final String code;
private final String thirdCode;
private final String desc;
}
public static final int VALID_STATUS_BAN = -1;
public static final int VALID_STATUS_NORMAL = 0;
public static final int VALID_STATUS_IN_USE = 1;
/**
* 微信认证授权状态 - 未授权
*/
@ -96,6 +150,9 @@ public class MerchantChannelStatus {
private Integer channel;
@TableField(exist = false)
private String channelName;
private String merchantCode;
private String merchantId;
@ -105,9 +162,11 @@ public class MerchantChannelStatus {
*/
private String status;
@TableField(exist = false)
private String statusDesc;
/**
* 微信认证状态0未认证1已认证
* 微信认证状态, 0: 未认证; 1: 已认证; -1: 不支持
*/
private String authorizationStatus;
@ -117,6 +176,7 @@ public class MerchantChannelStatus {
* @return 简化的状态
*/
public String getAppStatus() {
if (Objects.equals(status, MerchantChannelStatus.AUDIT_STATUS_RESET)
&& Objects.equals(thirdStatus, MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING)) {
return MerchantChannelStatus.AUDIT_STATUS_REJECT;
@ -131,24 +191,20 @@ public class MerchantChannelStatus {
}
if (MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN.equals(status)) {
return MerchantChannelStatus.AUDIT_STATUS_EXAMINING;
return MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN;
}
if (MerchantChannelStatus.AUDIT_STATUS_SIGNED.equals(status)) {
return MerchantChannelStatus.AUDIT_STATUS_EXAMINING;
}
if (MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING.equals(status)) {
return MerchantChannelStatus.AUDIT_STATUS_EXAMINING;
}
return status;
}
public String getStatus() {
if (MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING.equals(status)) {
return MerchantChannelStatus.AUDIT_STATUS_EXAMINING;
}
return status;
}
private String thirdStatus;
private String remark;
@ -159,6 +215,11 @@ public class MerchantChannelStatus {
@TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Date createTime;
/**
* 进件完成时间
*/
private Date auditSuccessTime;
@TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Date updateTime;
@ -173,8 +234,8 @@ public class MerchantChannelStatus {
private String callbackStatus;
/**
* @description:结算类型D0D1T1
* @date: 2021/11/2 15:20
* 结算类型D0D1T1
* @since 2021/11/2 15:20
*/
private String settlementType;
@ -195,8 +256,27 @@ public class MerchantChannelStatus {
/**
* 其他数据
*/
@TableField(whereStrategy = FieldStrategy.NEVER)
private JSONObject extra;
public JSONObject initExtra() {
if (extra == null) {
extra = new JSONObject();
setExtra(extra);
}
return extra;
}
public JSONObject getExtra() {
if (extra == null) {
extra = new JSONObject();
setExtra(extra);
}
return extra;
}
private Integer valid;
/**
@ -205,6 +285,20 @@ public class MerchantChannelStatus {
@TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private String mercName;
/**
* 接口版本
*/
private String interfaceVersion;
/**
* 支付宝认证状态, 0: 未认证; 1: 已认证; -1: 不支持
*/
private String aliAuthorizationStatus;
private String wxCertUrl;
private String aliCertUrl;
/**
* 是否能付款
*
@ -235,7 +329,7 @@ public class MerchantChannelStatus {
}
if (AUDIT_STATUS_EXAMINING.equals(status)) {
MsgException.throwException("进件审核中,请勿重复提交");
MsgException.throwException("进件审核中,请勿重复进件");
}
}
@ -274,31 +368,4 @@ public class MerchantChannelStatus {
MerchantChannelStatus.AUDIT_STATUS_DATA_EDIT.equals(mcs.getStatus()) ||
MerchantChannelStatus.AUDIT_STATUS_FIRST_TRIAL_SUCCESS.equals(mcs.getStatus());
}
/**
* (已进件的)商户当前是否可编辑
* @param mcs 进件记录信息
* @return
*/
public static boolean isAuditedEditable(MerchantChannelStatus mcs) {
if (mcs == null) {
return false;
}
return mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
}
/**
* (未进件的)商户当前是否可编辑
* @param mcs 进件记录信息
* @return
*/
public static boolean isUnauditedEditable(MerchantChannelStatus mcs) {
if (mcs == null) {
return true;
}
return MerchantChannelStatus.AUDIT_STATUS_REJECT.equals(mcs.getStatus()) ||
MerchantChannelStatus.AUDIT_STATUS_RESET.equals(mcs.getStatus());
}
}

View File

@ -81,6 +81,10 @@ public class MerchantImage {
* 租赁合同
*/
public static final String TENANCY_AGREEMENTS = "12";
/**
* 变更申请表
*/
public static final String CHANGE_FORM = "13";
/**
* 结算人身份证正面
*/

View File

@ -0,0 +1,40 @@
package cn.pluss.platform.channel;
import cn.pluss.platform.entity.MerchantChannelStatus;
import cn.pluss.platform.pojo.CombineMercInfo;
import com.alibaba.fastjson.JSONObject;
/**
* 进件流程AOP
*/
public interface MercAuditListener {
/**
* 进件之前的检查操作
* @param userId 用户id
* @param channelId 通道id
*/
void beforeCheck(String userId, Integer channelId);
/**
* 获取商户信息
* @param userId 用户id
* @param channelType D0D1
* @return
*/
CombineMercInfo getMercInfo(String userId, String channelType);
/**
* 进件失败后的操作
* @param userId 用户id
* @param mcs 进件通道相关信息
* @param msg 驳回原因
*/
void onFail(String userId, MerchantChannelStatus mcs, String msg);
/**
* 进件成功后的操作
* @param userId 用户id
*/
void onSuccess(String userId, MerchantChannelStatus mcs);
}

View File

@ -0,0 +1,221 @@
package cn.pluss.platform.channel;
import cn.hutool.core.util.RandomUtil;
import cn.pluss.platform.IdCardService;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.*;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantCashPlaceService;
//import cn.pluss.platform.merchant.edit.MercChangeRecordService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.pojo.CombineMercInfo;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.IpUtils;
import cn.pluss.platform.util.LogExceptionUtils;
import cn.pluss.platform.wx.WxCertService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Service
public class MercAuditListenerImpl implements MercAuditListener {
@Autowired
private MerchantBaseInfoMapper mbiMapper;
@Autowired
private MerchantChannelStatusService mcsService;
@Autowired
private IdCardService idCardService;
@Autowired
private AccountService accountService;
@Autowired
private WxCertService wxCertService;
@Autowired
private NoticeService noticeService;
@Autowired
private GeneralPushUtil generalPushUtil;
@Resource
private UserAppMapper userAppMapper;
@Resource
private UserInfoMapper userInfoMapper;
@Resource
private MerchantStoreMapper merchantStoreMapper;
@Resource
private MerchantImageMapper merchantImageMapper;
@Autowired
private MerchantCashPlaceService cashPlaceService;
@Autowired
private RestTemplate restTemplate;
// @Autowired
// private MercChangeRecordService mcrService;
@Override
public void beforeCheck(String userId, Integer channelId) {
MerchantBaseInfo mbi = mbiMapper.getByUserId(userId);
MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channelId);
if (mcs == null) {
throw new MsgException("商户未发起进件");
}
if (!mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_EXAMINING)) {
throw new MsgException("商户进件状态错误");
}
if (mcs.getThirdStatus().equals(MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING)) {
throw new MsgException("当前商户已经在后台审核中");
}
}
@Override
public CombineMercInfo getMercInfo(String userId, String channelType) {
CombineMercInfo mercInfo = new CombineMercInfo();
MerchantBaseInfo mbi = mbiMapper.getByUserId(userId);
mercInfo.setMbi(mbi);
AccountDTO realAccount = accountService.getRealAccount(userId, channelType);
if (!mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
IdCard legalIdCard = idCardService.getLegalIdCard(userId);
mercInfo.setLegalIdCard(legalIdCard);
} else {
mercInfo.setLegalIdCard(realAccount.getIdcard());
}
mercInfo.setSettleIdCard(realAccount.getIdcard());
mercInfo.setBankCard(realAccount.getBankCard());
return mercInfo;
}
@Override
public void onFail(String userId, MerchantChannelStatus mcs, String msg) {
MerchantBaseInfo mbi = mbiMapper.queryByMerchantCode(mcs.getMerchantCode());
String title2 = "收银呗审核通知";
String msg2;
if (Objects.equals(mcs.getChannel(), 4)) {
msg2 = "商户D0进件驳回" + msg;
} else {
msg2 = "商户进件驳回," + msg;
}
Notice notice2 = new Notice(1, 1, mbi.getUserId());
notice2.setNoticeCode("SHSH_" + System.currentTimeMillis() + RandomUtil.randomString(2));
notice2.setConrtent(msg2);
noticeService.saveMerAuthNotice(notice2);
generalPushUtil.sendAllPlatByAlias(Collections.singletonList(mbi.getUserId() + ""), title2, msg2, "1");
}
@Override
public void onSuccess(String userId, MerchantChannelStatus mcs) {
MerchantBaseInfo mbi = mbiMapper.queryByMerchantCode(mcs.getMerchantCode() + "");
String title = "收银呗审核通知";
String msg;
if (Objects.equals(mcs.getChannel(), 4)) {
msg = "商户D0进件通过完成支付宝及微信认证后即可支持相应渠道收款";
} else {
msg = "商户进件通过,完成支付宝及微信认证后即可支持相应渠道收款";
}
Notice notice = new Notice(1, 1, mbi.getUserId());
notice.setNoticeCode("SHSH_" + System.currentTimeMillis() + RandomUtil.randomString(2));
notice.setConrtent(msg);
noticeService.saveMerAuthNotice(notice);
generalPushUtil.sendAllPlatByAlias(Collections.singletonList(mbi.getUserId() + ""), title, msg, "1");
wxCertService.wxCert(userId, mcs.getMerchantCode(), mcs.getChannel());
// 以下代码为进件结果处理后的操作
// 创建线上店铺
try {
log.info("===================>进件回调,创建店铺开始,商户编号为:{}<=====================", mcs.getMerchantId());
createStore(mcs);
} catch (Exception e) {
e.printStackTrace();
log.info("创建店铺信息异常,异常信息:{}", e.getMessage());
}
try {
MerchantBaseInfo merchantBaseInfo = mbiMapper.queryByMerchantCode(mcs.getMerchantCode());
if (StringUtils.isNotBlank(merchantBaseInfo.getUserId())) {
cashPlaceService.createDefaultCashPlace(Long.parseLong(merchantBaseInfo.getUserId()));
}
} catch (Exception e) {
LogExceptionUtils.printStack(log, e, "创建默认收银点失败,异常信息:{}");
}
}
public void createStore(MerchantChannelStatus merchantChannelStatus) {
UserApp userApp = userAppMapper.selectByMerchantCode(merchantChannelStatus.getMerchantCode());
UserInfo userInfo = userInfoMapper.selectById(userApp.getUserId());
log.info("==============>当前需要同步的用户进件数据为::{}<===================", JSONObject.toJSONString(merchantChannelStatus));
if (userInfo != null) {
MerchantStore merchantStore = new MerchantStore().setMerchantCode(merchantChannelStatus.getMerchantCode());
merchantStore = merchantStoreMapper.selectOne(new QueryWrapper<>(merchantStore));
MerchantBaseInfo merchantBaseInfo = mbiMapper.queryByMerchantCode(merchantChannelStatus.getMerchantCode());
QueryWrapper<MerchantImage> queryWrapper = new QueryWrapper<MerchantImage>()
.eq("merchantCode", merchantChannelStatus.getMerchantCode()).eq("photoType", "06");
MerchantImage merchantImage = merchantImageMapper.selectOne(queryWrapper);
String baseUrl = "https://shop.shouyinbei.net/web/wmerchant.php?c=site&a=entry&ctrl=store&ac=oauth&op=add_merchan&do=web&m=we7_wmall&i=1";
StringBuilder sb = new StringBuilder(baseUrl);
sb.append("&title=").append(merchantBaseInfo.getAlias());
sb.append("&password=").append(userInfo.getPassword().toLowerCase());
sb.append("&mobile=").append(userInfo.getLoginName());
sb.append("&syb_m_id=").append(merchantStore.getId());
sb.append("&addressNo=").append(merchantBaseInfo.getAddressNo());
String address = merchantBaseInfo.getProvince() + merchantBaseInfo.getCity() + merchantBaseInfo.getDistrict() + merchantBaseInfo.getAddress();
String area = merchantBaseInfo.getProvince() +"-"+ merchantBaseInfo.getCity() +"-"+ merchantBaseInfo.getDistrict();
try {
String decodeAddress = URLEncoder.encode(address, "UTF-8");
sb.append("&address=").append(decodeAddress);
String decodeArea = URLEncoder.encode(area, "UTF-8");
sb.append("&area=").append(decodeArea);
String logo = URLEncoder.encode(merchantImage.getPicUrl(), "GBK");
sb.append("&logo=").append(logo);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
log.error("=============>请求生成店铺logo门头照转码异常,异常信息:{}<===============", e.getMessage());
}
Map<String, String> lnxMap = IpUtils.getLocationByAddress(address);
if (lnxMap != null) {
sb.append("&location_x=").append(lnxMap.get("x"));
sb.append("&location_y=").append(lnxMap.get("y"));
}
// 请求生成店铺j
String result = restTemplate.getForObject(sb.toString(), String.class);
log.info("=============>请求生成店铺URL{},请求响应返回的参数为:{}<===============", sb.toString(), result);
}
}
}

View File

@ -0,0 +1,96 @@
package cn.pluss.platform.channel;
import cn.pluss.platform.entity.IdCard;
import cn.pluss.platform.entity.MercChangeRecord;
import cn.pluss.platform.entity.MerchantChannelStatus;
/**
* 进件请求接口定义
* 进件结果接口{@link MerchAuditResultService}
* @author DJH
*/
public interface MerchAuditReqService {
default String getChangeFormEmpty(String merchantId) {
return null;
};
default String getChangeFormDemo() {
return null;
};
default String getCertificateUrlEmpty(String merchantId) {
return null;
}
default String getCertificateUrlDemo() {
return null;
}
default String getCertificateForCorporateEmpty(String merchantId) {
return null;
}
default String getCertificateForCorporateDemo() {
return null;
}
/**
* 进件
* @param userId
*/
void audit(String userId);
void edit(String userId, MercChangeRecord.Type type);
/**
* 变更基本信息
*/
void editBaseInfo(String userId);
/**
* 变更结算卡
* 一般不支持非法人结算卡变更
*/
void editAccountInfo(String userId);
/**
* 修改费率
*/
void editRate(String userId);
/**
* 更新法人身份证
* @param userId
*/
void modifyLegalCard(String userId);
/**
* 更新结算身份证
* @param userId
*/
void modifyAccCard(String userId);
/**
* 修改营业执照
* @param userId 用户ID
*/
void editBusLicense(String userId);
/**
* 签约
*/
void sign(MerchantChannelStatus mcs);
/**
* 通道报备
* @param mcs 进件信息
*/
void report(MerchantChannelStatus mcs);
/**
* 重新报备
* @param mcs 进件信息
*/
void reportAgain(MerchantChannelStatus mcs);
}

View File

@ -0,0 +1,33 @@
package cn.pluss.platform.channel;
import cn.pluss.platform.entity.MerchantChannelStatus;
import com.alibaba.fastjson.JSONObject;
public interface MerchAuditResultService {
/**
* 回调通用回调
* @param jsonObject 回调参数
*/
void callback(JSONObject jsonObject) throws Exception;
/**
* 查询进件结果
* @param userId
*/
void auditResult(String userId);
void auditResult(MerchantChannelStatus mcs);
/**
* 查询签约结果该操作作为商户最终状态的判断
* @param userId 用户id
*/
void signResult(String userId);
/**
* 查询商户变更结果
* @param userId 用户id
*/
void editResult(String userId);
}

View File

@ -0,0 +1,39 @@
package cn.pluss.platform.channel;
import com.alibaba.fastjson.JSONObject;
public interface MerchantAliCertService {
/**
* 支付宝商户认证提交
*/
default void aliCert(String merchantId) {
// 走手动认证该方法为预留方法
}
/**
* 支付宝商户认证撤销
*/
default void aliCertCancel(String merchantId) {
// 走手动认证该方法为预留方法
}
/**
* 支付宝商户认证申请单结果
*/
default void aliCertResult(String merchantId) {
// 走手动认证该方法为预留方法
}
/**
* 支付宝商户认证结果处理
*/
default void aliCertResultHandle(JSONObject wxCertResult) {
// 走手动认证该方法为预留方法
}
/**
* 支付宝商户认证状态
*/
void aliCertStatus(String merchantId);
}

View File

@ -0,0 +1,27 @@
package cn.pluss.platform.channel.ys;
import cn.pluss.platform.entity.MerchantChannelStatus;
import com.alibaba.fastjson.JSONObject;
public interface YSAuditServiceV3 {
/**
* 银盛进件3.0
* @param userId 用户id
*/
void merchantAuditV3(String userId, boolean isFailCheck);
void sign(MerchantChannelStatus mcs);
/**
* 回调通用回调
* @param jsonObject 回调参数
*/
void callback(JSONObject jsonObject) throws Exception;
/**
* 查询进件结果
* @param userId
*/
void auditResult(String userId);
void openOnlinePay(MerchantChannelStatus mcs);
}

View File

@ -0,0 +1,845 @@
package cn.pluss.platform.channel.ys.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.pluss.platform.IdCardService;
import cn.pluss.platform.channel.MercAuditListener;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.AccountMapper;
import cn.pluss.platform.mapper.UserAppMapper;
import cn.pluss.platform.mcc.MccReflectService;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.JftMercPaymentChannelService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantImage.MerchantImageService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.pojo.CombineMercInfo;
import cn.pluss.platform.region.RegionReflectService;
import cn.pluss.platform.subMerchant.SubMerchantService;
import cn.pluss.platform.task.SxfMerAuditHandler;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.SignUtils;
import cn.pluss.platform.ys.YsConfig;
import cn.pluss.platform.ys.impl.v20210929.YsConstant;
import cn.pluss.platform.ys.impl.v20220527.ReqMethod;
import cn.pluss.platform.ys.impl.v20220527.RespEntity;
import cn.pluss.platform.ys.impl.v20220527.YsConfigV3;
import cn.pluss.platform.ys.impl.v20220527.YsServiceV3;
import cn.pluss.platform.ys.impl.v20220527.entity.*;
import cn.pluss.platform.ys.impl.v20220527.service.YsAuditServiceV3;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import static cn.pluss.platform.entity.MerchantBaseInfo.MERCH_TYPE_MICRO;
/**
* @author lyf
*/
@Slf4j
@Service("ysAuditServiceV3")
public class YSAuditServiceV3 implements cn.pluss.platform.channel.ys.YSAuditServiceV3 {
@Autowired
private MerchantBaseInfoService mbiService;
@Resource
private AccountMapper accountMapper;
@Autowired
protected MerchantChannelStatusService mcsService;
@Autowired
private JftMercPaymentChannelService mpcService;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private YsServiceV3 ysServiceV3;
@Autowired
private AccountService accountService;
@Autowired
private IdCardService idCardService;
@Autowired
private YsConfigV3 ysConfigV3;
@Autowired
private RegionReflectService regionReflectService;
@Autowired
private ExecutorService executorService;
@Autowired
private MerchantImageService miService;
@Autowired
private YSAuditServiceV3 self;
@Autowired
private MercAuditListener mercAuditListener;
@Autowired
private NoticeService noticeService;
@Autowired
private GeneralPushUtil generalPushUtil;
@Autowired
private YsConfig ysConfig;
@Autowired
private MccReflectService reflectService;
@Resource
private UserAppMapper userAppMapper;
@Autowired
private SxfMerAuditHandler sxfMerAuditHandler;
@Autowired
private SubMerchantService smService;
@Override
public void merchantAuditV3(String userId, boolean isFailCheck) {
try {
self.step1(userId);
executorService.execute(() -> {
try {
self.step2(userId);
Thread.sleep(10000);
self.step3(userId);
} catch (Exception e) {
e.printStackTrace();
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 4);
if (e instanceof MsgException) {
Serializable obj = ((MsgException) e).getObj();
if (obj instanceof RespEntity) {
mcs.getExtra().putAll((JSONObject) JSON.toJSON(obj));
}
}
if (mcs != null && mcs.getChannel() == 4) {
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_EXAMINING);
mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING);
mcs.setRemark("银盛审核失败: " + e.getMessage());
mcs.setUpdateTime(new Date());
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
mcsService.updateById(mcs);
}
});
}
}
});
} catch (Exception e) {
e.printStackTrace();
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 4);
if (mcs != null && Objects.equals(mcs.getChannel(), 4)) {
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_EXAMINING);
mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING);
mcs.setRemark("银盛审核失败: " + e.getMessage());
mcs.setUpdateTime(new Date());
// 这里将驳回的信息放入新的事务中防止被回滚
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
mcsService.updateById(mcs);
}
});
}
throw e;
}
}
@Override
public void sign(MerchantChannelStatus mcs) {
List<String> excludeStatus = Collections.singletonList(MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(mcs.getStatus()));
if (returnFlag) {
return;
}
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN);
mcsService.updateById(mcs);
JSONObject extra = mcs.getExtra();
String custId = extra.getString("custId");
RateInfo rateInfo = new RateInfo();
rateInfo.setCustId(custId);
rateInfo.setBusOpenType("00|01");
rateInfo.setContractType("2");
rateInfo.setIsSendConMsg("1");
rateInfo.setNotifyUrl(YsConfigV3.AUDIT_SIGN_NOTIFY_URL);
RateFeeInfo rateFeeInfo = new RateFeeInfo();
rateFeeInfo.setAliPayFee(new RateFeeDetail("0", "0.38", "1"));
rateFeeInfo.setWxPayFee(new RateFeeDetail("0", "0.38", "1"));
rateFeeInfo.setBank1debitPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
rateFeeInfo.setBank1creditPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
rateFeeInfo.setBank2debitPayFee(new RateFeeDetail("0", "0.60", "1", "999900"));
rateFeeInfo.setBank2creditPayFee(new RateFeeDetail("0", "0.60", "1"));
RateFeeDetail codeScanD0Fee = new RateFeeDetail("0", "0.10", "1");
rateInfo.setCodeScanD0Fee(codeScanD0Fee);
rateInfo.setCodeScanT1Fee(rateFeeInfo);
RespEntity respEntity = ysServiceV3.req(ReqMethod.sign, (JSONObject) JSON.toJSON(rateInfo));
if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
throw new MsgException("银盛云商服3.0商户签约申请请求失败, {}", respEntity.getSubMsg());
}
JSONObject businessData = JSON.parseObject(respEntity.getBusinessData());
mcs.getExtra().putAll(businessData);
mcsService.updateById(mcs);
Notice notice = new Notice(1, -1, mbi.getUserId());
String uniqueKey = "YS_QY" + System.currentTimeMillis();
String title = "电子协议签约通知";
String content = "尊敬的客户您好,请点此通知完成签约意愿授权。请注意,同意授权后,支付通道才会进行商户资料审核,否则会一直等待审核。";
String url = businessData.getString("signUrl");
notice.setUniqueKey(uniqueKey);
notice.setNoticeCode(uniqueKey);
notice.setTitle(title);
notice.setUrl(url);
notice.setDesc(content);
noticeService.save(notice);
generalPushUtil.sendAllPlatByAlias(Collections.singletonList(mbi.getUserId()), title, content, "1");
}
@Override
public void callback(JSONObject callback) throws Exception {
// String signContent = SignUtils.getSignContent(callback);
// String signStr = callback.getString("sign");
// Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, ysConfig.getOldPubKey());
// boolean verify;
//
// try {
// verify = sign.verify(signContent.getBytes(StandardCharsets.UTF_8), Base64.decode(signStr));
// } catch (Exception e) {
// log.info("回调验签异常");
// e.printStackTrace();
// verify = true;
// }
//
// if (!verify) {
// log.info("银盛云商服3.0回调验签失败");
// throw new MsgException("银盛云商服3.0回调验签失败");
// }
String bizContent = callback.getString("bizContent");
Notify notifyData = JSON.parseObject(bizContent, Notify.class);
switch (notifyData.getNotifyType()) {
case Notify.TYPE_MERC_APPLY:
// 资料确认通知
Notify.Cust cust = notifyData.getCust();
cust.setStatus(notifyData.getStatus());
auditResultHandle(cust);
break;
case Notify.TYPE_MERC_SIGN:
// 签约变更通知
Notify.Auth auth = notifyData.getAuth();
auth.setStatus(notifyData.getStatus());
signResultHandle(auth);
break;
case Notify.TYPE_MERC_CHANGE:
// 商户资料变更通知
case Notify.TYPE_MERC_RATE_CHANGE:
// 商户费率变更通知
Notify.Change change = notifyData.getChange();
change.setStatus(notifyData.getStatus());
// editResultHandle(change);
break;
case Notify.TYPE_MERC_REPORT:
// 报备通知
Notify.Report report = notifyData.getReport();
report.setStatus(notifyData.getStatus());
collectSubMerId(report);
break;
}
}
@Override
public void auditResult(String userId) {
}
public void preCheck(String userId) {
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
LambdaQueryWrapper<MerchantChannelStatus> qWrapper = Wrappers.lambdaQuery();
qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
qWrapper.eq(MerchantChannelStatus::getVirChannelFlag, Account.CHANNEL_TYPE_D1);
MerchantChannelStatus existD1 = mcsService.getOne(qWrapper);
if (existD1 != null && !MerchantChannelStatus.AUDIT_STATUS_SUCCESS.equals(existD1.getStatus()) && !MerchantChannelStatus.AUDIT_STATUS_SIGNED.equals(existD1.getStatus()) && !MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN.equals(existD1.getStatus())) {
throw new MsgException("当前D1通道存在未进件完成的的进件数据不允许进件银盛");
}
if (MERCH_TYPE_MICRO.equals(mbi.getMerchantType())) {
int ysCount = accountMapper.selectYSAuditSmallCount(mbi.getUserId());
if (ysCount >= 2) {
MsgException.throwException("非营业执照商户同一结算人仅可申请两次实时到账");
}
}
qWrapper.clear();
qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
qWrapper.eq(MerchantChannelStatus::getVirChannelFlag, "D0");
MerchantChannelStatus existD0 = mcsService.getOne(qWrapper);
if (existD0 == null) {
qWrapper.clear();
qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
qWrapper.isNull(MerchantChannelStatus::getChannel);
existD0 = mcsService.getOne(qWrapper);
}
if (existD0 != null) {
existD0 = mcsService.getByIdLock(existD0.getId());
if (existD0.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_REJECT)) {
return;
}
if (existD0.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_EXAMINING) && existD0.getThirdStatus().equals(MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING)) {
throw new MsgException("当前商户已经在后台审核中");
}
// 此处先将进件状态锁住
existD0.setChannel(4);
mcsService.saveOrUpdate(existD0);
}
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void step1(String userId) {
MercInfo mercInfo = combineBaseInfo(userId);
RespEntity req = ysServiceV3.req(ReqMethod.addCustInfoApply, (JSONObject) JSONObject.toJSON(mercInfo));
String subCode = req.getSubCode();
if (!Objects.equals(subCode, YsConfigV3.BIZ_SUCCESS)) {
throw new MsgException(req.getSubMsg());
}
preCheck(userId);
MerchantChannelStatus mcs = new MerchantChannelStatus();
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
mcs.setMerchantCode(mbi.getMerchantCode());
mcs.setChannel(4);
mcs = mcsService.getOne(new QueryWrapper<>(mcs));
if (mcs == null) {
mcs = new MerchantChannelStatus();
mcs.setMerchantCode(mcs.getMerchantCode());
mcs.setChannel(4);
}
JSONObject extra = mcs.getExtra();
extra.putAll(JSON.parseObject(req.getBusinessData()));
mcs.setApplicationId(extra.getString("sysFlowId"));
mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING);
//mcs.setInterfaceVersion(YsConfigV3.INTERFACE_VERSION);
mcsService.saveOrUpdate(mcs);
AccountDTO accountDTO = accountService.getRealAccount(userId, Account.CHANNEL_TYPE_D1);
IdCard legalIdCard = idCardService.getLegalIdCard(userId);
//upstreamInfoService.save(mbi, legalIdCard, accountDTO.getIdcard(), accountDTO.getBankCard(), 4);
}
private MercInfo combineBaseInfo(String userId) {
CombineMercInfo combineMercInfo = mercAuditListener.getMercInfo(userId, Account.CHANNEL_TYPE_D0);
LambdaQueryWrapper<MerchantBaseInfo> qWrapper = Wrappers.lambdaQuery();
qWrapper.eq(MerchantBaseInfo::getUserId, userId);
MerchantBaseInfo mbi = mbiService.getOne(qWrapper);
MercInfo mercInfo = new MercInfo();
CustInfo custInfo = new CustInfo();
mercInfo.setCustInfo(custInfo);
//商户基本信息
custInfo.setMercName(mbi.getMerchantName());
custInfo.setMercShortName(mbi.getAlias());
switch (mbi.getMerchantType()) {
case MerchantBaseInfo.MERCH_TYPE_MICRO:
custInfo.setMercType("2");
break;
case MerchantBaseInfo.MERCH_TYPE_INDIVIDUAL:
custInfo.setMercType("3");
break;
case MerchantBaseInfo.MERCH_TYPE_COMPANY:
custInfo.setMercType("4");
break;
default:
throw new MsgException("暂未找到用户类型");
}
MccReflect ysMccReflect = reflectService.getYsMccReflect(mbi.getMcc());
custInfo.setMccCd(mbi.getMcc());
custInfo.setContactMail("chaozhanggui2022@163.com");
custInfo.setCusMgrNm("蔡祥");
custInfo.setNotifyUrl(YsConfigV3.AUDIT_NOTIFY_URL);
custInfo.setAgtMercId(ysConfigV3.getAgentNo());
// custInfo.setRemark("测试商户");
//法人基本信息
CrpInfo crpInfo = new CrpInfo();
mercInfo.setCrpInfo(crpInfo);
IdCard legalIdCard = combineMercInfo.getLegalIdCard();
crpInfo.setCrpCertNo(legalIdCard.getCertNo());
crpInfo.setCrpCertType("00");
crpInfo.setCertBgn(legalIdCard.getCertStartTime().replace("-", ""));
if (legalIdCard.getCertEndTime().equals("长期")) {
crpInfo.setCertExpire("29991231");
} else {
crpInfo.setCertExpire(legalIdCard.getCertEndTime().replace("-", ""));
}
crpInfo.setCrpNm(legalIdCard.getCertName());
BankCard bankCard = combineMercInfo.getBankCard();
crpInfo.setCrpPhone(bankCard.getPhone());
//银行卡相关
StlAccInfo stlAccInfo = new StlAccInfo();
mercInfo.setStlAccInfo(stlAccInfo);
// 非法人授权信息
if (!legalIdCard.getCertNo().equals(combineMercInfo.getSettleIdCard().getCertNo())) {
IdCard idCard = combineMercInfo.getSettleIdCard();
PersonInfo authInfo = new PersonInfo();
authInfo.setName(idCard.getCertName());
authInfo.setCertType("00");
authInfo.setCertNo(idCard.getCertNo());
authInfo.setCertBgn(idCard.getCertStartTime().replace("-", ""));
if (idCard.getCertEndTime().equals("长期")) {
authInfo.setCertExpire("29991231");
} else {
authInfo.setCertExpire(idCard.getCertEndTime().replace("-", ""));
}
crpInfo.setAuthInfo(authInfo);
stlAccInfo.setIsUncrpSett("Y");
stlAccInfo.setBankMobile(bankCard.getPhone());
stlAccInfo.setOpenCertNo(idCard.getCertNo());
}
stlAccInfo.setStlAccNm(bankCard.getBankHolder());
stlAccInfo.setStlAccNo(bankCard.getBankCardNo());
stlAccInfo.setBankSubCode(bankCard.getContactLine());
RegionCodeYs ysRegionCode = regionReflectService.getYsRegionCode(bankCard);
// 由于联行号地址存在对应不上的问题所以这里还是将地区信息给带上
stlAccInfo.setBankProince(ysRegionCode.getProvinceCode());
stlAccInfo.setBankCity(ysRegionCode.getCityCode());
if (bankCard.getAccountType().equals(BankCard.ACCOUNT_TYPE_PRIVATE)) {
stlAccInfo.setStlAccType("11");
} else {
stlAccInfo.setStlAccType("21");
}
//营业执照相关
BusInfo busInfo = new BusInfo();
mercInfo.setBusInfo(busInfo);
if (!mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
busInfo.setBusNm(mbi.getBussAuthName());
busInfo.setBusNo(mbi.getBussAuthNum());
busInfo.setBusCertBgn(mbi.getBussAuthStartTime().replace("-", ""));
//TODO 有时营业执照有效日期没有填写
busInfo.setBusCertExpire(mbi.getBussAuthEndTime().replace("-", ""));
busInfo.setBusAddr(mbi.getBussAuthAddress());
busInfo.setBusCertType("19");
} else {
busInfo.setBusAddr(mbi.getProvince() + mbi.getCity() + mbi.getDistrict() + mbi.getAddress());
}
RegionCodeYs regionData = regionReflectService.getYsRegionCode(mbi.getProvince(), mbi.getCity(), mbi.getDistrict());
busInfo.setBusProviceCode(regionData.getProvinceCode());
busInfo.setBusCityCode(regionData.getCityCode());
busInfo.setBusAreaCode(regionData.getAreaCode());
return mercInfo;
}
/**
* 入网申请流水 sysFlowId
* 备注 note
* 客户号id custId
* 入网状态 status
*/
public void auditResultHandle(Notify.Cust cust) {
String status = cust.getStatus();
String sysFlowId = cust.getSysFlowId();
MerchantChannelStatus mcs = new MerchantChannelStatus();
mcs.setApplicationId(sysFlowId);
mcs.setChannel(4);
mcs = mcsService.getOne(new QueryWrapper<>(mcs));
mcs.setThirdStatus(status);
mcs.getExtra().putAll((JSONObject) JSON.toJSON(cust));
switch (status) {
case YsConfigV3.STATUS_SUCCESS:
mcs.setAuditSuccessTime(new Date());
mcsService.updateById(mcs);
sign(mcs);
break;
case YsConfigV3.STATUS_REFUSE:
List<String> excludeStatus = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_REJECT, MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
MerchantChannelStatus finalMcs = mcs;
boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(finalMcs.getStatus()));
if (returnFlag) {
return;
}
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
String note = cust.getNote();
mcs.setRemark(note);
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
mcsService.updateById(mcs);
mercAuditListener.onFail(mbi.getUserId(), mcs, note);
break;
case YsConfigV3.STATUS_TO_MANUAL:
List<String> excludeStatus2 = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_SUCCESS, MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
MerchantChannelStatus finalMcs2 = mcs;
boolean returnFlag2 = excludeStatus2.stream().anyMatch(s -> s.equals(finalMcs2.getStatus()));
if (returnFlag2) {
return;
}
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
mcsService.updateById(mcs);
break;
}
}
public void step2(String userId) {
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
List<MerchantImage> miList = miService.getListOfMerch(userId, Account.CHANNEL_TYPE_D0);
MerchantChannelStatus mcs = new MerchantChannelStatus();
mcs.setChannel(4);
mcs.setMerchantCode(mbi.getMerchantCode());
mcs = mcsService.getOne(new QueryWrapper<>(mcs));
if (mcs == null) {
throw new MsgException("无法上传图片,无法确认进件信息");
}
for (MerchantImage mi : miList) {
imageUpload(mi.getPhotoType(), mi.getPicUrl(), mcs.getApplicationId());
}
}
public void step3(String userId) {
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 4);
if (mcs == null) {
throw new MsgException("无法确认进件信息");
}
JSONObject param = new JSONObject();
param.put("auditFlag", "Y");
param.put("sysFlowId", mcs.getApplicationId());
RespEntity respEntity = ysServiceV3.req(ReqMethod.auditCustInfoApply, param);
JSONObject bizContent = JSON.parseObject(respEntity.getBusinessData());
mcs.getExtra().putAll(bizContent);
String status = bizContent.getString("status");
if (status == null) {
log.error("银盛云商服3.0进件异常, {}", respEntity.getSubMsg());
return;
}
mcs.setThirdStatus(status);
switch (status) {
case YsConfigV3.STATUS_SUCCESS:
// 这里不做任何处理交给回调操作防止数据错乱
break;
case YsConfigV3.STATUS_REFUSE:
mcs.setRemark(respEntity.getSubMsg());
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
mcsService.updateById(mcs);
mercAuditListener.onFail(mbi.getUserId(), mcs, respEntity.getSubMsg());
break;
case YsConfigV3.STATUS_TO_MANUAL:
mcs.setRemark(respEntity.getSubMsg());
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
mcsService.updateById(mcs);
break;
}
mcsService.updateById(mcs);
}
private void imageUpload(String photoType, String imgUrl, String flowId) {
int count = 0;
while (count < 3) {
count++;
String relPhotoType = imgTypeTransform(photoType);
if (photoType == null) {
throw new MsgException("缺少图片类型");
}
RespEntity respEntity = ysServiceV3.reqUpload(ReqMethod.upload, relPhotoType, imgUrl, flowId);
if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
log.info("第{}次上传失败:{}", count, respEntity.getSubMsg());
} else {
if (photoType.equals(MerchantImage.ImageType.BANK_CARD_FRONT)) {
imageUpload(MerchantImage.ImageType.BANK_CARD_BACK, imgUrl, flowId);
}
return;
}
}
throw new MsgException("图片多次上传失败");
}
public String imgTypeTransform(String imageType) {
if (imageType == null) {
throw new MsgException("图片类型不能为空");
}
switch (imageType) {
case MerchantImage.ImageType.SHOP_FRONT_DOOR:
return "A006";
case MerchantImage.ImageType.STORE_INTERIOR_PHOTO:
return "A007";
case MerchantImage.ImageType.CASH_DESK_PHOTO:
return "A008";
case MerchantImage.ImageType.ACCOUNT_PERMITS:
return "A011";
case MerchantImage.ImageType.BUSINESS_LICENSE:
return "A001";
case MerchantImage.ImageType.IDCARD_FRONT:
return "A002";
case MerchantImage.ImageType.IDCARD_BACK:
return "A003";
case MerchantImage.ImageType.BANK_CARD_FRONT:
return "A004";
case MerchantImage.ImageType.BANK_CARD_BACK:
return "A005";
case MerchantImage.ImageType.SETTLE_IDCARD_FRONT:
return "A013";
case MerchantImage.ImageType.SETTLE_IDCARD_BACK:
return "A014";
case MerchantImage.ImageType.NON_LEG_SETTLE_AUTH:
return "B005";
case MerchantImage.ImageType.CHANGE_FORM:
return "B008";
case MerchantImage.ImageType.CASH_DESK_WITH_PERSON:
return "B009";
}
return null;
}
public void signResultHandle(Notify.Auth authData) {
QueryWrapper<MerchantChannelStatus> qWrapper = Wrappers.query();
qWrapper.eq("extra ->> '$.authId'", authData.getAuthId());
qWrapper.eq("channel", 4);
MerchantChannelStatus mcs = mcsService.getOne(qWrapper);
mcs = mcsService.getByIdLock(mcs.getId());
mcs.getExtra().putAll((JSONObject) JSON.toJSON(authData));
MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
String status = authData.getStatus();
switch (status) {
case YsConfigV3.STATUS_SUCCESS:
if (mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_SUCCESS)) {
return;
}
AccountDTO accountDTO = accountService.getRealAccount(mbi.getUserId(), Account.CHANNEL_TYPE_D0);
String mercId = authData.getMercId();
mcs.setMerchantId(mercId);
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
mcs.setAuditSuccessTime(new Date());
if (mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
mcs.getExtra().put("mercCnm", accountDTO.getIdcard().getCertName());
} else {
mcs.getExtra().put("mercCnm", mbi.getBussAuthName());
}
mcsService.updateById(mcs);
openOnlinePay(mcs);
mercAuditListener.onSuccess(mbi.getUserId(), mcs);
break;
case YsConfigV3.STATUS_REFUSE:
case YsConfigV3.STATUS_SIGN_REFUSE:
List<String> excludeStatus = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_REJECT, MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
MerchantChannelStatus finalMcs = mcs;
boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(finalMcs.getStatus()));
if (returnFlag) {
return;
}
String note = authData.getNote();
mcs.setRemark(note);
mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
mcsService.updateById(mcs);
mercAuditListener.onFail(mbi.getUserId(), mcs, note);
break;
}
}
// public void editResultHandle(Notify.Change changeResult) {
// String status = changeResult.getStatus();
//
// MercChangeRecord entity = mcrService.get(changeResult.getChangeSysFlowId(), 4);
//
// if (entity == null && !Objects.equals(entity.getStatus(), MercChangeRecord.Status.AUDITING.getValue())) {
// return;
// }
//
// if (YsConfigV3.STATUS_SUCCESS.equals(status)) {
// // 变更成功
// entity.setStatus(MercChangeRecord.Status.SUCCESS.getValue());
// mcrService.updateById(entity);
//
// if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
// // 基本信息变更完成
// successChangeBaseInfo(entity, entity.getUserId() + "");
// } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
// // 结算卡变更完成
// successChangeSettlement(entity, entity.getUserId() + "");
// } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
// // 费率变更完成
// successChangeRate(entity, entity.getBaseInfo().getUserId());
// } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
// // TODO 证件补充, 云商服3.0没有该功能
// }
// }
//
// if (YsConfigV3.STATUS_REFUSE.equals(status)) {
// // 变更失败
// entity.setStatus(MercChangeRecord.Status.REFUSE.getValue());
// entity.setRemark(changeResult.getNote());
// mcrService.updateById(entity);
//
// if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
// // 基本信息变更失败
// failChangeBaseInfo(changeResult.getNote(), entity.getUserId() + "");
// } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
// // 结算卡变更失败
// failChangeBankCard(changeResult.getNote(), entity.getUserId() + "");
// } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
// // 费率变更失败
// failChangeRate(changeResult.getNote(), entity.getUserId() + "");
// } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
// // TODO 证件补充, 云商服3.0没有该功能
// }
// }
// }
@Override
public void openOnlinePay(MerchantChannelStatus mcs) {
try {
JSONObject param = new JSONObject();
param.put(YsConstant.MERC_ID, mcs.getMerchantId());
param.put("option", "ON");
param.put("rateFee", "0.38");
param.put("rateBottom", "1");
ysServiceV3.req(ReqMethod.openOnlinePay, param);
} catch (Exception e) {
log.error("云商服3.0开通线上D0接口报错: {}", e.getMessage());
}
}
public void collectSubMerId(Notify.Report report) {
List<Notify.ThirdMerc> thridMercList = report.getThridMercList();
if (thridMercList == null || thridMercList.isEmpty()) {
return;
}
String mercId = report.getMercId();
MerchantChannelStatus mcs = mcsService.getByMerchantId(mercId);
LambdaQueryWrapper<SubMerchant> qWrapper = Wrappers.lambdaQuery();
qWrapper.eq(SubMerchant::getMerchantId, mercId);
smService.remove(qWrapper);
for (Notify.ThirdMerc item : thridMercList) {
String status = item.getApprSts();
String thridMercId = item.getThridMercId();
String reportChannel = item.getReportChannel();
SubMerchant subMerchant = new SubMerchant();
subMerchant.setChannelTypeId("4");
String flagName = "";
String typeName = "";
if (reportChannel.contains("POS")) {
continue;
}
if (reportChannel.contains("WECHAT")) {
subMerchant.setSubMchType("WX");
flagName = "微信";
}
if (reportChannel.contains("ALIPAY")) {
subMerchant.setSubMchType("ZFB");
flagName = "支付宝";
}
if (reportChannel.contains("NUCC")) {
thridMercId += "_NUCC";
typeName = "网联";
}
if (reportChannel.contains("CUPS")) {
thridMercId += "_CUPS";
typeName = "银联";
}
if (Objects.equals("03", status)) {
LambdaQueryWrapper<UserApp> qWrapper2 = Wrappers.lambdaQuery();
qWrapper2.eq(UserApp::getMerchantCode, mcs.getMerchantCode());
qWrapper2.eq(UserApp::getUserType, "promoter");
UserApp userApp = userAppMapper.selectOne(qWrapper2);
String pushMsg = "D0通道" + flagName + typeName + "报备失败,请联系客服进行处理";
sxfMerAuditHandler.sendNotice(userApp, "收银呗审核通知", pushMsg, mcs.getApplicationId());
}
if (Objects.equals("00", status)) {
subMerchant.setMerchantId(mercId);
subMerchant.setStatus(status);
subMerchant.setSubMchId(thridMercId);
subMerchant.setRemark(item.getRemark());
try {
smService.save(subMerchant);
} catch (Exception ignored) {
// 插入报错不处理
}
}
}
}
@Test
public void main(){
JSONObject param = new JSONObject();
param.put("sysFlowId", "APPL202304061707282745251");
RespEntity req = ysServiceV3.req(ReqMethod.queryCustApply, param);
System.out.println(req);
}
}

View File

@ -188,7 +188,8 @@ public class MerchantChannelStatusServiceImpl extends ServiceImpl<MerchantChanne
UserApp userApp = new UserApp().setMerchantCode(merchantCode).setUserType("promoter");
userApp = userAppService.queryUserApp(userApp);
//TODO 微信机器人
//TODO 微信机器人消息推送暂时干掉
//wxTalkService.sendAuditAlert(userApp.getUserId() + "");
}

View File

@ -0,0 +1,20 @@
package cn.pluss.platform.pojo;
import cn.pluss.platform.entity.BankCard;
import cn.pluss.platform.entity.IdCard;
import cn.pluss.platform.entity.MerchantBaseInfo;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class CombineMercInfo {
private MerchantBaseInfo mbi;
private IdCard legalIdCard;
private IdCard settleIdCard;
private BankCard bankCard;
}

View File

@ -7,7 +7,7 @@ import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.channel.BaseMerchantAuditService;
import cn.pluss.platform.channel.MerchantAuditService;
//import cn.pluss.platform.channel.ys.YSAuditServiceV3;
import cn.pluss.platform.channel.ys.YSAuditServiceV3;
import cn.pluss.platform.common.CommonRemarkService;
import cn.pluss.platform.common.RiskBlacklistService;
import cn.pluss.platform.converter.Converter;
@ -174,8 +174,8 @@ public class UserAppServiceImpl extends ServiceImpl<UserAppMapper, UserApp> impl
@Autowired
private UserRoleMapper userRoleMapper;
//@Autowired
//private YSAuditServiceV3 ysAuditServiceV3;
@Setter(onMethod_ = {@Autowired, @Qualifier("ysAuditServiceV3")})
private YSAuditServiceV3 ysAuditServiceV3;
@Override
@ -799,7 +799,7 @@ public class UserAppServiceImpl extends ServiceImpl<UserAppMapper, UserApp> impl
case "4":
// 银盛
//ysAuditServiceV2.merchantAudit(userId, false);
//ysAuditServiceV3.merchantAuditV3(userId, false);
ysAuditServiceV3.merchantAuditV3(userId, false);
break;
default:
MsgException.throwException("未知的进件通道");

View File

@ -0,0 +1,7 @@
package cn.pluss.platform.ys.impl.v20220527;
public class Req {
public static class Url {
public static final String PREFIX = "https://ysgate.ysepay.com/openapi/";
}
}

View File

@ -0,0 +1,54 @@
package cn.pluss.platform.ys.impl.v20220527;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.pluss.platform.yinsheng.v20210929.ReqMethod;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReqEntity {
private String timeStamp;
private String method;
private String charset = "utf-8";
private String sign;
private String check;
private String bizContent;
private String reqId;
private String certId = "826521773920170";
private String version = "1.0";
public static ReqEntity get(ReqMethod reqMethod) {
Date date = new Date();
ReqEntity entity = new ReqEntity();
entity.timeStamp = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
entity.method = reqMethod.getMethod();
entity.reqId = "SYB_" + RandomUtil.randomString(4) + DateUtil.format(date, "yyMMddHHmmss");
return entity;
}
public static ReqEntity get(cn.pluss.platform.ys.impl.v20220527.ReqMethod reqMethod) {
Date date = new Date();
ReqEntity entity = new ReqEntity();
entity.timeStamp = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
entity.method = reqMethod.getMethod();
entity.reqId = "SYB_" + RandomUtil.randomString(4) + DateUtil.format(date, "yyMMddHHmmss");
return entity;
}
}

View File

@ -0,0 +1,46 @@
package cn.pluss.platform.ys.impl.v20220527;
import lombok.Getter;
@Getter
public enum ReqMethod {
addCustInfoApply(Req.Url.PREFIX + "t1/smsc/addCustInfoApply"),
modifyCustInfoApply(Req.Url.PREFIX + "smsc/modifyCustInfoApply"),
upload(Req.Url.PREFIX + "file/smsc/upload"),
auditCustInfoApply(Req.Url.PREFIX + "t1/smsc/auditCustInfoApply"),
queryCustApply(Req.Url.PREFIX + "smsc/queryCustApply"),
sign(Req.Url.PREFIX + "t1/smsc/sign"),
sendSmsOrEmailMsg(Req.Url.PREFIX + "smsc/sign/sendSmsOrEmailMsg"),
queryAuthInfo(Req.Url.PREFIX + "smsc/saas/constract/queryAuthInfo"),
queryContract(Req.Url.PREFIX + "smsc/sign/queryContract"),
sweepReport(Req.Url.PREFIX + "smsc/saas/sweep/sweepreport"),
reportAgain(Req.Url.PREFIX + "smsc/saas/sweep/reportAgain"),
changeMercBaseInfo(Req.Url.PREFIX + "smsc/changeMercBaseInfo"),
uploadChangePic(Req.Url.PREFIX + "file/smsc/uploadChangePic"),
queryCustChange(Req.Url.PREFIX + "smsc/queryCustChange"),
changeMercStlAccInfo(Req.Url.PREFIX + "t1/smsc/changeMercStlAccInfo"),
changeRate(Req.Url.PREFIX + "smsc/changeRate"),
openOnlinePay(Req.Url.PREFIX + "smsc/saas/authority/online"),
regionList(Req.Url.PREFIX + "pregate/trade/findCmmtAreaInfoList"),
repAndAppIdQry(Req.Url.PREFIX + "report/scan/union/repAndAppIdQry"),
/**
* 支付宝实名认证状态查询
*/
aliAuthStatus(Req.Url.PREFIX + "pregate/alipay/getAuthState"),
;
private final String url;
private final String method;
ReqMethod(String url, String method) {
this.url = url;
this.method = method;
}
ReqMethod(String url) {
this(url, url.replace(Req.Url.PREFIX, "").replace('/', '.'));
}
}

View File

@ -0,0 +1,50 @@
package cn.pluss.platform.ys.impl.v20220527;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Setter
@Getter
public class RespEntity implements Serializable{
/**
* 网关响应码
*/
private String code;
/**
* 网关响应码描述
*/
private String msg;
/**
* 业务响应码
*/
private String subCode;
/**
* 业务响应描述
*/
private String subMsg;
/**
* yyyy-MM-dd HH:mm:ss
*/
private String timeStamp;
/**
* 随机参数
*/
private String norce;
/**
* 签名串
*/
private String sign;
/**
* 业务响应参数集合
* 加密后的数据
*/
private String businessData;
}

View File

@ -41,9 +41,9 @@ public class YsConfigV3 {
public static final String BIZ_SUCCESS = "0000";
public static final String AUDIT_NOTIFY_URL = "https://ky.sxczgkj.cn/api/auditCallback/ysV3";
public static final String AUDIT_NOTIFY_URL = "http://wxgzh.sxczgkj.cn/api/auditCallback/ysV3";
public static final String AUDIT_SIGN_NOTIFY_URL = "https://www.shouyinbei.net/api/auditCallback/ysSignV3";
public static final String AUDIT_SIGN_NOTIFY_URL = "http://wxgzh.sxczgkj.cn/api/auditCallback/ysSignV3";
/** 成功 */
public static final String STATUS_SUCCESS = "00";

View File

@ -0,0 +1,249 @@
package cn.pluss.platform.ys.impl.v20220527;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.DES;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.util.*;
import cn.pluss.platform.ys.YsConfig;
import cn.pluss.platform.ys.YsOldConfig;
import cn.pluss.platform.ys.impl.v20210929.YsConfigV2;
import cn.pluss.platform.ys.impl.v20210929.YsConstant;
import cn.pluss.platform.ys.impl.v20220527.entity.Meta;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
@Service("ysServiceV3")
public class YsServiceV3 {
@Autowired
private YsConfig ysConfig;
@Autowired
private RestTemplate restTemplate;
/**
* 只用于新的进件接口
*
* @param reqMethod 请求方法
* @param reqData 请求参数
* @return
*/
public RespEntity req(ReqMethod reqMethod, JSONObject reqData) {
Calendar calendar = Calendar.getInstance();
int i = calendar.get(Calendar.HOUR_OF_DAY);
if (i < 8 || i >= 21) {
throw new MsgException("当前时段暂不支持入网请于8:00-21:00提交");
}
try {
ReqEntity request = ReqEntity.get(reqMethod);
request.setCertId(ysConfig.getSrcMerchantNo());
request.setBizContent(reqData.toJSONString());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
log.info("业务参数==============>" + JSONObject.toJSONString(reqData));
String key = RandomUtil.randomString(RandomUtil.BASE_NUMBER + "ABCDEF",16);
log.info("key = " + key);
AES aes = new AES(key.getBytes(StandardCharsets.UTF_8));
String s = aes.encryptBase64(request.getBizContent());
request.setBizContent(s);
RSA rsa = SecureUtil.rsa(ysConfig.getPriKey(), ysConfig.getOldPubKey());
request.setCheck(rsa.encryptBase64(key, KeyType.PublicKey));
String encryptOriginData = SignUtils.getSignContent((JSONObject) JSON.toJSON(request));
Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, ysConfig.getPriKey(), ysConfig.getOldPubKey());
log.info("加签源数据==============>" + encryptOriginData);
request.setSign(Base64.encode(sign.sign(encryptOriginData)));
log.warn("请求报文==============>" + JSONObject.toJSONString(request));
log.info("请求地址:{}", reqMethod.getUrl());
HttpEntity<JSONObject> reqEntity = new HttpEntity<>((JSONObject) JSON.toJSON(request), headers);
String respStr = restTemplate.postForObject(reqMethod.getUrl(), reqEntity, String.class);
log.info("返回信息base64{}", respStr);
byte[] decode = Base64.decode(respStr);
respStr = new String(decode, StandardCharsets.UTF_8);
log.info("返回信息:{}", respStr);
JSONObject param = JSON.parseObject(respStr);
String signContent = SignUtils.getSignContent(param);
System.out.println("加签原参数:" + signContent);
boolean checkSign;
try {
checkSign = sign.verify(signContent.getBytes(StandardCharsets.UTF_8), Base64.decode(param.getString("sign")));
} catch (Exception e) {
log.error("银盛云商服3.0接口验签失败{}", e.getMessage());
e.printStackTrace();
checkSign = true;
}
if (!checkSign) {
throw new MsgException("银盛云商服3.0接口验签不通过");
}
RespEntity respEntity = JSON.parseObject(respStr, RespEntity.class);
// 检查网关code码
if (!Objects.equals(respEntity.getCode(), YsConfigV3.REQ_SUCCESS)) {
throw new MsgException(respEntity.getMsg());
}
// 业务响应码这里不做判断交给具体接口业务逻辑去判断
if (StringUtils.hasText(respEntity.getBusinessData())) {
byte[] bizBytes = Base64.decode(respEntity.getBusinessData());
String decryptBizData = aes.decryptStr(bizBytes);
respEntity.setBusinessData(decryptBizData);
log.info("业务参数: {}", respEntity.getBusinessData());
}
return respEntity;
} catch (Exception e) {
if (e instanceof MsgException) {
throw e;
}
return null;
}
}
public RespEntity reqUpload(ReqMethod reqMethod, String picType, String fileUrl, String sysFlowId) {
Calendar calendar = Calendar.getInstance();
int i = calendar.get(Calendar.HOUR_OF_DAY);
if (i < 8 || i >= 21) {
throw new MsgException("当前时段暂不支持入网请于8:00-21:00提交");
}
Meta meta = new Meta();
meta.setPicType(picType);
meta.setSysFlowId(sysFlowId);
meta.setChangeFlowId(sysFlowId);
try {
ReqEntity request = ReqEntity.get(ReqMethod.upload);
request.setCertId(ysConfig.getSrcMerchantNo());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
MultiValueMap<String, Object> reqMap = new LinkedMultiValueMap<>();
try {
String imgBase64Data = FileUtil.getBase64FromUrl(fileUrl);
String compressPic = Base64Util.compressPic(imgBase64Data, 1024);
byte[] byteArray = Base64.decode(compressPic);
ByteArrayResource file = new ByteArrayResource(byteArray) {
@Override
public String getFilename() {
return "test.jpg";
}
};
reqMap.add("file", file);
String sha256 = DigestUtil.sha256Hex(file.getInputStream());
meta.setSha256(sha256);
meta.setPicNm("test.jpg");
} catch (IOException e) {
e.printStackTrace();
}
JSONObject reqData = new JSONObject();
reqData.put("meta", meta);
request.setBizContent(reqData.toString());
log.info("业务参数==============>" + reqData);
String key = RandomUtil.randomString(RandomUtil.BASE_NUMBER + "ABCDEF",16);
log.info("key = " + key);
AES aes = new AES(key.getBytes(StandardCharsets.UTF_8));
String s = aes.encryptBase64(request.getBizContent());
request.setBizContent(s);
RSA rsa = SecureUtil.rsa(ysConfig.getPriKey(), ysConfig.getOldPubKey());
request.setCheck(rsa.encryptBase64(key, KeyType.PublicKey));
String encryptOriginData = SignUtils.getSignContent((JSONObject) JSON.toJSON(request));
Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, ysConfig.getPriKey(), ysConfig.getOldPubKey());
log.info("加签源数据==============>" + encryptOriginData);
request.setSign(Base64.encode(sign.sign(encryptOriginData)));
reqMap.addAll(MapUtils.map2MultiValueMap((JSONObject) JSON.toJSON(request)));
HttpEntity<MultiValueMap<String, Object>> reqEntity = new HttpEntity<>(reqMap, headers);
String respStr = restTemplate.postForObject(reqMethod.getUrl(), reqEntity, String.class);
log.info("返回信息base64{}", respStr);
byte[] decode = Base64.decode(respStr);
respStr = new String(decode, StandardCharsets.UTF_8);
log.info("返回信息:{}", respStr);
JSONObject param = JSON.parseObject(respStr);
String signContent = SignUtils.getSignContent(param);
System.out.println("加签原参数:" + signContent);
boolean checkSign;
try {
checkSign = sign.verify(signContent.getBytes(StandardCharsets.UTF_8), Base64.decode(param.getString("sign")));
} catch (Exception e) {
log.error("银盛云商服3.0图片上传接口验签失败: {}", e.getMessage());
e.printStackTrace();
checkSign = true;
}
if (!checkSign) {
throw new MsgException("银盛云商服3.0接口验签不通过");
}
RespEntity respEntity = JSON.parseObject(respStr, RespEntity.class);
// 检查网关code码
if (!Objects.equals(respEntity.getCode(), YsConfigV3.REQ_SUCCESS)) {
throw new MsgException(respEntity.getMsg());
}
// 业务响应码这里不做判断交给具体接口业务逻辑去判断
if (respEntity.getBusinessData() != null) {
byte[] bizBytes = Base64.decode(respEntity.getBusinessData());
String decryptBizData = aes.decryptStr(bizBytes);
respEntity.setBusinessData(decryptBizData);
}
log.info("业务返回参数: {}", respEntity.getBusinessData());
return respEntity;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -1,6 +1,5 @@
package cn.pluss.platform.ys.impl.v20220527.entity;
import com.alipay.api.domain.PersonInfo;
import lombok.Getter;
import lombok.Setter;

View File

@ -8,7 +8,7 @@ import lombok.Setter;
*/
@Setter
@Getter
public class PersonInfo {
public class PersonInfo extends com.alipay.api.domain.PersonInfo {
/**
* 实际控制人姓名
*/

View File

@ -0,0 +1,6 @@
package cn.pluss.platform.ys.impl.v20220527.service;
public class YsAuditServiceV3 {
}

View File

@ -0,0 +1,690 @@
package cn.pluss.platform.ysExtension.v20220615;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 记录银盛接口的参数的key值
*/
public class YsConstantV3 {
@Getter
@AllArgsConstructor
public enum ReqStatus {
/** 请求状态值 */
SUCCESS("00", "请求成功");
private String code;
private String desc;
}
@Getter
@AllArgsConstructor
public enum AuditStatus {
/**
* 进件状态
*/
AUDIT_NO_AUDIT("03", "待审核"), AUDIT_FIRST_TRIAL_SUCCESS("04", "初审完成"), AUDIT_SUCCESS("05", "开户完成"), AUDIT_FIRST_TRIAL_FAIL("90", "初审拒绝");
private String code;
private String desc;
public static AuditStatus getByCode(String code) {
for (AuditStatus value : AuditStatus.values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
}
/**
* 营业执照全称
*/
public static final String BUSINESS_LICENCE = "businessLicence";
/**
* 商户简称
*/
public static final String ALIAS = "userShortName";
/**
* 营业执照全称
*/
public static final String BUSINESS_LICENCE_NO = "businessLicenceNo";
/**
* 营业执照开始日期
*/
public static final String BUSINESS_LICENCE_START = "businessLicenceSdate";
/**
* 营业执照结束日期
*/
public static final String BUSINESS_LICENCE_LIMIT = "businessLicenceEdate";
/**
* 营业执照注册地址
*/
public static final String REGISTERED_ADDRESS = "registeredAddress";
/**
* 营业地址
*/
public static final String BUSINESS_ADDRESS = "businessAddress";
/**
* 商户归属省
*/
public static final String MERC_PROV = "mercProv";
/**
* 商户归属省
*/
public static final String MERC_CITY = "mercCity";
/**
* 商户归属省
*/
public static final String MERC_AREA = "mercArea";
/**
* 法人姓名
*/
public static final String LEGAL_PERSON_NAME = "legalPersonName";
/**
* 法人身份证号
*/
public static final String LEGAL_PERSON_ID = "legalPersonId";
/**
* 法人身份证开始日期
*/
public static final String LEGAL_PERSON_START = "legalPersonIdSdate";
/**
* 法人身份证到期日期
*/
public static final String LEGAL_PERSON_LIMIT = "legalPersonIdEdate";
/**
* 法人电话
*/
public static final String LEGAL_PERSON_PHONE = "legalPersonPhone";
/**
* 非法人姓名
*/
public static final String ACCOUNT_PERSON_NAME = "unincorporatedName";
/**
* 非法人身份证号码
*/
public static final String ACCOUNT_PERSON_ID = "unincorporatedId";
/**
* 结算账户卡号
*/
public static final String ACCOUNT_CARD_NO = "balanceAccCardno";
/**
* 结算账户户名
*/
public static final String ACCOUNT_CARD_NAME = "balanceAccName";
/**
* 开户行省如湖北省
*/
public static final String BANK_PROVINCE = "openAccProvince";
/**
* 开户行市如武汉市
*/
public static final String BANK_CITY = "openAccCity";
/**
* 开户行市如武汉市
*/
public static final String BANK_AREA = "openAccArea";
/**
* 开户行行别名称
*/
public static final String BANK_NAME = "bankName";
/**
* 开户行行别
*/
public static final String BANK_TYPE = "bankType";
/**
* 开户行编号支行
*/
public static final String BANK_BRANCH_TYPE = "openAccBanktype";
/**
* 开户行名称支行
*/
public static final String BANK_BRANCH_NAME = "openAccBankname";
/**
* 联系人姓名
*/
public static final String CONTACTS_NAME = "contactsName";
/**
* 联系人电话
*/
public static final String CONTACTS_PHONE = "contactsPhone";
/**
* 联系人邮箱
*/
public static final String CONTACTS_EMAIL = "contactsEmail";
/**
* 微信签约费率( :0.01%)
*/
public static final String WECHAT_SIGN_RATE = "wechatSignRate";
/**
* 微信签约费率封底(单位:)
*/
public static final String WECHAT_SIGN_MIN = "wechatSignMin";
/**
* 支付宝签约费率(最低:0.01%)
*/
public static final String ALIPAY_SIGN_RATE = "alipaySignRate";
/**
* 支付宝签约费率封底(单位:)
*/
public static final String ALIPAY_SIGN_MIN = "alipaySignMin";
/**
* 银联一档>1000贷记卡费率
*/
public static final String CREDIT_RATE_1 = "creditRate1";
/**
* 银联一档>1000贷记卡封底.单位
*/
public static final String CREDIT_MIN_1 = "creditMin1";
/**
* 银联一档>1000借记卡费率
*/
public static final String DEBIT_RATE_1 = "debitRate1";
/**
* 银联一档>1000借记卡封底单位
*/
public static final String DEBIT_MIN_1 = "debitMin1";
/**
* 银联一档>1000借记卡封顶单位
*/
public static final String DEBIT_MAX_1 = "debitMax1";
/**
* 银联二档<=1000贷记卡费率
*/
public static final String CREDIT_RATE_2 = "creditRate2";
/**
* 银联二档<=1000贷记卡封底单位
*/
public static final String CREDIT_MIN_2 = "creditMin2";
/**
* 银联二档<=1000借记卡费率
*/
public static final String DEBIT_RATE_2 = "debitRate2";
/**
* 银联二档<=1000借记卡封底单位
*/
public static final String DEBIT_MIN_2 = "debitMin2";
/**
* 银联二档<=1000借记卡封顶单位
*/
public static final String DEBIT_MAX_2 = "debitMax2";
/**
* 是否开通刷卡业务
*/
public static final String OPEN_POS_P = "openPosp";
/* 以下为T1 */
/**
* 工作日到账-借记卡费率
*/
public static final String T_111_RATE = "t111Rate";
/**
* 工作日到账-借记卡费率封顶单位
*/
public static final String T_111_RATE_TOP = "t111RateTop";
/**
* 工作日到账-借记卡费率封底单位
*/
public static final String T_111_SIGN_RATE_MIN = "t111SignRateMin";
/**
* 工作日到账-贷记卡费率
*/
public static final String T_112_RATE = "t112Rate";
/**
* 工作日到账-贷记卡费率封底单位
*/
public static final String T_112_SIGN_RATE_MIN = "t112SignRateMin";
/* 以下为D1 */
/**
* 天天到账-借记卡费率
*/
public static final String T_11_RATE = "t11Rate";
/**
* 天天到账-借记卡费率封顶单位
*/
public static final String T_11_RATE_TOP = "t11RateTop";
/**
* 天天到账-借记卡费率封底单位
*/
public static final String T_11_SIGN_RATE_MIN = "t11SignRateMin";
/**
* 天天到账-贷记卡费率
*/
public static final String T_12_RATE = "t12Rate";
/**
* 天天到账-贷记卡费率封底单位
*/
public static final String T_12_SIGN_RATE_MIN = "t12SignRateMin";
/**
* 天天到账-垫资费类型百分比
*/
public static final String T_ADVANCE_TYPE = "tAdvanceType";
/**
* 天天到账-垫资费
*/
public static final String T_ADVANCE_FEE = "tAdvanceFee";
/**
* 天天到账-垫资费封底单位
*/
public static final String T_ADVANCE_MIN = "tAdvanceMin";
/* 以下为D0 */
/**
* 实时到账-借记卡费率
*/
public static final String D_011_RATE = "d011Rate";
/**
* 实时到账-借记卡费率封顶单位
*/
public static final String D_011_RATE_TOP = "d011RateTop";
/**
* 实时到账-借记卡费率最低单位
*/
public static final String D_011_RATE_BOTTOM = "d011RateBottom";
/**
* 实时到账-贷记卡费率
*/
public static final String D_012_RATE = "d012Rate";
/**
* 实时到账-贷记卡费率最低单位
*/
public static final String D_012_RATE_BOTTOM = "d012RateBottom";
/**
* 实时到账-借记卡签约费率垫资费类型(百分比)
*/
public static final String D_0_ADVANCE_J_SIGN_TYPE = "d0AdvanceJsignType";
/**
* 实时到账-借记卡签约费率垫资费
*/
public static final String D_0_ADVANCE_J_SIGN_FEE = "d0AdvanceJsignFee";
/**
* 实时到账-借记卡签约费率垫资费封底单位
*/
public static final String D_0_ADVANCE_J_SIGN_MIN = "d0AdvanceJsignMin";
/**
* 实时到账-借记卡签约费率垫资费封顶(单位:)
*/
public static final String D_0_ADVANCE_J_SIGN_MAX = "d0AdvanceJsignMax";
/**
* 实时到账-贷记卡签约费率垫资费类型(百分比)
*/
public static final String D_0_ADVANCE_D_SIGN_TYPE = "d0AdvanceDsignType";
/**
* 实时到账-贷记卡签约费率垫资费
*/
public static final String D_0_ADVANCE_D_SIGN_FEE = "d0AdvanceDsignFee";
/**
* 实时到账-贷记卡签约费率垫资费封底单位
*/
public static final String D_0_ADVANCE_D_SIGN_MIN = "d0AdvanceDsignMin";
/**
* 实时到账-贷记卡签约费率垫资费封顶(单位:)
*/
public static final String D_0_ADVANCE_D_SIGN_MAX = "d0AdvanceDsignMax";
/**
* 是否开通扫码快付
*/
public static final String CODE_ADVANCE_OPEN = "codeAdvanceOpen";
/**
* 是否开通快付
*/
public static final String FAST_PAY = "fastPay";
/**
* 到账方式, 开通刷卡业务时必填
*/
public static final String OPEN_BUS_RADIO = "openBusRadio";
/**
* 是否法人结算
*/
public static final String CODE_LEGAL_PERSON_ACC = "codeLegalPersonAcc";
/**
* 垫资费费率
*/
public static final String CODE_ADVANCE_RATE = "codeAdvanceRate";
/**
* 垫资费费率最低值单位
*/
public static final String CODE_ADVANCE_MIN = "codeAdvanceMin";
/**
* 银盛商户类型
*/
public static final String MCC_SUB_CD = "mccSubCd";
/**
* MCC
*/
public static final String MCC_CD = "mccCd";
/**
* 代理商编号
*/
public static final String CO_OPERATOR_NO = "coOperatorNo";
/**
* 代理商编号
*/
public static final String INDUSTRY = "industry";
/**
* 扫码报备所需商户类型
*/
public static final String MCH_TYPE = "mchtype";
/**
* 扫码报备所需商户类别
*/
public static final String MCH_CATEGORY = "mchcategory";
/**
* 法人国籍
*/
public static final String CRP_NATIONALITY = "crpNationality";
/**
* 法人性别
*/
public static final String CRP_GENDER = "crpGender";
/**
* 法人职业
*/
public static final String CRP_PROFESSION = "crpProfession";
/**
* 法人地址
*/
public static final String CRP_ADDR = "crpAddr";
/**
* 法人姓名
*/
public static final String CRP_NAME = "crpNm";
/**
* 证件有效期
*/
public static final String CERT_EXPIRE = "certExpire";
public static final String NOTIFY_URL = "notifyUrl";
/**
* 商户模式
*/
public static final String USER_TYPE = "userType";
/**
* 备注
*/
public static final String REMARK = "remark";
/**
* 结算起始金额
*/
public static final String LOWEST_STL_AMT = "lowestStlAmt";
/**
* 银行预留手机号
*/
public static final String BANK_MOBILE = "bankMobile";
/**
* 实际控制人
*/
public static final String ACTUAL_MANAGER = "actualManager";
/**
* 证件类型
*/
public static final String CERT_TYPE = "certType";
/**
* 证件类型
*/
public static final String MERC_LVL = "mercLvl";
/**
* 总店商户号
*/
public static final String MERC_UP_ID = "mercUpId";
/**
* 联系人通讯地址
*/
public static final String CONTACTS_ADDR = "contactsAddr";
/**
* 结算卡类型
*/
public static final String BALANCE_ACC_TYPE = "balanceAccType";
/**
* 拓展经理姓名
*/
public static final String EXPANDING_MANAGER = "expandingManager";
// ================ 以下为线上交易权限开通的接口参数名 ================
/**
* 商户号
*/
public static final String MERC_ID = "mercId";
/**
* 接入机构号
*/
public static final String ACC_ORG_NO = "accOrgNo";
/**
* 交易权限
*/
public static final String SCAN_SERVICE_OPEN = "scanServiceOpen";
/**
* 费率信息
*/
public static final String EASY_FEE_BEAN = "easyFeeBean";
/**
* 微信费率类型
* 必填 1 百分比2 固定金额
*/
public static final String R_SCAN_WX_FEE_TYPE = "rscanWxFeeType";
/**
* rscanWxFeeType 1时 必填
* 示例 0.3 表示 0.003
*/
public static final String R_SCAN_WX_FEE_RATE = "rscanWxFeeRate";
/**
* 微信费率金额
* 单位
* rscanWxFeeType 1 时为封底金额
* rscanWxFeeType 2 时为固定金额
*/
public static final String R_SCAN_WX_FEE_NUM = "rscanWxFeeNum";
/**
* 支付宝费率同微信
*/
public static final String R_SCAN_ALI_FEE_TYPE = "rscanAliFeeType";
public static final String R_SCAN_ALI_FEE_RATE = "rscanAliFeeRate";
public static final String R_SCAN_ALI_FEE_NUM = "rscanAliFeeNum";
/**
* 银联借记卡一档费率类型
* 1 百分比2 固定金额
*/
public static final String R_SCAN_DEBIT_TYPE_1 = "rscanDebitType1";
/**
* 银联借记卡一档金额
* rscanDebitType1 1 时为借记卡一档费率示例 0.3 表示 0.003
* rscanDebitType1 2 时为固定金额 单位
*/
public static final String R_SCAN_DEBIT_NUM_1 = "rscanDebitNum1";
/**
* 银联借记卡一档金额封底金额
* 单位
* rscanDebitType1为1 必填
*/
public static final String R_SCAN_DEBIT_MIN_1 = "rscanDebitMin1";
/**
* 银联借记卡一档金额封顶金额
* 单位
* rscanDebitType1为1, 必填
*/
public static final String R_SCAN_DEBIT_MAX_1 = "rscanDebitMax1";
/**
* 银联借记卡二档费率类型
* 1百分比; 2固定金额
*/
public static final String R_SCAN_DEBIT_TYPE_2 = "rscanDebitType2";
/**
* 银联借记卡二档金额
* rscanDebitType2为1时为借记卡一档费率示例 0.3表 0.003;
* rscanDebitType2为2时为固定金额 单位
*/
public static final String R_SCAN_DEBIT_NUM_2 = "rscanDebitNum2";
/**
* 银联借记卡二档金额封底金额
* 单位
* rscanDebitType2为1,必填
*/
public static final String R_SCAN_DEBIT_MIN_2 = "rscanDebitMin2";
/**
* 银联借记卡二档金额封顶金额
* 单位
* rscanDebitType2 1 必填
*/
public static final String R_SCAN_DEBIT_MAX_2 = "rscanDebitMax2";
/**
* 银联借记卡二档金额封顶金额
* 单位
* rscanDebitType2 1 必填
*/
public static final String R_SCAN_CREDIT_TYPE_1 = "rscanCreditType1";
/**
* 银联贷记卡 一档金额(>1000)
* rscanCreditType1 1 时为借记卡一 档费率示例 0.3 表示 0.003 rscanCreditType1 2 时为固定金额 单位
*/
public static final String R_SCAN_CREDIT_NUM_1 = "rscanCreditNum1";
/**
* 银联贷记卡 一档金额封底金额
* 单位
* rscanCreditType1 1 必填
*/
public static final String R_SCAN_CREDIT_MIN_1 = "rscanCreditMin1";
/**
* 银联贷记卡 二档费类型
* 1 百分比 2 固定金额
*/
public static final String R_SCAN_CREDIT_TYPE_2 = "rscanCreditType2";
/**
* 银联贷记卡 二档金额
* rscanCreditType2 1 时为借记卡一 档费率示例 0.3 表示 0.003;
* rscanCreditType2 2 时为固定金额 单位
*/
public static final String R_SCAN_CREDIT_NUM_2 = "rscanCreditNum2";
/**
* 银联贷记卡 二档金额封底金额
* 单位 rscanCreditType2 1 必填
*/
public static final String R_SCAN_CREDIT_MIN_2 = "rscanCreditMin2";
}