This commit is contained in:
Lemon
2023-08-14 11:41:29 +08:00
15 changed files with 719 additions and 168 deletions

View File

@@ -0,0 +1,84 @@
package com.jsowell.adapay.response;
import lombok.*;
/**
* 支付撤销对象
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PaymentReverseResponse {
/**
* Adapay生成的支付撤销对象id
*/
private String id;
/**
* 支付撤销对象payment_reverse
*/
private String object;
/**
* 当前支付撤销状态,参见 状态 说明
*/
private String status;
/**
* true是prod模式false是mock模式
*/
private String prod_mode;
/**
* 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一
*/
private String order_no;
/**
* 原支付交易id
*/
private String payment_id;
/**
* 控制台 主页面应用的app_id
*/
private String app_id;
/**
* 撤销金额必须大于0保留两位小数点如0.10、100.05等
*/
private String reverse_amt;
/**
* 原支付对象已撤销金额,包括已撤销完成金额和撤销处理中的金额
*/
private String reversed_amt;
/**
* 当前支付对象已确认金额
*/
private String confirmed_amt;
/**
* 当前支付确认对象已退款金额,包括已退款完成金额和退款处理中的金额
*/
private String refunded_amt;
/**
* 创建时间戳
*/
private String created_time;
/**
*
* 撤销成功时间戳
*/
private String succeed_time;
/**
* 扫码收银台返回的退款交易流水号
*/
private String channel_no;
}

View File

@@ -0,0 +1,48 @@
package com.jsowell.adapay.response;
import lombok.*;
/**
* 退款请求返回的对象
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RefundResponse {
/**
* 由 Adapay 生成的退款对象 id
*/
private String id;
/**
* 退款对象创建时间
*/
private String created_time;
/**
* 退款目标支付对象 id
*/
private String payment_id;
/**
* 退款金额(必须大于 0保留两位小数点如0.10、100.05等
*/
private String refund_amt;
/**
* 退款状态S-成功F-失败P-处理中
*/
private String trans_state;
/**
* 退款手续费
*/
private String fee_amt;
/**
* 当前交易状态,参见 状态 说明
*/
private String status;
}

View File

@@ -6,12 +6,11 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*;
import com.jsowell.adapay.common.DivMember;
import com.jsowell.adapay.dto.SettleAccountDTO;
import com.jsowell.adapay.dto.UpdateAccountConfigDTO;
import com.jsowell.adapay.dto.WithdrawDTO;
import com.jsowell.adapay.response.BalancePaymentResponse;
import com.jsowell.adapay.response.QueryCorpMemberResponse;
import com.jsowell.adapay.response.QueryMemberResponse;
import com.jsowell.adapay.response.*;
import com.jsowell.adapay.vo.AdapayAccountBalanceVO;
import com.jsowell.adapay.vo.AdapayCorpMemberVO;
import com.jsowell.adapay.vo.AdapayMemberInfoVO;
@@ -67,6 +66,13 @@ public class AdapayMemberService {
@Autowired
private ClearingBillInfoService clearingBillInfoService;
/**
* 创建结算账户
*
* @param dto
* @throws BaseAdaPayException
* @throws BusinessException
*/
public void createSettleAccount(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
String bankAcctType = dto.getBankAcctType();
if (StringUtils.equals(bankAcctType, Constants.ONE)) {
@@ -83,7 +89,7 @@ public class AdapayMemberService {
* @throws Exception
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void createMember(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
public void createMember(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (adapayMemberAccount != null) {
log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId());
@@ -444,6 +450,7 @@ public class AdapayMemberService {
/**
* 提现逻辑
*
* @param dto
* @throws BaseAdaPayException
*/
@@ -506,6 +513,7 @@ public class AdapayMemberService {
/**
* 更新汇付会员信息
*
* @param dto
* @return
* @throws BaseAdaPayException
@@ -544,15 +552,57 @@ public class AdapayMemberService {
return null;
}
/**
* 创建交易确认请求/创建分账请求
* 这个方法只适用于给一个用户分账
*
* @param paymentId 支付对象id
* @param adapayMemberAccount 收到该张的汇付会员信息
* @param confirmAmt 确认的金额
* @param orderCode 订单编号
*/
public PaymentConfirmResponse createPaymentConfirmRequest(String paymentId, AdapayMemberAccount adapayMemberAccount, BigDecimal confirmAmt, String orderCode) {
// 调汇付的分账接口 确认交易
Map<String, Object> confirmParams = Maps.newHashMap();
// Adapay生成的支付对象id
confirmParams.put("payment_id", paymentId);
// 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一
confirmParams.put("order_no", "PC" + System.currentTimeMillis());
// 确认金额必须大于0保留两位小数点如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。
confirmParams.put("confirm_amt", AdapayUtil.formatAmount(confirmAmt));
// 附加说明
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderCode);
jsonObject.put("adapayMemberId", adapayMemberAccount.getAdapayMemberId());
confirmParams.put("description", jsonObject.toJSONString());
// 分账对象信息 一次最多7个
DivMember divMember = new DivMember();
divMember.setMember_id(adapayMemberAccount.getAdapayMemberId());
divMember.setAmount(AdapayUtil.formatAmount(confirmAmt));
divMember.setFee_flag(Constants.Y);
confirmParams.put("div_members", Lists.newArrayList(divMember));
Map<String, Object> paymentConfirm = null;
try {
paymentConfirm = PaymentConfirm.create(confirmParams);
} catch (BaseAdaPayException e) {
log.error("创建交易确认请求error", e);
}
String jsonString = JSON.toJSONString(paymentConfirm);
log.info("调分账接口param:{}, result:{}", JSON.toJSONString(confirmParams), jsonString);
return JSONObject.parseObject(jsonString, PaymentConfirmResponse.class);
}
/**
* 创建余额支付请求
*
* @param outMemberId 出账用户的member_id 若为商户本身时请传入0
* @param inMemberId 入账用户的member_id 若为商户本身时请传入0
* @param transAmt 交易金额, 必须大于0保留两位小数点如0.10、100.05等
* @param title 标题
* @param desc 描述信息
* @param inMemberId 入账用户的member_id 若为商户本身时请传入0
* @param transAmt 交易金额, 必须大于0保留两位小数点如0.10、100.05等
* @param title 标题
* @param desc 描述信息
*/
public BalancePaymentResponse createBalancePaymentRequest(String outMemberId, String inMemberId, String transAmt, String title, String desc) throws BaseAdaPayException {
public BalancePaymentResponse createBalancePaymentRequest(String outMemberId, String inMemberId, String transAmt, String title, String desc) {
Map<String, Object> balanceParam = Maps.newHashMap();
balanceParam.put("app_id", ADAPAY_APP_ID);
balanceParam.put("adapay_func_code", "settle_accounts.balancePay");
@@ -562,9 +612,15 @@ public class AdapayMemberService {
balanceParam.put("trans_amt", AdapayUtil.formatAmount(transAmt));
balanceParam.put("goods_title", title);
balanceParam.put("goods_desc", desc);
Map<String, Object> paymentResult = AdapayCommon.requestAdapay(balanceParam);
log.info("创建余额支付param:{}, result:{}", JSON.toJSONString(balanceParam), JSON.toJSONString(paymentResult));
return JSONObject.parseObject(JSON.toJSONString(paymentResult), BalancePaymentResponse.class);
Map<String, Object> paymentResult = null;
try {
paymentResult = AdapayCommon.requestAdapay(balanceParam);
} catch (BaseAdaPayException e) {
log.error("创建余额支付请求error", e);
}
String jsonString = JSON.toJSONString(paymentResult);
log.info("创建余额支付param:{}, result:{}", JSON.toJSONString(balanceParam), jsonString);
return JSONObject.parseObject(jsonString, BalancePaymentResponse.class);
}
/**
@@ -579,4 +635,48 @@ public class AdapayMemberService {
Map<String, Object> confirmReverseResult = AdapayCommon.requestAdapay(confirmReverseParams);
log.info("创建支付确认撤销param:{}, result:{}", JSON.toJSONString(confirmReverseParams), JSON.toJSONString(confirmReverseResult));
}
/**
* 创建退款请求
*/
public RefundResponse createRefundRequest(String paymentId, BigDecimal refundAmt) {
// 延迟分账确认的调退款接口
Map<String, Object> refundParams = Maps.newHashMap();
refundParams.put("refund_amt", AdapayUtil.formatAmount(refundAmt));
refundParams.put("refund_order_no", IdUtils.fastSimpleUUID());
refundParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> resultResponse = null;
try {
resultResponse = Refund.create(paymentId, refundParams);
} catch (BaseAdaPayException e) {
log.error("汇付支付创建退款对象error", e);
}
String jsonString = JSON.toJSONString(resultResponse);
log.info("汇付支付创建退款对象param:{}, result:{}", JSON.toJSONString(refundParams), JSON.toJSONString(jsonString));
return JSONObject.parseObject(jsonString, RefundResponse.class);
}
/**
* 创建交易撤销请求
* 延迟分账未确认, 调交易撤销接口退款
*/
public PaymentReverseResponse createPaymentReverseRequest(String paymentId, BigDecimal reverseAmt) {
PaymentReverseResponse response;
// 延迟分账未确认调撤销调撤销接口退款
Map<String, Object> reverseParams = Maps.newHashMap();
reverseParams.put("app_id", ADAPAY_APP_ID);
reverseParams.put("payment_id", paymentId);
reverseParams.put("reverse_amt", AdapayUtil.formatAmount(reverseAmt));
reverseParams.put("order_no", IdUtils.fastSimpleUUID());
reverseParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> paymentReverse = null;
try {
paymentReverse = PaymentReverse.create(reverseParams);
} catch (BaseAdaPayException e) {
log.error("汇付支付创建交易撤销对象error", e);
}
String jsonString = JSON.toJSONString(paymentReverse);
log.info("汇付支付创建交易撤销对象param:{}, result:{}", JSON.toJSONString(reverseParams), jsonString);
return JSONObject.parseObject(jsonString, PaymentReverseResponse.class);
}
}

View File

@@ -24,5 +24,5 @@ public class OrderSettleResult {
/**
* 附加说明
*/
private String description;
// private String description;
}

View File

@@ -1,16 +1,13 @@
package com.jsowell.pile.domain;
import lombok.*;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 会员汇付支付记录表
*/
* 会员汇付支付记录表
*/
@Getter
@Setter
@Builder
@@ -20,62 +17,67 @@ public class MemberAdapayRecord {
private Integer id;
/**
* 会员id
*/
* 会员id
*/
private String memberId;
/**
* 场景类型order, balance
*/
* 场景类型order, balance
*/
private String scenarioType;
/**
* 汇付支付id
*/
* 汇付支付id
*/
private String paymentId;
/**
* 汇付支付单号
*/
* 汇付支付单号
*/
private String paymentOrderNo;
/**
* 支付金额
*/
* 支付金额
*/
private BigDecimal payAmt;
/**
* 退款金额
*/
* 退款金额
*/
private BigDecimal refundAmt;
/**
* 消费金额
*/
* 消费金额
*/
private BigDecimal spendAmt;
/**
* 创建人
*/
* 剩余金额
*/
private BigDecimal balanceAmt;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
* 创建时间
*/
private Date createTime;
/**
* 更新人
*/
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
* 更新时间
*/
private Date updateTime;
/**
* 删除标识
*/
* 删除标识
*/
private String delFlag;
}

View File

@@ -1,12 +1,14 @@
package com.jsowell.pile.mapper;
import com.jsowell.pile.domain.MemberAdapayRecord;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface MemberAdapayRecordMapper {
/**
* insert record to table selective
*
* @param record the record
* @return insert count
*/
@@ -14,6 +16,7 @@ public interface MemberAdapayRecordMapper {
/**
* select by primary key
*
* @param id primary key
* @return object by primary key
*/
@@ -21,6 +24,7 @@ public interface MemberAdapayRecordMapper {
/**
* update record selective
*
* @param record the updated record
* @return update count
*/
@@ -33,4 +37,10 @@ public interface MemberAdapayRecordMapper {
int insertOrUpdate(MemberAdapayRecord record);
int insertOrUpdateSelective(MemberAdapayRecord record);
List<MemberAdapayRecord> selectAdapayRecordList(@Param("memberId") String memberId, @Param("scenarioType") String scenarioType);
MemberAdapayRecord selectByPaymentId(@Param("paymentId") String paymentId);
List<MemberAdapayRecord> selectAvailableBalance(@Param("memberId") String memberId);
}

View File

@@ -16,11 +16,13 @@ import com.jsowell.pile.vo.lianlian.AccumulativeInfoVO;
import com.jsowell.pile.vo.uniapp.OrderVO;
import com.jsowell.pile.vo.uniapp.PersonPileConnectorSumInfoVO;
import com.jsowell.pile.vo.uniapp.SendMessageVO;
import com.jsowell.pile.vo.web.BalanceDeductionAmountVO;
import com.jsowell.pile.vo.web.IndexOrderInfoVO;
import com.jsowell.pile.vo.web.OrderListVO;
import com.jsowell.pile.vo.web.OrderTotalDataVO;
import com.jsowell.wxpay.response.WechatPayRefundResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.List;
@@ -150,7 +152,9 @@ public interface IOrderBasicInfoService {
void tempOrderSplittingOperations(String merchantId, String tradeDate);
/**
List<BalanceDeductionAmountVO> calculateTheBalanceDeductionAmount(String memberId, BigDecimal amount);
/**
* 执行订单分账
* @param orderBasicInfo
* @param adapayMemberAccount

View File

@@ -1,9 +1,9 @@
package com.jsowell.pile.service;
import java.util.List;
import com.jsowell.pile.domain.MemberAdapayRecord;
public interface MemberAdapayRecordService{
import java.util.List;
public interface MemberAdapayRecordService{
int insertSelective(MemberAdapayRecord record);
@@ -19,4 +19,13 @@ public interface MemberAdapayRecordService{
int insertOrUpdateSelective(MemberAdapayRecord record);
List<MemberAdapayRecord> selectAdapayRecordList(String memberId, String scenarioType);
MemberAdapayRecord selectByPaymentId(String paymentId);
/**
* 查询会员可用余额充值记录
* @param memberId 会员id
*/
List<MemberAdapayRecord> selectAvailableBalance(String memberId);
}

View File

@@ -1,11 +1,12 @@
package com.jsowell.pile.service.impl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import com.jsowell.pile.domain.MemberAdapayRecord;
import com.jsowell.pile.mapper.MemberAdapayRecordMapper;
import com.jsowell.pile.service.MemberAdapayRecordService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class MemberAdapayRecordServiceImpl implements MemberAdapayRecordService{
@@ -47,4 +48,30 @@ public class MemberAdapayRecordServiceImpl implements MemberAdapayRecordService{
return memberAdapayRecordMapper.insertOrUpdateSelective(record);
}
/**
* 查询会员的支付记录,按照支付成功时间正序
* @param memberId 会员id
* @param scenarioType 支付订单/充值余额
* @return 支付记录列表
*/
@Override
public List<MemberAdapayRecord> selectAdapayRecordList(String memberId, String scenarioType) {
return memberAdapayRecordMapper.selectAdapayRecordList(memberId, scenarioType);
}
@Override
public MemberAdapayRecord selectByPaymentId(String paymentId) {
return memberAdapayRecordMapper.selectByPaymentId(paymentId);
}
/**
* 查询会员可用余额充值记录
* @param memberId 会员id
* @return
*/
@Override
public List<MemberAdapayRecord> selectAvailableBalance(String memberId) {
return memberAdapayRecordMapper.selectAvailableBalance(memberId);
}
}

View File

@@ -12,12 +12,11 @@ import com.google.common.collect.Sets;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.Payment;
import com.huifu.adapay.model.PaymentConfirm;
import com.huifu.adapay.model.PaymentReverse;
import com.huifu.adapay.model.Refund;
import com.jsowell.adapay.common.CreateAdaPaymentParam;
import com.jsowell.adapay.common.DivMember;
import com.jsowell.adapay.response.BalancePaymentResponse;
import com.jsowell.adapay.response.PaymentConfirmResponse;
import com.jsowell.adapay.response.PaymentReverseResponse;
import com.jsowell.adapay.service.AdapayMemberService;
import com.jsowell.adapay.vo.OrderSettleResult;
import com.jsowell.common.constant.CacheConstants;
@@ -170,6 +169,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
@Autowired
private AdapayMemberService adapayMemberService;
@Autowired
private MemberAdapayRecordService memberAdapayRecordService;
/**
* 条件查询订单基本信息
*
@@ -184,6 +186,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 查询订单列表
* 带权限过滤
*
* @param dto 订单
* @return 订单
*/
@@ -203,6 +206,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 查询订单列表
* 无权限过滤
*
* @param dto 订单
* @return 订单
*/
@@ -472,6 +476,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 关闭启动失败订单
*
* @param startTime
* @param endTime
*/
@@ -614,6 +619,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 通过交易流水号查询订单信息
*
* @param transactionCode 交易流水号
* @return 订单信息
*/
@@ -677,6 +683,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
public void settleOrder(TransactionRecordsData data, OrderBasicInfo orderBasicInfo) {
logger.info("结算订单start data:{}, orderBasicInfo:{}", data.toString(), orderBasicInfo.toString());
String orderCode = orderBasicInfo.getOrderCode();
String memberId = orderBasicInfo.getMemberId();
// 判断订单状态
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
@@ -714,9 +721,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
}
}
// 查询订单详情 修改订单数据
OrderDetail orderDetail = getOrderDetailByOrderCode(orderCode);
// 把交易记录中的用电量,金额等信息 更新到orderBasicInfo和orderDetail
orderBasicInfo.setVirtualAmount(virtualAmount); // 虚拟金额
orderBasicInfo.setSettleAmount(orderAmount.subtract(virtualAmount)); // 结算金额
@@ -725,7 +729,8 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
orderBasicInfo.setSettlementTime(DateUtils.getNowDate()); // 结算时间
orderBasicInfo.setRefundAmount(residue); // 结算退款金额
// 更新订单详情
// 更新订单详情 查询订单详情 修改订单数据
OrderDetail orderDetail = getOrderDetailByOrderCode(orderCode);
try {
// 总电费金额
BigDecimal totalElectricityAmount = BigDecimal.ZERO;
@@ -808,28 +813,14 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
transactionService.doUpdateOrder(dto);
logger.info("结算订单end:{} OrderTransactionDTO:{}", orderCode, JSONObject.toJSONString(dto));
try {
// 将卡/vin状态解锁
if (!StringUtils.equals("0000000000000000", data.getLogicCard())) {
// 根据物理卡号查出当前为锁定状态的卡
PileAuthCard cardInfo = pileAuthCardService.selectSomeStatusCardInfo(CardStatusEnum.START_LOCK.getCode(), orderBasicInfo.getLogicCard());
if (cardInfo != null) {
// orderBasicInfo.setMemberId(cardInfo.getMemberId());
// 将此卡状态改为正常
cardInfo.setStatus(CardStatusEnum.NORMAL.getCode());
pileAuthCardService.updatePileAuthCard(cardInfo);
}
}
// 如果是vin启动将启动锁定状态改为正常
if (StringUtils.equals(data.getTransactionIdentifier(), "05")) {
MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(data.getVinCode());
if (plateInfo != null && (StringUtils.equals(plateInfo.getVinStatus(), "2"))) {
plateInfo.setVinStatus("1");
memberPlateNumberRelationService.updateMemberPlateNumberRelation(plateInfo);
}
}
} catch (Exception e) {
logger.error("解锁卡/vin状态 error,", e);
// 将卡/vin状态解锁
if (!StringUtils.equals("0000000000000000", data.getLogicCard())) {
cardStatusUnlocked(orderBasicInfo.getLogicCard());
}
// 如果是vin启动将启动锁定状态改为正常
if (StringUtils.equals(data.getTransactionIdentifier(), "05")) {
vinStatusUnlocked(data.getVinCode());
}
// 发送停止充电订阅消息
@@ -839,13 +830,50 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderCode);
}
/**
* 卡状态解锁
*/
private void cardStatusUnlocked(String logicCard) {
try {
// 根据物理卡号查出当前为锁定状态的卡
PileAuthCard cardInfo = pileAuthCardService.selectSomeStatusCardInfo(CardStatusEnum.START_LOCK.getCode(), logicCard);
if (cardInfo != null) {
// 将此卡状态改为正常
cardInfo.setStatus(CardStatusEnum.NORMAL.getCode());
pileAuthCardService.updatePileAuthCard(cardInfo);
}
} catch (Exception e) {
logger.error("解锁卡状态 error,", e);
}
}
/**
* 解锁vin状态
*
* @param vinCode
*/
private void vinStatusUnlocked(String vinCode) {
try {
MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode);
if (plateInfo != null && (StringUtils.equals(plateInfo.getVinStatus(), "2"))) {
plateInfo.setVinStatus("1");
memberPlateNumberRelationService.updateMemberPlateNumberRelation(plateInfo);
}
} catch (Exception e) {
logger.error("解锁vin状态 error,", e);
}
}
/**
* 订单退款逻辑
*
* @param orderBasicInfo 订单信息
* @param residue 需退款金额
* @param residue 需退款金额
*/
private void refundOrder(OrderBasicInfo orderBasicInfo, BigDecimal residue) {
// 订单编号
String orderCode = orderBasicInfo.getOrderCode();
// 订单消费金额
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
// 查支付记录
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
@@ -984,10 +1012,11 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 执行分账
for (OrderBasicInfo orderBasicInfo : orderBasicInfos) {
try {
OrderSettleResult orderSettleResult = null;
OrderSettleResult orderSettleResult;
if (OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) {
// 余额支付的订单 只用余额支付转账
orderSettleResult = doBalancePayment(orderBasicInfo, adapayMemberAccount);
// 余额支付的订单
// orderSettleResult = doBalancePayment(orderBasicInfo, adapayMemberAccount);
orderSettleResult = doBalancePaymentV2(orderBasicInfo, adapayMemberAccount);
} else {
// 在线支付,进行支付确认分账
orderSettleResult = doPaymentConfirm(orderBasicInfo, adapayMemberAccount);
@@ -1109,6 +1138,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 余额支付订单,使用余额支付转账
*
* @param orderBasicInfo
* @param adapayMemberAccount
* @return
@@ -1133,15 +1163,109 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
result.setConfirm_amt(balancePaymentRequest.getTrans_amt());
result.setStatus(balancePaymentRequest.getStatus());
result.setFee_amt(feeAmount.toString());
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderCode);
result.setDescription(jsonObject.toJSONString());
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("orderCode", orderCode);
// result.setDescription(jsonObject.toJSONString());
return result;
}
/**
* 余额支付订单,使用余额支付转账
*
* @param orderBasicInfo
* @param adapayMemberAccount
* @return
*/
public OrderSettleResult doBalancePaymentV2(OrderBasicInfo orderBasicInfo, AdapayMemberAccount adapayMemberAccount) throws BaseAdaPayException {
BigDecimal settleAmount = orderBasicInfo.getSettleAmount();
String orderCode = orderBasicInfo.getOrderCode();
BigDecimal confirmAmt = BigDecimal.ZERO;
BigDecimal feeAmt = BigDecimal.ZERO;
String status = null;
String description = null;
// 获取余额支付扣除金额 也许存在一笔不够扣,需要扣多笔的情况
List<BalanceDeductionAmountVO> list = calculateTheBalanceDeductionAmount(orderBasicInfo.getMemberId(), settleAmount);
for (BalanceDeductionAmountVO vo : list) {
String paymentId = vo.getPaymentId();
BigDecimal deductionAmount = vo.getDeductionAmount();
// 调汇付的分账接口 确认交易
PaymentConfirmResponse paymentConfirmResponse = adapayMemberService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, deductionAmount, orderCode);
if (paymentConfirmResponse != null) {
confirmAmt = confirmAmt.add(new BigDecimal(paymentConfirmResponse.getConfirmed_amt()));
feeAmt = feeAmt.add(new BigDecimal(paymentConfirmResponse.getFee_amt()));
status = paymentConfirmResponse.getStatus();
description = paymentConfirmResponse.getDescription();
}
// 更新这笔交易的剩余金额
MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId);
// 更新此笔交易单的消费金额 = 历史消费金额 + 本次消费金额
record.setSpendAmt(record.getSpendAmt().add(deductionAmount));
// 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额
record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt()));
memberAdapayRecordService.updateByPrimaryKeySelective(record);
}
// 分账接口返回的信息
OrderSettleResult result = new OrderSettleResult();
result.setConfirm_amt(confirmAmt.toString());
result.setStatus(status);
result.setFee_amt(feeAmt.toString());
// result.setDescription(description);
return result;
}
/**
* 计算余额扣除金额
* @param memberId 会员id
* @param amount 消费金额/退款金额
*/
@Override
public List<BalanceDeductionAmountVO> calculateTheBalanceDeductionAmount(String memberId, BigDecimal amount) {
List<BalanceDeductionAmountVO> resultList = Lists.newArrayList();
// 查询会员的余额充值记录 按照充值时间正序
List<MemberAdapayRecord> memberAdapayRecords = memberAdapayRecordService.selectAvailableBalance(memberId);
// 定义一个临时金额等于消费金额
BigDecimal tempAmount = new BigDecimal(amount.toString());
for (MemberAdapayRecord memberAdapayRecord : memberAdapayRecords) {
// 该笔支付剩余金额 取出一笔判断是否剩余金额够支付订单消费吗
BigDecimal balanceAmt = memberAdapayRecord.getBalanceAmt();
// 该笔支付扣除金额
BigDecimal deductionAmount;
// 消费金额 - 剩余金额
tempAmount = tempAmount.subtract(balanceAmt);
if (tempAmount.compareTo(BigDecimal.ZERO) >= 0) {
// 计算以后大于等于0说明这笔支付剩余金额需要扣完
deductionAmount = balanceAmt;
BalanceDeductionAmountVO build = BalanceDeductionAmountVO.builder()
.memberId(memberId)
.paymentId(memberAdapayRecord.getPaymentId())
.deductionAmount(deductionAmount)
.build();
resultList.add(build);
} else {
// 如果小于0则说明剩余的钱用不完扣除金额等于消费金额并结束循环
deductionAmount = balanceAmt.add(tempAmount);
BalanceDeductionAmountVO build = BalanceDeductionAmountVO.builder()
.memberId(memberId)
.paymentId(memberAdapayRecord.getPaymentId())
.deductionAmount(deductionAmount)
.build();
resultList.add(build);
break;
}
}
return resultList;
}
/**
* 延迟交易订单 交易确认
* @param orderBasicInfo 订单
*
* @param orderBasicInfo 订单
* @param adapayMemberAccount 结算账户
* @throws BaseAdaPayException
*/
@@ -1159,22 +1283,17 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 调汇付的分账接口 确认交易
Map<String, Object> confirmParams = Maps.newHashMap();
// Adapay生成的支付对象id
confirmParams.put("payment_id", adapayCallbackRecord.getPaymentId());
// 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一
confirmParams.put("order_no", "PC" + System.currentTimeMillis());
// 确认金额必须大于0保留两位小数点如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。
confirmParams.put("confirm_amt", settleAmount);
// 附加说明
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderBasicInfo.getOrderCode());
jsonObject.put("adapayMemberId", adapayMemberAccount.getAdapayMemberId());
confirmParams.put("description", jsonObject.toJSONString());
// 分账对象信息
DivMember divMember = new DivMember();
divMember.setMember_id(adapayMemberAccount.getAdapayMemberId());
@@ -1183,13 +1302,14 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
confirmParams.put("div_members", Lists.newArrayList(divMember));
Map<String, Object> paymentConfirm = PaymentConfirm.create(confirmParams);
logger.info("调分账接口param:{}, result:{}", JSON.toJSONString(confirmParams), JSON.toJSONString(paymentConfirm));
// 分账接口返回的信息
PaymentConfirmResponse paymentConfirmResponse = JSONObject.parseObject(JSON.toJSONString(paymentConfirm), PaymentConfirmResponse.class);
OrderSettleResult result = new OrderSettleResult();
result.setConfirm_amt(paymentConfirmResponse.getConfirm_amt());
result.setStatus(paymentConfirmResponse.getStatus());
result.setFee_amt(paymentConfirmResponse.getFee_amt());
result.setDescription(paymentConfirmResponse.getDescription());
// result.setDescription(paymentConfirmResponse.getDescription());
return result;
}
@@ -1207,6 +1327,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 批量查询订单
*
* @param orderCodeList
* @return
*/
@@ -1382,6 +1503,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 生成订单编号
*
* @return
*/
private String generateNewOrderCode() {
@@ -1397,6 +1519,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 保存异常订单到订单主表
*
* @param data 交易记录数据
*/
@Override
@@ -1983,12 +2106,12 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(dto.getPileSn());
PileStationWhitelist pileStationWhitelist = pileStationWhitelistService.queryWhitelistByMemberId(String.valueOf(pileBasicInfo.getStationId()), dto.getMemberId());
if(platformTesterVO != null && StringUtils.equals(Constants.ONE, platformTesterVO.getStatus())) {
if (platformTesterVO != null && StringUtils.equals(Constants.ONE, platformTesterVO.getStatus())) {
// 是平台测试员
accountBalance = new BigDecimal("500");
payMode = OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue();
}else if(pileStationWhitelist != null) {
} else if (pileStationWhitelist != null) {
// 站点白名单
accountBalance = new BigDecimal("500");
payMode = OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue();
@@ -2232,59 +2355,55 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 汇付支付-订单退款处理逻辑
*
* @param dto
*/
@Override
public void refundOrderWithAdapay(ApplyRefundDTO dto) {
logger.info("汇付支付订单:{}, 执行退款逻辑 param:{}", dto.getOrderCode(), JSON.toJSONString(dto));
// 查出来原来的支付信息
AdapayCallbackRecord record = adapayCallbackRecordService.selectByOrderCode(dto.getOrderCode());
if (Objects.isNull(record)) {
AdapayCallbackRecord callbackRecord = adapayCallbackRecordService.selectByOrderCode(dto.getOrderCode());
if (Objects.isNull(callbackRecord)) {
logger.error("汇付支付orderCode:{}, 订单退款处理逻辑, 查询订单微信支付记录为空!", dto.getOrderCode());
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_CALLBACK_RECORD_ERROR);
}
// 判断支付金额和退款金额
String paymentId = callbackRecord.getPaymentId();
BigDecimal refundAmount = dto.getRefundAmount();
BigDecimal payAmt = record.getPayAmt();
BigDecimal payAmt = callbackRecord.getPayAmt();
if (refundAmount.compareTo(payAmt) > 0) {
logger.error("汇付支付订单号:{}, 退款金额:{}(元),大于可退金额{}(元), 抛出异常", dto.getOrderCode(), refundAmount, payAmt);
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR);
}
// 创建汇付退款对象 在完成初始化设置情况下,调用方法,获取 Refund对象
String id = record.getPaymentId(); //
String snowflakeId = SnowflakeIdWorker.getSnowflakeId();
String amount = AdapayUtil.formatAmount(dto.getRefundAmount());
// TODO 拿orderCode查询清分状态
String payMode = "delay";
if (StringUtils.equals("", payMode)) {
// 延迟分账确认的调退款接口
Map<String, Object> refundParams = Maps.newHashMap();
refundParams.put("refund_amt", amount);
refundParams.put("refund_order_no", snowflakeId);
refundParams.put("notify_url", ADAPAY_CALLBACK_URL);
try {
Map<String, Object> response = Refund.create(id, refundParams);
logger.info("汇付支付创建退款对象:{}", JSON.toJSONString(response));
} catch (BaseAdaPayException e) {
logger.error("汇付支付创建退款对象error", e);
}
adapayMemberService.createRefundRequest(paymentId, refundAmount);
} else {
// 延迟分账未确认调撤销调撤销接口退款
Map<String, Object> reverseParams = Maps.newHashMap();
reverseParams.put("app_id", ADAPAY_APP_ID);
reverseParams.put("payment_id", id);
reverseParams.put("reverse_amt", amount);
reverseParams.put("order_no", snowflakeId);
reverseParams.put("notify_url", ADAPAY_CALLBACK_URL);
try {
Map<String, Object> paymentReverse = PaymentReverse.create(reverseParams);
logger.info("汇付支付创建交易撤销对象:{}", JSON.toJSONString(paymentReverse));
} catch (BaseAdaPayException e) {
logger.error("汇付支付创建交易撤销对象error", e);
PaymentReverseResponse response = adapayMemberService.createPaymentReverseRequest(paymentId, refundAmount);
if (response != null) {
MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId);
BigDecimal reverseAmt = new BigDecimal(response.getReverse_amt());
// 更新此笔交易单的消费金额 = 支付金额 - 撤销金额
BigDecimal spendAmt = callbackRecord.getPayAmt().subtract(reverseAmt);
record.setSpendAmt(spendAmt);
// 退款金额
record.setRefundAmt(reverseAmt);
// 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额
record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt()));
if (BigDecimal.ZERO.compareTo(record.getBalanceAmt()) != 0) {
logger.error("订单分账结束后账不平paymentId:{}, orderCode:{}, 支付金额:{}, 消费金额:{}, 退款金额:{}",
paymentId, dto.getOrderCode(), payAmt, spendAmt, reverseAmt);
}
memberAdapayRecordService.updateByPrimaryKeySelective(record);
}
}
}
@@ -2295,6 +2414,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
if (memberVO == null) {
throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_NOT_FOUND_ERROR);
}
// 校验退款金额
BigDecimal principalBalance = memberVO.getPrincipalBalance();
BigDecimal refundAmount = dto.getRefundAmount();
@@ -2303,12 +2423,27 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
}
// 查询用户充值余额订单 过滤掉已经退款的充值订单
List<BalanceDeductionAmountVO> list = calculateTheBalanceDeductionAmount(dto.getMemberId(), refundAmount);
for (BalanceDeductionAmountVO vo : list) {
String paymentId = vo.getPaymentId();
BigDecimal deductionAmount = vo.getDeductionAmount();
// 也许需要多笔支付订单才够退款
// 调汇付的交易撤销接口
adapayMemberService.createPaymentReverseRequest(paymentId, deductionAmount);
// 更新这笔交易的剩余金额
MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId);
// 更新此笔交易单的消费金额 = 历史消费金额 + 本次消费金额
record.setSpendAmt(record.getSpendAmt().add(deductionAmount));
// 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额
record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt()));
memberAdapayRecordService.updateByPrimaryKeySelective(record);
}
}
/**
* 计算站点订单报表
*
* @param stationId 站点id
* @param tradeDate 交易日期
*/
@@ -2427,6 +2562,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/**
* 通过结算金额,计算客户到账金额和手续费
*
* @param settleAmount 需要拆分的结算金额
* @return
*/
@@ -2505,10 +2641,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
*
* @param dto
* @return
* @throws Exception
*/
@Override
public Map<String, Object> payOrder(PayOrderDTO dto) throws Exception {
public Map<String, Object> payOrder(PayOrderDTO dto) {
OrderBasicInfo orderInfo = this.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_NULL_ERROR);
@@ -2530,8 +2665,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 返回微信支付参数
resultMap.put("weixinMap", weixinMap);
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) { // 支付宝支付
// TODO 返回支付宝支付参数
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue())) { // 白名单支付
// 白名单支付可以直接调支付回调方法
dto.setPayAmount(new BigDecimal("500"));
@@ -2662,6 +2795,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
map.put("type", ScenarioEnum.ORDER.getValue());
map.put("orderCode", dto.getOrderCode());
map.put("payMode", payMode);
map.put("memberId", dto.getMemberId());
createAdaPaymentParam.setDescription(JSON.toJSONString(map));
// 异步通知地址url为http/https路径服务器POST回调URL 上请勿附带参数
createAdaPaymentParam.setNotify_url(ADAPAY_CALLBACK_URL);
@@ -2675,7 +2809,8 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
if (response != null && !response.isEmpty()) {
JSONObject expend = JSONObject.parseObject(response.get("expend").toString());
JSONObject pay_info = expend.getJSONObject("pay_info");
Map<String, Object> resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference<Map<String, Object>>() {});
Map<String, Object> resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference<Map<String, Object>>() {
});
if (resultMap != null) {
// 表示已经获取到支付参数了,后续再有支付请求就拒绝
redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES);
@@ -2802,7 +2937,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 如果是鉴权卡或者vin启动不判断枪口状态
if (!(StringUtils.equals(dto.getStartMode(), StartModeEnum.AUTH_CARD.getValue())
|| StringUtils.equals(dto.getStartMode(), StartModeEnum.VIN_CODE.getValue()))) {
|| StringUtils.equals(dto.getStartMode(), StartModeEnum.VIN_CODE.getValue()))) {
// 判断枪口状态
if (!(StringUtils.equals(pileConnector.getConnectorStatus(), PileConnectorDataBaseStatusEnum.FREE.getValue())

View File

@@ -0,0 +1,27 @@
package com.jsowell.pile.vo.web;
import lombok.*;
import java.math.BigDecimal;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BalanceDeductionAmountVO {
/**
* 会员id
*/
private String memberId;
/**
* 支付id
*/
private String paymentId;
/**
* 扣除金额
*/
private BigDecimal deductionAmount;
}