ForcePilot/backend/package/yuxi/channel/extensions/alipay/errors.py
Kris 71364ea579 feat(alipay): 新增支付宝渠道插件完整实现
实现了支付宝生活号渠道的完整功能,包括消息接收回调、发送、安全验证、去重、配对绑定、流式回复支持等完整能力。
2026-05-21 10:39:23 +08:00

66 lines
2.2 KiB
Python

from enum import StrEnum
class AlipayErrorCode(StrEnum):
SIGN_FAILED = "sign_failed"
VERIFY_FAILED = "verify_failed"
AUTH_FAILED = "auth_failed"
RATE_LIMITED = "rate_limited"
OUT_OF_WINDOW = "out_of_window"
DAILY_LIMIT_EXCEEDED = "daily_limit_exceeded"
USER_NOT_FOLLOWED = "user_not_followed"
MSG_TOO_LONG = "msg_too_long"
NETWORK_ERROR = "network_error"
BUSINESS_ERROR = "business_error"
UNKNOWN = "unknown"
class AlipayError(Exception):
def __init__(
self,
code: AlipayErrorCode,
message: str = "",
sub_code: str = "",
sub_msg: str = "",
retryable: bool = False,
retry_after: float | None = None,
):
self.code = code
self.message = message
self.sub_code = sub_code
self.sub_msg = sub_msg
self.retryable = retryable
self.retry_after = retry_after
super().__init__(f"[{code}] {message}" + (f" | {sub_code}: {sub_msg}" if sub_code else ""))
_ERROR_CLASSIFICATION: dict[str, tuple[AlipayErrorCode, bool]] = {
"40001": (AlipayErrorCode.SIGN_FAILED, False),
"40002": (AlipayErrorCode.VERIFY_FAILED, False),
"40004": (AlipayErrorCode.BUSINESS_ERROR, False),
"40006": (AlipayErrorCode.AUTH_FAILED, False),
"20000": (AlipayErrorCode.NETWORK_ERROR, True),
"20001": (AlipayErrorCode.AUTH_FAILED, False),
}
_SUB_CODE_CLASSIFICATION: dict[str, tuple[AlipayErrorCode, bool]] = {
"isv.invalid-signature": (AlipayErrorCode.SIGN_FAILED, False),
"isv.invalid-app-id": (AlipayErrorCode.VERIFY_FAILED, False),
"isv.message-count-per-day-isv-error": (AlipayErrorCode.DAILY_LIMIT_EXCEEDED, False),
"isv.invalid-auth-token": (AlipayErrorCode.AUTH_FAILED, False),
"isv.business-fail": (AlipayErrorCode.USER_NOT_FOLLOWED, False),
}
def classify_alipay_error(code: str, sub_code: str = "") -> tuple[AlipayErrorCode, bool]:
if sub_code and sub_code in _SUB_CODE_CLASSIFICATION:
return _SUB_CODE_CLASSIFICATION[sub_code]
if code in _ERROR_CLASSIFICATION:
return _ERROR_CLASSIFICATION[code]
return (AlipayErrorCode.UNKNOWN, False)
def is_retryable_error(code: str, sub_code: str = "") -> bool:
_, retryable = classify_alipay_error(code, sub_code)
return retryable