|
|
@@ -7,7 +7,9 @@ import com.etotem.cfc.dto.VirtualPayParamsDTO;
|
|
|
import com.etotem.cfc.entity.AssessmentOrder;
|
|
|
import com.etotem.cfc.entity.MemberSubscriptionOrder;
|
|
|
import com.etotem.cfc.entity.PaymentOrder;
|
|
|
+import com.etotem.cfc.entity.PurchaseOrder;
|
|
|
import com.etotem.cfc.entity.VirtualGoodsConfig;
|
|
|
+import com.etotem.cfc.mapper.PurchaseOrderMapper;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.http.HttpEntity;
|
|
|
@@ -51,6 +53,12 @@ public class VirtualPayService {
|
|
|
@Resource
|
|
|
private MemberSubscriptionService memberSubscriptionService;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private PurchaseService purchaseService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PurchaseOrderMapper purchaseOrderMapper;
|
|
|
+
|
|
|
@Resource
|
|
|
private WechatService wechatService; // 复用 getAccessToken()(带缓存)
|
|
|
|
|
|
@@ -253,6 +261,40 @@ public class VirtualPayService {
|
|
|
return generatePayParams(config, orderNo, order.getAmount(), config.getGoodsName(), attach, sessionKey);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 健康启航计划购买虚拟支付下单参数编排。
|
|
|
+ * 订单保持 pending;查不到道具映射返回 null(调用方转 46001 "该商品暂未开放购买")。
|
|
|
+ */
|
|
|
+ public VirtualPayParamsDTO generatePurchasePayParams(String orderNo, String sessionKey) {
|
|
|
+ // 1. 查订单 + 校验 pending
|
|
|
+ PurchaseOrder order = purchaseService.getByOrderNo(orderNo);
|
|
|
+ if (order == null || !"pending".equals(order.getStatus())) {
|
|
|
+ log.warn("生成健康启航计划支付参数失败,订单不存在或非pending: orderNo={}", orderNo);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查 virtual_goods_config:goodsType=PURCHASE, bizKey=订单orderNo前缀(如HQ)
|
|
|
+ VirtualGoodsConfig config = virtualGoodsConfigService.getEnabled("PURCHASE", "HQ");
|
|
|
+ if (config == null) {
|
|
|
+ log.warn("健康启航计划道具未配置或停用");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 金额 = order.amount(服务端已算,不重算),校验 >= 1元
|
|
|
+ if (order.getAmount() == null || order.getAmount() < 100) {
|
|
|
+ log.warn("健康启航计划订单金额异常(<1元): orderNo={}, amount={}", orderNo, order.getAmount());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 组装 attach + product_info 并生成支付参数(订单保持 pending,不置 paid)
|
|
|
+ String attach = "purchase:" + order.getOrderNo();
|
|
|
+ VirtualPayParamsDTO dto = generatePayParams(config, orderNo, order.getAmount(), config.getGoodsName(), attach, sessionKey);
|
|
|
+ dto.setOrderNo(orderNo);
|
|
|
+ dto.setTotalPeriods(1);
|
|
|
+ dto.setCurrentPeriod(1);
|
|
|
+ return dto;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 处理虚拟支付发货推送(xpay_goods_deliver_notify)。
|
|
|
* 按 OutTradeNo 前缀路由:A→测评,ORD→会员,SUB→订阅。
|
|
|
@@ -294,6 +336,16 @@ public class VirtualPayService {
|
|
|
} else {
|
|
|
log.warn("虚拟支付发货推送订阅订单不存在: outTradeNo={}", outTradeNo);
|
|
|
}
|
|
|
+ } else if (outTradeNo.startsWith("HQ")) {
|
|
|
+ // 健康启航计划购买订单:复用 confirmPayment 逻辑(需幂等)
|
|
|
+ PurchaseOrder purchaseOrder = purchaseService.getByOrderNo(outTradeNo);
|
|
|
+ if (purchaseOrder != null && ("paid".equals(purchaseOrder.getStatus()) || "refunded".equals(purchaseOrder.getStatus()))) {
|
|
|
+ log.info("虚拟支付发货推送重复通知,购买订单已终态: outTradeNo={}, status={}", outTradeNo, purchaseOrder.getStatus());
|
|
|
+ } else if (purchaseOrder != null) {
|
|
|
+ purchaseService.confirmPayment(outTradeNo, "virtual", transactionId);
|
|
|
+ } else {
|
|
|
+ log.warn("虚拟支付发货推送购买订单不存在: outTradeNo={}", outTradeNo);
|
|
|
+ }
|
|
|
} else {
|
|
|
log.warn("虚拟支付发货推送未知订单前缀: outTradeNo={}", outTradeNo);
|
|
|
}
|
|
|
@@ -326,6 +378,14 @@ public class VirtualPayService {
|
|
|
memberSubscriptionService.refundByOrderNo(outTradeNo);
|
|
|
} else if (outTradeNo.startsWith("ORD")) {
|
|
|
membershipService.refundByOrderNo(outTradeNo);
|
|
|
+ } else if (outTradeNo.startsWith("HQ")) {
|
|
|
+ // 健康启航计划购买订单退款
|
|
|
+ PurchaseOrder purchaseOrder = purchaseService.getByOrderNo(outTradeNo);
|
|
|
+ if (purchaseOrder != null && !"refunded".equals(purchaseOrder.getStatus())) {
|
|
|
+ purchaseOrder.setStatus("refunded");
|
|
|
+ purchaseOrderMapper.updateById(purchaseOrder);
|
|
|
+ log.info("健康启航计划订单退款: outTradeNo={}", outTradeNo);
|
|
|
+ }
|
|
|
} else {
|
|
|
log.warn("虚拟支付退款推送未知订单前缀: outTradeNo={}", outTradeNo);
|
|
|
}
|
|
|
@@ -380,6 +440,13 @@ public class VirtualPayService {
|
|
|
alreadyRefunded = "refunded".equals(order.getStatus());
|
|
|
levelInfo = "订阅订单,状态=" + order.getStatus();
|
|
|
}
|
|
|
+ } else if (payOrderId.startsWith("HQ")) {
|
|
|
+ PurchaseOrder order = purchaseService.getByOrderNo(payOrderId);
|
|
|
+ if (order != null) {
|
|
|
+ exists = true;
|
|
|
+ alreadyRefunded = "refunded".equals(order.getStatus());
|
|
|
+ levelInfo = "健康启航计划订单,状态=" + order.getStatus();
|
|
|
+ }
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("iOS退款问询查单异常: payOrderId={}", payOrderId, e);
|