余额支付订单 进行分账处理

This commit is contained in:
2023-08-10 17:03:20 +08:00
parent df776b0466
commit 275962f201
8 changed files with 184 additions and 29 deletions

View File

@@ -6,10 +6,12 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.huifu.adapay.core.exception.BaseAdaPayException; import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*; import com.huifu.adapay.model.*;
import com.jsowell.adapay.common.DivMember;
import com.jsowell.adapay.dto.SettleAccountDTO; import com.jsowell.adapay.dto.SettleAccountDTO;
import com.jsowell.adapay.dto.UpdateAccountConfigDTO; import com.jsowell.adapay.dto.UpdateAccountConfigDTO;
import com.jsowell.adapay.dto.WithdrawDTO; import com.jsowell.adapay.dto.WithdrawDTO;
import com.jsowell.adapay.response.BalancePaymentResponse; import com.jsowell.adapay.response.BalancePaymentResponse;
import com.jsowell.adapay.response.PaymentConfirmResponse;
import com.jsowell.adapay.response.QueryCorpMemberResponse; import com.jsowell.adapay.response.QueryCorpMemberResponse;
import com.jsowell.adapay.response.QueryMemberResponse; import com.jsowell.adapay.response.QueryMemberResponse;
import com.jsowell.adapay.vo.AdapayAccountBalanceVO; import com.jsowell.adapay.vo.AdapayAccountBalanceVO;
@@ -544,6 +546,46 @@ public class AdapayMemberService {
return null; 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 outMemberId 出账用户的member_id 若为商户本身时请传入0
@@ -552,7 +594,7 @@ public class AdapayMemberService {
* @param title 标题 * @param title 标题
* @param desc 描述信息 * @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(); Map<String, Object> balanceParam = Maps.newHashMap();
balanceParam.put("app_id", ADAPAY_APP_ID); balanceParam.put("app_id", ADAPAY_APP_ID);
balanceParam.put("adapay_func_code", "settle_accounts.balancePay"); balanceParam.put("adapay_func_code", "settle_accounts.balancePay");
@@ -562,9 +604,15 @@ public class AdapayMemberService {
balanceParam.put("trans_amt", AdapayUtil.formatAmount(transAmt)); balanceParam.put("trans_amt", AdapayUtil.formatAmount(transAmt));
balanceParam.put("goods_title", title); balanceParam.put("goods_title", title);
balanceParam.put("goods_desc", desc); balanceParam.put("goods_desc", desc);
Map<String, Object> paymentResult = AdapayCommon.requestAdapay(balanceParam); Map<String, Object> paymentResult = null;
log.info("创建余额支付param:{}, result:{}", JSON.toJSONString(balanceParam), JSON.toJSONString(paymentResult)); try {
return JSONObject.parseObject(JSON.toJSONString(paymentResult), BalancePaymentResponse.class); 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 +627,5 @@ public class AdapayMemberService {
Map<String, Object> confirmReverseResult = AdapayCommon.requestAdapay(confirmReverseParams); Map<String, Object> confirmReverseResult = AdapayCommon.requestAdapay(confirmReverseParams);
log.info("创建支付确认撤销param:{}, result:{}", JSON.toJSONString(confirmReverseParams), JSON.toJSONString(confirmReverseResult)); log.info("创建支付确认撤销param:{}, result:{}", JSON.toJSONString(confirmReverseParams), JSON.toJSONString(confirmReverseResult));
} }
} }

View File

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

View File

@@ -37,4 +37,8 @@ public interface MemberAdapayRecordMapper {
int insertOrUpdate(MemberAdapayRecord record); int insertOrUpdate(MemberAdapayRecord record);
int insertOrUpdateSelective(MemberAdapayRecord record); int insertOrUpdateSelective(MemberAdapayRecord record);
List<MemberAdapayRecord> selectAdapayRecordList(@Param("memberId") String memberId, @Param("scenarioType") String scenarioType);
MemberAdapayRecord selectByPaymentId(@Param("paymentId") String paymentId);
} }

View File

@@ -19,4 +19,7 @@ public interface MemberAdapayRecordService{
int insertOrUpdateSelective(MemberAdapayRecord record); int insertOrUpdateSelective(MemberAdapayRecord record);
List<MemberAdapayRecord> selectAdapayRecordList(String memberId, String scenarioType);
MemberAdapayRecord selectByPaymentId(String paymentId);
} }

View File

@@ -1,11 +1,12 @@
package com.jsowell.pile.service.impl; 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.domain.MemberAdapayRecord;
import com.jsowell.pile.mapper.MemberAdapayRecordMapper; import com.jsowell.pile.mapper.MemberAdapayRecordMapper;
import com.jsowell.pile.service.MemberAdapayRecordService; import com.jsowell.pile.service.MemberAdapayRecordService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service @Service
public class MemberAdapayRecordServiceImpl implements MemberAdapayRecordService{ public class MemberAdapayRecordServiceImpl implements MemberAdapayRecordService{
@@ -47,4 +48,20 @@ public class MemberAdapayRecordServiceImpl implements MemberAdapayRecordService{
return memberAdapayRecordMapper.insertOrUpdateSelective(record); 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);
}
} }

View File

@@ -170,6 +170,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
@Autowired @Autowired
private AdapayMemberService adapayMemberService; private AdapayMemberService adapayMemberService;
@Autowired
private MemberAdapayRecordService memberAdapayRecordService;
/** /**
* 条件查询订单基本信息 * 条件查询订单基本信息
* *
@@ -957,10 +960,11 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 执行分账 // 执行分账
for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { for (OrderBasicInfo orderBasicInfo : orderBasicInfos) {
try { try {
OrderSettleResult orderSettleResult = null; OrderSettleResult orderSettleResult;
if (OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) { if (OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) {
// 余额支付的订单 只用余额支付转账 // 余额支付的订单
orderSettleResult = doBalancePayment(orderBasicInfo, adapayMemberAccount); // orderSettleResult = doBalancePayment(orderBasicInfo, adapayMemberAccount);
orderSettleResult = doBalancePaymentV2(orderBasicInfo, adapayMemberAccount);
} else { } else {
// 在线支付,进行支付确认分账 // 在线支付,进行支付确认分账
orderSettleResult = doPaymentConfirm(orderBasicInfo, adapayMemberAccount); orderSettleResult = doPaymentConfirm(orderBasicInfo, adapayMemberAccount);
@@ -1106,9 +1110,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
result.setConfirm_amt(balancePaymentRequest.getTrans_amt()); result.setConfirm_amt(balancePaymentRequest.getTrans_amt());
result.setStatus(balancePaymentRequest.getStatus()); result.setStatus(balancePaymentRequest.getStatus());
result.setFee_amt(feeAmount.toString()); result.setFee_amt(feeAmount.toString());
JSONObject jsonObject = new JSONObject(); // JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderCode); // jsonObject.put("orderCode", orderCode);
result.setDescription(jsonObject.toJSONString()); // result.setDescription(jsonObject.toJSONString());
return result; return result;
} }
@@ -1119,20 +1123,55 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
* @return * @return
*/ */
public OrderSettleResult doBalancePaymentV2(OrderBasicInfo orderBasicInfo, AdapayMemberAccount adapayMemberAccount) throws BaseAdaPayException { public OrderSettleResult doBalancePaymentV2(OrderBasicInfo orderBasicInfo, AdapayMemberAccount adapayMemberAccount) throws BaseAdaPayException {
// 计算应该支付金额,和手续费 BigDecimal settleAmount = orderBasicInfo.getSettleAmount();
SplitSettleAmountVO splitSettleAmountVO = splitSettleAmount(orderBasicInfo.getSettleAmount()); String orderCode = orderBasicInfo.getOrderCode();
BigDecimal feeAmount = splitSettleAmountVO.getFeeAmount();
BigDecimal tradeAmount = splitSettleAmountVO.getTradeAmount();
logger.info("余额支付订单使用余额支付转账, orderCode:{}, inMemberId:{}, transAmt:{}", orderBasicInfo.getOrderCode(), orderBasicInfo, tradeAmount);
// 查询会员的余额充值记录 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.getBalanceAmt().subtract(deductionAmount));
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 消费金额
*/
private List<BalanceDeductionAmountVO> calculateTheBalanceDeductionAmount(String memberId, BigDecimal amount) {
List<BalanceDeductionAmountVO> resultList = Lists.newArrayList();
// 查询会员的余额充值记录 按照充值时间正序
List<MemberAdapayRecord> memberAdapayRecords = memberAdapayRecordService.selectAdapayRecordList(memberId, ScenarioEnum.BALANCE.getValue());
return null; return resultList;
} }
/** /**
@@ -1155,22 +1194,17 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 调汇付的分账接口 确认交易 // 调汇付的分账接口 确认交易
Map<String, Object> confirmParams = Maps.newHashMap(); Map<String, Object> confirmParams = Maps.newHashMap();
// Adapay生成的支付对象id // Adapay生成的支付对象id
confirmParams.put("payment_id", adapayCallbackRecord.getPaymentId()); confirmParams.put("payment_id", adapayCallbackRecord.getPaymentId());
// 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一 // 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一
confirmParams.put("order_no", "PC" + System.currentTimeMillis()); confirmParams.put("order_no", "PC" + System.currentTimeMillis());
// 确认金额必须大于0保留两位小数点如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。 // 确认金额必须大于0保留两位小数点如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。
confirmParams.put("confirm_amt", settleAmount); confirmParams.put("confirm_amt", settleAmount);
// 附加说明 // 附加说明
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderBasicInfo.getOrderCode()); jsonObject.put("orderCode", orderBasicInfo.getOrderCode());
jsonObject.put("adapayMemberId", adapayMemberAccount.getAdapayMemberId()); jsonObject.put("adapayMemberId", adapayMemberAccount.getAdapayMemberId());
confirmParams.put("description", jsonObject.toJSONString()); confirmParams.put("description", jsonObject.toJSONString());
// 分账对象信息 // 分账对象信息
DivMember divMember = new DivMember(); DivMember divMember = new DivMember();
divMember.setMember_id(adapayMemberAccount.getAdapayMemberId()); divMember.setMember_id(adapayMemberAccount.getAdapayMemberId());
@@ -1179,13 +1213,14 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
confirmParams.put("div_members", Lists.newArrayList(divMember)); confirmParams.put("div_members", Lists.newArrayList(divMember));
Map<String, Object> paymentConfirm = PaymentConfirm.create(confirmParams); Map<String, Object> paymentConfirm = PaymentConfirm.create(confirmParams);
logger.info("调分账接口param:{}, result:{}", JSON.toJSONString(confirmParams), JSON.toJSONString(paymentConfirm)); logger.info("调分账接口param:{}, result:{}", JSON.toJSONString(confirmParams), JSON.toJSONString(paymentConfirm));
// 分账接口返回的信息 // 分账接口返回的信息
PaymentConfirmResponse paymentConfirmResponse = JSONObject.parseObject(JSON.toJSONString(paymentConfirm), PaymentConfirmResponse.class); PaymentConfirmResponse paymentConfirmResponse = JSONObject.parseObject(JSON.toJSONString(paymentConfirm), PaymentConfirmResponse.class);
OrderSettleResult result = new OrderSettleResult(); OrderSettleResult result = new OrderSettleResult();
result.setConfirm_amt(paymentConfirmResponse.getConfirm_amt()); result.setConfirm_amt(paymentConfirmResponse.getConfirm_amt());
result.setStatus(paymentConfirmResponse.getStatus()); result.setStatus(paymentConfirmResponse.getStatus());
result.setFee_amt(paymentConfirmResponse.getFee_amt()); result.setFee_amt(paymentConfirmResponse.getFee_amt());
result.setDescription(paymentConfirmResponse.getDescription()); // result.setDescription(paymentConfirmResponse.getDescription());
return result; return result;
} }

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;
}

View File

@@ -450,4 +450,24 @@
</if> </if>
</trim> </trim>
</insert> </insert>
<select id="selectAdapayRecordList" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from member_adapay_record
where del_flag = '0'
and member_id = #{memberId,jdbcType=VARCHAR}
<if test="scenarioType != null and scenarioType != ''">
and scenario_type = #{scenarioType,jdbcType=VARCHAR}
</if>
order by create_time
</select>
<select id="selectByPaymentId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from member_adapay_record
where del_flag = '0'
and payment_id = #{paymentId,jdbcType=VARCHAR}
</select>
</mapper> </mapper>