package com.talentcard.server.business.payment;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import com.talentcard.server.business.BusinessIdGenerator;
import com.talentcard.server.business.DatabaseRows;
import com.talentcard.server.business.payment.huifu.HuifuDelayAccountGateway;
import com.talentcard.server.business.payment.huifu.HuifuDelayAccountGateway.HuifuDelayConfirmCommand;
import com.talentcard.server.business.payment.huifu.HuifuDelayAccountGateway.HuifuDelayConfirmation;
import com.talentcard.server.business.payment.huifu.HuifuPaymentGatewayException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
/**
* 延迟交易的资金确认。
*
*
商户开通延迟入账后,用 {@code delay_acct_flag=Y} 下的支付会把钱留在通道的「待确认」状态。业务规则是
* 「核销之后商户才能拿到钱」,所以核销成功时才调用交易确认接口,把这笔钱分配给收款子商户。
*
*
状态记在 {@code payment_transaction.funds_confirmation_status}:{@code NULL} 表示这笔支付没有延迟
* (支付即核销的到店消费),{@code pending} 表示钱还在通道冻着,{@code confirmed} 表示已经分配完成。
* 自动提现只认 {@code NULL} 和 {@code confirmed},因此「忘了确认」不会变成「提前把钱提走」。
*/
@Service
public class PaymentFundConfirmationService {
/**
* 资金没有走延迟入账,不需要确认。
*
*
这些常量是「返回给调用方的结论」,与 {@code payment_transaction.funds_confirmation_status} 里存的
* 状态不同名:库里存小写({@code pending}/{@code confirming}/{@code confirmed}),所以比较一律走
* {@link #isConfirmed(String)},不要直接拿常量去比字段值。
*/
public static final String NOT_DELAYED = "NOT_DELAYED";
/** 资金已分配给收款商户。 */
public static final String CONFIRMED = "CONFIRMED";
/** 支付本身还没有成功,稍后再确认。 */
public static final String NOT_SETTLED = "NOT_SETTLED";
/** 已经有一笔确认请求在途,交给定时任务收敛。 */
public static final String PROCESSING = "PROCESSING";
/** 通道明确拒绝,需要人工处理。 */
public static final String FAILED = "FAILED";
/** 找不到对应的支付记录。 */
public static final String UNKNOWN = "UNKNOWN";
private static final DateTimeFormatter REQUEST_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");
private static final Logger log = LoggerFactory.getLogger(PaymentFundConfirmationService.class);
private final JdbcTemplate jdbc;
private final TransactionTemplate transactions;
private final HuifuDelayAccountGateway gateway;
public PaymentFundConfirmationService(JdbcTemplate jdbc, TransactionTemplate transactions,
HuifuDelayAccountGateway gateway) {
this.jdbc = jdbc;
this.transactions = transactions;
this.gateway = gateway;
}
/**
* 为某个订单确认资金。订单必须已经有成功的支付记录。
*
*
幂等:资金已经确认、或这笔支付本来就没有延迟时直接返回,不会重复向通道发确认请求。
*/
public String confirmForOrder(long orderId) {
List