fix: 加固支付宝充值回调幂等履约,避免付成功不到账与误删单
禁止 Czjilu 回调地址回落到订单 notify;回调失败回 fail 重试;取消支付改关单不删;客服补单走同一履约防多加。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,11 @@ CZJILU_LEIXING_KAOHE = 5
|
||||
CZJILU_LEIXING_FAKUAN = 6
|
||||
|
||||
CZJILU_PAID_STATUS = 3
|
||||
# 用户取消/关闭:保留流水,不物理删除;若官方已付款,回调/查单仍可履约入账(防少加)
|
||||
CZJILU_CANCELLED_STATUS = 2
|
||||
CZJILU_PENDING_STATUS = 9
|
||||
# 可被「官方已付款」触发履约的状态(仅这些会入账,已付 3 不会再加 → 防多加)
|
||||
CZJILU_FULFILLABLE_STATUSES = (CZJILU_PENDING_STATUS, CZJILU_CANCELLED_STATUS)
|
||||
|
||||
FAKUAN_ORDER_PREFIX = 'FK'
|
||||
PENALTY_SHUOMING_MARKER = '罚款'
|
||||
@@ -79,3 +84,41 @@ def penalty_payment_cz_qs(qs):
|
||||
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_SHUOMING_MARKER)
|
||||
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_FADAN_TAG)
|
||||
)
|
||||
|
||||
|
||||
def is_czjilu_fulfillable_status(zhuangtai):
|
||||
"""是否允许在确认官方已付款后执行履约(9 待付 / 2 用户取消但仍可能已扣款)。"""
|
||||
try:
|
||||
return int(zhuangtai) in CZJILU_FULFILLABLE_STATUSES
|
||||
except (TypeError, ValueError):
|
||||
return False
|
||||
|
||||
|
||||
def close_unpaid_czjilu(order, reason='用户取消支付'):
|
||||
"""
|
||||
关闭未支付充值单:只改状态为取消(2),绝不 delete。
|
||||
若用户其实已付款,后续回调/查单仍可通过 is_czjilu_fulfillable_status 履约。
|
||||
返回 True 表示本次从 9 改为 2。
|
||||
"""
|
||||
if int(getattr(order, 'zhuangtai', 0) or 0) != CZJILU_PENDING_STATUS:
|
||||
return False
|
||||
note = (getattr(order, 'shuoming', None) or '').strip()
|
||||
tag = f'|关单:{reason}'
|
||||
if tag not in note:
|
||||
merged = f'{note}{tag}' if note else f'关单:{reason}'
|
||||
order.shuoming = merged[:100]
|
||||
order.zhuangtai = CZJILU_CANCELLED_STATUS
|
||||
order.save(update_fields=['zhuangtai', 'shuoming'])
|
||||
return True
|
||||
|
||||
|
||||
def looks_like_czjilu_out_trade_no(out_trade_no):
|
||||
"""粗判商户订单号是否为 Czjilu 充值单(避免打进老板订单回调后被 success 吞掉)。"""
|
||||
s = (out_trade_no or '').strip()
|
||||
if not s:
|
||||
return False
|
||||
prefixes = (
|
||||
'CzHY', 'CzYJ', 'CzJF', 'CzSJ', 'KH', 'FK',
|
||||
getattr(settings, 'SHANGJIA_CZ_PREFIX', 'CzSJ') or 'CzSJ',
|
||||
)
|
||||
return any(s.startswith(p) for p in prefixes if p)
|
||||
|
||||
@@ -7,9 +7,9 @@ from .views import ShangpinHuoquView, ShangpinXiangqingHuoquView, DashouHuiyuanL
|
||||
ShangjiaChongzhi, ShangjiaHuitiao, ShangjiaShibai, GuanshiFenhongListAPI, AdGetAllDataView, ShangpinLeixingFabuView, \
|
||||
ShangpinZhuanquFabuView, ShangpinFabuView, GuizeTupianShangchuanView, AdHuiyuanHqView, HuiyuanXiugaiView, \
|
||||
AdHuiyuanFbView, AdShangpinHuQu, AdLeixingXiuGai, AdLunboXiuGai, AdZhuanquXiuGai, AdGonggaoXiuGai, \
|
||||
AdShangpinGuizeXiuGai, AdShangpinXiuGai, AdShangpinNeiRongHuoQu,\
|
||||
AdShangpinGuizeXiuGai, AdShangpinXiuGai, AdShangpinNeiRongHuoQu, \
|
||||
HuiyuanTypeListView, HuiyuanRecordListView, ZuzhangFenhongView, CzhqdyView, DsqrgmdhView, \
|
||||
AlipayCzjiluNotifyView
|
||||
AlipayCzjiluNotifyView, CzjiluRepairView
|
||||
|
||||
urlpatterns = [
|
||||
#path('shangpinhuoqu/', ShangpinHuoquView.as_view(), name='获取商品数据商品类型和专区'),
|
||||
@@ -37,6 +37,8 @@ urlpatterns = [
|
||||
path('sjhuitiao', csrf_exempt(ShangjiaHuitiao.as_view()), name='商家支付官方回调'),
|
||||
# 支付宝 Czjilu 充值统一回调(押金/积分/会员/商家/考核/罚款)
|
||||
path('alipay-czjilu-notify/', csrf_exempt(AlipayCzjiluNotifyView.as_view()), name='支付宝Czjilu充值统一回调'),
|
||||
# 客服补单:官方查单确认后幂等履约
|
||||
path('czjilu-budan', CzjiluRepairView.as_view(), name='充值单客服补单'),
|
||||
#path('sjhuitiao', ShangjiaHuitiao.as_view(), name='商家支付官方回调'), # 商家支付回调
|
||||
path('sjshibai', ShangjiaShibai.as_view(), name='商家支付失败'), # 商家支付失败处理
|
||||
path('sjcg', ShangjiaChenggong.as_view(), name='商家支付成功'), # 商家支付成功轮询
|
||||
|
||||
@@ -56,7 +56,7 @@ from .chongzhi_payment import (
|
||||
MAX_INTEGRAL,
|
||||
IDENTITY_CONFIG,
|
||||
)
|
||||
from .alipay_czjilu_notify import AlipayCzjiluNotifyView
|
||||
from .alipay_czjilu_notify import AlipayCzjiluNotifyView, CzjiluRepairView
|
||||
from .shangpin_admin import (
|
||||
ShangpinLeixingFabuView,
|
||||
ShangpinZhuanquFabuView,
|
||||
@@ -98,7 +98,7 @@ __all__ = [
|
||||
'CzhqdyView', 'DsqrgmdhView',
|
||||
'INTEGRAL_PRICE', 'INTEGRAL_INCREMENT', 'MAX_INTEGRAL', 'IDENTITY_CONFIG',
|
||||
# alipay_czjilu_notify
|
||||
'AlipayCzjiluNotifyView',
|
||||
'AlipayCzjiluNotifyView', 'CzjiluRepairView',
|
||||
# shangpin_admin
|
||||
'ShangpinLeixingFabuView', 'ShangpinZhuanquFabuView', 'ShangpinFabuView',
|
||||
'GuizeTupianShangchuanView',
|
||||
|
||||
@@ -8,16 +8,44 @@ import traceback
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.views import View
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
||||
from products.models import Czjilu
|
||||
from products.czjilu_types import (
|
||||
CZJILU_LEIXING_HUIYUAN, CZJILU_LEIXING_YAJIN, CZJILU_LEIXING_JIFEN,
|
||||
CZJILU_LEIXING_SHANGJIA, CZJILU_LEIXING_KAOHE, CZJILU_LEIXING_FAKUAN,
|
||||
CZJILU_PAID_STATUS, is_czjilu_fulfillable_status,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _fulfill_czjilu_by_leixing(out_trade_no, leixing, paid_amount, source='callback'):
|
||||
"""按 leixing 调幂等履约;入账只在 fulfill_* 内发生一次。"""
|
||||
if leixing == CZJILU_LEIXING_HUIYUAN:
|
||||
from jituan.services.member_recharge import fulfill_member_recharge
|
||||
return fulfill_member_recharge(out_trade_no, paid_amount_yuan=paid_amount, source=source)
|
||||
if leixing == CZJILU_LEIXING_YAJIN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_yajin_recharge
|
||||
return fulfill_yajin_recharge(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
if leixing == CZJILU_LEIXING_JIFEN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_jifen_recharge
|
||||
return fulfill_jifen_recharge(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
if leixing == CZJILU_LEIXING_SHANGJIA:
|
||||
from jituan.services.czjilu_fulfill import fulfill_shangjia
|
||||
return fulfill_shangjia(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
if leixing == CZJILU_LEIXING_KAOHE:
|
||||
from jituan.services.czjilu_fulfill import fulfill_kaohe
|
||||
return fulfill_kaohe(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
if leixing == CZJILU_LEIXING_FAKUAN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_fakuan
|
||||
return fulfill_fakuan(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
raise ValueError(f'未知 leixing={leixing}')
|
||||
|
||||
|
||||
class AlipayCzjiluNotifyView(View):
|
||||
"""支付宝 Czjilu 充值统一回调:验签 + 按 leixing 路由履约。
|
||||
|
||||
@@ -60,58 +88,81 @@ class AlipayCzjiluNotifyView(View):
|
||||
# 查询充值单
|
||||
order = Czjilu.query.filter(dingdan_id=out_trade_no).first()
|
||||
if not order:
|
||||
# 找不到单回 fail,让支付宝重试,避免「钱付了永久无履约」
|
||||
logger.error('[ALIPAY_CZJILU_NOTIFY] 充值单不存在: %s', out_trade_no)
|
||||
return HttpResponse('fail', content_type='text/plain')
|
||||
|
||||
# 已支付:补记收支后直接返回成功(幂等)
|
||||
if order.zhuangtai == 3:
|
||||
# 已支付:幂等成功(绝不再加余额/会员)
|
||||
if order.zhuangtai == CZJILU_PAID_STATUS:
|
||||
logger.info('[ALIPAY_CZJILU_NOTIFY] 订单已支付,幂等返回: %s', out_trade_no)
|
||||
return HttpResponse('success', content_type='text/plain')
|
||||
|
||||
if order.zhuangtai != 9:
|
||||
logger.warning(
|
||||
'[ALIPAY_CZJILU_NOTIFY] 订单状态异常: %s, zhuangtai=%s',
|
||||
out_trade_no, order.zhuangtai,
|
||||
)
|
||||
# 待付(9) 或用户关单(2):官方已付则履约
|
||||
if is_czjilu_fulfillable_status(order.zhuangtai):
|
||||
paid_amount = total_amount or order.jine
|
||||
leixing = order.leixing
|
||||
try:
|
||||
_fulfill_czjilu_by_leixing(out_trade_no, leixing, paid_amount, source='callback')
|
||||
except Exception as fulfill_exc:
|
||||
logger.error(
|
||||
'[ALIPAY_CZJILU_NOTIFY] 履约异常 out_trade_no=%s leixing=%s: %s',
|
||||
out_trade_no, leixing, fulfill_exc, exc_info=True,
|
||||
)
|
||||
# 履约异常返回 fail,让支付宝重试
|
||||
return HttpResponse('fail', content_type='text/plain')
|
||||
|
||||
logger.info('[ALIPAY_CZJILU_NOTIFY] 履约完成: %s, leixing=%s', out_trade_no, leixing)
|
||||
return HttpResponse('success', content_type='text/plain')
|
||||
|
||||
# 按 leixing 路由到对应履约函数
|
||||
paid_amount = total_amount or order.jine
|
||||
leixing = order.leixing
|
||||
try:
|
||||
if leixing == CZJILU_LEIXING_HUIYUAN:
|
||||
from jituan.services.member_recharge import fulfill_member_recharge
|
||||
fulfill_member_recharge(out_trade_no, paid_amount_yuan=paid_amount, source='callback')
|
||||
elif leixing == CZJILU_LEIXING_YAJIN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_yajin_recharge
|
||||
fulfill_yajin_recharge(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
elif leixing == CZJILU_LEIXING_JIFEN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_jifen_recharge
|
||||
fulfill_jifen_recharge(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
elif leixing == CZJILU_LEIXING_SHANGJIA:
|
||||
from jituan.services.czjilu_fulfill import fulfill_shangjia
|
||||
fulfill_shangjia(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
elif leixing == CZJILU_LEIXING_KAOHE:
|
||||
from jituan.services.czjilu_fulfill import fulfill_kaohe
|
||||
fulfill_kaohe(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
elif leixing == CZJILU_LEIXING_FAKUAN:
|
||||
from jituan.services.czjilu_fulfill import fulfill_fakuan
|
||||
fulfill_fakuan(out_trade_no, paid_amount_yuan=paid_amount)
|
||||
else:
|
||||
logger.error('[ALIPAY_CZJILU_NOTIFY] 未知 leixing=%s: %s', leixing, out_trade_no)
|
||||
return HttpResponse('fail', content_type='text/plain')
|
||||
except Exception as fulfill_exc:
|
||||
logger.error(
|
||||
'[ALIPAY_CZJILU_NOTIFY] 履约异常 out_trade_no=%s leixing=%s: %s',
|
||||
out_trade_no, leixing, fulfill_exc, exc_info=True,
|
||||
)
|
||||
# 履约异常返回 fail,让支付宝重试
|
||||
return HttpResponse('fail', content_type='text/plain')
|
||||
|
||||
logger.info('[ALIPAY_CZJILU_NOTIFY] 履约完成: %s, leixing=%s', out_trade_no, leixing)
|
||||
# 终态异常(如会员履约失败 8、考核业务失败 10):停止重试,留人工处理
|
||||
logger.warning(
|
||||
'[ALIPAY_CZJILU_NOTIFY] 订单终态不再履约: %s, zhuangtai=%s',
|
||||
out_trade_no, order.zhuangtai,
|
||||
)
|
||||
return HttpResponse('success', content_type='text/plain')
|
||||
|
||||
except Exception as e:
|
||||
logger.error('[ALIPAY_CZJILU_NOTIFY] 回调处理异常: %s', str(e))
|
||||
logger.error(traceback.format_exc())
|
||||
return HttpResponse('fail', content_type='text/plain')
|
||||
|
||||
|
||||
class CzjiluRepairView(APIView):
|
||||
"""客服补单:查官方支付结果后走同一幂等履约。
|
||||
|
||||
路径:POST /shangpin/czjilu-budan
|
||||
参数:dingdanid
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
from backend.utils import verify_kefu_permission
|
||||
from jituan.services.czjilu_fulfill import repair_czjilu_payment, CzjiluFulfillError
|
||||
from jituan.services.member_recharge import MemberRechargeError
|
||||
|
||||
username = (
|
||||
request.data.get('username')
|
||||
or request.data.get('phone')
|
||||
or getattr(request.user, 'Phone', None)
|
||||
)
|
||||
kefu, permissions_or_resp = verify_kefu_permission(request, username)
|
||||
if not kefu:
|
||||
return permissions_or_resp
|
||||
|
||||
dingdanid = (request.data.get('dingdanid') or request.data.get('dingdan_id') or '').strip()
|
||||
if not dingdanid:
|
||||
return Response({'code': 400, 'message': '订单ID不能为空'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
result = repair_czjilu_payment(dingdanid)
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '补单成功' if not result.get('already_done') else '订单已到账(幂等)',
|
||||
'data': result,
|
||||
})
|
||||
except (CzjiluFulfillError, MemberRechargeError) as exc:
|
||||
logger.warning('[CZJILU_REPAIR] 补单未完成 dingdan=%s: %s', dingdanid, exc)
|
||||
return Response({'code': 400, 'message': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
except Exception as exc:
|
||||
logger.error('[CZJILU_REPAIR] 补单异常 dingdan=%s: %s', dingdanid, exc, exc_info=True)
|
||||
return Response({'code': 500, 'message': '补单失败,请稍后重试'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
@@ -540,20 +540,20 @@ class ShangjiaShibai(APIView):
|
||||
'message': '订单不存在或不属于当前用户'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 3. 检查订单状态是否为未支付(9)
|
||||
# 3. 检查订单状态是否为未支付(9):关单不删
|
||||
if order.zhuangtai == 9:
|
||||
# 删除订单
|
||||
order.delete()
|
||||
logger.info(f"商家{request.user.ShopProfile.nicheng}删除未支付订单: {dingdanid}")
|
||||
from products.czjilu_types import close_unpaid_czjilu
|
||||
close_unpaid_czjilu(order, reason='用户取消支付')
|
||||
logger.info(f"商家{request.user.ShopProfile.nicheng}关闭未支付订单(不删): {dingdanid}")
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '订单已删除'
|
||||
'message': '订单已取消'
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '订单状态不是未支付,无法删除'
|
||||
'message': '订单状态不是未支付,无法取消'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except UserShangjia.DoesNotExist:
|
||||
@@ -606,8 +606,9 @@ class ShangjiaChenggong(APIView):
|
||||
'message': '订单不存在或不属于当前用户'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 3. 订单未支付时,尝试补偿履约(回调延迟/失败时通过轮询兜底)
|
||||
if order.zhuangtai == 9:
|
||||
# 3. 未支付/已关单时,尝试补偿履约(回调延迟/失败时通过轮询兜底)
|
||||
from products.czjilu_types import is_czjilu_fulfillable_status
|
||||
if is_czjilu_fulfillable_status(order.zhuangtai):
|
||||
from jituan.services.czjilu_fulfill import confirm_czjilu_paid, CzjiluFulfillError
|
||||
try:
|
||||
confirm_czjilu_paid(dingdanid, request.user.UserUID, expected_leixing=4)
|
||||
|
||||
@@ -551,20 +551,20 @@ class HuiyuanShibai(APIView):
|
||||
'message': '订单类型错误,不是会员订单'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 4. 检查订单状态是否为未支付(9)
|
||||
# 4. 检查订单状态是否为未支付(9):关单不删,保留流水便于官方已付后补履约
|
||||
if order.zhuangtai == 9:
|
||||
# 删除订单
|
||||
order.delete()
|
||||
logger.info(f"用户{request.user.UserUID}删除未支付会员订单: {dingdanid}")
|
||||
from products.czjilu_types import close_unpaid_czjilu
|
||||
close_unpaid_czjilu(order, reason='用户取消支付')
|
||||
logger.info(f"用户{request.user.UserUID}关闭未支付会员订单(不删): {dingdanid}")
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '会员订单已删除'
|
||||
'message': '会员订单已取消'
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '会员订单状态不是未支付,无法删除'
|
||||
'message': '会员订单状态不是未支付,无法取消'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except Exception as e:
|
||||
@@ -616,8 +616,9 @@ class HuiyuanLunxun(APIView):
|
||||
'message': '订单类型错误,不是会员订单'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 4. 未支付:查微信并幂等履约(与回调互斥,zhuangtai!=9 则跳过)
|
||||
if order.zhuangtai == 9:
|
||||
# 4. 未支付/已关单:查官方并幂等履约
|
||||
from products.czjilu_types import is_czjilu_fulfillable_status
|
||||
if is_czjilu_fulfillable_status(order.zhuangtai):
|
||||
from jituan.services.member_recharge import (
|
||||
confirm_member_recharge_paid,
|
||||
MemberRechargeError,
|
||||
|
||||
@@ -511,20 +511,20 @@ class JifenShibai(APIView):
|
||||
'message': '订单类型错误,不是积分订单'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 4. 检查订单状态是否为未支付(9)
|
||||
# 4. 检查订单状态是否为未支付(9):关单不删
|
||||
if order.zhuangtai == 9:
|
||||
# 删除订单
|
||||
order.delete()
|
||||
logger.info(f"用户{request.user.UserUID}删除未支付积分订单: {dingdanid}")
|
||||
from products.czjilu_types import close_unpaid_czjilu
|
||||
close_unpaid_czjilu(order, reason='用户取消支付')
|
||||
logger.info(f"用户{request.user.UserUID}关闭未支付积分订单(不删): {dingdanid}")
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '积分订单已删除'
|
||||
'message': '积分订单已取消'
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '积分订单状态不是未支付,无法删除'
|
||||
'message': '积分订单状态不是未支付,无法取消'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except Exception as e:
|
||||
@@ -576,8 +576,9 @@ class JifenLunxun(APIView):
|
||||
'message': '订单类型错误,不是积分订单'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 4. 未支付则查微信并幂等履约
|
||||
if order.zhuangtai == 9:
|
||||
# 4. 未支付/已关单则查官方并幂等履约
|
||||
from products.czjilu_types import is_czjilu_fulfillable_status
|
||||
if is_czjilu_fulfillable_status(order.zhuangtai):
|
||||
from jituan.services.czjilu_fulfill import confirm_czjilu_paid, CzjiluFulfillError
|
||||
try:
|
||||
confirm_czjilu_paid(dingdanid, request.user.UserUID, expected_leixing=3)
|
||||
|
||||
@@ -524,20 +524,20 @@ class YajinShibai(APIView):
|
||||
'message': '订单不存在或不属于当前用户'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 3. 检查订单状态是否为未支付(9)
|
||||
# 3. 检查订单状态是否为未支付(9):关单不删
|
||||
if order.zhuangtai == 9:
|
||||
# 删除订单
|
||||
order.delete()
|
||||
logger.info(f"用户{request.user.UserUID}删除未支付订单: {dingdanid}")
|
||||
from products.czjilu_types import close_unpaid_czjilu
|
||||
close_unpaid_czjilu(order, reason='用户取消支付')
|
||||
logger.info(f"用户{request.user.UserUID}关闭未支付押金订单(不删): {dingdanid}")
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '订单已删除'
|
||||
'message': '订单已取消'
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '订单状态不是未支付,无法删除'
|
||||
'message': '订单状态不是未支付,无法取消'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except Exception as e:
|
||||
@@ -582,8 +582,9 @@ class YajinLunxun(APIView):
|
||||
'message': '订单不存在或不属于当前用户'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 3. 未支付则查微信并幂等履约
|
||||
if order.zhuangtai == 9:
|
||||
# 3. 未支付/已关单则查官方并幂等履约
|
||||
from products.czjilu_types import is_czjilu_fulfillable_status
|
||||
if is_czjilu_fulfillable_status(order.zhuangtai):
|
||||
from jituan.services.czjilu_fulfill import confirm_czjilu_paid, CzjiluFulfillError
|
||||
try:
|
||||
confirm_czjilu_paid(dingdanid, request.user.UserUID, expected_leixing=2)
|
||||
|
||||
Reference in New Issue
Block a user