| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.talentcard.server.business.BusinessIdGenerator; |
| | | import com.talentcard.server.business.DatabaseRows; |
| | | import com.talentcard.server.business.payment.PaymentReconciliationService.PendingPaymentConfirmation; |
| | | import com.talentcard.server.business.payment.PaymentReconciliationService.PendingPaymentState; |
| | | import com.talentcard.server.business.payment.huifu.HuifuMiniProgramPaymentCommand; |
| | | import com.talentcard.server.business.payment.huifu.HuifuMiniProgramPaymentGateway; |
| | | import com.talentcard.server.business.payment.huifu.HuifuPaymentGatewayException; |
| | |
| | | private final JdbcTemplate jdbc; |
| | | private final TransactionTemplate transactions; |
| | | private final HuifuMiniProgramPaymentGateway gateway; |
| | | private final PaymentReconciliationService reconciliationService; |
| | | |
| | | public HuifuPaymentService( |
| | | JdbcTemplate jdbc, |
| | | TransactionTemplate transactions, |
| | | HuifuMiniProgramPaymentGateway gateway |
| | | HuifuMiniProgramPaymentGateway gateway, |
| | | PaymentReconciliationService reconciliationService |
| | | ) { |
| | | this.jdbc = jdbc; |
| | | this.transactions = transactions; |
| | | this.gateway = gateway; |
| | | this.reconciliationService = reconciliationService; |
| | | } |
| | | |
| | | public Map<String, Object> beginMiniProgramPayment(String orderNo, Long talentId, int priceVersion, String idempotencyKey) { |
| | | // 上一次支付可能已经被通道收下、回调却没到。那笔钱必须先落成本地已支付:否则这里会再发起一次 |
| | | // 支付(同一笔订单付第二次),或者把用户送进「订单已经支付,请勿重复发起支付」的死胡同。 |
| | | PendingPaymentConfirmation confirmation = reconciliationService.confirmPendingPayments(orderNo); |
| | | if (confirmation.collected()) return completedResult(confirmation.paymentNo()); |
| | | if (confirmation.state() == PendingPaymentState.UNCONFIRMED) { |
| | | throw new BusinessException(ErrorCode.CONFLICT, "支付结果确认中,请稍后再试"); |
| | | } |
| | | PreparedPayment prepared = transactions.execute(status -> prepare(orderNo, talentId, priceVersion, idempotencyKey)); |
| | | if (prepared == null) throw new BusinessException(ErrorCode.INTERNAL_ERROR, "支付初始化失败"); |
| | | if (prepared.completed()) return completedResult(prepared.paymentNo()); |
| | |
| | | |
| | | Map<String, Object> order = orders.get(0); |
| | | if (number(order.get("orderStatus")) == 1) return completedResult(paymentNo == null ? "" : paymentNo); |
| | | // 回调没到、本地还停在待支付时,通道是唯一知道钱有没有收下的地方。问一次就能把状态收敛回来, |
| | | // 人才端也就不会一直停在待支付页。 |
| | | PendingPaymentConfirmation confirmation = reconciliationService.confirmPendingPayments(orderNo); |
| | | if (confirmation.collected()) return completedResult(confirmation.paymentNo()); |
| | | |
| | | String filter = paymentNo == null || paymentNo.isBlank() ? "" : " and payment_no = ?"; |
| | | Object[] args = paymentNo == null || paymentNo.isBlank() |
| | |
| | | private String statusText(String status) { |
| | | return switch (status) { |
| | | case "SUCCEEDED" -> "PAID"; |
| | | case "CLOSED" -> "CANCELLED"; |
| | | case "CLOSED", "CANCEL_UNCONFIRMED" -> "CANCELLED"; |
| | | case "CREATE_FAILED" -> "PAYMENT_CREATE_FAILED"; |
| | | case "CREATED", "PREPAY_CREATED" -> "PAYMENT_PENDING"; |
| | | case "CREATE_UNKNOWN" -> "PAYMENT_CONFIRMING"; |