update 实时分账

This commit is contained in:
2023-08-25 16:07:15 +08:00
parent 18548fb83d
commit 033ddb40e7
8 changed files with 141 additions and 44 deletions

View File

@@ -608,8 +608,11 @@ public class MemberService {
} }
log.info("使用汇付支付充值余额 支付配置参数:{}", JSON.toJSONString(config)); log.info("使用汇付支付充值余额 支付配置参数:{}", JSON.toJSONString(config));
// 查询延时支付模式,由一级运营商配置决定
String payMode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
// 封装对象 // 封装对象
String payMode = Constants.ADAPAY_PAY_MODE_DELAY; // 汇付延时分账 // String payMode = Constants.ADAPAY_PAY_MODE_DELAY; // 汇付延时分账
CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam(); CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam();
createAdaPaymentParam.setOrder_no(SnowflakeIdWorker.getSnowflakeId()); createAdaPaymentParam.setOrder_no(SnowflakeIdWorker.getSnowflakeId());
createAdaPaymentParam.setPay_amt(AdapayUtil.formatAmount(dto.getAmount())); createAdaPaymentParam.setPay_amt(AdapayUtil.formatAmount(dto.getAmount()));
@@ -627,7 +630,9 @@ public class MemberService {
map.put("memberId", dto.getMemberId()); map.put("memberId", dto.getMemberId());
createAdaPaymentParam.setDescription(JSON.toJSONString(map)); createAdaPaymentParam.setDescription(JSON.toJSONString(map));
// 延时分账 // 延时分账
createAdaPaymentParam.setPay_mode(payMode); if (StringUtils.isNotBlank(payMode)) {
createAdaPaymentParam.setPay_mode(payMode);
}
try { try {
log.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam)); log.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam));
Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId()); Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId());

View File

@@ -11,6 +11,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import com.huifu.adapay.core.exception.BaseAdaPayException; import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.Payment;
import com.huifu.adapay.model.Refund; import com.huifu.adapay.model.Refund;
import com.jsowell.JsowellApplication; import com.jsowell.JsowellApplication;
import com.jsowell.adapay.config.AbstractAdapayConfig; import com.jsowell.adapay.config.AbstractAdapayConfig;
@@ -205,6 +206,15 @@ public class SpringBootTestController {
@Autowired @Autowired
private LTYTService ltytService; private LTYTService ltytService;
@Test
public void queryPaymentInfoTest() throws BaseAdaPayException {
String wechatAppId = "wxbb3e0d474569481d";
String paymentId = "002212023082514501110541039779091623936";
// 在完成初始化设置情况下,调用查询方法,获取 Payment 查询结果
Map<String, Object> response = Payment.query(paymentId, wechatAppId);
System.out.println(response);
}
/** /**
* 手动变更银行卡信息 * 手动变更银行卡信息
*/ */

View File

@@ -99,15 +99,12 @@ public class AdapayService {
if (memberBasicInfo == null) { if (memberBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
} }
String openId =memberBasicInfo.getOpenId(); String openId = memberBasicInfo.getOpenId();
// String openId = wxAppletRemoteService.getOpenIdByCode(dto.getCode());
// if (StringUtils.isBlank(openId)) {
// throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
// }
// 封装对象 // 封装对象
String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额 String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额
String payMode = Constants.ADAPAY_PAY_MODE_DELAY; // 汇付延时分账 // String payMode = Constants.ADAPAY_PAY_MODE_DELAY; // 汇付延时分账
String payMode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam(); CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam();
createAdaPaymentParam.setOrder_no(dto.getOrderCode()); createAdaPaymentParam.setOrder_no(dto.getOrderCode());
createAdaPaymentParam.setPay_amt(amount); createAdaPaymentParam.setPay_amt(amount);
@@ -126,14 +123,17 @@ public class AdapayService {
createAdaPaymentParam.setExpend(JSONObject.toJSONString(ImmutableMap.of("open_id", openId))); createAdaPaymentParam.setExpend(JSONObject.toJSONString(ImmutableMap.of("open_id", openId)));
// 延时分账 // 延时分账
createAdaPaymentParam.setPay_mode(payMode); if (StringUtils.isNotBlank(payMode)) {
createAdaPaymentParam.setPay_mode(payMode);
}
try { try {
log.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam)); log.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam));
Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId()); Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId());
if (response != null && !response.isEmpty()) { if (response != null && !response.isEmpty()) {
JSONObject expend = JSONObject.parseObject(response.get("expend").toString()); JSONObject expend = JSONObject.parseObject(response.get("expend").toString());
JSONObject pay_info = expend.getJSONObject("pay_info"); 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) { if (resultMap != null) {
// 请求参数放入缓存15分钟以内返回同一个支付参数 // 请求参数放入缓存15分钟以内返回同一个支付参数
redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES); redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES);
@@ -666,7 +666,7 @@ public class AdapayService {
// 发送提现申请 // 发送提现申请
Map<String, Object> settleCountParams = Maps.newHashMap(); Map<String, Object> settleCountParams = Maps.newHashMap();
String orderNo = "drawcash_" + dto.getMerchantId() + "_" +System.currentTimeMillis(); String orderNo = "drawcash_" + dto.getMerchantId() + "_" + System.currentTimeMillis();
settleCountParams.put("order_no", orderNo); settleCountParams.put("order_no", orderNo);
settleCountParams.put("cash_amt", AdapayUtil.formatAmount(cashAmt)); settleCountParams.put("cash_amt", AdapayUtil.formatAmount(cashAmt));
settleCountParams.put("member_id", adapayAccountBalanceVO.getAdapayMemberId()); settleCountParams.put("member_id", adapayAccountBalanceVO.getAdapayMemberId());
@@ -710,6 +710,7 @@ public class AdapayService {
/** /**
* 查询取现对象 * 查询取现对象
*
* @param orderNo 请求订单号 * @param orderNo 请求订单号
*/ */
public DrawCashDetailVO queryDrawCashDetail(String orderNo, String wechatAppId) throws BaseAdaPayException { public DrawCashDetailVO queryDrawCashDetail(String orderNo, String wechatAppId) throws BaseAdaPayException {
@@ -877,15 +878,30 @@ public class AdapayService {
/** /**
* 创建退款请求 * 创建退款请求
*/ */
public RefundResponse createRefundRequest(String paymentId, BigDecimal refundAmt) { public RefundResponse createRefundRequest(String paymentId, BigDecimal refundAmt, String wechatAppId, String memberId, String scenarioType, String orderCode) {
// 延迟分账确认的调退款接口 AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 实时分账的调退款接口
Map<String, Object> refundParams = Maps.newHashMap(); Map<String, Object> refundParams = Maps.newHashMap();
refundParams.put("refund_amt", AdapayUtil.formatAmount(refundAmt)); refundParams.put("refund_amt", AdapayUtil.formatAmount(refundAmt));
refundParams.put("refund_order_no", IdUtils.fastSimpleUUID()); refundParams.put("refund_order_no", IdUtils.fastSimpleUUID());
// expand 为扩展域
Map<String, String> expendMap = Maps.newHashMap();
expendMap.put("memberId", memberId);
expendMap.put("scenarioType", scenarioType);
if (StringUtils.isNotBlank(orderCode)) {
expendMap.put("orderCode", orderCode);
}
refundParams.put("expand", expendMap);
refundParams.put("reason", expendMap);
refundParams.put("notify_url", ADAPAY_CALLBACK_URL); refundParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> resultResponse = null; Map<String, Object> resultResponse = null;
try { try {
resultResponse = Refund.create(paymentId, refundParams); resultResponse = Refund.create(paymentId, refundParams, config.getWechatAppId());
} catch (BaseAdaPayException e) { } catch (BaseAdaPayException e) {
log.error("汇付支付创建退款对象error", e); log.error("汇付支付创建退款对象error", e);
} }
@@ -897,10 +913,10 @@ public class AdapayService {
/** /**
* 创建交易撤销请求 * 创建交易撤销请求
* 延迟分账未确认, 调交易撤销接口退款 * 延迟分账未确认, 调交易撤销接口退款
*
* @param wechatAppId 微信小程序appId * @param wechatAppId 微信小程序appId
*/ */
public PaymentReverseResponse createPaymentReverseRequest(String paymentId, BigDecimal reverseAmt, String wechatAppId, String memberId, String scenarioType, String orderCode) { public PaymentReverseResponse createPaymentReverseRequest(String paymentId, BigDecimal reverseAmt, String wechatAppId, String memberId, String scenarioType, String orderCode) {
PaymentReverseResponse response;
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId); AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) { if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);

View File

@@ -95,7 +95,7 @@ public interface PileMerchantInfoMapper {
* @param appId * @param appId
* @return * @return
*/ */
String getFirstLevelMerchantIdByAppId(String appId); PileMerchantInfo getFirstLevelMerchantByAppId(String appId);
/** /**
* 通过appid查询运营商部门id * 通过appid查询运营商部门id

View File

@@ -66,7 +66,9 @@ public interface IPileMerchantInfoService {
*/ */
public int deletePileMerchantInfoById(Long id); public int deletePileMerchantInfoById(Long id);
/** PileMerchantInfo getFirstLevelMerchantByAppId(String appId);
/**
* 通过微信小程序appId查询一级运营商merchantId * 通过微信小程序appId查询一级运营商merchantId
* @param appId 微信小程序appId * @param appId 微信小程序appId
* @return 一级运营商merchantId * @return 一级运营商merchantId
@@ -105,4 +107,6 @@ public interface IPileMerchantInfoService {
* @return * @return
*/ */
List<String> getDeptIdsByAppId(String appId); List<String> getDeptIdsByAppId(String appId);
String getDelayModeByWechatAppId(String wechatAppId);
} }

View File

@@ -12,6 +12,7 @@ import com.jsowell.adapay.dto.QueryPaymentConfirmDTO;
import com.jsowell.adapay.response.PaymentConfirmResponse; import com.jsowell.adapay.response.PaymentConfirmResponse;
import com.jsowell.adapay.response.PaymentReverseResponse; import com.jsowell.adapay.response.PaymentReverseResponse;
import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse; import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse;
import com.jsowell.adapay.response.RefundResponse;
import com.jsowell.adapay.service.AdapayService; import com.jsowell.adapay.service.AdapayService;
import com.jsowell.adapay.vo.OrderSettleResult; import com.jsowell.adapay.vo.OrderSettleResult;
import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.constant.CacheConstants;
@@ -2338,23 +2339,21 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
BigDecimal refundAmount = dto.getRefundAmount(); BigDecimal refundAmount = dto.getRefundAmount();
BigDecimal payAmt = callbackRecord.getPayAmt(); BigDecimal payAmt = callbackRecord.getPayAmt();
if (refundAmount.compareTo(payAmt) > 0) { if (refundAmount.compareTo(payAmt) > 0) {
logger.error("汇付支付订单号:{}, 退款金额:{}(元),大于可退金额{}(元), 抛出异常", dto.getOrderCode(), refundAmount, payAmt); logger.error("汇付支付订单号:{}, 退款金额:{}(元),大于付款金额{}(元), 抛出异常", dto.getOrderCode(), refundAmount, payAmt);
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR);
} }
// 创建汇付退款对象 在完成初始化设置情况下,调用方法,获取 Refund对象 // 拿orderCode查询延时分账模式 延时分账的使用撤销方法退款,实时分账的使用退款方法
String expend = callbackRecord.getExpend();
// TODO 拿orderCode查询清分状态 JSONObject expendJsonObject = JSON.parseObject(expend);
String payMode = "delay"; String payMode = expendJsonObject.getString("payMode");
if (StringUtils.equals("", payMode)) { // String payMode = "delay";
// 延迟分账确认的调退款接口 if (StringUtils.equalsIgnoreCase(payMode, Constants.ADAPAY_PAY_MODE_DELAY)) {
adapayService.createRefundRequest(paymentId, refundAmount);
} else {
// 延迟分账未确认调撤销调撤销接口退款 // 延迟分账未确认调撤销调撤销接口退款
PaymentReverseResponse response = adapayService.createPaymentReverseRequest( PaymentReverseResponse response = adapayService.createPaymentReverseRequest(
paymentId, refundAmount, dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(), paymentId, refundAmount, dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(),
dto.getOrderCode()); dto.getOrderCode());
if (response != null && response.isFailed()) { if (response != null && response.isNotFailed()) {
MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId); MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId);
BigDecimal reverseAmt = new BigDecimal(response.getReverse_amt()); BigDecimal reverseAmt = new BigDecimal(response.getReverse_amt());
// 更新此笔交易单的消费金额 = 支付金额 - 撤销金额 // 更新此笔交易单的消费金额 = 支付金额 - 撤销金额
@@ -2370,7 +2369,52 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
} }
memberAdapayRecordService.updateByPrimaryKeySelective(record); memberAdapayRecordService.updateByPrimaryKeySelective(record);
} }
} else {
// 实时分账的调退款接口
RefundResponse refundRequest = adapayService.createRefundRequest(paymentId, refundAmount, dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(),
dto.getOrderCode());
if (refundRequest != null && refundRequest.isNotFailed()) {
MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId);
BigDecimal refundAmt = new BigDecimal(refundRequest.getRefund_amt());
// 更新此笔交易单的消费金额 = 支付金额 - 撤销金额
BigDecimal spendAmt = callbackRecord.getPayAmt().subtract(refundAmt);
record.setSpendAmt(spendAmt);
// 退款金额
record.setRefundAmt(refundAmt);
// 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额
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, refundAmt);
}
memberAdapayRecordService.updateByPrimaryKeySelective(record);
}
} }
// if (StringUtils.equals("", payMode)) {
// // 延迟分账确认的调退款接口
// adapayService.createRefundRequest(paymentId, refundAmount);
// } else {
// // 延迟分账未确认调撤销调撤销接口退款
// PaymentReverseResponse response = adapayService.createPaymentReverseRequest(
// paymentId, refundAmount, dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(),
// dto.getOrderCode());
// if (response != null && response.isFailed()) {
// 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);
// }
// }
} }
@Override @Override

View File

@@ -260,7 +260,19 @@ public class PileMerchantInfoServiceImpl implements IPileMerchantInfoService {
// 逻辑删除部门 // 逻辑删除部门
sysDeptService.deleteDeptById(Long.parseLong(deptId)); sysDeptService.deleteDeptById(Long.parseLong(deptId));
} }
}
/**
* 通过微信小程序appId查询一级运营商merchant对象
* @param appId 微信小程序appId
* @return 一级运营商merchant对象
*/
@Override
public PileMerchantInfo getFirstLevelMerchantByAppId(String appId) {
if (StringUtils.isBlank(appId)) {
return null;
}
return pileMerchantInfoMapper.getFirstLevelMerchantByAppId(appId);
} }
/** /**
@@ -270,18 +282,12 @@ public class PileMerchantInfoServiceImpl implements IPileMerchantInfoService {
*/ */
@Override @Override
public String getFirstLevelMerchantIdByAppId(String appId) { public String getFirstLevelMerchantIdByAppId(String appId) {
if (StringUtils.isBlank(appId)) { String merchantId = null;
return null; PileMerchantInfo merchant = getFirstLevelMerchantByAppId(appId);
if (Objects.nonNull(merchant)) {
merchantId = String.valueOf(merchant.getId());
} }
try { return merchantId;
String merchantId = pileMerchantInfoMapper.getFirstLevelMerchantIdByAppId(appId);
if (StringUtils.isNotBlank(merchantId)) {
return merchantId;
}
} catch (Exception e) {
log.error("通过appid获取运营商id error", e);
}
return null;
} }
@Override @Override
@@ -327,10 +333,6 @@ public class PileMerchantInfoServiceImpl implements IPileMerchantInfoService {
return pileMerchantInfoMapper.queryInfoListByIds(deptIds); return pileMerchantInfoMapper.queryInfoListByIds(deptIds);
} }
public List<String> getLoginUserMerchantIds() {
AuthorizedDeptVO authorizedMap = SecurityUtils.getAuthorizedMap();
return null;
}
/** /**
* 查询一级运营商列表 * 查询一级运营商列表
@@ -388,5 +390,21 @@ public class PileMerchantInfoServiceImpl implements IPileMerchantInfoService {
return pileMerchantInfoMapper.getDeptIdsByAppId(appId); return pileMerchantInfoMapper.getDeptIdsByAppId(appId);
} }
/**
* 通过wechatAppId查询一级运营商的延时支付模式配置
* @param wechatAppId 微信小程序id
* @return
*/
@Override
public String getDelayModeByWechatAppId(String wechatAppId) {
PileMerchantInfo merchant = getFirstLevelMerchantByAppId(wechatAppId);
if (merchant != null) {
String delayMode = merchant.getDelayMode();
if (StringUtils.equals(delayMode, Constants.ONE)) {
return Constants.ADAPAY_PAY_MODE_DELAY;
}
}
return null;
}
} }

View File

@@ -348,9 +348,9 @@
and merchant_level = '1' and merchant_level = '1'
</select> </select>
<select id="getFirstLevelMerchantIdByAppId" resultType="java.lang.String"> <select id="getFirstLevelMerchantByAppId" resultMap="PileMerchantInfoResult">
select select
id <include refid="Base_Column_List"/>
from from
pile_merchant_info pile_merchant_info
where del_flag = '0' where del_flag = '0'