代码优化-清理臃肿的前朝遗物代码

This commit is contained in:
2023-01-17 14:37:37 +08:00
parent 26e78a2753
commit 18b52a1214
281 changed files with 46 additions and 24598 deletions

View File

@@ -1,379 +0,0 @@
package com.accompany.admin.service.auditaudio;
import com.accompany.admin.common.BusinessException;
import com.accompany.admin.model.AdminUser;
import com.accompany.admin.service.AccountBlockAdminService;
import com.accompany.admin.service.base.BaseService;
import com.accompany.admin.service.system.AdminUserService;
import com.accompany.admin.vo.AuditAudioAdminVo;
import com.accompany.business.constant.AuditAudioResultEnum;
import com.accompany.business.constant.RiskLevelEnum;
import com.accompany.business.constant.RiskTypeEnum;
import com.accompany.business.model.AuditAudioRoom;
import com.accompany.business.mongodb.DAO.auditaudio.AuditAudioDAO;
import com.accompany.business.mongodb.document.auditaudio.AuditAudio;
import com.accompany.business.service.account.AccountBlockService;
import com.accompany.business.service.auditaudio.AuditAudioRoomService;
import com.accompany.business.service.auditaudio.AuditAudioService;
import com.accompany.business.service.room.RoomService;
import com.accompany.business.service.user.UsersService;
import com.accompany.business.vo.RunningRoomVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.constant.RoomMonitorTypeEnum;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.constant.BlockSourceEnum;
import com.accompany.core.constant.BlockTypeEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Room;
import com.accompany.core.model.Users;
import com.accompany.core.service.user.UsersBaseService;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 2 * @Author: zhuct
* 3 * @Date: 2019/8/19 17:08
* 4
*/
@Service
public class AuditAudioAdminService extends BaseService {
@Autowired
private UsersService usersService;
@Autowired
private UsersBaseService usersBaseService;
@Autowired
private AuditAudioDAO auditAudioDAO;
@Autowired
private AuditAudioService auditAudioService;
@Autowired
private AdminUserService adminUserService;
@Autowired
private AccountBlockAdminService accountBlockAdminService;
@Autowired
private AccountBlockService accountBlockService;
@Autowired
private AuditAudioRoomService auditAudioRoomService;
@Autowired
private RoomService roomService;
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public Map<String, Object> getAuditAudioList(Long erbanNo, Byte riskLevel, Integer riskType, String operatorName, Integer manualAuditResult,
Integer systemAuditResult, Integer pageNum, Integer pageSize, Date beginDate,
Date endDate, Integer startRejectCount, Integer endRejectCount, Integer startScore, Integer endScore) {
Map data = Maps.newHashMap();
logger.info("erbanNo:{}",erbanNo);
Long roomUid = null;
List<Long> roomUids = new ArrayList<>();
if (erbanNo != null) {
logger.info("getAuditAudioList erbanNo:{}",erbanNo);
Users user = usersService.getUserByErbanNo(erbanNo);
if (user == null) {
logger.info("getAuditAudioList erbanNo1:{}",erbanNo);
data.put("rows", Collections.emptyList());
data.put("total", 0);
return data;
} else {
roomUid = user.getUid();
roomUids.add(roomUid);
}
}
if (startRejectCount != null || endRejectCount != null) {
if (roomUid != null) {
Double score = jedisService.zscore(RedisKey.reject_audio_count.getKey(), roomUid.toString());
if (score == null || (startRejectCount != null && score.intValue() < startRejectCount)
|| (endRejectCount != null && score.intValue() > endRejectCount)) {
logger.info("getAuditAudioList erbanNo2:{}",erbanNo);
data.put("rows", Collections.emptyList());
data.put("total", 0);
return data;
}
} else {
String start = startRejectCount == null ? "-inf" : startRejectCount.toString();
String end = endRejectCount == null ? "+inf" : endRejectCount.toString();
Set<String> strings = jedisService.zrangeByScore(RedisKey.reject_audio_count.getKey(), start, end);
if (CollectionUtils.isEmpty(strings)) {
logger.info("getAuditAudioList erbanNo3:{}",erbanNo);
data.put("rows", Collections.emptyList());
data.put("total", 0);
return data;
}
roomUids = strings.stream().map(uid -> Long.valueOf(uid)).collect(Collectors.toList());
}
}
pageNum = pageNum != null ? pageNum : Constant.DEFAULT_PAGE;
pageSize = pageSize != null ? pageSize : Constant.DEFAULT_PAGE_SIZE;
int start = (pageNum - 1) * pageSize;
Query query = new Query();
if (CollectionUtils.isNotEmpty(roomUids)) {
query.addCriteria(Criteria.where("roomUid").in(roomUids));
}
if (riskLevel != null) {
query.addCriteria(Criteria.where("riskLevel").is(riskLevel));
}
if (riskType != null) {
query.addCriteria(Criteria.where("riskType").is(riskType));
}
if (StringUtils.isNotBlank(operatorName)) {
query.addCriteria(Criteria.where("operatorName").is(operatorName));
}
if (manualAuditResult != null) {
query.addCriteria(Criteria.where("manualAuditResult").is(manualAuditResult));
}
if (systemAuditResult != null) {
query.addCriteria(Criteria.where("systemAuditResult").is(systemAuditResult));
}
if (beginDate != null && endDate == null) {
query.addCriteria(Criteria.where("createTime").gte(beginDate.getTime()));
} else if (endDate != null && beginDate == null) {
query.addCriteria(Criteria.where("createTime").lte(endDate.getTime()));
} else if (beginDate != null && endDate != null) {
Criteria cr = new Criteria();
cr.andOperator(Criteria.where("createTime").gte(beginDate.getTime()),
Criteria.where("createTime").lte(endDate.getTime()));
query.addCriteria(cr);
}
if (startScore != null && endScore == null) {
query.addCriteria(Criteria.where("score").gte(startScore));
} else if (endScore != null && startScore == null) {
query.addCriteria(Criteria.where("score").lte(endScore));
} else if (startScore != null && endScore != null) {
Criteria cr = new Criteria();
cr.andOperator(Criteria.where("score").gte(startScore),
Criteria.where("score").lte(endScore));
query.addCriteria(cr);
}
long count = auditAudioDAO.count(query);
query.skip(start).limit(pageSize);
query.with(Sort.by(Sort.Order.desc("createTime")));
List<AuditAudio> auditAudioList = auditAudioDAO.findByQuery(query);
logger.info("getAuditAudioList auditAudioList:{}",auditAudioList);
data.put("rows", buildAuditAudioAdminVo(auditAudioList));
data.put("total", count);
return data;
}
private List<AuditAudioAdminVo> buildAuditAudioAdminVo(List<AuditAudio> audioList) {
if (CollectionUtils.isEmpty(audioList)) {
return Collections.emptyList();
}
List<AuditAudioAdminVo> voList = new ArrayList<>();
audioList.forEach(auditAudio -> {
AuditAudioAdminVo vo = new AuditAudioAdminVo();
BeanUtils.copyProperties(auditAudio, vo);
Users user = usersService.getUsersByUid(auditAudio.getRoomUid());
vo.setErbanNo(user == null ? null : user.getErbanNo());
vo.setRejectCount(auditAudioService.getRejectAudioCount(auditAudio.getRoomUid()));
voList.add(vo);
});
return voList;
}
/**
* 处理为正常
*
* @param recordId
* @return
*/
@Transactional(rollbackFor = Exception.class)
public void handlePass(String recordId, Integer adminId) {
AuditAudio auditAudio = auditAudioDAO.findById(recordId);
if (auditAudio == null || auditAudio.getManualAuditResult() != AuditAudioResultEnum.TO_BE_HANDLE.getValue()) {
throw new ServiceException(BusiStatus.PARAMERROR);
}
AdminUser adminUser = adminUserService.getAdminUserById(adminId);
auditAudio.setManualAuditResult(AuditAudioResultEnum.NORMAL.getValue());
auditAudio.setUpdateTime(System.currentTimeMillis());
auditAudio.setOperatorName(adminUser == null ? null : adminUser.getUsername());
auditAudioDAO.save(auditAudio);
}
/**
* 解禁
*
* @param recordId
* @return
*/
@Transactional(rollbackFor = Exception.class)
public void handleUnBlock(String recordId, String adminName) throws Exception{
AuditAudio auditAudio = auditAudioDAO.findById(recordId);
if (auditAudio == null) {
throw new BusinessException("音频记录不存在");
}
if (auditAudio.getBlockId() == null) {
throw new BusinessException("封禁记录不存在");
}
if (auditAudio.getManualAuditResult() != null && auditAudio.getManualAuditResult() == AuditAudioResultEnum.REMOVE_BLOCK.getValue()) {
throw new BusinessException("该记录已处理为解禁");
}
//解除封禁
accountBlockAdminService.deleteAccountBlock(auditAudio.getBlockId().toString(), adminName);
}
public void updateMultiAuditAudioStatus(Integer blockId, String adminName) {
Query query = new Query();
query.addCriteria(Criteria.where("blockId").is(blockId).and("manualAuditResult").ne(AuditAudioResultEnum.REMOVE_BLOCK.getValue()));
Update update = new Update();
update.set("updateTime", System.currentTimeMillis());
update.set("operatorName", adminName);
update.set("manualAuditResult", AuditAudioResultEnum.REMOVE_BLOCK.getValue());
auditAudioDAO.updateMulti(query, update);
}
/**
* 处理违规
*
* @param recordId
* @return
*/
@Transactional(rollbackFor = Exception.class)
public void handleReject(String recordId, Integer resultValue, Integer riskType, String adminName) throws Exception {
AuditAudio auditAudio = auditAudioDAO.findById(recordId);
if (auditAudio == null) {
throw new BusinessException("音频记录不存在");
}
if (auditAudio.getManualAuditResult() != null && auditAudio.getManualAuditResult() != AuditAudioResultEnum.TO_BE_HANDLE.getValue()) {
throw new BusinessException("不能处理该记录");
}
Long roomUid = auditAudio.getRoomUid();
Users users = usersService.getUsersByUid(roomUid);
if (users == null) {
throw new BusinessException("房主用户不存在");
}
LocalDateTime now = LocalDateTime.now();
AuditAudioResultEnum resultEnum = AuditAudioResultEnum.get(resultValue);
String endBlockTime = getEndBlockTime(resultEnum, now);
Integer blockedAccountId = null;
riskType = riskType == null ? auditAudio.getRiskType() : riskType;
RiskTypeEnum riskTypeEnum = RiskTypeEnum.get(riskType);
if (StringUtils.isNotBlank(endBlockTime)) {
//封禁账号
accountBlockService.saveBlockedAccount(users.getErbanNo(), BlockTypeEnum.BLOCK_ACCOUNT.getValue(), now.format(formatter),
endBlockTime, riskTypeEnum.getDesc(), BlockSourceEnum.AUDIT_AUDIO.getValue(), adminName, false);
}
auditAudio.setBlockId(users.getErbanNo().intValue());
auditAudio.setManualAuditResult(resultEnum.getValue());
auditAudio.setUpdateTime(System.currentTimeMillis());
auditAudio.setOperatorName(adminName);
auditAudioDAO.save(auditAudio);
if(auditAudio.getRiskLevel() != RiskLevelEnum.REJECT.getValue()){
//违规次数加一
jedisService.zincrby(RedisKey.reject_audio_count.getKey(), 1d, roomUid.toString());
}
auditAudioService.sendAuditAudioMsg(roomUid.toString(), riskTypeEnum.getDesc(), resultEnum.getDesc());
}
private String getEndBlockTime(AuditAudioResultEnum resultEnum, LocalDateTime now) {
switch (resultEnum) {
case BLOCK_24_HOURS:
return now.plusDays(1).format(formatter);
case BLOCK_THREE_DAY:
return now.plusDays(3).format(formatter);
case BLOCK_SEVEN_HOURS:
return now.plusDays(7).format(formatter);
case BLOCK_PERMANENT:
return now.plusYears(10).format(formatter);
default:
return null;
}
}
/**
* 获取监控规则
*
* @return
*/
public Map<String, Object> getMonitorRule() {
Map data = Maps.newHashMap();
Integer monitorType = auditAudioRoomService.getRoomMonitorType();
String erbanNoStr = "";
if (monitorType != null && monitorType == RoomMonitorTypeEnum.GIVEN_ROOM.getValue()) {
Set<String> roomUids = jedisService.smembers(RedisKey.given_audit_audio_room.getKey());
for (String roomUid : roomUids) {
Users users = usersService.getUsersByUid(Long.valueOf(roomUid));
if (users != null) {
erbanNoStr += users.getErbanNo() + ",";
}
}
}
data.put("roomMonitorType", monitorType);
data.put("erbanNos", erbanNoStr);
return data;
}
public void saveMonitorRule(Byte type, String erbanNos) {
Integer beforeMonitorType = auditAudioRoomService.getRoomMonitorType();
List<AuditAudioRoom> auditAudioRoomList = auditAudioRoomService.getAuditAudioRoomList();
if (beforeMonitorType != null && beforeMonitorType != type.intValue()) {
//关闭之前送审的房间
for (AuditAudioRoom room : auditAudioRoomList) {
auditAudioRoomService.closeAuditAudioRoom(room);
}
if (beforeMonitorType == RoomMonitorTypeEnum.GIVEN_ROOM.getValue()) {
jedisService.del(RedisKey.given_audit_audio_room.getKey());
}
}
if (type == RoomMonitorTypeEnum.GIVEN_ROOM.getValue()) {
List<String> erbanNoList = Arrays.asList(erbanNos.split(",")).stream().filter(string -> !"".equals(string)).collect(Collectors.toList());
Set<String> roomUids = jedisService.smembers(RedisKey.given_audit_audio_room.getKey());
for (String roomUid : roomUids) {
Users users = usersService.getUsersByUid(Long.valueOf(roomUid));
if (!erbanNoList.contains(users.getErbanNo().toString())) {//如果之前送审房间已经不存在这次保存的指定房间内,则关闭对应房间
String jsonStr = jedisService.hget(RedisKey.audit_audio_room.getKey(), roomUid);
if (StringUtils.isNotBlank(jsonStr)) {//如果房间在审核,则关闭房间
auditAudioRoomService.closeAuditAudioRoom(gson.fromJson(jsonStr, AuditAudioRoom.class));
}
//移除指定房间
jedisService.srem(RedisKey.given_audit_audio_room.getKey(), roomUid);
}
}
//送审这次保存的房间
for (String erbanNo : erbanNoList) {
Users users = usersBaseService.getUsersByErBanNo(Long.valueOf(erbanNo));
if (users == null) {
continue;
}
long result = jedisService.sadd(RedisKey.given_audit_audio_room.getKey(), users.getUid().toString());
if (result > 0) {//如果保存成功,说明是新增指定房间,则判断是否开房中并且有人,如果是,则立马送审
String runningRoomStr = jedisService.hget(RedisKey.room_running.getKey(), users.getUid().toString());
if (StringUtils.isNotBlank(runningRoomStr)) {
RunningRoomVo runningRoomVo = gson.fromJson(runningRoomStr, RunningRoomVo.class);
if (runningRoomVo != null && runningRoomVo.getOnlineNum() != 0) {
Room room = roomService.getRoomByUid(users.getUid());
auditAudioRoomService.sendAuditRoom(room, type);
}
}
}
}
} else {
//送审所有在线房间
auditAudioRoomService.sendAuditOnlineRoom();
}
jedisService.set(RedisKey.room_monitor_type.getKey(), type.toString());
}
}

View File

@@ -16,7 +16,6 @@ import com.accompany.business.service.purse.UserPurseService;
import com.accompany.admin.service.push.EnterpriseWeChatPushAdminService;
import com.accompany.business.service.record.BillRecordService;
import com.accompany.business.service.user.UsersService;
import com.accompany.business.service.wx.WXPubService;
import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.result.BusiResult;
@@ -68,8 +67,6 @@ public class OfficialGoldRecordService extends BaseService {
@Autowired
private JedisService jedisService;
@Autowired
private WXPubService wxPubService;
@Autowired
private OfficialGoldBusTypeAdminService officialGoldBusTypeAdminService;
@Autowired
private EnterpriseWeChatPushAdminService enterpriseWeChatPushAdminService;
@@ -493,7 +490,7 @@ public class OfficialGoldRecordService extends BaseService {
keyword3 += "笔数";
}
String keyword4 = "充值时间:" + DateTimeUtil.convertDate(new Date(),"yyyy-MM-dd hh:mm");
wxPubService.sendAlertMsg(openId,first,keyword1,keyword2,keyword3,keyword4,"");
//wxPubService.sendAlertMsg(openId,first,keyword1,keyword2,keyword3,keyword4,"");
}
}

View File

@@ -8,7 +8,6 @@ import com.accompany.admin.model.AdminLoginRecordExample;
import com.accompany.admin.model.AdminUser;
import com.accompany.admin.model.AdminUserExample;
import com.accompany.admin.service.base.BaseService;
import com.accompany.business.util.MD5;
import com.accompany.business.util.ReplaceDomainUtil;
import com.accompany.common.constant.Constant;
import com.accompany.common.constant.SmsTypeEnum;
@@ -20,6 +19,7 @@ import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.RandomUtil;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.service.SysConfService;
import com.accompany.core.util.MD5;
import com.accompany.sms.service.SmsService;
import com.aliyuncs.exceptions.ClientException;
import com.github.pagehelper.PageHelper;
@@ -151,15 +151,15 @@ public class AdminUserService extends BaseService {
return adminUserMapper.deleteByPrimaryKey(id);
}
public BusiResult sendSmsCode(String account, String realIpAddress) throws UnsupportedEncodingException, ClientException {
public BusiResult<Void> sendSmsCode(String account, String realIpAddress) throws UnsupportedEncodingException, ClientException {
logger.info("getUserByName");
AdminUser adminUser = getUserByName(account);
if (adminUser == null) {
jedisService.setex(RedisKey.admin_account_not_exist.getKey(account), 10, account);
return new BusiResult(BusiStatus.USERNOTEXISTS);
return new BusiResult<>(BusiStatus.USERNOTEXISTS);
}
if (BlankUtil.isBlank(adminUser.getPhone())) {
return new BusiResult(BusiStatus.ADMIN_PHONE_NO_BIND);
return new BusiResult<>(BusiStatus.ADMIN_PHONE_NO_BIND);
}
CompletableFuture<String> templateCodeFuture = CompletableFuture.supplyAsync(() ->
sysConfService.getSysConfValueById(Constant.SysConfId.ADMIN_SMS_TEMPLATE_CODE)
@@ -170,7 +170,7 @@ public class AdminUserService extends BaseService {
smsService.sendSmsCode(adminUser.getPhone(),
SmsTypeEnum.SUPER_ADMIN_LOGIN.value, null, realIpAddress, smsCode);
saveSmsCode(adminUser, smsCode, realIpAddress);
return new BusiResult(BusiStatus.SUCCESS);
return new BusiResult<>(BusiStatus.SUCCESS);
}
/**

View File

@@ -1,99 +0,0 @@
package com.accompany.admin.service.transfer;
import com.accompany.payment.alipay.AlipayService;
import com.accompany.payment.config.AliPayConfig;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransOrderQueryModel;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.request.AlipayFundTransOrderQueryRequest;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.accompany.admin.transfer.*;
import com.accompany.business.apppay.constant.PayConstant;
import com.accompany.common.constant.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* {这里添加描述}
*
* @author fangchengyan
* @date 2019-12-26 10:08 上午
*/
@Service
@Slf4j
public class AlipayTransferService implements ITransferService {
@Override
public Byte getAccountType() {
return Constant.WithdrawAccountType.ALIPAY;
}
@Autowired
private AlipayService alipayService;
@Override
public TransferPayResult transferPay(TransferPayParam param) throws Exception {
AlipayClient alipayClient = alipayService.getAlipayClientInstance();
AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
model.setOutBizNo(param.getBillId());
model.setPayeeType(PayConstant.ALIPAY_PAYEE_TYPE);
model.setPayeeAccount(param.getAccount());
model.setAmount(param.getTransferAmount().toString());
model.setPayeeRealName(param.getAccountName());
model.setRemark(param.getDescription());
AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
request.setBizModel(model);
AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
//构建返回值
TransferPayResult transferPayResult = new TransferPayResult();
if(response != null && PayConstant.ALIPAY_TRANSFER_SUCCESS_CODE.equals(response.getCode())) {
transferPayResult.setStatus(PayConstant.Transfer.RESULT_SUCCESS);
} else {
transferPayResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
transferPayResult.setPayId(response.getOrderId());
transferPayResult.setErrorCode(response.getSubCode());
transferPayResult.setErrorMsg(response.getSubMsg());
return transferPayResult;
}
@Override
public TransferQueryResult transferQuery(TransferQueryParam param) throws AlipayApiException {
AlipayClient alipayClient = alipayService.getAlipayClientInstance();
AlipayFundTransOrderQueryModel model = new AlipayFundTransOrderQueryModel();
model.setOutBizNo(param.getBillId());
model.setOrderId(param.getPayId());
AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
request.setBizModel(model);
AlipayFundTransOrderQueryResponse response = alipayClient.execute(request);
//构建返回值
TransferQueryResult transferQueryResult = new TransferQueryResult();
if(response != null && PayConstant.ALIPAY_TRANSFER_SUCCESS_CODE.equals(response.getCode())) {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_SUCCESS);
} else {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
transferQueryResult.setPayId(response.getOrderId());
transferQueryResult.setErrorCode(response.getSubCode());
transferQueryResult.setErrorMsg(response.getSubMsg());
return transferQueryResult;
}
@Override
public TransferNotifyResult handlerNotify(Object param) {
throw new NotImplementedException("方法未实现");
}
}

View File

@@ -1,45 +0,0 @@
package com.accompany.admin.service.transfer;
import com.accompany.admin.transfer.*;
/**
* {这里添加描述}
*
* @author fangchengyan
* @date 2019-12-25 5:37 下午
*/
public interface ITransferService {
/**
* 转账类型
* @return
*/
Byte getAccountType();
/**
* 转账-付款
* @param param
* @return
*
* @throws Exception
*/
TransferPayResult transferPay(TransferPayParam param) throws Exception;
/**
* 转账-查询
* @param param
* @return
*
* @throws Exception
*/
TransferQueryResult transferQuery(TransferQueryParam param) throws Exception;
/**
* 处理异步
*
* @param param
* @return
*/
TransferNotifyResult handlerNotify(Object param);
}

View File

@@ -1,196 +0,0 @@
package com.accompany.admin.service.transfer;
import com.accompany.admin.transfer.*;
import com.accompany.admin.util.PropertyUtil;
import com.accompany.business.apppay.constant.JoinpayTransferStatusEnum;
import com.accompany.business.apppay.constant.PayConstant;
import com.accompany.common.constant.Constant;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.HttpUtils;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.util.StringUtils;
import com.accompany.payment.config.JoinPayConfig;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* 汇聚代付
* <a href="https://www.joinpay.com/open-platform/pages/document.html?apiName=%E4%BB%A3%E4%BB%98%E4%BA%A7%E5%93%81&id=10">代付产品</a>
*
* @author fangchengyan
* @date 2019-12-26 3:39 下午
*/
@Service
@Slf4j
public class JoinpayTransferService implements ITransferService {
/**
* 单笔代付
*/
private String singlePayUrl = "https://www.joinpay.com/payment/pay/singlePay";
/**
* 单笔代付查询AlipayTransferService
*/
private String singlePayQueryUrl = "https://www.joinpay.com/payment/pay/singlePayQuery";
@Override
public Byte getAccountType() {
return Constant.WithdrawAccountType.BANK;
}
/**
* 汇聚代付
* @param param
* @return
* @throws Exception
*/
@Override
public TransferPayResult transferPay(TransferPayParam param) throws Exception {
JoinpayTransferPayReq req = new JoinpayTransferPayReq();
// 商户编号
req.setUserNo(String.valueOf(JoinPayConfig.merchantNo));
// 产品类型, BANK_PAY_DAILY_ORDER: 朝夕付
req.setProductCode("BANK_PAY_DAILY_ORDER");
req.setRequestTime(DateTimeUtil.convertDate(new Date(), DateTimeUtil.DEFAULT_DATETIME_PATTERN));
req.setMerchantOrderNo(param.getBillId());
req.setReceiverAccountNoEnc(param.getAccount());
req.setReceiverNameEnc(param.getAccountName());
// 账户类型: 对私账户201 对公账户204
req.setReceiverAccountType(201);
req.setPaidAmount(param.getTransferAmount());
req.setCurrency("201");
// 是否复核复核201不复核202
req.setIsChecked("202");
// 代付描述最长为25个字符
String desc = param.getDescription();
if(StringUtils.length(desc) > 25) {
desc = StringUtils.substring(desc, 0, 25);
}
req.setPaidDesc(desc);
// 代付用途: 202: 活动经费
req.setPaidUse("202");
// 代付完成后异步回调通知地址
req.setCallbackUrl(PropertyUtil.getProperty("transferCallbackUrl"));
req.setHmac(signByMD5(req.plainTextSign(), JoinPayConfig.key));
String reqJson = JSON.toJSONString(req);
log.info("请求参数:{}", reqJson);
String jsonResp = HttpUtils.doPostForJson(singlePayUrl, reqJson);
log.info("转账结果:{}", jsonResp);
TransferPayResult transferPayResult = new TransferPayResult();
if(StringUtils.isBlank(jsonResp)) {
transferPayResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
return transferPayResult;
}
JoinpayTransferPayResp payResp = JSON.parseObject(jsonResp, JoinpayTransferPayResp.class);
// 转账是异步操作,这里的成功仅表示受理成功,转账结果还需要另外查询
if(PayConstant.JOINPAY_TRANSFER_SUCCESS.equals(payResp.getStatusCode())) {
transferPayResult.setStatus(PayConstant.Transfer.RESULT_PROCESSING);
} else {
transferPayResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
transferPayResult.setPayId(payResp.getData().getMerchantOrderNo());
transferPayResult.setErrorCode(payResp.getData().getErrorCode());
transferPayResult.setErrorMsg(payResp.getData().getErrorDesc());
return transferPayResult;
}
/**
* 转账查询
* @param param
* @return
* @throws Exception
*/
@Override
public TransferQueryResult transferQuery(TransferQueryParam param) throws Exception {
JoinpayTransQueryReq req = new JoinpayTransQueryReq();
req.setMerchantOrderNo(param.getBillId());
req.setUserNo(String.valueOf(JoinPayConfig.merchantNo));
req.setHmac(signByMD5(req.plainTextSign(), JoinPayConfig.key));
String reqJson = JSON.toJSONString(req);
log.info("请求参数:{}", reqJson);
String jsonResp = HttpUtils.doPostForJson(singlePayQueryUrl, reqJson);
log.info("查询结果:{}", jsonResp);
//构建返回值
TransferQueryResult transferQueryResult = new TransferQueryResult();
if(StringUtils.isBlank(jsonResp)) {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
return transferQueryResult;
}
JoinpayTransQueryResp response = JSON.parseObject(jsonResp, JoinpayTransQueryResp.class);
JoinpayTransferQueryRespData data = response.getData();
if(PayConstant.JOINPAY_TRANSFER_SUCCESS.equals(response.getStatusCode())) {
if(null != data.getStatus()
&& data.getStatus().equals(JoinpayTransferStatusEnum.JOINPAY_TRANSFER_DETAIL_SUCCESS.getCode())) {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_SUCCESS);
} else {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
} else {
transferQueryResult.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
transferQueryResult.setPayId(data.getPlatformSerialNo());
if(StringUtils.isNotEmpty(data.getErrorCode())) {
transferQueryResult.setErrorCode(data.getErrorCode());
transferQueryResult.setErrorMsg(data.getErrorDesc());
} else {
transferQueryResult.setErrorCode(String.valueOf(data.getStatus()));
transferQueryResult.setErrorMsg(JoinpayTransferStatusEnum.getDescByCode(String.valueOf(data.getStatus())));
}
return transferQueryResult;
}
@Override
public TransferNotifyResult handlerNotify(Object param) {
JoinpayTransferPayNotifyReq req = (JoinpayTransferPayNotifyReq)param;
String key = signByMD5(req.plainTextSign(), JoinPayConfig.key);
// 验证签名
if(!StringUtils.equalsIgnoreCase(req.getHmac(), key)) {
log.warn("签名验证失败参数中的hmac:{}生成的hmac:{}", req.getHmac(), key);
throw new ServiceException("签名错误!");
}
TransferNotifyResult result = new TransferNotifyResult();
String statusStr = String.valueOf(req.getStatus());
if(StringUtils.equalsIgnoreCase(JoinpayTransferStatusEnum.JOINPAY_TRANSFER_DETAIL_SUCCESS.getCode(), statusStr)) {
result.setStatus(PayConstant.Transfer.RESULT_SUCCESS);
} else {
result.setStatus(PayConstant.Transfer.RESULT_FAIL);
}
result.setPayId(req.getPlatformSerialNo());
result.setBillId(req.getMerchantOrderNo());
result.setAccountType(getAccountType());
if(StringUtils.isNotEmpty(req.getErrorCode())) {
result.setErrorCode(req.getErrorCode());
result.setErrorMsg(req.getErrorCodeDesc());
} else {
result.setErrorCode(String.valueOf(req.getStatus()));
result.setErrorMsg(JoinpayTransferStatusEnum.getDescByCode(String.valueOf(req.getStatus())));
}
return result;
}
/**
* 对请求参数进行签名
* @param signString
* @param encryptKey
* @return
*/
private String signByMD5(String signString, String encryptKey) {
String plain = signString + encryptKey;
log.info("签名原文:{}", plain);
return DigestUtils.md5Hex(plain).toUpperCase();
}
}

View File

@@ -1,52 +0,0 @@
package com.accompany.admin.service.transfer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* {这里添加描述}
*
* @author fangchengyan
* @date 2019-07-26 23:06
*/
@Slf4j
@Component
public class TransferFactory implements ApplicationContextAware {
private volatile ApplicationContext applicationContext;
private Map<Byte, ITransferService> serviceMap = new HashMap<>();
/**
* 根据payType与platform获取ChannelService
* @return
*/
public ITransferService getChannelService(Byte accountType) {
if(serviceMap.size() == 0){
load();
}
return Optional.ofNullable(serviceMap.get(accountType))
.orElseThrow(() -> new IllegalStateException("Can't be find the account type:" + accountType));
}
private void load() {
Map<String, ITransferService> beanMap = applicationContext.getBeansOfType(ITransferService.class);
beanMap.forEach((name, bean) -> {
serviceMap.put(bean.getAccountType(), bean);
log.info("Successful register pay type-{} of bean.The beanName: {}",
bean.getAccountType(), name);
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

View File

@@ -2,9 +2,8 @@ package com.accompany.admin.service.user;
import com.accompany.admin.common.BusinessException;
import com.accompany.core.model.Account;
import com.accompany.core.mybatismapper.AccountMapper;
import com.accompany.business.util.MD5;
import com.accompany.core.service.account.AccountService;
import com.accompany.core.util.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@@ -1,244 +0,0 @@
package com.accompany.admin.service.withdraw;
import com.accompany.admin.service.transfer.ITransferService;
import com.accompany.admin.service.transfer.TransferFactory;
import com.accompany.admin.service.user.BillRecordAdminService;
import com.accompany.admin.transfer.TransferPayParam;
import com.accompany.admin.transfer.TransferPayResult;
import com.accompany.business.apppay.constant.PayConstant;
import com.accompany.business.model.PacketWithdrawRecord;
import com.accompany.business.mybatismapper.PacketWithdrawRecordExpandMapper;
import com.accompany.business.mybatismapper.PacketWithdrawRecordMapper;
import com.accompany.business.service.user.UsersService;
import com.accompany.business.vo.PacketWithdrawRecordAdminVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.UUIDUitl;
import com.accompany.core.model.Users;
import com.accompany.core.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
/**
* @author yangziwen
* @description
* @date 2018/1/31 21:05
*/
@Service
public class PacketWithdrawAdminService {
private static final Logger logger = LoggerFactory.getLogger(PacketWithdrawAdminService.class);
@Autowired
private PacketWithdrawRecordMapper packetWithdrawRecordMapper;
@Autowired
private PacketWithdrawRecordExpandMapper packetWithdrawRecordExpandMapper;
@Autowired
private UsersService usersService;
@Autowired
private BillRecordAdminService billRecordAdminService;
@Autowired
private TransferFactory transferFactory;
public BusiResult getPacketWithdrawList(String erbanNo, String account, String accountName, String phone, String beginDate,
String endDate, Byte status, String payStatus, Integer pageNum, Integer pageSize) {
//为了尽量降低表结构修改,使用连表查询(仅在管理后台使用)
BusiResult busiResult = new BusiResult(BusiStatus.SUCCESS);
pageNum = pageNum != null ? pageNum : Constant.DEFAULT_PAGE;
pageSize = pageSize != null ? pageSize : Constant.DEFAULT_PAGE_SIZE;
Integer start = (pageNum-1)*pageSize;
Map record = Maps.newHashMap();
if (StringUtils.isNotEmpty(erbanNo)) {
record.put("erbanNo",erbanNo);
}
if (StringUtils.isNotBlank(account)) {
record.put("account",account);
}
if (StringUtils.isNotBlank(accountName)) {
record.put("accountName",accountName);
}
if (StringUtils.isNotBlank(payStatus) && !Constant.WithdrawPayStatus.ALL.equalsIgnoreCase(payStatus)) {
record.put("payStatus",payStatus);
}
if (StringUtils.isNotBlank(phone)) {
record.put("phone",phone);
}
if (StringUtils.isNotBlank(beginDate)) {
record.put("beginDate",beginDate);
}
if (StringUtils.isNotBlank(endDate)) {
record.put("endDate",endDate);
}
if (status != null && status != -1) {
record.put("recordStatus",status);
}
List<PacketWithdrawRecordAdminVo> withdrawList = this.packetWithdrawRecordExpandMapper.queryPacketWithdrowList(record,start,pageSize);
int count = this.packetWithdrawRecordExpandMapper.queryPacketWithdrowCount(record);
JSONObject data = new JSONObject();
data.put("rows",withdrawList);
data.put("total",count);
busiResult.setData(data);
return busiResult;
}
@Transactional(rollbackFor = Exception.class)
public String approvePacketWithdraw(String id) {
PacketWithdrawRecord packetWithdrawRecord = this.packetWithdrawRecordMapper.selectByPrimaryKey(id);
if (packetWithdrawRecord == null) {
logger.error("illegal data, packet withdrad record not exists[id={}]", id);
return "提现申请记录不存在";
}
if (packetWithdrawRecord.getRecordStatus().byteValue()!=Constant.WithDrawStatus.ing) {
logger.error("request is not in progress[id={}]", id);
return "该请求不是发起提现状态";
}
packetWithdrawRecord.setRecordStatus(Constant.WithDrawStatus.APPROVED);
packetWithdrawRecord.setUpdateTime(Calendar.getInstance().getTime());
this.packetWithdrawRecordMapper.updateByPrimaryKeySelective(packetWithdrawRecord);
return null;
}
/**
* 驳回提现申请
*
* @param id
* @param remark
*/
public String reject(String id, String remark) {
PacketWithdrawRecord packetWithdrawRecord = this.packetWithdrawRecordMapper.selectByPrimaryKey(id);
if(packetWithdrawRecord == null){
logger.error("illegal data, packet withdrad record not exists[id={}]", id);
return "提现申请记录不存在";
}
if(Constant.WithdrawPayStatus.PENDING.equals(packetWithdrawRecord.getPayStatus())
||Constant.WithdrawPayStatus.SCHEDULED.equals(packetWithdrawRecord.getPayStatus())
||Constant.WithdrawPayStatus.PAID.equals(packetWithdrawRecord.getPayStatus())){
logger.error("request is not in progress[id={}]", id);
return "正在支付中或已支付成功";
}
packetWithdrawRecord.setRecordStatus(Constant.WithDrawStatus.reject);
packetWithdrawRecord.setRemark(remark);
packetWithdrawRecord.setUpdateTime(Calendar.getInstance().getTime());
this.packetWithdrawRecordMapper.updateByPrimaryKeySelective(packetWithdrawRecord);
return null;
}
/**
* 单个转账
*
* @param id
*/
public String transfer(String id) {
PacketWithdrawRecord packetWithdrawRecord = this.packetWithdrawRecordMapper.selectByPrimaryKey(id);
Long uid = packetWithdrawRecord.getUid();
Users user = usersService.getUsersByUid(uid);
if(user==null){
return "转账用户信息不存在uid="+uid;
}
//校验红包提现条件
String message = checkPacketTransfer(packetWithdrawRecord);
if(!StringUtils.isEmpty(message)){
return message;
}
//实际提现金额为扣除税额后的金额
Double TaxNum = 0D;
if(packetWithdrawRecord.getTaxNum()!=null){
TaxNum = packetWithdrawRecord.getTaxNum();
}
Double withdrawMoney = packetWithdrawRecord.getPacketNum().doubleValue() - TaxNum.doubleValue();
if(withdrawMoney.doubleValue()<0){
return "提现金额小于税额,不允许提现";
}
BigDecimal realMoney = new BigDecimal(withdrawMoney).setScale(0, BigDecimal.ROUND_HALF_UP);
String defDes = user.getAlipayAccountName()+DateTimeUtil.convertDate(Calendar.getInstance().getTime(), DateTimeUtil.SIMPLE_MONTH_DATE_PATTERN)+packetWithdrawRecord.getPacketNum().doubleValue()+"红包提现款";
//防止description为空导致转账失败
String description = StringUtils.isBlank(packetWithdrawRecord.getDescription())?defDes:packetWithdrawRecord.getDescription();
try {
ITransferService transferService = transferFactory.getChannelService(Constant.WithdrawAccountType.ALIPAY);
TransferPayParam param = TransferPayParam.builder()
.billId(UUIDUitl.get())
.account(user.getAlipayAccount())
.accountName(user.getAlipayAccountName())
.transferAmount(realMoney)
.description(description)
.build();
TransferPayResult transfer = transferService.transferPay(param);
if (PayConstant.Transfer.RESULT_SUCCESS == transfer.getStatus()) {
packetWithdrawRecord.setPayId(transfer.getPayId());
packetWithdrawRecord.setPayStatus(Constant.WithdrawPayStatus.PAID);
packetWithdrawRecord.setUpdateTime(Calendar.getInstance().getTime());
this.packetWithdrawRecordMapper.updateByPrimaryKeySelective(packetWithdrawRecord);
}else{
packetWithdrawRecord.setPayStatus(Constant.WithdrawPayStatus.FAILED);
packetWithdrawRecord.setPayResult(transfer.getErrorMsg());
packetWithdrawRecord.setRemark(transfer.getErrorCode());
packetWithdrawRecord.setUpdateTime(Calendar.getInstance().getTime());
this.packetWithdrawRecordMapper.updateByPrimaryKeySelective(packetWithdrawRecord);
message = transfer.getErrorMsg();
}
} catch (Exception e) {
logger.error("红包提现转账失败[id={}, reason={}]", id, e.getMessage(), e);
message = e.getMessage();
packetWithdrawRecord.setPayStatus(Constant.WithdrawPayStatus.FAILED);
packetWithdrawRecord.setPayResult("支付失败");
packetWithdrawRecord.setRemark("发起转账请求失败,详情请查看日志");
packetWithdrawRecord.setUpdateTime(Calendar.getInstance().getTime());
this.packetWithdrawRecordMapper.updateByPrimaryKeySelective(packetWithdrawRecord);
}
return message;
}
public String batchTransfer(List<String> withdrawIds) {
logger.info("batchTransfer(), withdrawIds={}", withdrawIds);
StringBuilder builder = new StringBuilder();
for (String withdrawId : withdrawIds) {
String message = this.transfer(withdrawId);
if (!StringUtils.isEmpty(message)) {
builder.append(message).append("[").append(withdrawId).append("]\n");
}
}
return builder.toString();
}
private String checkPacketTransfer(PacketWithdrawRecord packetWithdrawRecord){
if (packetWithdrawRecord == null || (Constant.WithDrawStatus.APPROVED!=packetWithdrawRecord.getRecordStatus().byteValue())) {
return "非批准状态无法转账";
}
if (Constant.WithdrawPayStatus.PAID.equals(packetWithdrawRecord.getPayStatus())){
return "已经支付成功无法再次转账";
}
if (Constant.WithdrawPayStatus.SCHEDULED.equals(packetWithdrawRecord.getPayStatus()) || Constant.WithdrawPayStatus.PENDING.equals(packetWithdrawRecord.getPayStatus())){
return "等待支付完成";
}
return null;
}
}

View File

@@ -1,45 +0,0 @@
package com.accompany.admin.controller.api;
import com.alibaba.fastjson.JSON;
import com.accompany.admin.service.transfer.JoinpayTransferService;
import com.accompany.admin.service.user.WithdrawAdminService;
import com.accompany.admin.transfer.JoinpayTransferPayNotifyReq;
import com.accompany.admin.transfer.JoinpayTransferPayNotifyResp;
import com.accompany.admin.transfer.TransferNotifyResult;
import com.accompany.business.apppay.constant.PayConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* {这里添加描述}
*
* @author fangchengyan
* @date 2019-12-27 5:03 下午
*/
@Slf4j
@RestController
@RequestMapping("/api/joinpay/transfer")
public class JoinpayTransferController {
@Autowired
private WithdrawAdminService withdrawAdminService;
@Autowired
private JoinpayTransferService joinpayTransferService;
/**
* 汇聚转账结果通知
*/
@RequestMapping(value = "/notify")
public JoinpayTransferPayNotifyResp notify(@RequestBody JoinpayTransferPayNotifyReq req) {
log.info("收到汇聚转账结果通知:{}", JSON.toJSONString(req));
TransferNotifyResult result = joinpayTransferService.handlerNotify(req);
return JoinpayTransferPayNotifyResp.builder()
.statusCode(PayConstant.JOINPAY_TRANSFER_SUCCESS)
.message("成功")
.build();
}
}

View File

@@ -1,171 +0,0 @@
package com.accompany.admin.controller.auditaudio;
import com.alibaba.fastjson.JSON;
import com.accompany.admin.common.BusinessException;
import com.accompany.admin.controller.BaseController;
import com.accompany.admin.service.auditaudio.AuditAudioAdminService;
import com.accompany.admin.vo.AuditAudioAdminVo;
import com.accompany.business.constant.AuditAudioResultEnum;
import com.accompany.business.constant.RiskLevelEnum;
import com.accompany.business.constant.RiskTypeEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 2 * @Author: zhuct
* 3 * @Date: 2019/8/16 11:33
* 4
*/
@RestController
@RequestMapping("/admin/audit/audio")
public class AuditAudioAdminController extends BaseController {
@Autowired
private AuditAudioAdminService auditAudioAdminService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public void getTopicStatistic(Long erbanNo, Byte riskLevel, Integer riskType, String operatorName, Integer manualAuditResult,
Integer systemAuditResult, Integer pageNum, Integer pageSize, Date beginDate, Date endDate,
Integer startRejectCount, Integer endRejectCount, Integer startScore, Integer endScore) {
Map<String, Object> map = this.auditAudioAdminService.getAuditAudioList(erbanNo, riskLevel, riskType, operatorName, manualAuditResult,
systemAuditResult, pageNum, pageSize, beginDate, endDate, startRejectCount, endRejectCount, startScore, endScore);
writeJson(JSON.toJSONString(map));
}
@RequestMapping(value = "/handle/pass", method = RequestMethod.POST)
public BusiResult handlePass(String recordId) {
logger.info("handlePass recordId={}", recordId);
try {
auditAudioAdminService.handlePass(recordId, getAdminId());
} catch (ServiceException e) {
return new BusiResult(BusiStatus.SERVERERROR, e.getBusiStatus().getReasonPhrase());
} catch (Exception e) {
logger.error("Failed to handlePass.Cause by {}", e.getMessage());
return new BusiResult(BusiStatus.SERVERERROR);
}
return new BusiResult(BusiStatus.SUCCESS);
}
@RequestMapping(value = "/handle/unBlock", method = RequestMethod.POST)
public BusiResult handleUnBlock(String recordId){
logger.info("handleUnBlock recordId={}", recordId);
try {
auditAudioAdminService.handleUnBlock(recordId, getAdminName());
} catch (BusinessException e) {
return new BusiResult(BusiStatus.SERVERERROR, e.getMessage());
} catch (Exception e) {
logger.error("Failed to handleUnBlock.Cause by {}", e.getMessage());
return new BusiResult(BusiStatus.SERVERERROR);
}
return new BusiResult(BusiStatus.SUCCESS);
}
@RequestMapping(value = "/handle/reject", method = RequestMethod.POST)
public BusiResult handleReject(String recordId, Integer resultValue, Integer riskType) {
logger.info("handleReject recordId={},resultValue={},riskType={}", recordId, resultValue, riskType);
try {
auditAudioAdminService.handleReject(recordId, resultValue, riskType, getAdminName());
} catch (BusinessException e) {
return new BusiResult(BusiStatus.SERVERERROR, e.getMessage());
} catch (ServiceException e) {
return new BusiResult(BusiStatus.SERVERERROR, e.getBusiStatus().getReasonPhrase());
} catch (Exception e) {
logger.error("Failed to handleReject.Cause by {}", e.getMessage());
return new BusiResult(BusiStatus.SERVERERROR);
}
return new BusiResult(BusiStatus.SUCCESS);
}
@RequestMapping(value = "/export", method = RequestMethod.GET)
public void export(HttpServletResponse response, Long erbanNo, Byte riskLevel, Integer riskType, String operatorName, Integer manualAuditResult,
Integer systemAuditResult, Date beginDate, Date endDate, Integer startRejectCount, Integer endRejectCount, Integer startScore, Integer endScore) throws IOException {
Map<String, Object> map = auditAudioAdminService.getAuditAudioList(erbanNo, riskLevel, riskType, operatorName, manualAuditResult,
systemAuditResult, 1, 5000, beginDate, endDate, startRejectCount, endRejectCount, startScore, endScore);
List<AuditAudioAdminVo> carRecordStatisticsList = (List<AuditAudioAdminVo>) map.get("rows");
HSSFWorkbook workbook = this.buildWithdrawExcel(carRecordStatisticsList);
// 设置下载时客户端Excel的名称
String filename = "audit_audio_list.xls";
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=" + filename);
response.setCharacterEncoding("UTF-8");
OutputStream ouputStream = response.getOutputStream();
workbook.write(ouputStream);
ouputStream.flush();
ouputStream.close();
}
@RequestMapping(value = "/get/rule", method = RequestMethod.GET)
public BusiResult getMonitorRule() {
try {
Map<String, Object> monitorRule = auditAudioAdminService.getMonitorRule();
return new BusiResult(monitorRule);
} catch (Exception e) {
logger.error("Failed to getMonitorRule.Cause by {}", e.getMessage());
return new BusiResult(BusiStatus.SERVERERROR);
}
}
@RequestMapping(value = "/rule/save", method = RequestMethod.POST)
public BusiResult saveMonitorRule(Byte type, String erbanNos) {
logger.info("saveMonitorRule type={},erbanNos={}", type, erbanNos);
if (type == null) {
return new BusiResult(BusiStatus.PARAMERROR);
}
try {
auditAudioAdminService.saveMonitorRule(type, erbanNos);
} catch (Exception e) {
logger.error("Failed to saveMonitorRule.Cause by {}", e.getMessage());
return new BusiResult(BusiStatus.SERVERERROR);
}
return new BusiResult(BusiStatus.SUCCESS);
}
private HSSFWorkbook buildWithdrawExcel(List<AuditAudioAdminVo> voList) {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("音频监控记录");
String[] headers = {"房间号", "房间UID", "语音url", "数美判断结果", "违规类型", "人工审核结果", "系统审核结果", "历史违规次数",
"发生时间", "处理时间", "风险值", "操作人"};
HSSFRow header = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
header.createCell(i).setCellValue(headers[i]);
}
int rowNum = 1;
for (AuditAudioAdminVo item : voList) {
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(item.getErbanNo());
row.createCell(1).setCellValue(item.getRoomUid());
row.createCell(2).setCellValue(item.getAudioUrl());
row.createCell(3).setCellValue(item.getRiskLevel() == RiskLevelEnum.REJECT.getValue() ? "违规" : "可疑");
row.createCell(4).setCellValue(item.getRiskType() == null ? "" : RiskTypeEnum.get(item.getRiskType()).getDesc());
row.createCell(5).setCellValue(item.getManualAuditResult() == null ? "" : AuditAudioResultEnum.get(item.getManualAuditResult()).getDesc());
row.createCell(6).setCellValue(item.getSystemAuditResult() == null ? "" : AuditAudioResultEnum.get(item.getSystemAuditResult()).getDesc());
row.createCell(7).setCellValue(item.getRejectCount() == null ? 0 : item.getRejectCount());
row.createCell(8).setCellValue(item.getCreateTime() == null ? "" : DateTimeUtil.convertDate(new Date(item.getCreateTime())));
row.createCell(9).setCellValue(item.getUpdateTime() == null ? "" : DateTimeUtil.convertDate(new Date(item.getUpdateTime())));
row.createCell(10).setCellValue(item.getScore() == null ? "" : item.getScore() + "");
row.createCell(11).setCellValue(item.getOperatorName() == null ? "" : item.getOperatorName());
}
return workbook;
}
}

View File

@@ -1,6 +1,7 @@
package com.accompany.admin.controller.system;
import com.accompany.core.util.MD5;
import com.aliyuncs.exceptions.ClientException;
import com.accompany.admin.common.AdminConstants;
import com.accompany.admin.controller.BaseController;
@@ -12,7 +13,6 @@ import com.accompany.admin.util.StringUtil;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.service.common.JedisService;
import com.accompany.common.utils.IPUitls;
import com.accompany.business.util.MD5;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
@@ -190,7 +190,7 @@ public class LoginController extends BaseController {
}
String smsCode = jedisService.get(RedisKey.admin_sms_code.getKey(account));
return Optional.ofNullable(smsCode)
.map(sc -> MD5.getMD5(sc))
.map(MD5::getMD5)
.map(sc -> sc.equals(authCode))
.orElse(false);
}
@@ -201,25 +201,25 @@ public class LoginController extends BaseController {
@RequestMapping("/login/sendSmsCode")
@ResponseBody
public BusiResult sendSmsCode(String account, HttpServletRequest request) throws UnsupportedEncodingException, ClientException {
public BusiResult<Void> sendSmsCode(String account, HttpServletRequest request) throws UnsupportedEncodingException, ClientException {
String realIpAddress = IPUitls.getRealIpAddress(request);
logger.info("admin getSmsCode account:{},ip:{}", account, realIpAddress);
if (BlankUtil.isBlank(accountFilter(account))) {
return new BusiResult(BusiStatus.ALERT_PARAMETER_ILLEGAL);
return new BusiResult<>(BusiStatus.ALERT_PARAMETER_ILLEGAL);
}
if (jedisService.exits(RedisKey.admin_account_not_exist.getKey(account))) {
return new BusiResult(BusiStatus.USERNOTEXISTS);
return new BusiResult<>(BusiStatus.USERNOTEXISTS);
}
if (jedisService.exits(RedisKey.admin_sent_sms.getKey(account))) {
return new BusiResult(BusiStatus.SMS_NOT_EXPIRED3);
return new BusiResult<>(BusiStatus.SMS_NOT_EXPIRED3);
}
if (adminUserService.checkSendCodeLimit(account)) {
return new BusiResult(BusiStatus.SMS_SENDING_FREQUENCY_TOO_HIGH);
return new BusiResult<>(BusiStatus.SMS_SENDING_FREQUENCY_TOO_HIGH);
}
try {
return adminUserService.sendSmsCode(account, realIpAddress);
} catch (ServiceException e) {
return new BusiResult(e.getBusiStatus());
return new BusiResult<>(e.getBusiStatus());
}
}
}

View File

@@ -5,7 +5,7 @@ import com.accompany.admin.mapper.AdminUserMapper;
import com.accompany.admin.model.AdminUser;
import com.accompany.admin.service.system.AdminUserService;
import com.accompany.admin.service.user.UserPurseAdminService;
import com.accompany.business.util.MD5;
import com.accompany.core.util.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@@ -1,242 +0,0 @@
package com.accompany.admin.controller.withdraw;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.accompany.admin.controller.BaseController;
import com.accompany.admin.service.withdraw.PacketWithdrawAdminService;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.util.StringUtils;
import com.accompany.business.vo.PacketWithdrawRecordAdminVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.utils.DateTimeUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by yangziwen on 2018/01/31.
*/
@RestController
@RequestMapping("/admin/packet/withdraw")
public class PacketWithdrawAdminController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(PacketWithdrawAdminController.class);
@Autowired
PacketWithdrawAdminService packetWithdrawAdminService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public void getList(String erbanNo, String account, String accountName, String phone, String beginDate, String endDate, Byte status, String payStatus, Integer pageNum,
Integer pageSize) {
BusiResult busiResult = this.packetWithdrawAdminService.getPacketWithdrawList(erbanNo, account, accountName, phone, beginDate, endDate, status, payStatus, pageNum, pageSize);
JSONObject jsonObject = (JSONObject) busiResult.getData();
writeJson(jsonObject.toJSONString());
}
@RequestMapping(value = "/approve", method = RequestMethod.POST)
public void approveWithdraw(@RequestParam(value = "id", required = true) String id) {
logger.debug("approveWithdraw({})", id);
try {
String result = this.packetWithdrawAdminService.approvePacketWithdraw(id);
if (StringUtils.isEmpty(result)) {
writeJson(true, "操作成功");
return;
}
writeJson(false, result);
return;
} catch (Exception e) {
logger.error("Failed to save withdraw. Cause by {}", e.getCause().getMessage());
}
writeJson(false, "操作失败");
}
@RequestMapping(value = "/batchApprove", method = RequestMethod.POST)
public void batchApproveWithdraw(HttpServletRequest request) {
List<String> ids = getRequestArray(request, "ids", String.class);
logger.debug("batchConfirmPayment(), ids={}", ids);
if (CollectionUtils.isEmpty(ids)) {
writeJson(false, "参数有误");
return;
}
Integer success = 0;
for (String id : ids) {
try {
String result = this.packetWithdrawAdminService.approvePacketWithdraw(id);
logger.debug("batchConfirmPayment(), result={}", result);
if (StringUtils.isBlank(result)) {
success++;
}
} catch (Exception e) {
logger.error("Failed to save withdraw {}. Cause by {}", id, e.getCause().getMessage(), e);
}
}
if (ids.size() == success.intValue()) {
writeJson(true, "全部批准成功");
return;
}
if (success.intValue() > 0 && success.intValue() < ids.size()) {
writeJson(true, "部分批准成功");
return;
}
writeJson(false, "全部批准失败");
}
@RequestMapping(value = "/transfer", method = RequestMethod.POST)
public void transfer(String id) {
try {
String message = this.packetWithdrawAdminService.transfer(id);
if (StringUtils.isEmpty(message)) {
writeJson(true, "转账成功");
return;
} else {
writeJson(false, message);
}
}catch (ServiceException se){
writeJson(false,se.getMessage());
}catch (Exception e){
writeJson(false,e.getMessage());
}
}
@RequestMapping(value = "/batchTransfer", method = RequestMethod.POST)
public void batchTransfer(HttpServletRequest request) {
List<String> ids = getRequestArray(request, "ids", String.class);
logger.debug("batchConfirmPayment(), ids={}", ids);
if (CollectionUtils.isEmpty(ids)) {
writeJson(false, "参数有误");
return;
}
try {
String message = this.packetWithdrawAdminService.batchTransfer(ids);
if (!StringUtils.isEmpty(message)) {
writeJson(false, "具体原因请查看备注");
return;
}
} catch (Exception e) {
logger.error("转账失败[withdrawIds={}]", JSON.toJSONString(ids), e);
writeJson(false, e.getMessage());
}
writeJson(true, "已成功转账");
}
@RequestMapping(value = "/reject", method = RequestMethod.POST)
public void reject(String withdrawId, String remark) {
logger.info("reject(), id={}, remark={}", withdrawId, remark);
try {
String message = this.packetWithdrawAdminService.reject(withdrawId, remark);
if(StringUtils.isEmpty(message)) {
writeJson(true, "已拒绝提现申请");
}
writeJson(false,message);
}catch (ServiceException se){
writeJson(false,se.getMessage());
}catch (Exception e){
writeJson(false,e.getMessage());
}
}
@RequestMapping(value = "/export", method = RequestMethod.GET)
public void export(HttpServletRequest request, HttpServletResponse response, String erbanNo, String account, String accountName, String payStatus, String phone,
String beginDate, String endDate, Byte status) throws IOException {
BusiResult busiResult = this.packetWithdrawAdminService.getPacketWithdrawList(erbanNo, account, accountName, phone, beginDate, endDate, status, payStatus, 1, 5000);
List<PacketWithdrawRecordAdminVo> list = new ArrayList<>();
if(busiResult.getData()!=null){
Map data = (Map)busiResult.getData();
list =(List)data.get("rows");
}
HSSFWorkbook workbook = this.buildPacketWithdrawExcel(list);
// 设置下载时客户端Excel的名称
String filename = "packet_withdraw_list.xls";
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=" + filename);
response.setCharacterEncoding("UTF-8");
OutputStream ouputStream = response.getOutputStream();
workbook.write(ouputStream);
ouputStream.flush();
ouputStream.close();
}
private HSSFWorkbook buildPacketWithdrawExcel(List<PacketWithdrawRecordAdminVo> withdrawList) {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("红包提现申请名单");
String[] headers = {"平台号", "手机号码", "支付宝账号", "账号名", "提现金额(元)","税额(元)", "审核状态", "支付状态", "支付结果","申请时间", "备注"};
HSSFRow header = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
header.createCell(i).setCellValue(headers[i]);
}
int rowNum = 1;
for (PacketWithdrawRecordAdminVo withdraw : withdrawList) {
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(withdraw.getErbanNo() == null ? 0 : withdraw.getErbanNo());
row.createCell(1).setCellValue(withdraw.getPhone() == null ? "" : withdraw.getPhone());
row.createCell(2).setCellValue(withdraw.getAccount() == null ? "" : withdraw.getAccount());
row.createCell(3).setCellValue(withdraw.getAccountName() == null ? "" : withdraw.getAccountName());
row.createCell(4).setCellValue(String.valueOf(withdraw.getPacketNum()==null?0:withdraw.getPacketNum()));
row.createCell(5).setCellValue(String.valueOf(withdraw.getTaxNum()==null?0:withdraw.getTaxNum()));
String recordStatus = "";
if(withdraw.getRecordStatus()!=null) {
if (withdraw.getRecordStatus().byteValue()==Constant.WithDrawStatus.deleted) {
recordStatus = "作废";
} else if (withdraw.getRecordStatus().byteValue()==Constant.WithDrawStatus.ing) {
recordStatus = "申请中";
} else if (withdraw.getRecordStatus().byteValue()==Constant.WithDrawStatus.APPROVED) {
recordStatus = "已批准";
} else if (withdraw.getRecordStatus().byteValue()==Constant.WithDrawStatus.reject) {
recordStatus = "已驳回";
}
}
row.createCell(6).setCellValue(recordStatus);
String payStatus = "";
if (withdraw.getPayStatus() != null) {
if (Constant.WithdrawPayStatus.PENDING.equals(withdraw.getPayStatus())) {
payStatus = "申请中";
} else if (Constant.WithdrawPayStatus.SCHEDULED.equals(withdraw.getPayStatus())) {
payStatus = "计划中";
} else if (Constant.WithdrawPayStatus.PAID.equals(withdraw.getPayStatus())) {
payStatus = "已支付";
} else if (Constant.WithdrawPayStatus.FAILED.equals(withdraw.getPayStatus())) {
payStatus = "支付失败";
} else {
payStatus = "支付出错";
}
}
row.createCell(7).setCellValue(payStatus);
row.createCell(8).setCellValue(withdraw.getPayResult() == null ? "" : withdraw.getPayResult());
row.createCell(9).setCellValue(DateTimeUtil.convertDate(withdraw.getCreateTime()));
row.createCell(10).setCellValue(withdraw.getRemark() == null ? "" : withdraw.getRemark());
}
return workbook;
}
}

View File

@@ -4,13 +4,13 @@ package com.accompany.flowteam.admin.controller.system;
import com.accompany.admin.common.AdminConstants;
import com.accompany.admin.frame.Scope;
import com.accompany.admin.util.StringUtil;
import com.accompany.business.util.MD5;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.*;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.service.common.JedisService;
import com.accompany.core.util.MD5;
import com.accompany.flowteam.admin.common.FlowTeamAdminConstants;
import com.accompany.flowteam.admin.controller.BaseController;
import com.accompany.flowteam.admin.service.FlowTeamAdminUserService;
@@ -189,7 +189,7 @@ public class LoginController extends BaseController {
}
String smsCode = jedisService.get(RedisKey.flow_team_admin_sms_code.getKey(account));
return Optional.ofNullable(smsCode)
.map(sc -> MD5.getMD5(sc))
.map(MD5::getMD5)
.map(sc -> sc.equals(authCode))
.orElse(false);
}

View File

@@ -1,49 +0,0 @@
package com.accompany.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Lazy(value = false)
@Order(-1)
@ConfigurationProperties(prefix = "audit.media")
public class AuditMediaConfig {
public static String accessKey;
public static String appId;
public static String url;
public static String callBackUrl;
public static String queryUrl;
public static String closeUrl;
public void setAccessKey(String accessKey) {
AuditMediaConfig.accessKey = accessKey;
}
public void setAppId(String appId) {
AuditMediaConfig.appId = appId;
}
public void setUrl(String url) {
AuditMediaConfig.url = url;
}
public void setCallBackUrl(String callBackUrl) {
AuditMediaConfig.callBackUrl = callBackUrl;
}
public void setQueryUrl(String queryUrl) {
AuditMediaConfig.queryUrl = queryUrl;
}
public void setCloseUrl(String closeUrl) {
AuditMediaConfig.closeUrl = closeUrl;
}
}

View File

@@ -1,102 +0,0 @@
package com.accompany.common.constant;
/**
* @author yangziwen
* @description 账单类型常量类.
* @date 2018/3/19 14:42
*/
public class BillTypeConstant {
// 充值
public static final Byte IN_RECHARGE = 1;
// 提现
public static final Byte OUT_WITHDRAW = 2;
// 拍卖
public static final Byte OUT_AUCTION = 3;
// 订单收入
public static final Byte IN_ORDER_INCOME = 4;
// 刷礼物支出
public static final Byte OUT_GIFT_PAY = 5;
// 收礼物收入
public static final Byte IN_GIFT_INCOME = 6;
// 发红包支出
public static final Byte OUT_RED_PACKET_PAY = 7;
// 收红包收入
public static final Byte IN_RED_PACKET_INCOME = 8;
// 房主佣金收入
public static final Byte IN_ROOM_OWNER_COMMISSION = 9;
// 注册送金币奖励
public static final Byte IN_REGISTER_REWARD = 10;
// 分享送金币奖励
public static final Byte IN_SHARE_REWARD = 11;
// 官方赠送金币
public static final Byte IN_OFFICAL_DONATE = 12;
// 关注公众号奖励金币
public static final Byte IN_FOLLOW_OFFICAL_ACCOUNT_REWARD = 13;
// 钻石兑换金币支出
public static final Byte OUT_EXCHANGE_DIAMOND_TO_GOLD_PAY = 14;
// 钻石兑换金币收入
public static final Byte IN_EXCHANGE_DIAMOND_TO_GOLD_INCOME = 15;
// 万圣节活动奖励
public static final Byte IN_HALLOWEEN_REWARD = 16;
// 活动奖励
public static final Byte IN_ACTIVITY_REWARD = 17;
// 打款至公司账号充值
public static final Byte IN_RECHARGE_BY_COMPANY_ACCOUNT = 20;
// 兑换码兑换金币
public static final Byte IN_REDEEM_CODE_EXCHANGE = 21;
// 促销活动得金币
public static final Byte IN_LUCKY_DRAW = 23;
// 发送的
public static Byte bonusPerDaySend = 24;
// 钻石回馈账单
public static Byte bonusPerDayRecv = 25;
// 开通贵族
public static final Byte OUT_OPEN_NOBLE = 26;
// 续费贵族
public static Byte OUT_RENEW_NOBLE = 27;
//public static Byte roomNoble = 28;
// 房间内开通贵族分成
public static final Byte IN_ROOM_NOBLE_COMMISSION = 28;
//public static Byte openNobleReturn = 29;
// 开通贵族返还
public static final Byte IN_OPEN_NOBLE_RETURN = 29;
//public static Byte renewNobleReturn = 30;
// 续费贵族
public static final Byte IN_RENEW_NOBLE_RETURN = 30;
//public static Byte purchaseCarGoods = 31;
// 购买座驾
public static final Byte OUT_BUY_CAR_GOODS = 31;
//public static Byte renewCarGoods = 32;
// 续费座驾
public static Byte OUT_RENEW_CAR_GOODS = 32;
}

View File

@@ -1285,16 +1285,6 @@ public class Constant {
*/
public static final String ACTIVITY_ANNIVERSARY_LOTTERY = "activity_anniversary_lottery";
/**
* 青少年模式充值开关
*/
public static final String TEEN_CHARGE_SWITCH = "teen_charge_switch";
/**
* 青少年模式提现开关
*/
public static final String TEEN_WITHDRAWAL_SWITCH = "teen_withdrawal_switch";
/**
* 实名未成年人充值开关
*/

View File

@@ -1,8 +0,0 @@
package com.accompany.common.constant;
/**
* Created By LeeNana on 2019/12/25.
*/
public class FirstPageConstant {
public static final Integer HALF_HOUR_RANKS_ROOM_NUM = 1;
}

View File

@@ -1,19 +0,0 @@
package com.accompany.common.constant;
/**
* @author yangziwen
* @description
* @date 2018/3/19 17:45
*/
public class MQConstant {
// 赠送礼物队列
public static final String QUEUE_GIFT = "gift-queue";
// 开通或者续费规则队列
public static final String QUEUE_NOBLE = "noble-queue";
// 魔法表情队列名
public static final String QUEUE_MAGIC_GIFT = "magic-gift-queue";
}

View File

@@ -1,25 +0,0 @@
package com.accompany.common.constant;
/**
*性别常量
*/
public enum SexType {
MAEL(1), //男性
FEMAEL(2); //女性
Integer type;
SexType(Integer type) {
this.type = type;
}
public byte getType() {
return type.byteValue();
}
}

View File

@@ -1,19 +0,0 @@
package com.accompany.common.constant;
/**
* 微信开启的支付方式
*
* @author linuxea
* @date 2019/8/8 16:02
*/
public enum WeXinPayTypeEnum {
/**
* app 支付
*/
APP,
/**
* 小程序支付
*/
MINI_APP
}

View File

@@ -1,334 +0,0 @@
package com.accompany.common.wx;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* HTTP工具类
*
* @author lixiangyang
*
*/
public class HttpUtils {
private static Log log = LogFactory.getLog ( HttpUtils.class );
/**
* 定义编码格式 UTF-8
*/
public static final String URL_PARAM_DECODECHARSET_UTF8 = "UTF-8";
/**
* 定义编码格式 GBK
*/
public static final String URL_PARAM_DECODECHARSET_GBK = "GBK";
private static final String URL_PARAM_CONNECT_FLAG = "&";
private static final String EMPTY = "";
private static MultiThreadedHttpConnectionManager connectionManager = null;
private static int connectionTimeOut = 25000;
private static int socketTimeOut = 25000;
private static int maxConnectionPerHost = 20;
private static int maxTotalConnections = 20;
private static HttpClient client;
static {
connectionManager = new MultiThreadedHttpConnectionManager ( );
connectionManager.getParams ( ).setConnectionTimeout ( connectionTimeOut );
connectionManager.getParams ( ).setSoTimeout ( socketTimeOut );
connectionManager.getParams ( ).setDefaultMaxConnectionsPerHost ( maxConnectionPerHost );
connectionManager.getParams ( ).setMaxTotalConnections ( maxTotalConnections );
client = new HttpClient ( connectionManager );
}
/**
* POST方式提交数据
* @param url
* 待请求的URL
* @param params
* 要提交的数据
* @param enc
* 编码
* @return
* 响应结果
* @throws IOException
* IO异常
*/
public static String URLPost ( String url, Map <String, String> params, String enc ) {
String response = EMPTY;
PostMethod postMethod = null;
try {
postMethod = new PostMethod ( url );
postMethod.setRequestHeader ( "Content-Type", "application/x-www-form-urlencoded;charset=" + enc );
//将表单的值放入postMethod中
Set <String> keySet = params.keySet ( );
for ( String key : keySet ) {
String value = params.get ( key );
postMethod.addParameter ( key, value );
}
//执行postMethod
int statusCode = client.executeMethod ( postMethod );
if ( statusCode == HttpStatus.SC_OK ) {
response = postMethod.getResponseBodyAsString ( );
} else {
log.error ( "响应状态码 = " + postMethod.getStatusCode ( ) );
}
} catch ( HttpException e ) {
log.error ( "发生致命的异常,可能是协议不对或者返回的内容有问题", e );
e.printStackTrace ( );
} catch ( IOException e ) {
log.error ( "发生网络异常", e );
e.printStackTrace ( );
} finally {
if ( postMethod != null ) {
postMethod.releaseConnection ( );
postMethod = null;
}
}
return response;
}
/**
* GET方式提交数据
* @param url
* 待请求的URL
* @param params
* 要提交的数据
* @param enc
* 编码
* @return
* 响应结果
* @throws IOException
* IO异常
*/
public static String URLGet ( String url, Map <String, String> params, String enc ) {
String response = EMPTY;
GetMethod getMethod = null;
StringBuffer strtTotalURL = new StringBuffer ( EMPTY );
if ( strtTotalURL.indexOf ( "?" ) == - 1 ) {
strtTotalURL.append ( url ).append ( "?" ).append ( getUrl ( params, enc ) );
} else {
strtTotalURL.append ( url ).append ( "&" ).append ( getUrl ( params, enc ) );
}
log.debug ( "GET请求URL = \n" + strtTotalURL.toString ( ) );
try {
getMethod = new GetMethod ( strtTotalURL.toString ( ) );
getMethod.setRequestHeader ( "Content-Type", "application/x-www-form-urlencoded;charset=" + enc );
//执行getMethod
int statusCode = client.executeMethod ( getMethod );
if ( statusCode == HttpStatus.SC_OK ) {
response = getMethod.getResponseBodyAsString ( );
} else {
log.debug ( "响应状态码 = " + getMethod.getStatusCode ( ) );
}
} catch ( HttpException e ) {
log.error ( "发生致命的异常,可能是协议不对或者返回的内容有问题", e );
e.printStackTrace ( );
} catch ( IOException e ) {
log.error ( "发生网络异常", e );
e.printStackTrace ( );
} finally {
if ( getMethod != null ) {
getMethod.releaseConnection ( );
getMethod = null;
}
}
return response;
}
/**
* 据Map生成URL字符串
* @param map
* Map
* @param valueEnc
* URL编码
* @return
* URL
*/
private static String getUrl ( Map <String, String> map, String valueEnc ) {
if ( null == map || map.keySet ( ).size ( ) == 0 ) {
return ( EMPTY );
}
StringBuffer url = new StringBuffer ( );
Set <String> keys = map.keySet ( );
for ( Iterator <String> it = keys.iterator ( ) ; it.hasNext ( ) ; ) {
String key = it.next ( );
if ( map.containsKey ( key ) ) {
String val = map.get ( key );
String str = val != null ? val : EMPTY;
try {
str = URLEncoder.encode ( str, valueEnc );
} catch ( UnsupportedEncodingException e ) {
e.printStackTrace ( );
}
url.append ( key ).append ( "=" ).append ( str ).append ( URL_PARAM_CONNECT_FLAG );
}
}
String strURL = EMPTY;
strURL = url.toString ( );
if ( URL_PARAM_CONNECT_FLAG.equals ( EMPTY + strURL.charAt ( strURL.length ( ) - 1 ) ) ) {
strURL = strURL.substring ( 0, strURL.length ( ) - 1 );
}
return ( strURL );
}
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet ( String url, String param ) {
String result = "";
BufferedReader in = null;
try {
//自带“?”
String urlNameString = url + "?" + param;
//创建URL对象
URL realUrl = new URL ( urlNameString );
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection ( );
// 设置通用的请求属性
connection.setRequestProperty ( "accept", "*/*" );
connection.setRequestProperty ( "connection", "Keep-Alive" );
connection.setRequestProperty ( "user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)" );
// 建立实际的连接
connection.connect ( );
// 获取所有响应头字段
/*
* Map<String, List<String>> map = connection.getHeaderFields(); //
* 遍历所有的响应头字段 for (String key : map.keySet()) { //禁止数据
* System.out.println(key + "--->" + map.get(key)); }
*/
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader ( new InputStreamReader ( connection.getInputStream ( ) ) );
String line;
while ( ( line = in.readLine ( ) ) != null ) {
result += line;
}
} catch ( Exception e ) {
System.out.println ( "发送GET请求出现异常" + e );
e.printStackTrace ( );
}
// 使用finally块来关闭输入流
finally {
try {
if ( in != null ) {
in.close ( );
}
} catch ( Exception e2 ) {
e2.printStackTrace ( );
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost ( String url, String param ) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL ( url );
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection ( );
// 设置通用的请求属性
conn.setRequestProperty ( "accept", "*/*" );
conn.setRequestProperty ( "connection", "Keep-Alive" );
conn.setRequestProperty ( "user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)" );
// conn.setRequestProperty ( "charset" , "UTF-8");
// 发送POST请求必须设置如下两行
conn.setDoOutput ( true );
conn.setDoInput ( true );
// 获取URLConnection对象对应的输出流
out = new PrintWriter ( conn.getOutputStream ( ) );
// 发送请求参数
out.print ( param );
// flush输出流的缓冲
out.flush ( );
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader ( new InputStreamReader ( conn.getInputStream ( ) ) );
String line;
while ( ( line = in.readLine ( ) ) != null ) {
result += line;
}
} catch ( Exception e ) {
System.out.println ( "发送 POST 请求出现异常!" + e );
e.printStackTrace ( );
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if ( out != null ) {
out.close ( );
}
if ( in != null ) {
in.close ( );
}
} catch ( IOException ex ) {
ex.printStackTrace ( );
}
}
return result;
}
public static void main ( String[] args ) throws Exception {
/*Map map = new HashMap <> ( );
map.put ( "appid", "wx009d793f92c24eec" );
map.put ( "mch_id", "1484701192" );
map.put ( "nonce_str", PayUtil.getRandomStringByLength(16) );
map.put ( "out_trade_no", "20150806125346" );
map.put ( "sign", PayUtil.getSign ( map ) );
//以XML格式的数据发送
String request = XMLParser.getXMLFromMap (map );
System.out.println (request );
String data = sendPost ( "https://api.mch.weixin.qq.com/pay/orderquery", request);
System.out.println ( data );*/
}
}

View File

@@ -1,11 +0,0 @@
package com.accompany.common.wx;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
public interface IServiceRequest {
String sendPost(String var1, Object var2) throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException;
}

View File

@@ -1,76 +0,0 @@
package com.accompany.common.wx;
import java.security.MessageDigest;
/**
* User: rizenguo
* Date: 2014/10/23
* Time: 15:43
*/
public class MD5 {
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "a", "b", "c", "d", "e", "f"};
/**
* 转换字节数组为16进制字串
* @param b 字节数组
* @return 16进制字串
*/
public static String byteArrayToHexString(byte[] b) {
StringBuilder resultSb = new StringBuilder();
for (byte aB : b) {
resultSb.append(byteToHexString(aB));
}
return resultSb.toString();
}
/**
* 转换byte到16进制
* @param b 要转换的byte
* @return 16进制格式
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n = 256 + n;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* MD5编码
* @param origin 原始字符串
* @return 经过MD5加密之后的结果
*/
public static String MD5Encode(String origin) {
String resultString = null;
try {
resultString = origin;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(resultString.getBytes("UTF-8"));
resultString = byteArrayToHexString(md.digest());
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
}

View File

@@ -1,87 +0,0 @@
package com.accompany.common.wx;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.*;
public class PayUtil {
public static String getTime_stamp ( ) {
/*String stamp="1472275204";
*//*Date d=new Date();
d.getTime();*//*
return stamp;*/
String stamp = String.valueOf ( new Date ( ).getTime ( ) );
return stamp;
}
public static String getRandomStringByLength ( int len ) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random ( );
StringBuffer sb = new StringBuffer ( );
for ( int i = 0 ; i < len ; i++ ) {
int number = random.nextInt ( base.length ( ) );
sb.append ( base.charAt ( number ) );
}
return sb.toString ( );
}
public static String getSign ( Map <String, String> map ,String wxPayKey) {
ArrayList <String> list = new ArrayList <String> ( );
for ( Map.Entry <String, String> entry : map.entrySet ( ) ) {
if ( entry.getValue ( ) != "" && ! entry.toString ( ).equals ( "return_code" ) && ! entry.toString ( ).equals ( "return_msg" ) && ! entry.toString ( ).equals ( "result_code" ) ) {
// System.out.println ( );
list.add ( entry.getKey ( ) + "=" + entry.getValue ( ) + "&" );
}
}
int size = list.size ( );
String[] arrayToSort = list.toArray ( new String[ size ] );
Arrays.sort ( arrayToSort, String.CASE_INSENSITIVE_ORDER );
StringBuilder sb = new StringBuilder ( );
for ( int i = 0 ; i < size ; i++ ) {
sb.append ( arrayToSort[ i ] );
}
String result = sb.toString ( );
//key 该方法key的需要根据你当前公众号的key进行修改
result += "key="+wxPayKey;
//Util.log("Sign Before MD5:" + result);
result = MD5.MD5Encode ( result ).toUpperCase ( );
//Util.log("Sign Result:" + result);
return result;
}
public static void main ( String[] args ) throws IOException, SAXException, ParserConfigurationException {
/*String string = "<xml>\n" +
" <appid><![CDATA[wx009d793f92c24eec]]></appid>\n" +
" <attach><![CDATA[支付测试]]></attach>\n" +
" <bank_type><![CDATA[CFT]]></bank_type>\n" +
" <fee_type><![CDATA[CNY]]></fee_type>\n" +
" <is_subscribe><![CDATA[Y]]></is_subscribe>\n" +
" <mch_id><![CDATA[1484701192]]></mch_id>\n" +
" <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>\n" +
" <openid><![CDATA[o5fpU1bSN0b8xcU3syC8Md8ZfrJ4]]></openid>\n" +
" <out_trade_no><![CDATA[1409811653]]></out_trade_no>\n" +
*//* " <sign><![CDATA[C96E9728B45C69D9CE093A7D733EB8E2]]></sign>\n" +*//*
" <sub_mch_id><![CDATA[10000100]]></sub_mch_id>\n" +
" <time_end><![CDATA[20140903131540]]></time_end>\n" +
" <total_fee>1</total_fee>\n" +
" \n" +
" <trade_type><![CDATA[JSAPI]]></trade_type>\n" +
" <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>\n" +
"</xml>";
Map map = XMLParser.getMapFromXML ( string );
String s = PayUtil.getSign ( map );
System.out.println (s );//"0C1D1ADD0DD75F9F90D6CF48C90E5AB0"*/
}
}

View File

@@ -1,122 +0,0 @@
package com.accompany.common.wx;
import com.thoughtworks.xstream.XStream;
import java.io.*;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.util.Map;
public class Util {
//打log用
//private static Log logger = new Log(log)
/**
* 通过反射的方式遍历对象的属性和属性值,方便调试
*
* @param o 要遍历的对象
* @throws Exception
*/
public static void reflect(Object o) throws Exception {
Class cls = o.getClass();
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true);
Util.log(f.getName() + " -> " + f.get(o));
}
}
public static byte[] readInput(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.close();
in.close();
return out.toByteArray();
}
public static String inputStreamToString(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
}
public static InputStream getStringStream(String sInputString) throws UnsupportedEncodingException {
ByteArrayInputStream tInputStringStream = null;
if (sInputString != null && !sInputString.trim().equals("")) {
tInputStringStream = new ByteArrayInputStream(sInputString.getBytes("UTF-8"));
}
return tInputStringStream;
}
public static Object getObjectFromXML(String xml, Class tClass) {
//将从API返回的XML数据映射到Java对象
XStream xStreamForResponseData = new XStream();
xStreamForResponseData.alias("xml", tClass);
xStreamForResponseData.ignoreUnknownElements();//暂时忽略掉一些新增的字段
return xStreamForResponseData.fromXML(xml);
}
public static String getStringFromMap( Map<String, Object> map, String key, String defaultValue) {
if (key == "" || key == null) {
return defaultValue;
}
String result = (String) map.get(key);
if (result == null) {
return defaultValue;
} else {
return result;
}
}
public static int getIntFromMap(Map<String, Object> map, String key) {
if (key == "" || key == null) {
return 0;
}
if (map.get(key) == null) {
return 0;
}
return Integer.parseInt((String) map.get(key));
}
/**
* 打log接口
* @param log 要打印的log字符串
* @return 返回log
*/
public static String log(Object log){
// logger.i(log.toString());
System.out.println(log);
return log.toString();
}
/**
* 获取ip
* @return
* @throws IOException
*/
public static String getIpAdd()throws IOException {
InetAddress[] inetAdds = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
return inetAdds[0].getHostAddress();
}
/**
* 读取本地的xml数据一般用来自测用
* @param localPath 本地xml文件路径
* @return 读到的xml字符串
*/
public static String getLocalXMLString(String localPath) throws IOException {
return Util.inputStreamToString( Util.class.getResourceAsStream(localPath));
}
}

View File

@@ -1,104 +0,0 @@
package com.accompany.common.wx;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* User: rizenguo
* Date: 2014/11/1
* Time: 14:06
*/
public class XMLParser {
/**
* 修复XXE漏洞
* @return
* @throws ParserConfigurationException
*/
private static DocumentBuilderFactory getSafeDocumentBuilderFactory() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
String reature = "http://apache.org/xml/features/disallow-doctype-decl";
factory.setFeature(reature, true);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
reature = "http://xml.org/sax/features/external-general-entities";
factory.setFeature(reature, false);
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
reature = "http://xml.org/sax/features/external-parameter-entities";
factory.setFeature(reature, false);
// Disable external DTDs as well
reature = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
factory.setFeature(reature, false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
return factory;
}
public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
//这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
DocumentBuilderFactory factory = XMLParser.getSafeDocumentBuilderFactory();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = Util.getStringStream(xmlString);
Document document = builder.parse(is);
//获取到document里面的全部结点
NodeList allNodes = document.getFirstChild().getChildNodes();
Node node;
Map<String, Object> map = new HashMap<String, Object>();
int i=0;
while (i < allNodes.getLength()) {
node = allNodes.item(i);
if(node instanceof Element){
map.put(node.getNodeName(),node.getTextContent());
}
i++;
}
return map;
}
public static String getXMLFromMap(Map<String, Object> map)throws Exception{
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key = it.next();
sb.append("<"+key+">").append(map.get(key)).append("</"+key+">");
}
sb.append("</xml>");
return sb.toString();
}
}

View File

@@ -1,42 +0,0 @@
package com.accompany.common.wx.result;
/**
* Created by liuguofu on 2017/7/10.
*/
public class WxAccessTokenRet {
private String access_token;// 获取到的凭证
private int expires_in;//凭证有效时间,单位:秒
private int errcode;
private String errmsg;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public int getErrcode() {
return errcode;
}
public void setErrcode(int errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
}

View File

@@ -1,43 +0,0 @@
package com.accompany.common.wx.result;
/**
* Created by liuguofu on 2017/7/10.
*/
public class WxTicketRet {
private String ticket;// 获取到的ticket
private int expires_in;//凭证有效时间,单位:秒
private int errcode;
private String errmsg;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public int getErrcode() {
return errcode;
}
public void setErrcode(int errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
}

View File

@@ -1,11 +0,0 @@
package com.accompany.core.model;
import lombok.Data;
@Data
public class UserTeenConf {
/**
* 每日限额充值元
*/
private Integer limitEveryDay;
}

View File

@@ -5,7 +5,6 @@ import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.*;
import com.accompany.core.model.Account;
import com.accompany.core.model.UserTeenConf;
import com.accompany.core.model.Users;
import com.accompany.core.model.UsersExample;
import com.accompany.core.mybatismapper.AccountMapper;
@@ -508,25 +507,6 @@ public class UsersBaseService extends BaseService {
return usersList;
}
public UserTeenConf getUserTeenConfig() {
UserTeenConf userTeenConf = JSONObject.parseObject(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.USER_TEEN, "{}"), UserTeenConf.class);
if (userTeenConf.getLimitEveryDay() == null) {
userTeenConf.setLimitEveryDay(50);
}
return userTeenConf;
}
public Boolean getTeenChargeSwitch(){
Boolean teenChargeSwitch = Boolean.valueOf(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.TEEN_CHARGE_SWITCH, "true"));
return teenChargeSwitch;
}
public Boolean getTeenWithdrawalSwitch(){
Boolean teenWithdrawalSwitch = Boolean.valueOf(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.TEEN_WITHDRAWAL_SWITCH, "true"));
return teenWithdrawalSwitch;
}
/**
* 获取客服uid
*/

View File

@@ -1,5 +1,7 @@
package com.accompany.core.util;
import java.nio.charset.StandardCharsets;
public class MD5 {
public static void main(String[] args) throws Exception {
String str = "12345678";
@@ -7,7 +9,7 @@ public class MD5 {
}
public static String getMD5(String source){
return getMD5(source.getBytes());
return getMD5(source.getBytes(StandardCharsets.UTF_8));
}
public static String getMD5(byte[] source) {

View File

@@ -1,206 +0,0 @@
package com.accompany.payment.agentchangestrategy;
import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.RandomUtil;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.service.SysConfService;
import com.accompany.core.service.common.JedisService;
import com.accompany.payment.config.AliPayConfig;
import com.accompany.payment.constant.PayConstant;
import com.accompany.payment.dto.AgentChangeStrategyConfigDTO;
import com.accompany.payment.dto.AlipayAgentDTO;
import com.accompany.payment.dto.PayAgentConfDTO;
import com.accompany.payment.model.ChargeRecord;
import com.accompany.payment.params.AgentChangeDimensions;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
@Service("alipayNativeAgentChangeStrategy")
@Slf4j
public class AlipayNativeAgentChangeStrategy implements IAgentChangeStrategy {
@Autowired
private SysConfService sysConfService;
@Autowired
private JedisService jedisService;
@Autowired
private AliPayConfig aliPayConfig;
private PayAgentConfDTO defaultAlipayAgentConf;
@PostConstruct
public void init() {
defaultAlipayAgentConf = new PayAgentConfDTO();
AlipayAgentDTO defaultAlipayAgent = new AlipayAgentDTO();
defaultAlipayAgent.setAppId(aliPayConfig.getAppId());
defaultAlipayAgent.setAppPrivateKey(aliPayConfig.getAppPrivateKey());
defaultAlipayAgent.setPublicKey(aliPayConfig.getPublicKey());
defaultAlipayAgentConf.setPayAgent(defaultAlipayAgent);
}
@Override
public PayAgentConfDTO getPayAgentConfig(AgentChangeDimensions dimensions) {
String strategyStr = sysConfService.getSysConfValueById(Constant.SysConfId.ALIPAY_NATIVE_AGENT_CHANGE_STRATEGY);
if (StringUtils.isBlank(strategyStr)) {
log.warn("[AlipayNativeAgentChangeStrategy]没有支付宝实体切换策略配置,返回默认的支付宝商户");
return defaultAlipayAgentConf;
}
AgentChangeStrategyConfigDTO strategyConfig = JSONObject.parseObject(strategyStr, AgentChangeStrategyConfigDTO.class);
log.info("[AlipayNativeAgentChangeStrategy]当前启用的模式为:{}", strategyConfig.getMode());
switch (strategyConfig.getMode()) {
case PayConstant.AgentChangeMode.MANUAL:
return getManualModeAgentConf(strategyConfig);
case PayConstant.AgentChangeMode.AUTO:
return getAutoModeAgentConf(dimensions, strategyConfig);
default:
return getManualModeAgentConf(strategyConfig);
}
}
@Override
public Object getPayAgentByConfId(String confId) {
String agentConfigStr = sysConfService.getSysConfValueById(confId);
if (StringUtils.isBlank(agentConfigStr)) {
return null;
}
AlipayAgentDTO alipayAgent = JSONObject.parseObject(agentConfigStr, AlipayAgentDTO.class);
if (StringUtils.isBlank(alipayAgent.getAppId()) || StringUtils.isBlank(alipayAgent.getAppPrivateKey()) || StringUtils.isBlank(alipayAgent.getPublicKey())) {
return null;
}
return alipayAgent;
}
@Override
public void postProcessAfterPay(ChargeRecord chargeRecord) {
if (chargeRecord == null) {
return;
}
Long uid = chargeRecord.getUid();
jedisService.hincr(RedisKey.alipay_native_user_pay_count.getKey(), uid.toString());
}
private PayAgentConfDTO getAutoModeAgentConf(AgentChangeDimensions dimensions, AgentChangeStrategyConfigDTO strategyConfig) {
if (dimensions == null || dimensions.getUid() == null) {
log.warn("[AlipayNativeAgentChangeStrategy]策略判断必要维度为空,返回默认的支付宝商户");
return defaultAlipayAgentConf;
}
String usingAgentConfigId = jedisService.hget(RedisKey.alipay_user_using_agent.getKey(), dimensions.getUid().toString());
if (StringUtils.isBlank(usingAgentConfigId)) {
usingAgentConfigId = getRandomAgentConfigId(strategyConfig.getAutoAgentConfigIds());
if (StringUtils.isBlank(usingAgentConfigId)) {
// 获取不到初始的id则使用默认的
return defaultAlipayAgentConf;
} else {
renewUserUsingAgent(dimensions.getUid(), usingAgentConfigId);
}
} else {
if (CollectionUtils.isNotEmpty(strategyConfig.getAutoAgentConfigIds()) && strategyConfig.getAutoAgentConfigIds().indexOf(usingAgentConfigId) >= 0) {
String paidCountStr = jedisService.hget(RedisKey.alipay_native_user_pay_count.getKey(), dimensions.getUid().toString());
if (StringUtils.isNotBlank(paidCountStr)) {
Integer paidCount = Integer.valueOf(paidCountStr);
if (paidCount >= strategyConfig.getUserPaidCount()) {
String oldUsingAgentConfigId = usingAgentConfigId;
usingAgentConfigId = getNextAgentConfigId(strategyConfig, usingAgentConfigId);
log.info("用户 {} 已使用 {} 支付了 {} 次,下一次使用 {} 支付", dimensions.getUid(), oldUsingAgentConfigId, paidCount, usingAgentConfigId);
if (StringUtils.isNotBlank(usingAgentConfigId)) {
renewUserUsingAgent(dimensions.getUid(), usingAgentConfigId);
} else {
return defaultAlipayAgentConf;
}
}
}
} else {
// 不在当前配置的id数组中则认为是存在问题等原因去掉了重新随机选择
log.info("用户 {} 使用的id {} 已从候选库中移除,重新选择", dimensions.getUid(), usingAgentConfigId);
usingAgentConfigId = getRandomAgentConfigId(strategyConfig.getAutoAgentConfigIds());
if (StringUtils.isBlank(usingAgentConfigId)) {
// 获取不到初始的id则使用默认的
return defaultAlipayAgentConf;
} else {
renewUserUsingAgent(dimensions.getUid(), usingAgentConfigId);
}
}
}
return getAlipayAgentDTOByConfId(usingAgentConfigId);
}
private void renewUserUsingAgent(Long uid, String usingAgentConfigId) {
jedisService.hset(RedisKey.alipay_user_using_agent.getKey(), uid.toString(), usingAgentConfigId);
jedisService.hdel(RedisKey.alipay_native_user_pay_count.getKey(), uid.toString());
}
private String getNextAgentConfigId(AgentChangeStrategyConfigDTO strategyConfig, String usingAgentConfigId) {
List<String> autoAgentConfigIds = strategyConfig.getAutoAgentConfigIds();
if (CollectionUtils.isEmpty(autoAgentConfigIds)) {
log.warn("[AlipayNativeAgentChangeStrategy]支付宝实体切换策略配置中的autoAgentConfigIds为空");
return null;
}
int idx = autoAgentConfigIds.indexOf(usingAgentConfigId);
if (idx < 0) {
// 不在列表中,可能是被移除了,则随机返回一个
return getRandomAgentConfigId(autoAgentConfigIds);
} else {
int nextIdx = (idx + 1) % autoAgentConfigIds.size();
return autoAgentConfigIds.get(nextIdx);
}
}
private String getRandomAgentConfigId(List<String> autoAgentConfigIds) {
if (CollectionUtils.isEmpty(autoAgentConfigIds)) {
log.warn("[AlipayNativeAgentChangeStrategy]支付宝实体切换策略配置中的autoAgentConfigIds为空");
return null;
}
int idx = RandomUtil.randomByRange(0, autoAgentConfigIds.size()) % autoAgentConfigIds.size();
log.info("[AlipayNativeAgentChangeStrategy]随机选择支付商户,候选配置: {}, 随机使用第 {} 个", JSONArray.toJSONString(autoAgentConfigIds), idx + 1);
return autoAgentConfigIds.get(idx);
}
private PayAgentConfDTO getManualModeAgentConf(AgentChangeStrategyConfigDTO strategyConfig) {
if (StringUtils.isBlank(strategyConfig.getManualAgentConfigId())) {
log.warn("[AlipayNativeAgentChangeStrategy]支付宝实体切换策略配置中的manualAgentConfigId为空返回默认的支付宝商户");
return defaultAlipayAgentConf;
}
return getAlipayAgentDTOByConfId(strategyConfig.getManualAgentConfigId());
}
private PayAgentConfDTO getAlipayAgentDTOByConfId(String configId) {
String manualAgentConfigStr = sysConfService.getSysConfValueById(configId);
if (StringUtils.isBlank(manualAgentConfigStr)) {
log.warn("[AlipayNativeAgentChangeStrategy]没有{}这个配置项,返回默认的支付宝商户", configId);
return defaultAlipayAgentConf;
}
AlipayAgentDTO alipayAgent = JSONObject.parseObject(manualAgentConfigStr, AlipayAgentDTO.class);
if (StringUtils.isBlank(alipayAgent.getAppId()) || StringUtils.isBlank(alipayAgent.getAppPrivateKey()) || StringUtils.isBlank(alipayAgent.getPublicKey())) {
log.warn("[AlipayNativeAgentChangeStrategy]{}配置项不正确:{},返回默认的支付宝商户", configId, JSONObject.toJSONString(alipayAgent));
return defaultAlipayAgentConf;
}
PayAgentConfDTO agentConf = new PayAgentConfDTO();
agentConf.setConfigId(configId);
agentConf.setPayAgent(alipayAgent);
return agentConf;
}
}

View File

@@ -1,22 +0,0 @@
package com.accompany.payment.agentchangestrategy;
import com.accompany.payment.dto.PayAgentConfDTO;
import com.accompany.payment.model.ChargeRecord;
import com.accompany.payment.params.AgentChangeDimensions;
/**
* 支付实体切换策略接口
*/
public interface IAgentChangeStrategy {
/**
* 获取实体配置
* @param dimensions
* @return
*/
PayAgentConfDTO getPayAgentConfig(AgentChangeDimensions dimensions);
Object getPayAgentByConfId(String confId);
void postProcessAfterPay(ChargeRecord chargeRecord);
}

View File

@@ -1,120 +0,0 @@
package com.accompany.payment.alipay;
import com.accompany.common.constant.Constant;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.service.SysConfService;
import com.accompany.core.util.StringUtils;
import com.accompany.payment.config.AliPayConfig;
import com.accompany.payment.config.BaseAliPayConfig;
import com.accompany.payment.constant.PayConstant;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.domain.ExtUserInfo;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Calendar;
import java.util.Date;
/**
* @date 2021年01月12日
* @descrition 支付宝支付业务处理抽象类
*/
public abstract class AbstractAlipayService {
@Autowired
private SysConfService sysConfService;
public AlipayClient getAlipayClientInstance() {
BaseAliPayConfig aliPayConfig = getAliPayConfig();
return new DefaultAlipayClient(
aliPayConfig.getUrl(),
aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(),
PayConstant.ALIPAY_FORMAT,
PayConstant.ALIPAY_CHATSET,
aliPayConfig.getPublicKey(),
PayConstant.ALIPAY_SIGN_TYPE);
}
public AlipayTradeAppPayRequest buildAliAppRequest(Long amount, String orderNo, String subject, String body,
String realName, String idCardNum) {
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody(body);
model.setSubject(subject);
model.setOutTradeNo(orderNo);
model.setTotalAmount(amount.toString());
model.setProductCode(PayConstant.alipayProdCode.QUICK_MSECURITY_PAY);
model.setGoodsType("0");
String userSwitch = sysConfService.getSysConfValueById(Constant.SysConfId.ALIPAY_ORDER_USER);
if (StringUtils.isNotBlank(userSwitch) && Boolean.parseBoolean(userSwitch)) {
//买家实名信息
ExtUserInfo userInfo = buildAlipayUserInfo(realName, idCardNum);
model.setExtUserInfo(userInfo);
}
//订单失效时间
String timeout = sysConfService.getSysConfValueById(Constant.SysConfId.ALIPAY_ORDER_TIMEOUT);
if (StringUtils.isNotBlank(timeout)) {
Date date = DateTimeUtil.getNextMinute(Calendar.getInstance().getTime(), Integer.parseInt(timeout));
String time = DateTimeUtil.convertDate(date, DateTimeUtil.DEFAULT_DATE_MINUTE_PATTERN);
model.setTimeExpire(time);
}
model.setDisablePayChannels("pcredit,pcreditpayInstallment");
request.setBizModel(model);
request.setNotifyUrl(getAliPayConfig().getNotifyUrl());
return request;
}
public AlipayTradeWapPayRequest buildAliWapRequest(Long amount, String orderNo, String subject, String body,
String successUrl, String realName, String idCardNum) {
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setBody(body);
model.setSubject(subject);
model.setOutTradeNo(orderNo);
model.setTotalAmount(amount.toString());
model.setProductCode(PayConstant.alipayProdCode.QUICK_WAP_WAY);
model.setGoodsType("0");
//买家实名信息
String userSwitch = sysConfService.getSysConfValueById(Constant.SysConfId.ALIPAY_ORDER_USER);
if (StringUtils.isNotBlank(userSwitch) && Boolean.parseBoolean(userSwitch)) {
ExtUserInfo userInfo = buildAlipayUserInfo(realName, idCardNum);
model.setExtUserInfo(userInfo);
}
//订单失效时间
String timeout = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.H5_ORDER_TIMEOUT, "1");
Date date = DateTimeUtil.getNextMinute(Calendar.getInstance().getTime(), Integer.parseInt(timeout));
String time = DateTimeUtil.convertDate(date, DateTimeUtil.DEFAULT_DATE_MINUTE_PATTERN);
model.setTimeExpire(time);
model.setDisablePayChannels("pcredit,pcreditpayInstallment");
request.setBizModel(model);
request.setNotifyUrl(getAliPayConfig().getNotifyUrl());
request.setReturnUrl(successUrl);
return request;
}
private ExtUserInfo buildAlipayUserInfo(String realName, String idCardNum) {
ExtUserInfo userInfo = new ExtUserInfo();
userInfo.setMinAge("18");
userInfo.setNeedCheckInfo("T");
if (StringUtils.isNotBlank(realName) && StringUtils.isNotBlank(idCardNum)) {
userInfo.setName(realName);
userInfo.setCertType("IDENTITY_CARD");
userInfo.setCertNo(idCardNum);
userInfo.setFixBuyer("T");
}
return userInfo;
}
protected abstract BaseAliPayConfig getAliPayConfig();
}

View File

@@ -1,93 +0,0 @@
package com.accompany.payment.alipay;
/**
* 支付宝客户端配置
*/
public class AliPayClientParam {
/**
* 开放状态
*/
private Boolean status;
/**
* 支付配置的序号
* 用于回调的时候获取公钥
*/
private Integer index;
/**
* 支付url
*/
private String url;
/**
* appId
*/
private String appId;
/**
* 应用私钥
*/
private String appPrivateKey;
/**
* 支付宝公钥
*/
private String publicKey;
/**
* 回调地址
*/
private String notifyUrl;
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppPrivateKey() {
return appPrivateKey;
}
public void setAppPrivateKey(String appPrivateKey) {
this.appPrivateKey = appPrivateKey;
}
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}

View File

@@ -1,265 +0,0 @@
package com.accompany.payment.alipay;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author yangming
* @date 2018-10-24
* @descrition 支付宝回调参数实体
*/
public class AlipayNotifyParam {
/**
* 应用appId
**/
private String app_id;
/**
* 支付宝交易凭证号
**/
private String trade_no;
/**
* 原支付请求的商户订单号
**/
private String out_trade_no;
/**
* 商户业务ID主要是退款通知中返回退款申请的流水号
**/
private String out_biz_no;
/**
* 买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字
**/
private String buyer_id;
/**
* 买家支付宝账号
**/
private String buyer_logon_id;
/**
* 卖家支付宝用户号
**/
private String seller_id;
/**
* 卖家支付宝账号
**/
private String seller_email;
/**
* 交易目前所处的状态,见交易状态说明
**/
private String trade_status;
/**
* 本次交易支付的订单金额
**/
private BigDecimal total_amount;
/**
* 商家在交易中实际收到的款项
**/
private BigDecimal receipt_amount;
/**
* 用户在交易中支付的金额
**/
private BigDecimal buyer_pay_amount;
/**
* 退款通知中,返回总退款金额,单位为元,支持两位小数
**/
private BigDecimal refund_fee;
/**
* 商品的标题/交易标题/订单标题/订单关键字等
**/
private String subject;
/**
* 该订单的备注、描述、明细等。对应请求时的body参数原样通知回来
**/
private String body;
/**
* 该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss
**/
private Date gmt_create;
/**
* 该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss
**/
private Date gmt_payment;
/**
* 该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S
**/
private Date gmt_refund;
/**
* 该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss
**/
private Date gmt_close;
/**
* 支付成功的各个渠道金额信息,array
**/
private String fund_bill_list;
/**
* 公共回传参数,如果请求时传递了该参数,则返回给商户时会在异步通知时将该参数原样返回
**/
private String passback_params;
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public String getTrade_no() {
return trade_no;
}
public void setTrade_no(String trade_no) {
this.trade_no = trade_no;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getOut_biz_no() {
return out_biz_no;
}
public void setOut_biz_no(String out_biz_no) {
this.out_biz_no = out_biz_no;
}
public String getBuyer_id() {
return buyer_id;
}
public void setBuyer_id(String buyer_id) {
this.buyer_id = buyer_id;
}
public String getBuyer_logon_id() {
return buyer_logon_id;
}
public void setBuyer_logon_id(String buyer_logon_id) {
this.buyer_logon_id = buyer_logon_id;
}
public String getSeller_id() {
return seller_id;
}
public void setSeller_id(String seller_id) {
this.seller_id = seller_id;
}
public String getSeller_email() {
return seller_email;
}
public void setSeller_email(String seller_email) {
this.seller_email = seller_email;
}
public String getTrade_status() {
return trade_status;
}
public void setTrade_status(String trade_status) {
this.trade_status = trade_status;
}
public BigDecimal getTotal_amount() {
return total_amount;
}
public void setTotal_amount(BigDecimal total_amount) {
this.total_amount = total_amount;
}
public BigDecimal getReceipt_amount() {
return receipt_amount;
}
public void setReceipt_amount(BigDecimal receipt_amount) {
this.receipt_amount = receipt_amount;
}
public BigDecimal getBuyer_pay_amount() {
return buyer_pay_amount;
}
public void setBuyer_pay_amount(BigDecimal buyer_pay_amount) {
this.buyer_pay_amount = buyer_pay_amount;
}
public BigDecimal getRefund_fee() {
return refund_fee;
}
public void setRefund_fee(BigDecimal refund_fee) {
this.refund_fee = refund_fee;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Date getGmt_create() {
return gmt_create;
}
public void setGmt_create(Date gmt_create) {
this.gmt_create = gmt_create;
}
public Date getGmt_payment() {
return gmt_payment;
}
public void setGmt_payment(Date gmt_payment) {
this.gmt_payment = gmt_payment;
}
public Date getGmt_refund() {
return gmt_refund;
}
public void setGmt_refund(Date gmt_refund) {
this.gmt_refund = gmt_refund;
}
public Date getGmt_close() {
return gmt_close;
}
public void setGmt_close(Date gmt_close) {
this.gmt_close = gmt_close;
}
public String getFund_bill_list() {
return fund_bill_list;
}
public void setFund_bill_list(String fund_bill_list) {
this.fund_bill_list = fund_bill_list;
}
public String getPassback_params() {
return passback_params;
}
public void setPassback_params(String passback_params) {
this.passback_params = passback_params;
}
}

View File

@@ -1,23 +0,0 @@
package com.accompany.payment.alipay;
import com.accompany.payment.config.AliPayConfig;
import com.accompany.payment.config.BaseAliPayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author yangming
* @date 2018-10-18
* @descrition 支付宝支付业务处理
*/
@Service
public class AlipayService extends AbstractAlipayService {
@Autowired
private AliPayConfig aliPayConfig;
@Override
protected BaseAliPayConfig getAliPayConfig() {
return aliPayConfig;
}
}

View File

@@ -1,58 +0,0 @@
package com.accompany.payment.alipay;
import com.accompany.payment.config.AliPayConfig;
import com.accompany.payment.constant.PayConstant;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author yangming
* @date 2018-10-22
* @description 支付宝转账处理
*/
@Service
public class TransferService {
@Autowired
private AlipayService alipayService;
/**
* 支付宝单人转账
*
* @param model
* @return
* @throws Exception
*/
public AlipayFundTransToaccountTransferResponse AlipayTransfer(AlipayFundTransToaccountTransferModel model) throws Exception {
AlipayClient alipayClient = alipayService.getAlipayClientInstance();
AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
request.setBizModel(model);
AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
return response;
}
/**
* 构造Transfer对象
*
* @param orderNo
* @param account
* @param accountName
* @param amount
* @param remark
* @return
*/
public AlipayFundTransToaccountTransferModel buildTransferModel(String orderNo, String account, String accountName, String amount, String remark) {
AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
model.setOutBizNo(orderNo);
model.setPayeeType(PayConstant.ALIPAY_PAYEE_TYPE);
model.setPayeeAccount(account);
model.setAmount(amount);
model.setPayeeRealName(accountName);
model.setRemark(remark);
return model;
}
}

View File

@@ -1,23 +0,0 @@
package com.accompany.payment.alipay;
import com.accompany.payment.config.AliPayConfig;
import com.accompany.payment.config.BaseAliPayConfig;
import com.accompany.payment.config.YinyouAliPayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @date 2021年01月12日
* @descrition 平台支付宝支付业务处理
*/
@Service
public class YinyouAlipayService extends AbstractAlipayService {
@Autowired
private YinyouAliPayConfig aliPayConfig;
@Override
protected BaseAliPayConfig getAliPayConfig() {
return aliPayConfig;
}
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:41
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig extends BaseAliPayConfig {
}

View File

@@ -1,24 +0,0 @@
package com.accompany.payment.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:41
*/
@Data
public abstract class BaseAliPayConfig {
private String url;
private String appId;
private String appPrivateKey;
private String publicKey;
private String notifyUrl;
}

View File

@@ -1,23 +0,0 @@
package com.accompany.payment.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 微信支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:35
*/
@Data
public class BaseWxPayConfig {
private String url;
private String appId;
private String mchId;
private String apiKey;
private String notifyUrl;
}

View File

@@ -1,59 +0,0 @@
package com.accompany.payment.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.validation.constraints.NotBlank;
/**
* @author linuxea
* @date 2019/8/6 10:24
*/
@ConfigurationProperties(prefix = "hui-ka")
@Configuration
@Data
public class HuiKaConfig {
/**
* 统一下单地址
*/
@NotBlank(message = "统一下单地址不能为空")
private String unifiedOrderUrl;
/**
* 后端通知地址
*/
@NotBlank(message = "后端通知地址不能为空")
private String backendNotifyUrl;
/**
* 机构号
*/
@NotBlank(message = "机构号不能空")
private String orgId;
/**
* 商户号
*/
@NotBlank(message = "商户号不能为空")
private String mchNo;
/**
* 私钥
*/
@NotBlank(message = "商户号不能为空")
private String accessPrvKey;
/**
* 公钥
*/
@NotBlank(message = "公钥不能为空")
private String accessPubKey;
/**
* 平台公钥
*/
@NotBlank(message = "平台公钥不能为空")
private String platformPubKey;
}

View File

@@ -1,45 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 汇聚支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:42
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "joinpay")
public class JoinPayConfig {
public static String merchantNo;
public static String key;
public static String applyTradeUrl;
public static String callbackUrl;
public static Boolean open;
public void setMerchantNo(String merchantNo) {
JoinPayConfig.merchantNo = merchantNo;
}
public void setKey(String key) {
JoinPayConfig.key = key;
}
public void setApplyTradeUrl(String applyTradeUrl) {
JoinPayConfig.applyTradeUrl = applyTradeUrl;
}
public void setCallbackUrl(String callbackUrl) {
JoinPayConfig.callbackUrl = callbackUrl;
}
public static void setOpen(Boolean open) {
JoinPayConfig.open = open;
}
}

View File

@@ -1,27 +0,0 @@
package com.accompany.payment.config;
import com.accompany.payment.alipay.AliPayClientParam;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "multi-alipay")
public class MultiAliPayConfig {
public static List<AliPayClientParam> alipayConfigs = new ArrayList<>();
public List<AliPayClientParam> getAlipayConfigs() {
return alipayConfigs;
}
public void setAlipayConfigs(List<AliPayClientParam> alipayConfigs) {
MultiAliPayConfig.alipayConfigs = alipayConfigs;
}
}

View File

@@ -1,49 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Created by PaperCut on 2018/2/3.
* Pingxx支付配置
*/
@Configuration
@ConfigurationProperties(prefix = "pingxx")
public class PingxxConfig {
public String apiKey;
public String appId;
public String publicKey;
private String privateKey;
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public void setAppId(String appId) {
this.appId = appId;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getApiKey() {
return apiKey;
}
public String getAppId() {
return appId;
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {
return privateKey;
}
}

View File

@@ -1,116 +0,0 @@
package com.accompany.payment.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 衫德支付配置
*
*/
@Configuration
@ConfigurationProperties("sand-pay")
@Lazy(false)
@Data
public class SandPayConfig {
/**
* 商户号
*/
private String agentId;
/**
* 约定秘钥,无需更改
*/
private String alipayPrivateKeyMi;
/**
* 约定的公钥,无需更改
*/
private String alipayPublicKey;
/**
* 商户秘钥
*/
private String alipayPrivateKey;
/**
* 随机md5 key
*/
private String md5Key;
/**
* 支付宝支付回调地址
*/
private String alipayNotifyUrl;
/**
* 支付宝支付地址
*/
private String alipayUrl;
/**
* 支付成功返回地址
*/
private String returnUrl;
private String metaOption;
/**
* 订单过期时间(分钟)
*/
private Integer expireMinutes;
@Component
@Lazy(value = false)
@Order(-1)
@ConfigurationProperties(prefix = "sand-pay.wxminiapps")
public static class MiniAppConfig {
public static String mid;
/**
* 商户公钥base64
*/
public static String pubKeyBase64;
/**
* 商户私钥base64
*/
public static String privateKeyBase64;
/**
* 商户私钥密码
*/
public static String privateKeyPwd;
public static String createOrderUrl;
// 小程序appid
public static String subAppid;
public static String notifyUrl;
// 公众号appId
public static String wxpubAppid;
public void setPubKeyBase64(String pubKeyBase64) {
MiniAppConfig.pubKeyBase64 = pubKeyBase64;
}
public void setPrivateKeyBase64(String privateKeyBase64) {
MiniAppConfig.privateKeyBase64 = privateKeyBase64;
}
public void setPrivateKeyPwd(String privateKeyPwd) {
MiniAppConfig.privateKeyPwd = privateKeyPwd;
}
public void setWxpubAppid(String wxpubAppid) { MiniAppConfig.wxpubAppid = wxpubAppid; }
public void setNotifyUrl(String notifyUrl) {
MiniAppConfig.notifyUrl = notifyUrl;
}
public void setSubAppid(String subAppid) { MiniAppConfig.subAppid = subAppid; }
public void setCreateOrderUrl(String createOrderUrl) {
MiniAppConfig.createOrderUrl = createOrderUrl;
}
public void setMid(String mid) {
MiniAppConfig.mid = mid;
}
}
}

View File

@@ -1,107 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* Created by PaperCut on 2018/2/3.
* 微信配置
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "wx")
public class WxConfig {
public static String appId;
public static String appSecret;
public static String mchId;
public static String token;
public static String returnUrl;
public static Boolean isCreateMenu;
public static String key;
public static String getCodeUrl;
public static String modelMsgId;
public static String guide;
public static String home;
public static String payUrl;
public static String giveGold;
public static String alertMsgId;
public static String alertAdminUser;
public static String wxEncodingAESKey;
public static Boolean pubValidOpenId;
public static String openIdKey;
public void setAppId(String appId) {
WxConfig.appId = appId;
}
public void setAppSecret(String appSecret) {
WxConfig.appSecret = appSecret;
}
public void setMchId(String mchId) {
WxConfig.mchId = mchId;
}
public void setToken(String token) {
WxConfig.token = token;
}
public void setReturnUrl(String returnUrl) {
WxConfig.returnUrl = returnUrl;
}
public void setIsCreateMenu(Boolean isCreateMenu) {
WxConfig.isCreateMenu = isCreateMenu;
}
public void setKey(String key) {
WxConfig.key = key;
}
public void setGetCodeUrl(String getCodeUrl) {
WxConfig.getCodeUrl = getCodeUrl;
}
public void setModelMsgId(String modelMsgId) {
WxConfig.modelMsgId = modelMsgId;
}
public void setGuide(String guide) {
WxConfig.guide = guide;
}
public void setHome(String home) {
WxConfig.home = home;
}
public void setPayUrl(String payUrl) {
WxConfig.payUrl = payUrl;
}
public void setGiveGold(String giveGold) {
WxConfig.giveGold = giveGold;
}
public void setAlertMsgId(String alertMsgId) {
WxConfig.alertMsgId = alertMsgId;
}
public void setAlertAdminUser(String alertAdminUser) {
WxConfig.alertAdminUser = alertAdminUser;
}
public void setWxEncodingAESKey(String wxEncodingAESKey) {
WxConfig.wxEncodingAESKey = wxEncodingAESKey;
}
public void setPubValidOpenId(Boolean pubValidOpenId) {
WxConfig.pubValidOpenId = pubValidOpenId;
}
public void setOpenIdKey(String openIdKey) {
WxConfig.openIdKey = openIdKey;
}
}

View File

@@ -1,106 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 微商城公众号配置
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "wx-micro-mall")
public class WxMicroMallConfig {
public static String appId;
public static String appSecret;
public static String mchId;
public static String token;
public static String returnUrl;
public static Boolean isCreateMenu;
public static String key;
public static String getCodeUrl;
public static String modelMsgId;
public static String guide;
public static String home;
public static String payUrl;
public static String giveGold;
public static String alertMsgId;
public static String alertAdminUser;
public static String wxEncodingAESKey;
public static Boolean pubValidOpenId;
public static String openIdKey;
public void setAppId(String appId) {
WxMicroMallConfig.appId = appId;
}
public void setAppSecret(String appSecret) {
WxMicroMallConfig.appSecret = appSecret;
}
public void setMchId(String mchId) {
WxMicroMallConfig.mchId = mchId;
}
public void setToken(String token) {
WxMicroMallConfig.token = token;
}
public void setReturnUrl(String returnUrl) {
WxMicroMallConfig.returnUrl = returnUrl;
}
public void setIsCreateMenu(Boolean isCreateMenu) {
WxMicroMallConfig.isCreateMenu = isCreateMenu;
}
public void setKey(String key) {
WxMicroMallConfig.key = key;
}
public void setGetCodeUrl(String getCodeUrl) {
WxMicroMallConfig.getCodeUrl = getCodeUrl;
}
public void setModelMsgId(String modelMsgId) {
WxMicroMallConfig.modelMsgId = modelMsgId;
}
public void setGuide(String guide) {
WxMicroMallConfig.guide = guide;
}
public void setHome(String home) {
WxMicroMallConfig.home = home;
}
public void setPayUrl(String payUrl) {
WxMicroMallConfig.payUrl = payUrl;
}
public void setGiveGold(String giveGold) {
WxMicroMallConfig.giveGold = giveGold;
}
public void setAlertMsgId(String alertMsgId) {
WxMicroMallConfig.alertMsgId = alertMsgId;
}
public void setAlertAdminUser(String alertAdminUser) {
WxMicroMallConfig.alertAdminUser = alertAdminUser;
}
public void setWxEncodingAESKey(String wxEncodingAESKey) {
WxMicroMallConfig.wxEncodingAESKey = wxEncodingAESKey;
}
public void setPubValidOpenId(Boolean pubValidOpenId) {
WxMicroMallConfig.pubValidOpenId = pubValidOpenId;
}
public void setOpenIdKey(String openIdKey) {
WxMicroMallConfig.openIdKey = openIdKey;
}
}

View File

@@ -1,53 +0,0 @@
package com.accompany.payment.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.validation.constraints.NotBlank;
/**
* @author linuxea
* @date 2019/8/6 17:47
*/
@ConfigurationProperties(prefix = "wxmini")
@Configuration
@Data
public class WxMiniAppConfig {
/**
* appId 小程序 id
*/
@NotBlank(message = "小程序 appId 不能为空")
private String appId;
/**
* appSecret 小程序后台管理可生成
*/
@NotBlank(message = "小程序 appSecret 不能为空")
private String appSecret;
/**
* 获取 openId 的请求 url
*/
@NotBlank(message = "小程序 openUrl 不能为空")
private String openUrl;
/**
* appId 小程序 id (芒果主体的)
*/
@NotBlank(message = "小程序 appId 不能为空")
private String mangguoAppId;
/**
* appSecret 小程序后台管理可生成(芒果主体的)
*/
@NotBlank(message = "小程序 appSecret 不能为空")
private String mangguoAppSecret;
/**
* 获取 openId 的请求 url芒果主体的
*/
@NotBlank(message = "小程序 openUrl 不能为空")
private String mangguoOpenUrl;
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 微信支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:35
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "wxpay")
public class WxPayConfig extends BaseWxPayConfig {
}

View File

@@ -1,107 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* Created by PaperCut on 2018/2/3.
* 微信配置
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "wx-pub2")
public class WxPub2Config {
public static String appId;
public static String appSecret;
public static String mchId;
public static String token;
public static String returnUrl;
public static Boolean isCreateMenu;
public static String key;
public static String getCodeUrl;
public static String modelMsgId;
public static String guide;
public static String home;
public static String payUrl;
public static String giveGold;
public static String alertMsgId;
public static String alertAdminUser;
public static String wxEncodingAESKey;
public static Boolean pubValidOpenId;
public static String openIdKey;
public void setAppId(String appId) {
WxPub2Config.appId = appId;
}
public void setAppSecret(String appSecret) {
WxPub2Config.appSecret = appSecret;
}
public void setMchId(String mchId) {
WxPub2Config.mchId = mchId;
}
public void setToken(String token) {
WxPub2Config.token = token;
}
public void setReturnUrl(String returnUrl) {
WxPub2Config.returnUrl = returnUrl;
}
public void setIsCreateMenu(Boolean isCreateMenu) {
WxPub2Config.isCreateMenu = isCreateMenu;
}
public void setKey(String key) {
WxPub2Config.key = key;
}
public void setGetCodeUrl(String getCodeUrl) {
WxPub2Config.getCodeUrl = getCodeUrl;
}
public void setModelMsgId(String modelMsgId) {
WxPub2Config.modelMsgId = modelMsgId;
}
public void setGuide(String guide) {
WxPub2Config.guide = guide;
}
public void setHome(String home) {
WxPub2Config.home = home;
}
public void setPayUrl(String payUrl) {
WxPub2Config.payUrl = payUrl;
}
public void setGiveGold(String giveGold) {
WxPub2Config.giveGold = giveGold;
}
public void setAlertMsgId(String alertMsgId) {
WxPub2Config.alertMsgId = alertMsgId;
}
public void setAlertAdminUser(String alertAdminUser) {
WxPub2Config.alertAdminUser = alertAdminUser;
}
public void setWxEncodingAESKey(String wxEncodingAESKey) {
WxPub2Config.wxEncodingAESKey = wxEncodingAESKey;
}
public void setPubValidOpenId(Boolean pubValidOpenId) {
WxPub2Config.pubValidOpenId = pubValidOpenId;
}
public void setOpenIdKey(String openIdKey) {
WxPub2Config.openIdKey = openIdKey;
}
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 微信支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:35
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "wx-pub2-h5")
public class WxPub2WapConfig extends BaseWxPayConfig {
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*
* @author xiaoyuyou
* @date 2019/5/31 16:41
*/
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "yinyou-alipay")
public class YinyouAliPayConfig extends BaseAliPayConfig {
}

View File

@@ -1,13 +0,0 @@
package com.accompany.payment.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(-1)
@Lazy(false)
@ConfigurationProperties(prefix = "yinyou-wxpay")
public class YinyouWxPayConfig extends BaseWxPayConfig {
}

View File

@@ -1,29 +0,0 @@
package com.accompany.payment.dto;
import lombok.Data;
import java.util.List;
@Data
public class AgentChangeStrategyConfigDTO {
/**
* mode策略模式manual手动模式1|auto自动模式2
*/
private String mode;
/**
* 模式2时单人单实体接受的笔数
*/
private Integer userPaidCount;
/**
* 模式1时对应实体的配置id必须是在系统配置中已有的配置
*/
private String manualAgentConfigId;
/**
* 模式2时轮询的实体配置ID也是必须都在系统配置中已有的配置
*/
private List<String> autoAgentConfigIds;
}

View File

@@ -1,13 +0,0 @@
package com.accompany.payment.dto;
import lombok.Data;
@Data
public class AlipayAgentDTO {
private String appId;
private String appPrivateKey;
private String publicKey;
}

View File

@@ -1,17 +0,0 @@
package com.accompany.payment.dto;
import lombok.Data;
@Data
public class PayAgentConfDTO {
/**
* 配置id
*/
private String configId;
/**
* 配置信息
*/
private Object payAgent;
}

View File

@@ -1,29 +0,0 @@
package com.accompany.payment.fufeitong;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("fu-fei-tong")
@Data
public class FufeitongConfig {
/** 后台异步通知 url */
private String notifyUrl;
/** 商户号 */
private String agentId;
/** 商户密钥 */
private String agentKey;
/** 微信公众号、小程序支付地址 */
private String wxOpenPayUrl;
/** h5支付地址 */
private String wapPayUrl;
/** 支付宝地址 */
private String aliPayUrl;
}

View File

@@ -1,16 +0,0 @@
package com.accompany.payment.fufeitong;
public final class FufeitongConstant {
public final static String SUCCESS_CODE = "00";
public final static String CUST1_MINIAPP = "miniApp";
public final static String PAY_TYPE_ZFB = "1";
public final static String PAY_TYPE_WX = "2";
public final static String SETTLE_TYPE_T1 = "1";
public static final String SIGN_FIELD_NAME = "signature";
}

View File

@@ -1,191 +0,0 @@
package com.accompany.payment.fufeitong;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.BeanUtil;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.dto.HttpForm;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.util.JsonUtil;
import com.accompany.core.util.OkHttpUtils;
import com.accompany.payment.fufeitong.bo.FufeitongBaseRes;
import com.accompany.payment.fufeitong.bo.FufeitongWxOpenOrderRes;
import com.accompany.payment.fufeitong.params.FufeitongCreateOrderBaseReqParams;
import com.accompany.payment.fufeitong.params.FufeitongWxOrderReqParams;
import com.accompany.payment.utils.CommonPayUtils;
import com.accompany.payment.vo.WeChatMiniAppPayResponseVO;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class FufeitongPayService {
@Autowired
private FufeitongConfig fufeitongConfig;
/**
* 微信公众号、小程序支付
* @param orderReqParams
* @return
*/
public FufeitongWxOpenOrderRes createWxOpenOrder(FufeitongWxOrderReqParams orderReqParams) {
checkParams(orderReqParams);
String result = null;
try {
Map<String, String> requestParams = toMapParams(orderReqParams);
requestParams.put("payType", FufeitongConstant.PAY_TYPE_WX);
String sign = getSign(requestParams, fufeitongConfig);
requestParams.put(FufeitongConstant.SIGN_FIELD_NAME, sign);
log.info("付费通公众号、小程序支付请求参数:{}", JSONObject.toJSONString(requestParams));
List<HttpForm> httpForms = requestParams.entrySet().stream().map(it -> {
HttpForm form = new HttpForm(it.getKey(), it.getValue());
return form;
}).collect(Collectors.toList());
result = OkHttpUtils.postWithForm(fufeitongConfig.getWxOpenPayUrl(), httpForms);
log.info("付费通公众号、小程序请求结果:{}",result);
} catch (Exception e) {
log.error("付费通公众号、小程序创建订单失败。params:" + JSONObject.toJSONString(orderReqParams), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
FufeitongWxOpenOrderRes res = JSONObject.parseObject(result, FufeitongWxOpenOrderRes.class);
if (!res.getRespCode().equals(FufeitongConstant.SUCCESS_CODE)) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
res.setMiniAppPayInfo(JsonUtil.parseToClass(res.getPayInfoStr(), WeChatMiniAppPayResponseVO.class));
return res;
}
private Map<String, String> toMapParams(FufeitongCreateOrderBaseReqParams orderReqParams) {
Map<String, Object> tmpParams = BeanUtil.map(orderReqParams, Map.class);
Map<String, String> requestParams = tmpParams.keySet().stream().filter(it -> tmpParams.get(it) != null)
.collect(Collectors.toMap(it -> it, it -> {
if (tmpParams.containsKey(it) && tmpParams.get(it) != null) {
return tmpParams.get(it).toString();
} else {
return "";
}
}));
requestParams.put("merchno", fufeitongConfig.getAgentId());
requestParams.put("notifyUrl", fufeitongConfig.getNotifyUrl());
requestParams.put("settleType", FufeitongConstant.SETTLE_TYPE_T1);
return requestParams;
}
private String getSign(Map<String, String> requestParams, FufeitongConfig payConfig) {
return CommonPayUtils.signParams(requestParams, null, payConfig.getAgentKey());
}
private void checkParams(FufeitongCreateOrderBaseReqParams params) {
if (params == null) {
throw new ServiceException(BusiStatus.PARAMERROR);
}
if (params.getAmount() == null || params.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
params.setAmount(new BigDecimal("0.01"));
}
if (StringUtils.isBlank(params.getTraceno())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商户订单号不能为空");
}
if (StringUtils.isBlank(params.getGoodsName())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商品订单描述不能为空");
}
}
/**
* h5支付
* @param orderReqParams
* @return
*/
public FufeitongBaseRes createWapOrder(FufeitongCreateOrderBaseReqParams orderReqParams) {
checkParams(orderReqParams);
String result = null;
try {
Map<String, String> requestParams = toMapParams(orderReqParams);
String sign = getSign(requestParams, fufeitongConfig);
requestParams.put(FufeitongConstant.SIGN_FIELD_NAME, sign);
log.info("付费通h5支付请求参数{}", JSONObject.toJSONString(requestParams));
List<HttpForm> httpForms = requestParams.entrySet().stream().map(it -> {
HttpForm form = new HttpForm(it.getKey(), it.getValue());
return form;
}).collect(Collectors.toList());
result = OkHttpUtils.postWithForm(fufeitongConfig.getWapPayUrl(), httpForms);
log.info("付费通h5请求结果{}",result);
} catch (Exception e) {
log.error("付费通h5创建订单失败。params:" + JSONObject.toJSONString(orderReqParams), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
FufeitongBaseRes res = JSONObject.parseObject(result, FufeitongBaseRes.class);
if (!res.getRespCode().equals(FufeitongConstant.SUCCESS_CODE)) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
return res;
}
public FufeitongBaseRes createAlipayOrder(FufeitongCreateOrderBaseReqParams orderReqParams) {
checkParams(orderReqParams);
String result = null;
try {
Map<String, String> requestParams = toMapParams(orderReqParams);
requestParams.put("payType", FufeitongConstant.PAY_TYPE_ZFB);
String sign = getSign(requestParams, fufeitongConfig);
requestParams.put(FufeitongConstant.SIGN_FIELD_NAME, sign);
log.info("付费通支付宝支付请求参数:{}", JSONObject.toJSONString(requestParams));
List<HttpForm> httpForms = requestParams.entrySet().stream().map(it -> {
HttpForm form = new HttpForm(it.getKey(), it.getValue());
return form;
}).collect(Collectors.toList());
result = OkHttpUtils.postWithForm(fufeitongConfig.getAliPayUrl(), httpForms);
log.info("付费通支付宝请求结果:{}",result);
} catch (Exception e) {
log.error("付费通支付宝创建订单失败。params:" + JSONObject.toJSONString(orderReqParams), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
FufeitongBaseRes res = JSONObject.parseObject(result, FufeitongBaseRes.class);
if (!res.getRespCode().equals(FufeitongConstant.SUCCESS_CODE)) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
return res;
}
public boolean verifySign(Map resultMap) {
Map<String, String> paramsMap = new HashMap<>(resultMap.size());
resultMap.forEach((key, value) -> {
if (!key.toString().equals(FufeitongConstant.SIGN_FIELD_NAME) && value != null) {
paramsMap.put(key.toString(), value.toString());
}
});
String sign = getSign(paramsMap, fufeitongConfig);
String resultSign = resultMap.get(FufeitongConstant.SIGN_FIELD_NAME).toString();
return sign.equalsIgnoreCase(resultSign);
}
}

View File

@@ -1,25 +0,0 @@
package com.accompany.payment.fufeitong.bo;
import lombok.Data;
@Data
public class FufeitongBaseRes {
/** 响应码 */
protected String respCode;
/** 响应信息 */
protected String message;
/** 商户编号 */
protected String merchno;
/** 商户支付订单号 */
protected String traceno;
/** 渠道订单号 */
protected String refno;
/** 跳转地址或二维码地址 */
protected String barCode;
}

View File

@@ -1,14 +0,0 @@
package com.accompany.payment.fufeitong.bo;
import com.accompany.payment.vo.WeChatMiniAppPayResponseVO;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class FufeitongWxOpenOrderRes extends FufeitongBaseRes {
private WeChatMiniAppPayResponseVO miniAppPayInfo;
@JSONField(name = "payInfo")
private String payInfoStr;
}

View File

@@ -1,37 +0,0 @@
package com.accompany.payment.fufeitong.params;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class FufeitongCreateOrderBaseReqParams {
/**
* 商户订单号
*/
protected String traceno;
/**
* 交易金额
*/
protected BigDecimal amount;
/**
* 支付方式
*/
protected String payType;
/**
* 页面返回地址
*/
protected String returnUrl;
/**
* 商品名称
*/
protected String goodsName;
/** 自定义域1 **/
protected String cust1;
}

View File

@@ -1,9 +0,0 @@
package com.accompany.payment.fufeitong.params;
import lombok.Data;
@Data
public class FufeitongWxOrderReqParams extends FufeitongCreateOrderBaseReqParams {
private String openId;
}

View File

@@ -1,25 +0,0 @@
package com.accompany.payment.guotongpay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
public class BaseGuotongPayConfig {
private String account;
private String key;
private String wxMiniproAppId;
private String notifyUrl;
private String unifiedorderUrl;
private String wxMiniproOrderUrl;
/**
* 微信公众号appid
*/
private String wxPubAppId;
}

View File

@@ -1,15 +0,0 @@
package com.accompany.payment.guotongpay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 中嘉主体的国通配置
*/
@Configuration
@ConfigurationProperties("guotong-pay-zjlx")
@Data
public class GuotongForZjlxPayConfig extends BaseGuotongPayConfig {
}

View File

@@ -1,15 +0,0 @@
package com.accompany.payment.guotongpay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 芒果主体的国通配置
*/
@Configuration
@ConfigurationProperties("guotong-pay")
@Data
public class GuotongPayConfig extends BaseGuotongPayConfig {
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.guotongpay;
public class GuotongPayConstant {
public final static int PAY_TYPE_WX = 0;
public final static int PAY_TYPE_ZFB = 1;
/**
* 下单成功
*/
public final static int CREATE_ORDER_STATUS_SUCCESS = 100;
public final static String SIGN_FIELD_NAME = "sign";
/**
* 支付状态
*/
public final static int PAY_STATUS_SUCCESS = 0;
}

View File

@@ -1,256 +0,0 @@
package com.accompany.payment.guotongpay;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.BeanUtil;
import com.accompany.common.utils.HttpUtils;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.util.JsonUtil;
import com.accompany.payment.guotongpay.bo.GuotongPayResultBO;
import com.accompany.payment.guotongpay.bo.GuotongWxMiniPayResultBO;
import com.accompany.payment.guotongpay.params.GuoTongCreateOrderReqParams;
import com.accompany.payment.guotongpay.params.GuotongWxMiniPayReqParams;
import com.accompany.payment.utils.CommonPayUtils;
import com.accompany.payment.vo.JsapiReturnVo;
import com.accompany.payment.vo.WeChatMiniAppPayResponseVO;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class GuotongPayService {
@Autowired
private GuotongPayConfig guotongPayConfig;
@Autowired
GuotongForZjlxPayConfig guotongForZjlxPayConfig;
/**
* 公众号、小程序支付中设置是否小程序支付
*/
private static final String IS_MINI_PG = "1";
private static final String IS_NOT_MINI_PG = "0";
public GuotongPayResultBO createOrder(GuoTongCreateOrderReqParams params) {
checkParams(params);
String result = null;
try {
Map<String, Object> tmpParams = BeanUtil.objectToMap(params);
Map<String, String> requestParams = tmpParams.keySet().stream().collect(Collectors.toMap(it -> it, it -> {
if (tmpParams.containsKey(it)) {
return tmpParams.get(it).toString();
} else {
return null;
}
}));
requestParams.put("account", guotongPayConfig.getAccount());
requestParams.put("notifyUrl", guotongPayConfig.getNotifyUrl());
String sign = getSign(requestParams, guotongPayConfig);
requestParams.put("sign", sign);
Map<String, String> headers = buildHeaders();
log.info("国通支付请求参数:{}, 请求头:{}",JSONObject.toJSONString(requestParams), JSONObject.toJSONString(headers));
result = HttpUtils.doPostForJson(guotongPayConfig.getUnifiedorderUrl(), JSONObject.toJSONString(requestParams), headers);
log.info("国通支付请求结果:{}",result);
} catch (IOException e) {
log.error("国通创建订单失败。params:" + JSONObject.toJSONString(params), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
GuotongPayResultBO res = JSONObject.parseObject(result, GuotongPayResultBO.class);
if (res.getStatus() != GuotongPayConstant.CREATE_ORDER_STATUS_SUCCESS) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
return res;
}
@NotNull
private String getSign(Map<String, String> requestParams, BaseGuotongPayConfig guotongPayConfig) {
return CommonPayUtils.signParams(requestParams, "key", guotongPayConfig.getKey());
}
private Map<String, String> buildHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
return headers;
}
private void checkParams(GuoTongCreateOrderReqParams params) {
if (params == null) {
throw new ServiceException(BusiStatus.PARAMERROR);
}
if (params.getPayMoney() == null || params.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
params.setPayMoney(new BigDecimal("0.01"));
}
if (StringUtils.isBlank(params.getLowOrderId())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商户订单号不能为空");
}
if (StringUtils.isBlank(params.getBody())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商品订单描述不能为空");
}
if (params.getPayType() == null) {
throw new ServiceException(BusiStatus.PARAMERROR, "支付方式不能为空");
}
}
public GuotongWxMiniPayResultBO createWxMiniproOrder(GuotongWxMiniPayReqParams params) {
return createWxMiniproOrderBase(params, guotongPayConfig);
}
public GuotongWxMiniPayResultBO createWxMiniproOrderForZjlx(GuotongWxMiniPayReqParams params) {
return createWxMiniproOrderBase(params, guotongForZjlxPayConfig);
}
private GuotongWxMiniPayResultBO createWxMiniproOrderBase(GuotongWxMiniPayReqParams params, BaseGuotongPayConfig guotongPayConfig) {
checkWxMiniPayParams(params);
String result = null;
try {
Map<String, Object> tmpParams = BeanUtil.objectToMap(params);
Map<String, String> requestParams = tmpParams.keySet().stream().collect(Collectors.toMap(it -> it, it -> {
if (tmpParams.containsKey(it)) {
return tmpParams.get(it).toString();
} else {
return null;
}
}));
requestParams.put("account", guotongPayConfig.getAccount());
requestParams.put("notifyUrl", guotongPayConfig.getNotifyUrl());
requestParams.put("appId", guotongPayConfig.getWxMiniproAppId());
requestParams.put("isMinipg", IS_MINI_PG);
String sign = getSign(requestParams, guotongPayConfig);
requestParams.put("sign", sign);
Map<String, String> headers = buildHeaders();
log.info("国通小程序支付请求参数:{}, 请求头:{}",JSONObject.toJSONString(requestParams), JSONObject.toJSONString(headers));
result = HttpUtils.doPostForJson(guotongPayConfig.getWxMiniproOrderUrl(), JSONObject.toJSONString(requestParams), headers);
log.info("国通支付请求结果:{}",result);
} catch (IOException e) {
log.error("国通小程序创建订单失败。params:" + JSONObject.toJSONString(params), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
GuotongWxMiniPayResultBO res = JSONObject.parseObject(result, GuotongWxMiniPayResultBO.class);
if (res.getStatus() != GuotongPayConstant.CREATE_ORDER_STATUS_SUCCESS) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
res.setPayInfo(JsonUtil.parseToClass(res.getPayInfoStr(), WeChatMiniAppPayResponseVO.class));
return res;
}
public JsapiReturnVo createWxPubOrderForZjlx(GuotongWxMiniPayReqParams params) {
return createWxPubOrderBase(params, guotongForZjlxPayConfig);
}
/**
* 创建公众号订单
* @param params
* @param guotongPayConfig
* @return
*/
private JsapiReturnVo createWxPubOrderBase(GuotongWxMiniPayReqParams params, BaseGuotongPayConfig guotongPayConfig) {
checkWxMiniPayParams(params);
String result = null;
try {
Map<String, Object> tmpParams = BeanUtil.objectToMap(params);
Map<String, String> requestParams = tmpParams.keySet().stream().collect(Collectors.toMap(it -> it, it -> {
if (tmpParams.containsKey(it)) {
return tmpParams.get(it).toString();
} else {
return null;
}
}));
requestParams.put("account", guotongPayConfig.getAccount());
requestParams.put("notifyUrl", guotongPayConfig.getNotifyUrl());
requestParams.put("appId", guotongPayConfig.getWxPubAppId());
requestParams.put("isMinipg", IS_NOT_MINI_PG);
String sign = getSign(requestParams, guotongPayConfig);
requestParams.put("sign", sign);
Map<String, String> headers = buildHeaders();
log.info("国通公众号支付请求参数:{}, 请求头:{}",JSONObject.toJSONString(requestParams), JSONObject.toJSONString(headers));
result = HttpUtils.doPostForJson(guotongPayConfig.getWxMiniproOrderUrl(), JSONObject.toJSONString(requestParams), headers);
log.info("国通公众号支付请求结果:{}",result);
} catch (IOException e) {
log.error("国通公众号创建订单失败。params:" + JSONObject.toJSONString(params), e);
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败,请重试");
}
GuotongWxMiniPayResultBO res = JSONObject.parseObject(result, GuotongWxMiniPayResultBO.class);
if (res.getStatus() != GuotongPayConstant.CREATE_ORDER_STATUS_SUCCESS) {
throw new ServiceException(BusiStatus.PAYMENT_FAIL, "支付失败:" + res.getMessage());
}
return buildUnionPublicVO(JsonUtil.parseToClass(res.getPayInfoStr(), WeChatMiniAppPayResponseVO.class));
}
private JsapiReturnVo buildUnionPublicVO(WeChatMiniAppPayResponseVO publicPayResponseVO) {
JsapiReturnVo jsapiReturnVo = new JsapiReturnVo();
jsapiReturnVo.setTimestamp(publicPayResponseVO.getTimeStamp());
jsapiReturnVo.setNonce_str(publicPayResponseVO.getNonceStr());
jsapiReturnVo.setPrepay_id(publicPayResponseVO.getPackageInfo());
jsapiReturnVo.setSign(publicPayResponseVO.getPaySign());
jsapiReturnVo.setAppid(publicPayResponseVO.getAppId());
jsapiReturnVo.setSign_type(publicPayResponseVO.getSignType());
return jsapiReturnVo;
}
private void checkWxMiniPayParams(GuotongWxMiniPayReqParams params) {
if (params == null) {
throw new ServiceException(BusiStatus.PARAMERROR);
}
if (params.getPayMoney() == null || params.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
params.setPayMoney(new BigDecimal("0.01"));
}
if (StringUtils.isBlank(params.getLowOrderId())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商户订单号不能为空");
}
if (StringUtils.isBlank(params.getBody())) {
throw new ServiceException(BusiStatus.PARAMERROR, "商品订单描述不能为空");
}
if (StringUtils.isBlank(params.getOpenId())) {
throw new ServiceException(BusiStatus.PARAMERROR, "微信openId不能为空");
}
}
public boolean checkSign(Map resultMap, BaseGuotongPayConfig guotongPayConfig) {
Map<String, String> paramsMap = new HashMap<>(resultMap.size());
resultMap.forEach((key, value) -> {
if (!key.toString().equals(GuotongPayConstant.SIGN_FIELD_NAME) && value != null) {
paramsMap.put(key.toString(), value.toString());
}
});
String sign = getSign(paramsMap, guotongPayConfig);
String resultSign = resultMap.get(GuotongPayConstant.SIGN_FIELD_NAME).toString();
return sign.equalsIgnoreCase(resultSign);
}
}

View File

@@ -1,47 +0,0 @@
package com.accompany.payment.guotongpay.bo;
import lombok.Data;
@Data
public class GuotongPayResultBO {
/**
* 订单二维码url
*/
private String codeUrl;
/**
* 通莞金服订单
*/
private String orderId;
/**
* 4待支付
*/
private String state;
/**
* 签名
*/
private String sign;
/**
* 信息描述
*/
private String message;
/**
* 下游订单号
*/
private String lowOrderId;
/**
* 聚合支付账号
*/
private String account;
/**
* 100:成功101失败
*/
private Integer status;
}

View File

@@ -1,46 +0,0 @@
package com.accompany.payment.guotongpay.bo;
import com.accompany.payment.vo.WeChatMiniAppPayResponseVO;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class GuotongWxMiniPayResultBO {
/**
* 通莞金服订单
*/
private String upOrderId;
/**
* 原生态js支付是的参数
*/
@JSONField(name = "pay_info")
private String payInfoStr;
/**
* 签名
*/
private String sign;
/**
* 信息描述
*/
private String message;
/**
* 微信禁用pay_url,返参为null
*/
@JSONField(name = "pay_url")
private String payUrl;
/**
* 100:成功101失败
*/
private Integer status;
/**
* payInfoStrjson解析后的对象
*/
private WeChatMiniAppPayResponseVO payInfo;
}

View File

@@ -1,13 +0,0 @@
package com.accompany.payment.guotongpay.params;
import lombok.Data;
@Data
public class GuoTongCreateOrderReqParams extends GuotongBaseReqParams {
/**
* 支付方式 0微信1支付宝4银联
*/
private Integer payType;
}

View File

@@ -1,23 +0,0 @@
package com.accompany.payment.guotongpay.params;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class GuotongBaseReqParams {
/**
* 支付金额 单位:元
*/
private BigDecimal payMoney;
/**
* 下游订单号
*/
private String lowOrderId;
/**
* 商品订单描述
*/
private String body;
}

View File

@@ -1,12 +0,0 @@
package com.accompany.payment.guotongpay.params;
import lombok.Data;
@Data
public class GuotongWxMiniPayReqParams extends GuotongBaseReqParams {
/**
* 微信openId
*/
private String openId;
}

View File

@@ -1,20 +0,0 @@
package com.accompany.payment.heepay;
import lombok.Data;
@Data
public abstract class BaseConfig {
/** 后台异步通知 url */
protected String notifyUrl;
/** 商户号 */
protected String agentId;
/** 商户密钥 */
protected String agentKey;
/**
* 请求时的meta_option参数
*/
protected String metaOption;
}

View File

@@ -1,18 +0,0 @@
package com.accompany.payment.heepay;
public class HeePayConstant {
public final static String VERSION = "1";
public final static int PAY_TYPE_WX = 30;
public final static String PAY_SCENE_H5 = "h5";
public final static String SIGN_TYPE = "MD5";
public final static String PAYMENT_MODE = "cashier";
public final static byte BANK_CARD_TYPE_UNKONW = -1;
public final static String SUCCESS_CODE = "0000";
}

View File

@@ -1,19 +0,0 @@
package com.accompany.payment.heepay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 汇付宝支付的配置
*/
@Component
@ConfigurationProperties("hui-fu-bao")
@Data
public class HeePayH5Config extends BaseConfig {
/**
* 微信h5支付url
*/
private String wxH5PayUrl;
}

View File

@@ -1,327 +0,0 @@
package com.accompany.payment.heepay;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.util.JsonUtil;
import com.accompany.payment.heepay.bo.WxH5PayResBO;
import com.accompany.payment.heepay.bo.WxMiniproPayResBO;
import com.accompany.payment.heepay.bo.WxPubPayResBO;
import com.accompany.payment.heepay.params.NotifyParams;
import com.accompany.payment.heepay.params.PayRequestParams;
import com.accompany.payment.heepay.params.WxH5PayReqParams;
import com.accompany.payment.heepay.sdk.Common.DataHelper;
import com.accompany.payment.heepay.sdk.Common.Md5Tools;
import com.accompany.payment.huiju.HuiJuWeChatMiniPayInfoVO;
import com.accompany.payment.wxpay.XMLParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.xml.sax.SAXException;
import sun.misc.BASE64Encoder;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
@Slf4j
@Lazy(false)
public class HeePayService {
@Autowired
private HeePayH5Config heePayH5Config;
@Autowired
private HeePayWxConfig heePayWxConfig;
private final static String RES_FIELD_RET_CODE = "ret_code";
private final static String RES_FIELD_RET_MSG = "ret_msg";
private static final String REAL_PAY_CHANNEL_HUI_FU_BAO = "hui_fu_bao";
// 用于匹配微信支付调用成功时返回的tokenId
private final static Pattern TOKEN_ID_PATTERN = Pattern.compile("<token_id>(.*)</token_id>");
private final static String IS_PHONE_YES = "1";
private final static String IS_FRAME_YES = "1";
/**
* 发起微信h5支付
*
* @param params
* @return
*
* @author Chenzhixiang
*/
public WxH5PayResBO wxH5Pay(WxH5PayReqParams params) {
String sign = signForH5Pay(params);
try {
String requestUrl = buildReqUrlForH5Pay(params, sign);
String result = DataHelper.RequestGetUrl(requestUrl);
return buildResForH5Pay(result);
} catch (Exception e) {
log.error("汇付宝支付异常", e);
throw new ServiceException(BusiStatus.UNKNOWN);
}
}
private WxH5PayResBO buildResForH5Pay(String result) throws IOException, SAXException, ParserConfigurationException {
log.info("pay result: {}", result);
Map<String, Object> resMap = XMLParser.getMapFromXML(result);
WxH5PayResBO res = new WxH5PayResBO();
res.setRetCode(resMap.get(RES_FIELD_RET_CODE).toString());
res.setRetMsg(resMap.get(RES_FIELD_RET_MSG).toString());
if (HeePayConstant.SUCCESS_CODE.equalsIgnoreCase(res.getRetCode())) {
res.setSuccess(true);
res.setRedirectUrl(resMap.get("redirectUrl").toString());
} else {
res.setSuccess(false);
}
return res;
}
private String signForH5Pay(WxH5PayReqParams params) {
StringBuilder strForSign = new StringBuilder("version=").append(HeePayConstant.VERSION)
.append("&agent_id=").append(heePayH5Config.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayH5Config.getNotifyUrl())
.append("&return_url=").append(params.getReturnUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&bank_card_type=").append(params.getBankCardType())
.append("&remark=").append(params.getRemark())
.append("&key=").append(heePayH5Config.getAgentKey());
return Md5Tools.MD5(strForSign.toString());
}
private String buildReqUrlForH5Pay(WxH5PayReqParams params, String sign) throws UnsupportedEncodingException {
StringBuilder reqUrl = new StringBuilder(heePayH5Config.getWxH5PayUrl()).append("?")
.append("version=").append(HeePayConstant.VERSION)
.append("&scene=").append(params.getScene())
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&agent_id=").append(heePayH5Config.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayH5Config.getNotifyUrl())
.append("&return_url=").append(params.getReturnUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&goods_name=").append(URLEncoder.encode(params.getGoodsName(), DataHelper.GBKEncode))
.append("&remark=").append(URLEncoder.encode(params.getRemark(), DataHelper.GBKEncode))
.append("&sign_type=").append(HeePayConstant.SIGN_TYPE);
if (StringUtils.isNotBlank(params.getGoodsNote())) {
reqUrl.append("&goods_note=").append(URLEncoder.encode(params.getGoodsNote(), DataHelper.GBKEncode));
}
String metaOption = encodeMetaOption(heePayH5Config.getMetaOption());
reqUrl.append("&meta_option=").append(metaOption)
.append("&payment_mode=").append(HeePayConstant.PAYMENT_MODE)
.append("&bank_card_type=").append(params.getBankCardType())
.append("&sign=").append(sign);
return reqUrl.toString();
}
private String encodeMetaOption(String metaOption) throws UnsupportedEncodingException {
return URLEncoder.encode(new BASE64Encoder().encode(metaOption.getBytes("gb2312")),DataHelper.UTF8Encode);
}
/**
* 发起小程序支付
*
* @param params
* @return
*
* @author Chenzhixiang
*/
public WxMiniproPayResBO payByWxMinipro(PayRequestParams params) {
try {
String sign = signForWxMiniproPay(params);
String requestUrl = buildReqUrlForWxMiniproPay(params, sign);
String result = DataHelper.RequestGetUrl(requestUrl);
return buildResForWxMiniproPay(result);
} catch (Exception e) {
log.error("汇付宝发起微信小程序支付异常", e);
throw new ServiceException(BusiStatus.UNKNOWN);
}
}
public HuiJuWeChatMiniPayInfoVO weChatMiniAppPay(PayRequestParams params) {
WxMiniproPayResBO bo = payByWxMinipro(params);
String requestUrl = heePayWxConfig.getWxMiniproJsUrl() + String.format("?stid=%s&sub_appid=%s&sub_openid=%s",
bo.getTokenId(), heePayWxConfig.getWxMiniproAppid(), params.getOpenId());
String result = DataHelper.RequestGetUrl(requestUrl);
return JsonUtil.parseToClass(result, HuiJuWeChatMiniPayInfoVO.class);
}
private String signForWxMiniproPay(PayRequestParams params) {
StringBuilder strForSign = new StringBuilder("version=").append(HeePayConstant.VERSION)
.append("&agent_id=").append(heePayWxConfig.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayWxConfig.getNotifyUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&key=").append(heePayWxConfig.getAgentKey());
return Md5Tools.MD5(strForSign.toString());
}
private String buildReqUrlForWxMiniproPay(PayRequestParams params, String sign) throws UnsupportedEncodingException {
String metaOption = encodeMetaOption(heePayWxConfig.getMetaOption());
StringBuilder reqUrl = new StringBuilder(heePayWxConfig.getWxMiniproPayUrl()).append("?")
.append("version=").append(HeePayConstant.VERSION)
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&agent_id=").append(heePayWxConfig.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayWxConfig.getNotifyUrl())
.append("&return_url=").append(params.getReturnUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&goods_name=").append(URLEncoder.encode(params.getGoodsName(), DataHelper.GBKEncode))
.append("&remark=").append(URLEncoder.encode(params.getRemark(), DataHelper.GBKEncode))
.append("&sign_type=").append(HeePayConstant.SIGN_TYPE)
.append("&meta_option=").append(metaOption)
.append("&sign=").append(sign);
return reqUrl.toString();
}
private WxMiniproPayResBO buildResForWxMiniproPay(String result) throws IOException, SAXException, ParserConfigurationException {
log.info("huifubao wx minipro pay result: {}", result);
Map<String, Object> resMap = XMLParser.getMapFromXML(result);
WxMiniproPayResBO res = new WxMiniproPayResBO();
res.setSuccess(false);
if (resMap.size() == 0) {
// 没有解析出来东西表示只有一个token_id节点使用正则表达式获取
Matcher matcher = TOKEN_ID_PATTERN.matcher(result);
if (matcher.find()) {
res.setSuccess(true);
res.setTokenId(matcher.group(1));
}
} else {
if (resMap.containsKey(RES_FIELD_RET_CODE)) {
res.setRetCode(resMap.get(RES_FIELD_RET_CODE).toString());
}
if (resMap.containsKey(RES_FIELD_RET_MSG)) {
res.setRetMsg(resMap.get(RES_FIELD_RET_MSG).toString());
}
if (StringUtils.isNotBlank(res.getRetCode()) && !HeePayConstant.SUCCESS_CODE.equalsIgnoreCase(res.getRetCode())) {
res.setSuccess(false);
} else {
res.setSuccess(true);
res.setTokenId(resMap.get("token_id").toString());
}
}
res.setRealPayChannel(REAL_PAY_CHANNEL_HUI_FU_BAO);
return res;
}
/**
* 微信公众号支付
*
* @param params
* @return
*/
public WxPubPayResBO payByWxPub(PayRequestParams params) {
try {
String sign = signforWxPubPay(params);
String requestUrl = buildReqUrlForWxPubPay(params, sign);
log.info("huifubao wx pub pay redirect: {}", requestUrl);
// 公众号的直接将拼接好的url给客户端跳转
WxPubPayResBO res = new WxPubPayResBO();
res.setSuccess(true);
res.setRealPayChannel(REAL_PAY_CHANNEL_HUI_FU_BAO);
res.setRedirectUrl(requestUrl);
return res;
} catch (Exception e) {
log.error("汇付宝发起微信公众号支付异常", e);
throw new ServiceException(BusiStatus.UNKNOWN);
}
}
private String signforWxPubPay(PayRequestParams params) {
StringBuilder strForSign = new StringBuilder("version=").append(HeePayConstant.VERSION)
.append("&agent_id=").append(heePayWxConfig.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayWxConfig.getNotifyUrl())
.append("&return_url=").append(params.getReturnUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&key=").append(heePayWxConfig.getAgentKey());
return Md5Tools.MD5(strForSign.toString());
}
private String buildReqUrlForWxPubPay(PayRequestParams params, String sign) throws UnsupportedEncodingException {
String metaOption = encodeMetaOption(heePayWxConfig.getMetaOption());
StringBuilder reqUrl = new StringBuilder(heePayWxConfig.getWxPubPayUrl()).append("?")
.append("version=").append(HeePayConstant.VERSION)
.append("&is_phone=").append(IS_PHONE_YES)
.append("&is_frame=").append(IS_FRAME_YES)
.append("&pay_type=").append(HeePayConstant.PAY_TYPE_WX)
.append("&agent_id=").append(heePayWxConfig.getAgentId())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&notify_url=").append(heePayWxConfig.getNotifyUrl())
.append("&return_url=").append(params.getReturnUrl())
.append("&user_ip=").append(params.getUserIp())
.append("&agent_bill_time=").append(params.getAgentBillTime())
.append("&goods_name=").append(URLEncoder.encode(params.getGoodsName(), DataHelper.GBKEncode))
.append("&remark=").append(URLEncoder.encode(params.getRemark(), DataHelper.GBKEncode))
.append("&sign_type=").append(HeePayConstant.SIGN_TYPE)
.append("&meta_option=").append(metaOption)
.append("&sign=").append(sign);
return reqUrl.toString();
}
/**
* 校验支付通知sign
* @param params
* @return
*/
public boolean verifyNotifySign(NotifyParams params) {
String signCalFromParams = calcSign(params, heePayH5Config.getAgentKey());
return signCalFromParams.equalsIgnoreCase(params.getSign());
}
/**
* 计算签名
*
* @param params
* @param agentKey
* @return
*/
private String calcSign(NotifyParams params, String agentKey) {
StringBuilder strForSign = new StringBuilder("result=").append(params.getResult())
.append("&agent_id=").append(params.getAgentId())
.append("&jnet_bill_no=").append(params.getJnetBillNo())
.append("&agent_bill_id=").append(params.getAgentBillId())
.append("&pay_type=").append(params.getPayType())
.append("&pay_amt=").append(params.getPayAmt().toString())
.append("&remark=").append(params.getRemark())
.append("&key=").append(agentKey);
return Md5Tools.MD5(strForSign.toString());
}
/**
* 校验支付通知sign供小程序、公众号环境使用
* @param params
* @return
*/
public boolean verifyNotifySignForWxEnv(NotifyParams params) {
String signCalFromParams = calcSign(params, heePayWxConfig.getAgentKey());
return signCalFromParams.equalsIgnoreCase(params.getSign());
}
}

View File

@@ -1,34 +0,0 @@
package com.accompany.payment.heepay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 用于微信公众号或小程序支付的配置
*/
@Component
@ConfigurationProperties("hui-fu-bao-wx-env")
@Data
public class HeePayWxConfig extends BaseConfig {
/**
* 微信小程序支付tokenid url
*/
private String wxMiniproPayUrl;
/**
* 微信小程序支付jsapi url
*/
private String wxMiniproJsUrl;
/**
* 微信公众号支付url
*/
private String wxPubPayUrl;
/**
* 微信小程序appid
*/
private String wxMiniproAppid;
}

View File

@@ -1,37 +0,0 @@
package com.accompany.payment.heepay.bo;
import lombok.Data;
/**
* 调用结果
*
* @author Chenzhixiang
* @date 2020年08月13日
*/
@Data
public class ResponseBO {
/**
* 请求是否成功
*/
private Boolean success;
/**
* 返回码
*/
private String retCode;
/**
* 返回码信息提示
*/
private String retMsg;
/**
* 昵称
*/
private String nick;
/**
* 平台号
*/
private Long erban_no;
}

View File

@@ -1,25 +0,0 @@
package com.accompany.payment.heepay.bo;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
* 微信h5调用结果
*
* @author Chenzhixiang
* @date 2020年08月13日
*/
@Data
public class WxH5PayResBO extends ResponseBO {
/**
* 返回的URL
*/
@JSONField(name = "mweb_url")
private String redirectUrl;
/**
* MD5签名
*/
private String sign;
}

View File

@@ -1,23 +0,0 @@
package com.accompany.payment.heepay.bo;
import lombok.Data;
/**
* 微信小程序支付调用结果
*
* @author Chenzhixiang
* @date 2020年08月14日
*/
@Data
public class WxMiniproPayResBO extends ResponseBO {
/**
* token
*/
private String tokenId;
/**
* 真正的支付渠道,供前端判断
*/
private String realPayChannel;
}

View File

@@ -1,25 +0,0 @@
package com.accompany.payment.heepay.bo;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
* 微信公众号支付结果
*
* @author Chenzhixiang
* @date 2020年08月17日
*/
@Data
public class WxPubPayResBO extends ResponseBO {
/**
* 返回的URL
*/
@JSONField(name = "mweb_url")
private String redirectUrl;
/**
* 真正的支付渠道,供前端判断
*/
private String realPayChannel;
}

View File

@@ -1,49 +0,0 @@
package com.accompany.payment.heepay.params;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class NotifyParams {
/**
* 支付结果,, 1=成功 其它为未知
*/
private Short result;
/**
* 商户编号
*/
private String agentId;
/**
* 汇付宝订单号
*/
private String jnetBillNo;
/**
* 商户系统内部的订单号
*/
private String agentBillId;
/**
* 支付类型
*/
private String payType;
/**
* 订单实际支付金额
*/
private BigDecimal payAmt;
/**
* 商家数据包,原样返回
*/
private String remark;
/**
* MD5签名
*/
private String sign;
}

View File

@@ -1,63 +0,0 @@
package com.accompany.payment.heepay.params;
import lombok.Data;
import java.math.BigDecimal;
/**
* 支付请求参数
*
*/
@Data
public class PayRequestParams {
/**
* 商户订单号
*/
private String agentBillId;
/**
* 支付金额,单位元
*/
private BigDecimal payAmt;
/**
* 同步通知地址
*/
private String returnUrl;
/**
* 用户ip
*/
private String userIp;
/**
* 提交单据的时间yyyyMMddHHmmss
*/
private String agentBillTime;
/**
* 商品名称
*/
private String goodsName;
/**
* 自定义参数
*/
private String remark;
/**
* 支付说明
*/
private String goodsNote;
/**
* 银行类型
*/
private Byte bankCardType;
/**
* openid
*/
private String openId;
}

View File

@@ -1,16 +0,0 @@
package com.accompany.payment.heepay.params;
import lombok.Data;
/**
* 微信h5支付请求参数
*
*/
@Data
public class WxH5PayReqParams extends PayRequestParams {
/**
* 支付方式h5表示h5
*/
private String scene;
}

View File

@@ -1,160 +0,0 @@
package com.accompany.payment.heepay.sdk.Common;
import java.io.DataInputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class DataHelper {
public final static String UTF8Encode="UTF-8";
public final static String GBKEncode="GBK";
public final static String sign_key = "33B1FEF26A9E445A9E683EEC"; //<2F><EFBFBD><E6BBBB><EFBFBD>̻<EFBFBD><CCBB>Լ<EFBFBD><D4BC><EFBFBD>key
public static String GetQueryString(Map<String, String> map)
{
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
StringBuilder sb = new StringBuilder();
while (iter.hasNext()) {
Entry<String, String> entry = iter.next();
Object key = entry.getKey().toString();
Object val = entry.getValue().toString();
sb.append(key + "=" +val).append("&");
}
if(sb.length()==0) return "";
return sb.substring(0, sb.length()-1);
}
//对值进行转码 将本地编码的字符 转换为汇付宝的编码
public static void TranferCharsetEncode(Map<String, String> map) throws UnsupportedEncodingException
{
for (Entry<String, String> entry : map.entrySet()) {
if(entry.getValue()==null) continue;
String utf8=URLEncoder.encode(entry.getValue(), DataHelper.UTF8Encode);
entry.setValue(utf8);
}
}
public static String GetSortQueryToLowerString(Map<String, String> map)
{
List<Entry<String, String>> keyValues =
new ArrayList<Entry<String, String>>(map.entrySet());
Collections.sort(keyValues, new Comparator<Entry<String, String>>() {
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
StringBuilder sb = new StringBuilder();
for (int i=0;i<keyValues.size();i++) {
if(keyValues.get(i).getValue()==null)
{
sb.append(keyValues.get(i).getKey()+ "= " );
}
else
{
sb.append(keyValues.get(i).getKey()+ "=" + keyValues.get(i).getValue().toLowerCase());
}
sb.append("&");
}
return sb.substring(0, sb.length()-1);
}
public static String GetSortQueryString(Map<String, String> map)
{
List<Entry<String, String>> keyValues =
new ArrayList<Entry<String, String>>(map.entrySet());
Collections.sort(keyValues, new Comparator<Entry<String, String>>() {
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
StringBuilder sb = new StringBuilder();
for (int i=0;i<keyValues.size();i++) {
sb.append(keyValues.get(i).getKey()+ "=" + keyValues.get(i).getValue());
sb.append("&");
}
return sb.substring(0, sb.length()-1);
}
public static String RequestGetUrl(String getUrl)
{
return GetPostUrl(null,getUrl,"GET");
}
public static String RequestPostUrl(String getUrl,String postData)
{
return GetPostUrl(postData,getUrl,"POST");
}
private static String GetPostUrl(String postData,String postUrl,String submitMethod) {
URL url = null;
HttpURLConnection httpurlconnection = null;
try {
url = new URL(postUrl);
httpurlconnection = (HttpURLConnection) url.openConnection();
httpurlconnection.setRequestMethod(submitMethod.toUpperCase());
httpurlconnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpurlconnection.setDoInput(true);
httpurlconnection.setDoOutput(true);
if(submitMethod.equalsIgnoreCase("POST"))
{
httpurlconnection.getOutputStream().write(postData.getBytes(GBKEncode));
httpurlconnection.getOutputStream().flush();
httpurlconnection.getOutputStream().close();
}
int code = httpurlconnection.getResponseCode();
if (code == 200)
{
DataInputStream in = new DataInputStream(httpurlconnection.getInputStream());
int len = in.available();
byte[] by = new byte[len];
in.readFully(by);
String rev=new String(by,"UTF-8");
in.close();
return rev;
}
else
{
//http <20><><EFBFBD>󷵻ط<F3B7B5BB> 200״̬ʱ<CCAC><CAB1><EFBFBD><EFBFBD>
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (httpurlconnection != null) {
httpurlconnection.disconnect();
}
}
return null;
}
}

View File

@@ -1,98 +0,0 @@
package com.accompany.payment.heepay.sdk.Common;
import com.accompany.payment.heepay.sdk.HeepayModel.GatewayModel;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class GatewayHelper {
public static String SignMd5(String key, GatewayModel gatewayModel)
{
StringBuilder _StringSign = new StringBuilder();
_StringSign.append("version=1")
.append("&agent_id=" + gatewayModel.getagent_id())
.append("&agent_bill_id=" + gatewayModel.getagent_bill_id())
.append("&agent_bill_time=" + gatewayModel.getagent_bill_time())
.append("&pay_type=" + gatewayModel.getpay_type());
_StringSign.append("&pay_amt=" + gatewayModel.getpay_amt())
.append("&notify_url=" + gatewayModel.getnotify_url())
.append("&user_ip=" + gatewayModel.getuser_ip());
_StringSign.append("&key=" + key);
return Md5Tools.MD5(_StringSign.toString()).toLowerCase();
}
@SuppressWarnings("deprecation")
public static String GatewaySubmitUrl(String sign,GatewayModel gatewayModel) throws UnsupportedEncodingException
{
StringBuilder sbURL = new StringBuilder();
sbURL.append("https://pay.heepay.com/Phone/SDK/PayInit.aspx?");//<2F><>Ϊ<EFBFBD><CEAA><EFBFBD>Ե<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>̻<EFBFBD>Ӧʹ<D3A6><CAB9><EFBFBD>ĵ<EFBFBD><C4B5>е<EFBFBD><D0B5><EFBFBD>ʽ<EFBFBD><CABD>ַ
sbURL.append("version=" + gatewayModel.getversion());
sbURL.append("&pay_type=" + gatewayModel.getpay_type());
sbURL.append("&agent_id=" + gatewayModel.getagent_id());
sbURL.append("&agent_bill_id=" + gatewayModel.getagent_bill_id());
sbURL.append("&pay_amt=" + gatewayModel.getpay_amt());
sbURL.append("&notify_url=" + gatewayModel.getnotify_url());
sbURL.append("&return_url=" + gatewayModel.getreturn_url());
sbURL.append("&user_ip=" + gatewayModel.getuser_ip());
sbURL.append("&agent_bill_time=" + gatewayModel.getagent_bill_time());
sbURL.append("&goods_name=" + URLEncoder.encode(gatewayModel.getgoods_name()));
sbURL.append("&goods_num=" + gatewayModel.getgoods_num());
sbURL.append("&remark=" + URLEncoder.encode(gatewayModel.getremark()));
sbURL.append("&goods_note=" + URLEncoder.encode(gatewayModel.getgoods_note()));
sbURL.append("&sign=" + sign);
return sbURL.toString();
}
//汇付宝查询构建签名
public static String SignQueryMd5(String key,GatewayModel gatewayModel)
{
StringBuilder _StringSign = new StringBuilder();
_StringSign.append("version=" + gatewayModel.getversion())
.append("&agent_id=" + gatewayModel.getagent_id())
.append("&agent_bill_id=" + gatewayModel.getagent_bill_id())
.append("&key=" + key);
return Md5Tools.MD5(_StringSign.toString()).toLowerCase();
}
//汇付宝查询构建提交url地址
public static String GatewaySubmitQuery(String sign,GatewayModel gatewayModel) throws UnsupportedEncodingException
{
StringBuilder sbURL = new StringBuilder();
sbURL.append("version=1");
sbURL.append("&agent_id=" + gatewayModel.getagent_id());
sbURL.append("&agent_bill_id=" + gatewayModel.getagent_bill_id());
sbURL.append("&sign=" + sign);
return sbURL.toString();
}
public static boolean VerifiSign(String urlStr)
{
String[] str = urlStr.split("sign=");
String[] str1=str[0].split("bill_info>");
String[] str2=str[1].split("</bill_info");
String mySign = Md5Tools.MD5(str1[1] + "key="+DataHelper.sign_key).toLowerCase();
System.out.println(str[0]+"-------"+str2[0]+"======="+mySign);
if(mySign.equals(str2[0]))
{
return true;
}
else
{
return false;
}
}
}

View File

@@ -1,33 +0,0 @@
package com.accompany.payment.heepay.sdk.Common;
import java.security.MessageDigest;
public class Md5Tools {
public static String MD5(String s) {
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
try {
//<2F><><EFBFBD><E3B8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
byte[] btInput = s.getBytes(DataHelper.UTF8Encode);
// <20><><EFBFBD>MD5ժҪ<D5AA><EFBFBD><E3B7A8> MessageDigest <20><><EFBFBD><EFBFBD>
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// ʹ<><CAB9>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ֽڸ<D6BD><DAB8><EFBFBD>ժҪ
mdInst.update(btInput);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
byte[] md = mdInst.digest();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>ʮ<EFBFBD><CAAE><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ʽ
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -1,140 +0,0 @@
package com.accompany.payment.heepay.sdk.HeepayModel;
public class GatewayModel
{
private String version;
private String agent_id;
private String agent_bill_id;
private String pay_type;
private String pay_amt;
private String notify_url;
private String return_url;
private String user_ip;
private String agent_bill_time;
private String goods_name;
private String goods_num;
private String remark;
private String goods_note;
public String getversion()//
{
return version;
}
public void setversion(String version)
{
this.version = version;
}
public String getagent_id()//
{
return agent_id;
}
public void setagent_id(String agent_id)
{
this.agent_id = agent_id;
}
public String getagent_bill_id()//
{
return agent_bill_id;
}
public void setagent_bill_id(String agent_bill_id)
{
this.agent_bill_id = agent_bill_id;
}
public String getpay_type()//
{
return pay_type;
}
public void setpay_type(String pay_type)
{
this.pay_type = pay_type;
}
public String getpay_amt()//
{
return pay_amt;
}
public void setpay_amt(String pay_amt)
{
this.pay_amt = pay_amt;
}
public String getnotify_url()//
{
return notify_url;
}
public void setnotify_url(String notify_url)
{
this.notify_url = notify_url;
}
public String getreturn_url()//
{
return return_url;
}
public void setreturn_url(String return_url)
{
this.return_url = return_url;
}
public String getuser_ip()//
{
return user_ip;
}
public void setuser_ip(String user_ip)
{
this.user_ip = user_ip;
}
public String getagent_bill_time()//
{
return agent_bill_time;
}
public void setagent_bill_time(String agent_bill_time)
{
this.agent_bill_time = agent_bill_time;
}
public String getgoods_name()//
{
return goods_name;
}
public void setgoods_name(String goods_name)
{
this.goods_name = goods_name;
}
public String getgoods_num()//
{
return goods_num;
}
public void setgoods_num(String goods_num)
{
this.goods_num = goods_num;
}
public String getremark()//
{
return remark;
}
public void setremark(String remark)
{
this.remark = remark;
}
public String getgoods_note()//
{
return goods_note;
}
public void setgoods_note(String goods_note)
{
this.goods_note = goods_note;
}
}

View File

@@ -1,32 +0,0 @@
package com.accompany.payment.heepay.sdk.HeepayReturn;
import java.util.Map;
public class SubmitReturn {
private boolean _success;
private String _error_message;
private Map<String, String> _map_list;
public boolean is_success() {
return _success;
}
public void set_success(boolean _success) {
this._success = _success;
}
public String get_error_message() {
return _error_message;
}
public void set_error_message(String _error_message) {
this._error_message = _error_message;
}
public Map<String, String> get_map_list() {
return _map_list;
}
public void set_map_list(Map<String, String> _map_list) {
this._map_list = _map_list;
}
}

View File

@@ -1,15 +0,0 @@
package com.accompany.payment.huiju;
/**
* @author linuxea
* @date 2019/9/5 10:56
*/
public class Constant {
/** 支付成功状态 */
public static final String PAY_SUCCESS = "100";
/** 接口版本 */
static final String API_VERSION = "1.0";
/** 支付币种 */
static final Integer RMB_CURRENCY = 1;
}

View File

@@ -1,33 +0,0 @@
package com.accompany.payment.huiju;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author linuxea
* @date 2019/9/5 14:43
*/
@Component
@ConfigurationProperties("hui-ju")
@Data
public class HuiJuConfig {
/** 请求支付参数 url */
private String payUrl;
/** 后台异步通知 url */
private String notifyUrl;
/** 商户订单号 */
private String merchantNo;
/** 商户密钥 */
private String merchantSecret;
/** 交易商户号(小程序) */
private String tradeMerchantNo;
/** 交易商户号(公众号) **/
private String pubTradeMerchantNo;
}

View File

@@ -1,33 +0,0 @@
package com.accompany.payment.huiju;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 汇聚微信公众号支付请求返回 sdk 参数类
*
* @author linuxea
* @date 2019/9/6 16:06
*/
@NoArgsConstructor
@Data
class HuiJuPublicPayResponseVO {
/**
* 示例 appId : wx06187f0efc2b85dd timeStamp : 1567757163 nonceStr :
* dabf18feb76749a3af391848eb9ee65c package : prepay_id=wx06160603180023df6e10d3e91324739700
* signType : RSA paySign :
* B6cwgBW3HGQ6F00Lh7K4ZcCcUptrKmgMD3cf65UAYBB8t1XgQqG7wBY7Vl9Z/fp/wbJhBCLUsYwh2tAkjsiWiWeCmextga/a7I0Wj4/vyLpDJxl01cueGaMIbFLajozGTZSKxD+AaSUstMIqnK2KP+tWhhoaQo808RM4vdK35Ynx+Oo1SOqaA/ZgXeNkIGJE1r1z8Cnco69Q5GiM9/Rnpg1fZhDqMsE53apl4JyEKqK3+/tyqCsC4/wjLy/tCWYUBi7sX5lsVpDNdXc/F2jjTZizRs8AcaCFhdK+SoUuJzNPQ3OGI4IGk+kNA+oVox4C9i3NBL3vqmV+yxNHE4T1dw==
*/
private String appId;
private String timeStamp;
private String nonceStr;
@JsonProperty("package")
private String packageInfo;
private String signType;
private String paySign;
}

View File

@@ -1,232 +0,0 @@
package com.accompany.payment.huiju;
import com.accompany.common.utils.BeanUtil;
import com.accompany.core.dto.HttpForm;
import com.accompany.core.service.base.BaseService;
import com.accompany.core.util.JsonUtil;
import com.accompany.core.util.OkHttpUtils;
import com.accompany.core.util.StringUtils;
import com.accompany.payment.config.WxConfig;
import com.accompany.payment.config.WxMiniAppConfig;
import com.accompany.payment.vo.JsapiReturnVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import static com.accompany.payment.huiju.Constant.API_VERSION;
import static com.accompany.payment.huiju.Constant.RMB_CURRENCY;
/**
* 汇聚 支付
*
* @author linuxea
* @date 2019/9/5 10:32
*/
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Lazy(false)
public class HuiJuService extends BaseService {
private final HuiJuConfig huiJuConfig;
private final WxMiniAppConfig wxMiniAppConfig;
@Autowired
public HuiJuService(HuiJuConfig huiJuConfig, WxMiniAppConfig wxMiniAppConfig) {
this.huiJuConfig = huiJuConfig;
this.wxMiniAppConfig = wxMiniAppConfig;
}
/**
* 小程序支付
*
* @param openId openId
* @param transAmount 交易金额(单位分)
* @param outTransNo 交易订单号
* @param goodsSubject 交易订单标题
* @param successUrl 页面跳转 url
* @return 交易 sdk 参数
*/
public HuiJuWeChatMiniPayInfoVO weChatMiniAppPay(
String openId, Long transAmount, String outTransNo, String goodsSubject, String successUrl) throws Exception{
RequestVO requestVO =
this.buildWechatMiniAppPay(openId, transAmount, outTransNo, goodsSubject, successUrl);
ResponseVO responseVO = this.send(requestVO);
return JsonUtil.parseToClass(responseVO.getRcResult(), HuiJuWeChatMiniPayInfoVO.class);
}
/**
* 公众号支付
*
* @param openId openId
* @param transAmount 交易金额(单位分)
* @param outTransNo 交易订单号
* @param goodsSubject 交易订单标题
* @param successUrl 页面跳转 url
* @param nick 昵称
* @param strawberryNo 抖抖号
* @return 交易 sdk 参数
*/
public JsapiReturnVo publicPay(
String openId,
Long transAmount,
String outTransNo,
String goodsSubject,
String successUrl,
String nick,
Long strawberryNo) throws Exception{
RequestVO requestVO =
this.buildWechatPublicPay(openId, transAmount, outTransNo, goodsSubject, successUrl);
ResponseVO responseVO = this.send(requestVO);
HuiJuPublicPayResponseVO huiJuPublicPayResponseVO =
Objects.requireNonNull(
JsonUtil.parseToClass(responseVO.getRcResult(), HuiJuPublicPayResponseVO.class));
final JsapiReturnVo jsapiReturnVo = buildUnionPublicVO(huiJuPublicPayResponseVO);
jsapiReturnVo.setErban_no(String.valueOf(strawberryNo));
jsapiReturnVo.setNick(nick);
return jsapiReturnVo;
}
/**
* 构建统一的公众号请求参数
*
* @param huiJuPublicPayResponseVO 汇聚微信公众号请求返回
* @return 统一的公众号请求参数
*/
private JsapiReturnVo buildUnionPublicVO(HuiJuPublicPayResponseVO huiJuPublicPayResponseVO) {
JsapiReturnVo jsapiReturnVo = new JsapiReturnVo();
jsapiReturnVo.setTimestamp(huiJuPublicPayResponseVO.getTimeStamp());
jsapiReturnVo.setNonce_str(huiJuPublicPayResponseVO.getNonceStr());
jsapiReturnVo.setPrepay_id(huiJuPublicPayResponseVO.getPackageInfo());
jsapiReturnVo.setSign(huiJuPublicPayResponseVO.getPaySign());
jsapiReturnVo.setAppid(huiJuPublicPayResponseVO.getAppId());
jsapiReturnVo.setSign_type(huiJuPublicPayResponseVO.getSignType());
return jsapiReturnVo;
}
private RequestVO buildWechatPublicPay(
String openId, Long transAmount, String outTransNo, String goodsSubject, String successUrl) {
return buildPay(
openId,
transAmount,
outTransNo,
goodsSubject,
successUrl,
TransactionTypeEnum.WEIXIN_GZH.name(),
WxConfig.appId);
}
/**
* 构建支付请求
*
* @param openId 微信 openId
* @param transAmount 交易金额 单位为: 分
* @param outTransNo 交易订单号
* @param goodsSubject 交易订单标题
* @param successUrl 页面跳转 url
* @return {@link RequestVO}
*/
private RequestVO buildWechatMiniAppPay(
String openId, Long transAmount, String outTransNo, String goodsSubject, String successUrl) {
return buildPay(
openId,
transAmount,
outTransNo,
goodsSubject,
successUrl,
TransactionTypeEnum.WEIXIN_XCX.name(),
wxMiniAppConfig.getAppId());
}
private RequestVO buildPay(
String openId,
Long transAmount,
String outTransNo,
String goodsSubject,
String successUrl,
String transactionType,
String appId) {
RequestVO requestVO = new RequestVO();
requestVO.setP0Version(API_VERSION);
requestVO.setP1MerchantNo(huiJuConfig.getMerchantNo());
requestVO.setP2OrderNo(outTransNo);
double amount = BigDecimal.valueOf(transAmount).divide(BigDecimal.valueOf(100))
.setScale(2,BigDecimal.ROUND_HALF_DOWN).doubleValue();
requestVO.setP3Amount(amount);
requestVO.setP5ProductName(goodsSubject);
requestVO.setQ5OpenId(openId);
requestVO.setP8ReturnUrl(successUrl);
requestVO.setP9NotifyUrl(huiJuConfig.getNotifyUrl());
requestVO.setQ1FrpCode(transactionType);
requestVO.setP4Cur(RMB_CURRENCY);
requestVO.setQ7AppId(appId);
if(transactionType.equalsIgnoreCase(TransactionTypeEnum.WEIXIN_XCX.name())){
requestVO.setQaTradeMerchantNo(huiJuConfig.getTradeMerchantNo());
}else if(transactionType.equalsIgnoreCase(TransactionTypeEnum.WEIXIN_GZH.name())){
requestVO.setQaTradeMerchantNo(huiJuConfig.getPubTradeMerchantNo());
}
// 签名要放在最后
requestVO.setHmac(requestSign(requestVO));
return requestVO;
}
/**
* 支付
*
* @param requestVO {@link RequestVO} 请求参数
* @return {@link ResponseVO} 响应参数
*/
@SuppressWarnings("unchecked")
public ResponseVO send(RequestVO requestVO){
Map<String,Object> requestMap = JsonUtil.parseToClass(JsonUtil.parseToString(requestVO),Map.class);
List<HttpForm> params = Objects.requireNonNull(requestMap).keySet().stream()
.map(x -> new HttpForm(x, requestMap.get(x).toString()))
.collect(Collectors.toList());
String responseBody = OkHttpUtils.postWithForm(huiJuConfig.getPayUrl(), params);
log.info("huiju response ,param:{}, body:{}",gson.toJson(requestVO),responseBody);
return JsonUtil.parseToClass(responseBody, ResponseVO.class);
}
/**
* 签名 除 hmac 字段外,所有参数按照文档要求的顺序设值,并参与拼接待签 名字符串; 在待签名字符串中,字段名和字段值都采用原始值,不进行 URL Encode
*
* @param requestVO 请求参数
* @return 生成签名数据
*/
@SuppressWarnings("unchecked")
public String requestSign(RequestVO requestVO) {
Map<String, Object> params = BeanUtil.objectToMap(requestVO);
return md5Sign(params);
}
/**
* md5 签名
*
* @param params 参数 map
* @return 签名结果
*/
public String md5Sign(Map<String, Object> params) {
List<String> keys = new ArrayList<>(Objects.requireNonNull(params).keySet());
Collections.sort(keys);
StringBuilder stringBuilder = new StringBuilder();
for (String key : keys) {
// hmac 不参与签名
Object value = params.get(key);
//空对象和空值不参与签名
if ("hmac".equalsIgnoreCase(key) || value == null || StringUtils.isBlank(value.toString())) {
continue;
}
stringBuilder.append(value);
}
log.info("按要求参数拼接的东东是 {}", stringBuilder.toString());
return DigestUtils.md5Hex(stringBuilder.toString() + huiJuConfig.getMerchantSecret())
.toUpperCase();
}
}

View File

@@ -1,33 +0,0 @@
package com.accompany.payment.huiju;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author linuxea
* @date 2019/9/5 15:18
*/
@NoArgsConstructor
@Data
public class HuiJuWeChatMiniPayInfoVO {
/** appId */
private String appId;
/** 创建支付时间戳 秒 */
private String timeStamp;
/** 随机字符串 */
private String nonceStr;
/** 前端调起支付参数 */
@JsonProperty("package")
private String packageInfo;
/** 签名类型 */
private String signType;
/** 支付签名 */
private String paySign;
}

View File

@@ -1,62 +0,0 @@
package com.accompany.payment.huiju;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 汇聚回调参数 get 请求,应该是因为不走 requestBody 封装,所以 JsonProperty 失效 所以有下划线 _ 这种东东去不掉 将就看一下吧
*
* @author linuxea
* @date 2019/9/5 10:49
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NotifyResponse {
/** 商户编号 */
private String r1_MerchantNo;
/** 商户订单号 */
private String r2_OrderNo;
/** 支付金额 */
private String r3_Amount;
/** 交易币种 1 代表人民币 */
private String r4_Cur;
/** 公用回传参数 */
private String r5_Mp;
/** 支付状态 100 表示成功 */
private String r6_Status;
/** 交易流水号 */
private String r7_TrxNo;
/** 银行订单号 */
private String r8_BankOrderNo;
/** 银行流水号 */
private String r9_BankTrxNo;
/** 支付时间 格式YYYY-MM-DD HH:mm:ss HH代表24小时制 */
private String ra_PayTime;
/** 交易通知时间 格式YYYY-MM-DD HH:mm:ss HH代表24小时制 */
private String rb_DealTime;
/** 银行编码 */
private String rc_BankCode;
/** 用户标识 */
private String rd_OpenId;
/** 平台优惠金额 平台优惠金额,单位:元,精确 到分,保留两位小数 */
private String re_DiscountAmount;
/** 签名数据 */
private String hmac;
}

Some files were not shown because too many files have changed in this diff Show More