diff --git a/unipay/init.py b/unipay/init.py index f36cf75..a1c104c 100644 --- a/unipay/init.py +++ b/unipay/init.py @@ -65,12 +65,6 @@ def _build_provider_conf(provider_name: str) -> dict: with open(privkey_path, "rb") as f: conf["private_key_pem"] = f.read() del conf["private_key_pem_file"] - # 校验 API v3 密钥(AES-256-GCM 需要 32 字节) - api_v3_key = conf.get("api_v3_key", "") - if not api_v3_key or api_v3_key in ("None", "none", ""): - raise ValueError(f"环境变量 WXP_API_V3_KEY 未设置或为占位符: {api_v3_key!r}") - if len(api_v3_key.encode()) != 32: - raise ValueError(f"WXP_API_V3_KEY 长度应为32字节(用于AES-256-GCM), 当前: {len(api_v3_key.encode())}字节") elif provider_name == "alipay": priv_path = conf.get("app_private_key_pem_file", "") diff --git a/unipay/providers/wechat.py b/unipay/providers/wechat.py index ace712d..0d92863 100644 --- a/unipay/providers/wechat.py +++ b/unipay/providers/wechat.py @@ -29,7 +29,15 @@ class WechatGateway(Gateway): self.mchid = mchid self.appid = appid self.cert_serial_no = cert_serial_no - self.api_v3_key = api_v3_key.encode() + self.api_v3_key = None + try: + key_bytes = api_v3_key.encode() + if len(key_bytes) == 32 and api_v3_key not in ("None", "none", ""): + self.api_v3_key = key_bytes + else: + print(f"[unipay] wechat WXP_API_V3_KEY invalid (len={len(key_bytes)}), callback will be disabled", flush=True) + except Exception: + print(f"[unipay] wechat WXP_API_V3_KEY invalid, callback will be disabled", flush=True) # 加载私钥 self._private_key = serialization.load_pem_private_key( @@ -86,6 +94,8 @@ class WechatGateway(Gateway): encrypt_info = cert["encrypt_certificate"] # 解密平台证书 + if self.api_v3_key is None: + raise ValueError("WXP_API_V3_KEY not configured, cannot verify callback") aesgcm = AESGCM(self.api_v3_key) pub_pem = aesgcm.decrypt( nonce=encrypt_info["nonce"].encode(), @@ -130,6 +140,8 @@ class WechatGateway(Gateway): # 工具:解密 resource.ciphertext # ----------------------------------------------------- def _decrypt_resource(self, resource: Dict[str, Any]) -> Dict[str, Any]: + if self.api_v3_key is None: + raise ValueError("WXP_API_V3_KEY not configured, cannot decrypt callback") aesgcm = AESGCM(self.api_v3_key) plaintext = aesgcm.decrypt( nonce=resource["nonce"].encode(),