diff --git a/jituan/services/member_recharge.py b/jituan/services/member_recharge.py index 18f657b..3a93e9b 100644 --- a/jituan/services/member_recharge.py +++ b/jituan/services/member_recharge.py @@ -1096,16 +1096,28 @@ def confirm_member_recharge_paid(dingdan_id, yonghuid): if order.zhuangtai != MEMBER_PENDING_STATUS: raise MemberRechargeError(f'订单状态异常: {order.zhuangtai}', 'status_error') - # 支付宝订单:异步回调会更新状态,轮询时只看本地状态,未支付则提示稍后重试 + # 主动查单确认支付状态 from django.core.cache import cache - if cache.get(f'alipay_pay_url_{dingdan_id}') is not None: - raise MemberRechargeError('支付宝支付结果尚未同步,请稍后再试', 'not_paid') + club_id = getattr(order, 'club_id', None) + is_alipay = cache.get(f'alipay_pay_url_{dingdan_id}') is not None - trade_state, _ = query_wechat_v2_trade_state( - dingdan_id, getattr(order, 'club_id', None), - ) - if trade_state != 'SUCCESS': - raise MemberRechargeError('微信侧尚未支付成功,请稍后再试', 'not_paid') + if is_alipay: + # 支付宝订单:主动查单(alipay.trade.query),TRADE_SUCCESS/FINISHED 则触发履约 + from jituan.services.alipay_pay import query_alipay_trade + trade_status = query_alipay_trade(dingdan_id, club_id) + if trade_status not in ('TRADE_SUCCESS', 'TRADE_FINISHED'): + raise MemberRechargeError('支付宝支付结果尚未同步,请稍后再试', 'not_paid') + else: + # 微信订单:主动查单 + trade_state, _ = query_wechat_v2_trade_state(dingdan_id, club_id) + if trade_state != 'SUCCESS': + # 兜底:cache 标记可能已过期(30分钟),尝试查支付宝确认 + from jituan.services.alipay_pay import query_alipay_trade + alipay_status = query_alipay_trade(dingdan_id, club_id) + if alipay_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'): + logger.info('cache 过期但支付宝查单成功 dingdan=%s', dingdan_id) + else: + raise MemberRechargeError('微信侧尚未支付成功,请稍后再试', 'not_paid') total_fee_yuan = Decimal(str(order.jine)) result = fulfill_member_recharge( diff --git a/orders/views/payment.py b/orders/views/payment.py index c3d287c..9f42c6e 100644 --- a/orders/views/payment.py +++ b/orders/views/payment.py @@ -527,12 +527,8 @@ class PaymentVerifyView(APIView): 'data': {'dingdanid': dingdanid, 'zhuangtai': dingdan.Status} }) - # ---------- 5. 如果状态为9,则主动查询微信支付状态 ---------- + # ---------- 5. 如果状态为9,则主动查询支付状态 ---------- if dingdan.Status == 9: - # 支付宝订单:异步回调会更新状态,这里返回支付中 - if cache.get(f'alipay_pay_url_{dingdanid}'): - return Response({'code': 1, 'msg': '支付中', 'data': {'zhuangtai': 9}}) - # 使用分布式锁防止并发处理同一订单 lock_key = f"payment_verify_lock_{dingdanid}" if not cache.add(lock_key, "locked", timeout=10): @@ -540,8 +536,33 @@ class PaymentVerifyView(APIView): return Response({'code': 1, 'msg': '订单正在处理中,请稍后'}) try: - # 调用微信订单查询接口 - trade_state, transaction_id = self._query_wechat_payment(dingdanid) + # 判断支付方式并主动查单 + is_alipay = cache.get(f'alipay_pay_url_{dingdanid}') is not None + trade_state = None + transaction_id = None + + if is_alipay: + # 支付宝订单:主动查单(alipay.trade.query) + from jituan.services.alipay_pay import query_alipay_trade + alipay_status = query_alipay_trade(dingdanid, getattr(dingdan, 'ClubID', None)) + if alipay_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'): + trade_state = 'SUCCESS' + else: + return Response({'code': 1, 'msg': '支付中', 'data': {'zhuangtai': 9}}) + else: + # 微信订单:主动查单 + trade_state, transaction_id = self._query_wechat_payment(dingdanid) + if trade_state != 'SUCCESS': + # 兜底:cache 标记可能已过期(30分钟),尝试查支付宝确认 + from jituan.services.alipay_pay import query_alipay_trade + alipay_status = query_alipay_trade(dingdanid, getattr(dingdan, 'ClubID', None)) + if alipay_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'): + trade_state = 'SUCCESS' + logger.info('cache 过期但支付宝查单成功 dingdan=%s', dingdanid) + elif trade_state in ['NOTPAY', 'USERPAYING']: + return Response({'code': 1, 'msg': '支付中', 'data': {'zhuangtai': 9}}) + else: + return Response({'code': 2, 'msg': '支付失败'}) if trade_state == 'SUCCESS': # 支付成功,执行本地更新 @@ -553,15 +574,9 @@ class PaymentVerifyView(APIView): 'msg': '支付成功', 'data': {'dingdanid': dingdanid, 'zhuangtai': dingdan.Status} }) - elif trade_state in ['NOTPAY', 'USERPAYING']: - # 用户尚未支付或支付中 - return Response({'code': 1, 'msg': '支付中', 'data': {'zhuangtai': 9}}) - else: - # 其他状态:CLOSED, REVOKED, PAYERROR 等,视为支付失败 - return Response({'code': 2, 'msg': '支付失败'}) except Exception as e: - logger.error(f"查询微信支付异常: {e}", exc_info=True) + logger.error(f"查询支付异常: {e}", exc_info=True) return Response({'code': 1, 'msg': '查询失败,请稍后重试'}) finally: cache.delete(lock_key)