From 1746480e79623c0f36d6b9992c62136a79d54477 Mon Sep 17 00:00:00 2001 From: wwwwwwwww <526125649@qq.com> Date: Thu, 11 Jun 2026 10:56:10 +0800 Subject: [PATCH] 1 --- video-gen-api/app/services/payment.py | 149 ++++++++++++++------------ 1 file changed, 81 insertions(+), 68 deletions(-) diff --git a/video-gen-api/app/services/payment.py b/video-gen-api/app/services/payment.py index c622fa22..e8e2ffca 100644 --- a/video-gen-api/app/services/payment.py +++ b/video-gen-api/app/services/payment.py @@ -57,18 +57,82 @@ class DailyFileHandler(logging.FileHandler): self._file_handler = logging.FileHandler( self.baseFilename, mode="a", encoding=self.encoding ) - self._file_handler.setFormatter(self.formatter) - self._current_date = date_str - self.stream = self._file_handler.stream - super().emit(record) + if self._file_handler: + self._file_handler.emit(record) + else: + super().emit(record) -_handler = DailyFileHandler(_log_dir) -_handler.setFormatter(logging.Formatter( - "[%(asctime)s] %(levelname)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S" -)) -if not logger.handlers: - logger.addHandler(_handler) +# Add daily file handler +_log_handler = DailyFileHandler(_log_dir) +_log_formatter = logging.Formatter( + "[%(asctime)s] %(levelname)s %(message)s", + datefmt="%Y-%m-%d %H:%M:%S" +) +_log_handler.setFormatter(_log_formatter) +logger.addHandler(_log_handler) + +# Monkey patch to fix alipay-sdk-python bytes/str issue +def _patch_alipay_sdk(): + try: + from alipay.aop.api.util import WebUtils + + # 直接用我们自己的安全实现替换 do_post + def safe_do_post(url, query_string, headers, params, charset, timeout): + import http.client + import socket + from urllib.parse import urlparse + + parse_result = urlparse(url) + if parse_result.scheme == 'https': + conn = http.client.HTTPSConnection( + parse_result.hostname, + parse_result.port or 443, + timeout=timeout + ) + else: + conn = http.client.HTTPConnection( + parse_result.hostname, + parse_result.port or 80, + timeout=timeout + ) + + try: + body = query_string.encode(charset) if params is None else params + conn.request( + 'POST', + parse_result.path + ('?' + parse_result.query if parse_result.query else ''), + body, + headers + ) + response = conn.getresponse() + if response.status == 200: + response_body = response.read() + # 确保返回的是 str,而不是 bytes + if isinstance(response_body, bytes): + response_body = response_body.decode(charset) + return response_body + else: + response_body = response.read() + if isinstance(response_body, bytes): + response_body = response_body.decode(charset) + raise Exception(f"invalid http status {response.status}, detail body: {response_body}") + except socket.timeout: + raise Exception("timeout") + finally: + conn.close() + + # Apply patch - 直接替换,避免原函数的问题 + WebUtils.do_post = safe_do_post + logger.info("Successfully replaced alipay-sdk-python WebUtils.do_post with safe implementation") + + except ImportError: + pass + except Exception as e: + logger.warning(f"Failed to patch alipay-sdk-python: {e}") + +# Apply the patch when module is loaded +_patch_alipay_sdk() # Orders pending payment for longer than this are auto-cancelled ORDER_EXPIRE_MINUTES = 5 @@ -140,51 +204,6 @@ def _is_mock_mode(db_configs: dict[str, str]) -> bool: # --------------------------------------------------------------------------- _alipay_client = None _alipay_client_app_id = None -_alipay_web_utils_patched = False - - -def _patch_alipay_web_utils(): - """Monkey-patch alipay SDK WebUtils.do_post to fix Python 3 bytes/str TypeError. - - The SDK's do_post raises:: - - TypeError: can only concatenate str (not "bytes") to str - - when the HTTP response is non-2xx, because ``response.read()`` returns - bytes but is used directly in a str concatenation inside the SDK. - """ - global _alipay_web_utils_patched - if _alipay_web_utils_patched: - return - - import alipay.aop.api.util.WebUtils as _web_utils - - _original_do_post = _web_utils.do_post - - def _patched_do_post(url, query_string, headers, params, charset, timeout): - try: - return _original_do_post(url, query_string, headers, params, charset, timeout) - except TypeError as e: - err_str = str(e) - if "bytes" not in err_str and "str" not in err_str: - raise - - # SDK bug: response.read() returned bytes but was used in str concat. - # The original HTTP status is lost due to the TypeError; we raise a - # descriptive RuntimeError so the caller can handle it gracefully. - try: - from alipay.aop.api.util.WebUtils import THREAD_LOCAL - uuid = THREAD_LOCAL.uuid - except Exception: - uuid = "???" - raise RuntimeError( - f"[{uuid}] Alipay HTTP request failed (non-2xx response). " - f"The SDK raised a bytes/str TypeError. " - f"URL: {url}" - ) from e - - _web_utils.do_post = _patched_do_post - _alipay_web_utils_patched = True def _get_alipay_client(app_id: str, private_key: str, public_key: str, gateway: str = ""): @@ -204,9 +223,6 @@ def _get_alipay_client(app_id: str, private_key: str, public_key: str, gateway: ) return None - # Fix SDK's Python 3 bytes/str bug in WebUtils.do_post (once per process) - _patch_alipay_web_utils() - config = AlipayClientConfig() config.server_url = gateway or "https://openapi.alipay.com/gateway.do" config.app_id = app_id @@ -422,16 +438,13 @@ def _create_alipay_order(order: PaymentOrder, db_configs: dict[str, str]) -> str ) return None - except RuntimeError as e: - # The patched WebUtils raises RuntimeError on non-2xx HTTP responses - # (the original SDK would have raised a confusing TypeError). This is - # expected — the Alipay gateway rejected the request for some reason. - logger.warning( - f"Alipay precreate HTTP error: order_no={order.order_no}, " - f"detail={str(e)}" - ) - return None - except Exception: + except Exception as e: + # 处理 SDK 内部的 bytes/str 错误 + if "TypeError" in str(e) and ("bytes" in str(e) or "str" in str(e)): + logger.error( + f"Alipay SDK TypeError (bytes/str issue): order_no={order.order_no}, " + f"error={str(e)}" + ) logger.exception(f"Alipay precreate exception: order_no={order.order_no}") return None