尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

抖音Cookie模拟登录与H5支付实战:微信支付宝调起全流程解析

抖音Cookie模拟登录与H5支付实战:微信支付宝调起全流程解析 先说明一点这类需求我自己在搞模拟登录、自动化脚本和 H5 支付联调的时候确实折腾过。说白了就是拿到自己抖音账号的 Cookie 之后模拟网页端充值的下单流程把后端返回的支付链接拿出来再根据你当前所处的终端环境去决定走微信 H5 还是支付宝 H5。整个过程不复杂但坑特别多尤其是“链接拿到了却调不起支付”这类问题十有八九是环境判断、UA 或者 referer 没处理好。这篇就把我实际操作中验证过的流程、参数逻辑、踩坑记录都整理出来给正在做同类项目或者想接 H5 支付联调的朋友一个能直接抄的作业。1. 整体设计与思路拆解1.1 这个项目的核心链路是什么整个需求可以拆成三个大环节Cookie 登录态获取、充值下单接口调用、支付链接的二次分发。很多人第一次看到“抖音 Cookie 充值接口”会觉得很高深其实本质就是你替浏览器完成了一次下单动作。抖音网页版的充值中心本身就是一个普通的前后端交互页面你手动操作时浏览器会带着你的登录 Cookie 去请求一个“创建订单”的接口服务端校验通过后返回一个有有效期的订单号以及对应的支付参数。支付参数通常不是一个完整的链接而是一串带签名的参数你要做的是把这串参数按照微信或支付宝各自的协议再组装成可用于 H5 调起的链接。整个链条里Cookie 不是全部但它决定了下单请求能不能过服务端校验。支付链接只是接口的返回值之一但它决定了最终的支付成功率。两者缺一不可。1.2 为什么选择 Cookie 方案而不是 App 抓包这里补充一点方案选型的对比因为很多人在一开始就会卡住到底是直接去抓 App 的请求包还是用网页版的 Cookie 方案我自己实测下来网页 Cookie 方案明显更适合做这类 H5 支付项目。原因有几点App 端的接口很多走的是私有协议请求包经过加密和混淆直接抓包看到的是二进制或者被加密的 body解析成本极高。App 端的风控力度大频繁操作容易触发滑块验证甚至封禁接口权限。网页端的接口结构相对清晰支付环节依赖 H5 标准协议跟微信支付、支付宝支付的对接方式完全一致便于复现。Cookie 方案本质上就是“模拟真人浏览器操作”风险低实现成本也低唯一的难点在于 Cookie 的获取和维护频率。2. 核心细节解析与实操要点2.1 Cookie 登录态的几个高频认知误区说到 Cookie很多人会把它理解成“一串固定的字符串”丢进请求头里就能一直用。实际做下来这件事有几个误区必须先澄清。第一抖音网页端的 Cookie 有多个字段真正决定登录态的是sessionid或者sessionid_ss这类会话标识很多其他字段其实只是埋点、追踪用的不是你拿过来就能用的关键内容。我见过有人把整个 Cookie 字符串从浏览器里复制出来丢进脚本后请求依然 401排查半天发现是sessionid已经过期但浏览器因为记忆了多次登录信息页面还能打开导致误判。第二Cookie 的存活时间并不固定。如果长期在同一 IP、同一设备环境下登录有时候能撑好几天一旦切换网络环境或者后台风控策略有变Cookie 说失效就失效。第三网页版抖音有“扫码登录”和“手机号验证码登录”两种常见登录方式。如果你是要做完全自动化的脚本需要额外处理验证码或扫码环节如果只是个人使用直接在浏览器里手动登录后再复制 Cookie是最省事的做法。实操中我用的是 Chrome 的开发者工具登录后到 Application 面板里找到对应域名的 Cookies然后直接复制整个 Cookie 字符串。用这种方式拿到的信息最完整也不容易漏字段。2.2 充值接口返回的“支付链接”到底是什么形态很多人在拿到接口返回后看到h5_pay_url、wx_pay_params这类字段会一脸懵不知道谁才是可以直接拿去用的东西。这里面要区分两个层级。第一层是订单创建接口直接返回的pay_url或redirect_url。这种通常是网页版的收银台地址你在 PC 浏览器里打开它能看到扫码支付的二维码。这个链接不能直接用于 H5 支付因为它是为了桌面网页设计的。第二层是服务端返回的支付参数集合。以微信支付为例通常包含appId、timeStamp、nonceStr、package、signType、paySign这些字段以支付宝为例通常是一串alipay_gateway开头、带大量业务参数的 URL或者是一段需要二次拼接的form表单。我们在项目里要用的就是第二层的数据需要自己组装成 H5 调起链接。判断依据很简单微信支付里如果返回的字段里有appId和paySign这基本就是给 JSAPI 或 H5 支付用的如果返回的是一整个http链接那通常是收银台地址。支付宝那边如果return_url和biz_content同时存在那大概率是标准化网关参数。3. 实操过程与核心环节实现3.1 第一步抓取并维护一套长期有效的抖音 Cookie先讲最基础的获取流程这部分步骤不复杂但对操作顺序有要求。打开 Chrome 无痕窗口访问抖音网页版并完成登录按 F12 进入开发者工具切到 Network 面板随便点开一个需要登录的页面比如个人订单页在请求列表里找任意一个同域名的请求点击后切到 Headers 标签页在 Request Headers 区域里找到Cookie字段整行复制下来。我建议存储的时候保持一行字符串不要手动换行。很多脚本框架在读取 Cookie 时是按行分割的如果你复制成多行会导致请求头拼接出错。关于 Cookie 持久化我一般会把它放到本地文件或者配置环境变量里脚本启动时动态读取。文件格式示例douyin_cookie sessionidxxx; passport_csrf_tokenyyy; ...这里有个细节如果你在多个场景下使用同一套 Cookie我强烈建议把浏览器 UA 也一起存下来。抖音网页端的接口会校验 UA 和 Cookie 的绑定关系如果你用 Python 的 requests 库默认 UA 去请求很可能直接触发风控返回一个“操作频繁”的提示。3.2 第二步定位充值接口并模拟下单接下来是重头戏定位充值接口。我没有办法给你一个完全固定的接口路径因为这类接口的命名和路径会随版本调整但定位思路是通用的。在 Network 面板里手动进入抖音钱包或充值中心页面随便发起一次充值下单操作然后观察请求列表优先关注 XHR 类型的请求请求路径里通常包含recharge、wallet、order、pay这类关键字请求方法是 POSTbody 是 JSON 格式。以我实际抓到的为例下单请求的核心 payload 类似这样{ product_id: 1000123456789, recharge_type: douyin_coin, count: 60, channel: web, return_url: https://yourdomain.com/callback }其中product_id是商品 IDcount是充值数量channel固定为web表示来自网页端return_url是你希望支付完成后跳转的地址。这一步最容易出错的地方是count字段的单位。抖音的虚拟币计费单位和现实货币不是 1:1有些场景下传的是虚拟币数量有些场景下传的是充值金额分。你不确定的时候先手动操作一次看接口实际发出的参数是多少再据此修改你的脚本。模拟请求的 Python 示例import requests cookies_str sessionidxxx; ... headers { User-Agent: Mozilla/5.0..., Referer: https://www.douyin.com/, Content-Type: application/json } cookies {} for item in cookies_str.split(; ): k, v item.split(, 1) cookies[k] v payload { product_id: 1000123456789, recharge_type: douyin_coin, count: 60, channel: web } resp requests.post( https://.../recharge/order/create/, headersheaders, cookiescookies, jsonpayload ) print(resp.json())响应里通常包含order_id、pay_url、pay_params等字段。到这一步你已经拿到了“支付链接”的原料。3.3 第三步H5 支付环境下微信和支付宝的调起方式拿到原始参数后真正的工作才刚开始因为微信和支付宝的 H5 调起逻辑是完全不同的两套协议。微信这边分两种情况。如果你是在微信内置浏览器里调起也就是俗称的公众号支付或 JSAPI 支付你需要把下单接口返回的支付参数传给微信的WeixinJSBridge.invoke方法示例如下function onBridgeReady(data) { WeixinJSBridge.invoke( getBrandWCPayRequest, { appId: data.appId, timeStamp: data.timeStamp, nonceStr: data.nonceStr, package: data.package, signType: data.signType, paySign: data.paySign }, function(res) { if (res.err_msg get_brand_wcpay_request:ok) { // 支付成功 } } ); }但如果你是在非微信浏览器里调起微信支付也就是微信 H5 支付那你需要的是另一个接口它通常会返回一个以https://wx.tenpay.com/开头的链接。这时你只需要把这个链接放在页面里由用户点击跳转微信客户端会自主完成收银台展示。支付宝那边就简单统一一些几乎都是走网关链接。你只需要把返回的参数按标准格式拼接成https://openapi.alipay.com/gateway.do?xxx形式的链接然后通过window.location.href跳转支付宝客户端会接管后续流程。这里我踩过一个大坑微信支付的 JSAPI 参数和 H5 支付参数不能混用如果你拿了一套 JSAPI 的参数放到非微信浏览器里跳转大概率会提示“当前环境无法支付”。项目里最稳妥的做法是根据当前浏览器的 UA 判断环境再决定用哪套参数。4. 常见问题与排查技巧实录4.1 问题速查表现象可能原因解决方案下单接口返回 401Cookie 过期或缺少某关键 Cookie 字段重新登录并抓取 Cookie检查是否包含sessionid下单接口返回“操作频繁”请求频率过高或 UA 与 Cookie 不绑定拉长请求间隔设置与浏览器一致的 UA拿到了 pay_params 但跳转后报“环境不支持”使用了错误的支付协议或参数版本区分 JSAPI 和 H5 支付检查跳转环境微信 H5 链接在 PC 浏览器打开只显示二维码这是收银台链接不是 H5 支付链接改用 JSAPI 或 H5 专用链接支付宝链接跳转后提示“缺少必要参数”biz_content未做 URL 编码或参数拼接顺序错误使用标准网关地址按官方文档顺序拼接Cookie 当天有效隔天失效风控策略导致登录态过期维护多套 Cookie轮询使用做好失效检测4.2 环境判断与 UA 伪装关于环境判断我在项目里是这样处理的先用正则从 UA 里提取设备信息再结合接口返回参数里的支付类型标记去决定调起方式。function isWechat() { return /MicroMessenger/i.test(navigator.userAgent); } function isAlipay() { return /AlipayClient/i.test(navigator.userAgent); }这个判断逻辑看似简单但实际用下来有个变数有些安卓手机的 WebView 会同时包含微信和支付宝 UA 关键字或者经过厂商定制后把 UA 抹掉了。所以我做了一层兜底在判断 UA 之外还会尝试读取navigator.standalone或者检查当前页面的protocol防止误判。顺带一提服务端在创建订单时可能已经通过referer或者是client_type字段锁定了支付方式。如果前端判断和后端锁定不一致就会出现“前端跳转了后端却认为这是非法支付请求”的情况。所以我建议前端的环境判断只是第一层最终的参数选择还是要以下单接口返回的pay_type字段为准。4.3 打通整个 H5 页面的完整示例最后给一个我之前项目里实际用过的 H5 支付页面核心逻辑功能很简单页面加载时请求后端后端带着你维护的 Cookie 去创建订单返回参数后前端根据环境自动跳转。后端伪代码这里就不展开了重点说前端的跳转部分fetch(/api/create_order, { method: POST, body: JSON.stringify({ productId: xxx }) }) .then(res res.json()) .then(data { if (data.pay_type wx_h5) { window.location.href data.pay_url; } else if (data.pay_type wx_jsapi) { const payParams data.pay_params; if (typeof WeixinJSBridge undefined) { document.addEventListener(WeixinJSBridgeReady, () { invokeWxPay(payParams); }); } else { invokeWxPay(payParams); } } else if (data.pay_type alipay_h5) { const form document.createElement(form); form.method POST; form.action data.gateway_url; for (const key in data.form_params) { const input document.createElement(input); input.name key; input.value data.form_params[key]; form.appendChild(input); } document.body.appendChild(form); form.submit(); } });这个示例里支付宝我特意用了一个隐藏表单去提交为什么呢因为支付宝 H5 的网关地址如果直接window.location.href跳转部分低版本手机浏览器对超长 URL 会有截断导致参数丢失。用表单提交可以有效避免这个问题而且和支付宝官方推荐的方式一致。微信 JSAPI 这边我监听WeixinJSBridgeReady事件是因为有时候页面脚本执行时微信的 JS API 还没注入完成不监听这个事件会出现“WeixinJSBridge 未定义”的报错。整个流程跑通之后你会发现在 H5 支付这件事上真正影响成败的往往不是接口能不能调通而是你对终端环境的理解够不够深。不同的 WebView、不同的微信版本、不同的支付协议版本都可能产生截然不同的行为。这也是为什么我一直强调这类项目一定要真机测试光在电脑模拟器上看到“支付链接生成了”并不能证明整个链路是通的。我个人在实际操作里的习惯是每次改完环境判断逻辑都会用三台设备过一遍一台 iPhone 的微信内置浏览器、一台 Android 的普通浏览器、一台 Android 的支付宝内置浏览器。这三条路径只要都能跳到支付收银台项目基本就稳了。环境判断、参数拼装、协议选择这些问题也只有在这种真实环境下才会暴露出来纸面推演很难提前发现。
返回列表