修复微信QQ支付参数分流

This commit is contained in:
yml2213
2026-08-12 21:59:56 +08:00
parent d610933f87
commit 8e4e394c4b
4 changed files with 70 additions and 24 deletions
@@ -221,9 +221,16 @@ def build_page_info_body(order: dict[str, str], cookies: dict[str, str], anti_to
return urllib.parse.urlencode(fields)
def make_encrypt_rand(params: dict[str, str], fk_extend: str, ts: str) -> str:
"""生成与当前订单明文长度匹配的 _rand,确保 goods VM 不截断尾块。"""
def make_encrypt_rand(params: dict[str, str], fk_extend: str, ts: str,
is_qq_login: bool) -> str:
"""按登录渠道生成页面已验证形态的 _rand,不能仅按长度替换控制字节。"""
prefix = "".join(random.choices(string.ascii_letters + string.digits, k=8))
# 微信历史成功请求固定使用 8 个随机字符加 \x01。_rand 位于加密明文中,
# 末控制字节是协议内容,不能为了对齐擅自替换为 QQ 使用的 \x03。
if not is_qq_login:
return prefix + "\x01"
# QQ 当前订单的明文长度会随 OAuth 字段变化;补齐后才能避免 VM 丢弃尾块。
base_length = len(build_plaintext(params, fk_extend, ts, "").encode("latin-1"))
padding_length = (-(base_length + len(prefix))) % 16
return prefix + ("\x03" * padding_length)
@@ -445,20 +452,22 @@ def main() -> int:
print(f"[jsdom-pay] fp-behv 失败: ret={fp_json.get('ret')} {fp_json.get('msg', '')}")
return 1
print("[jsdom-pay] 拉取 web_page_info...")
page_info = request_bytes(PAGE_INFO_URL, cookies, build_page_info_body(
order, cookies, anti_token, args.zone_id, payment_pf,
).encode())
(out_dir / "web-page-info-response.json").write_text(page_info, encoding="utf-8")
try:
page_info_json = json.loads(page_info)
except json.JSONDecodeError:
page_info_json = {}
if page_info_json.get("ret") != 0:
print(f"[jsdom-pay] web_page_info 失败: ret={page_info_json.get('ret')} "
f"{page_info_json.get('msg', '')}")
print(f"[jsdom-pay] 证据目录: {out_dir}")
return 1
# QQ 成功 HAR 包含该前置;微信历史成功链路没有,不能将 QQ 状态机混入微信请求。
if midas_login_params(cookies)["qq_appid"]:
print("[jsdom-pay] 拉取 QQ web_page_info...")
page_info = request_bytes(PAGE_INFO_URL, cookies, build_page_info_body(
order, cookies, anti_token, args.zone_id, payment_pf,
).encode())
(out_dir / "web-page-info-response.json").write_text(page_info, encoding="utf-8")
try:
page_info_json = json.loads(page_info)
except json.JSONDecodeError:
page_info_json = {}
if page_info_json.get("ret") != 0:
print(f"[jsdom-pay] QQ web_page_info 失败: ret={page_info_json.get('ret')} "
f"{page_info_json.get('msg', '')}")
print(f"[jsdom-pay] 证据目录: {out_dir}")
return 1
web_args = load_template_args()
# key 派生已破解(F-2052,2026-08-12):key16 可随机生成,key1 由反解器
@@ -489,7 +498,9 @@ def main() -> int:
params.update(midas_login_params(cookies))
now_seconds = str(int(time.time()))
fk_extend = "tdrc_session%3D" + fp["session_id"]
random_suffix = make_encrypt_rand(params, fk_extend, now_seconds)
random_suffix = make_encrypt_rand(
params, fk_extend, now_seconds, bool(midas_login_params(cookies)["qq_appid"]),
)
plaintext_length = len(build_plaintext(params, fk_extend, now_seconds, random_suffix).encode("latin-1"))
encrypt_msg = generate_encrypt_msg_offline(
params, fk_extend, now_seconds, random_suffix,