复查与充值轮询按通道查官方单:付呗单查付呗、直连查微信;履约仍幂等防多加,未完成返回业务码便于继续轮询。 Co-authored-by: Cursor <cursoragent@cursor.com>
89 lines
3.3 KiB
Python
89 lines
3.3 KiB
Python
"""统一远程支付确认:微信直连 / 付呗 / 支付宝,供复查与轮询调用。
|
|
|
|
返回:
|
|
{'ok': True, 'channel': 'fubei'|'wechat'|'alipay', 'transaction_id': str|None, 'amount': Decimal|None}
|
|
{'ok': False, 'pending': True, 'channel': ...} # 支付中,前端应继续轮询
|
|
{'ok': False, 'pending': False, 'channel': ..., 'msg': ...} # 明确失败(少见)
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from decimal import Decimal
|
|
from typing import Any, Dict, Optional
|
|
|
|
from django.core.cache import cache
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def confirm_remote_payment(
|
|
out_trade_no: str,
|
|
club_id: Optional[str] = None,
|
|
*,
|
|
prefer_amount: Any = None,
|
|
) -> Dict[str, Any]:
|
|
"""按通道查官方支付状态(付呗优先于微信直连,互不串单)。"""
|
|
from jituan.services.fubei_query import fubei_success_payload
|
|
|
|
fb = fubei_success_payload(out_trade_no, club_id)
|
|
if fb is not None:
|
|
txn, total_fee = fb
|
|
if not txn and total_fee is None:
|
|
return {'ok': False, 'pending': True, 'channel': 'fubei'}
|
|
amount = total_fee if total_fee not in (None, '') else prefer_amount
|
|
return {
|
|
'ok': True,
|
|
'pending': False,
|
|
'channel': 'fubei',
|
|
'transaction_id': txn,
|
|
'amount': Decimal(str(amount)) if amount not in (None, '') else None,
|
|
}
|
|
|
|
is_alipay = cache.get(f'alipay_pay_url_{out_trade_no}') is not None
|
|
if is_alipay:
|
|
from jituan.services.alipay_pay import query_alipay_trade
|
|
trade_status = query_alipay_trade(out_trade_no, club_id)
|
|
if trade_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'):
|
|
return {
|
|
'ok': True,
|
|
'pending': False,
|
|
'channel': 'alipay',
|
|
'transaction_id': None,
|
|
'amount': Decimal(str(prefer_amount)) if prefer_amount not in (None, '') else None,
|
|
}
|
|
return {'ok': False, 'pending': True, 'channel': 'alipay'}
|
|
|
|
from jituan.services.member_recharge import query_wechat_v2_trade_state
|
|
trade_state, transaction_id = query_wechat_v2_trade_state(out_trade_no, club_id)
|
|
if trade_state == 'SUCCESS':
|
|
return {
|
|
'ok': True,
|
|
'pending': False,
|
|
'channel': 'wechat',
|
|
'transaction_id': transaction_id,
|
|
'amount': Decimal(str(prefer_amount)) if prefer_amount not in (None, '') else None,
|
|
}
|
|
|
|
# cache 过期兜底:再试支付宝
|
|
from jituan.services.alipay_pay import query_alipay_trade
|
|
alipay_status = query_alipay_trade(out_trade_no, club_id)
|
|
if alipay_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'):
|
|
logger.info('confirm_remote: cache 过期但支付宝查单成功 %s', out_trade_no)
|
|
return {
|
|
'ok': True,
|
|
'pending': False,
|
|
'channel': 'alipay',
|
|
'transaction_id': None,
|
|
'amount': Decimal(str(prefer_amount)) if prefer_amount not in (None, '') else None,
|
|
}
|
|
|
|
if trade_state in (None, 'NOTPAY', 'USERPAYING', ''):
|
|
return {'ok': False, 'pending': True, 'channel': 'wechat', 'trade_state': trade_state}
|
|
return {
|
|
'ok': False,
|
|
'pending': False,
|
|
'channel': 'wechat',
|
|
'trade_state': trade_state,
|
|
'msg': f'支付状态异常: {trade_state}',
|
|
}
|