微信支付API v3接入实战:签名验签与回调处理全流程案例
微信支付 API v3 的接入是不少后端和全栈开发者在做交易类项目时绕不开的一道坎。相比早期的 v2 版本v3 在安全模型上做了一次彻底的重构签名机制、证书体系、回调验签逻辑全都换了新玩法。很多人第一次上手时照着文档一步步走结果卡在签名报错、回调验签失败、平台证书下载不了这些环节上一卡就是大半天。这篇内容就是围绕微信支付 WechatPay-API-v3 案例这个主题把我自己在实际项目里跑通过的一整套流程拆开讲清楚从整体设计思路到核心参数计算再到回调处理和问题排查尽量做到你照着抄就能跑起来。不管你是刚接触支付模块的新手还是从 v2 迁移过来的老手都能从里面找到能直接用的东西。1. 整体方案设计与选型思路1.1 为什么 v3 值得单独拿出来做一套案例先说说为什么 v3 值得单独写一套案例。v2 时代签名用的是 MD5 或 HMAC-SHA256密钥就是一个 API 密钥字符串简单直接但安全性偏弱密钥一旦泄露基本等于账户裸奔。v3 则全面转向了非对称加密体系请求签名用商户私钥平台回调验签和平台证书下载用平台公钥敏感信息再用 AES-256-GCM 做对称加密。这套组合拳下来安全等级上了一个台阶但代价就是接入复杂度明显上升。我见过不少团队的做法是直接找一个现成的 SDK 包一层能跑通就行内部细节一概不管。短期没问题可一旦线上出现验签失败、证书过期、回调重复通知这类问题没有底层理解就很难定位。所以这套案例的设计思路是先把签名和验签这两条主线吃透再往上搭业务接口。这样即使后面换语言、换框架核心逻辑依然能复用。从选型角度看v3 接入主要有三条路官方 SDK、社区 SDK、纯手写。官方 SDK 覆盖了主流语言稳定性和跟进速度都不错适合大多数团队社区 SDK 有些封装更顺手但维护节奏参差不齐选之前要看最近提交时间纯手写适合想彻底掌控细节或者语言没有官方 SDK 的场景。我的建议是业务项目优先用官方 SDK学习或特殊需求再考虑手写因为签名这块的坑实在太多没必要重复造轮子。1.2 核心概念先理清楚商户号、证书、密钥三件套在动手写代码之前有几个概念必须先分清楚否则后面看文档会一脸懵。商户号mchid你在支付平台上的唯一身份标识所有请求都要带上它。商户 API 证书包含商户私钥apiclient_key.pem和证书序列号serial_no。私钥用来对请求做签名序列号用来告诉平台我是用哪张证书签的。平台证书平台侧的公钥证书用来验证平台发来的回调签名以及加密敏感信息。它需要通过接口主动下载并且会定期轮换。APIv3 密钥一个 32 位的字符串专门用于 AES-256-GCM 对称加密比如解密回调里的敏感字段。这里最容易混淆的是商户 API 证书和平台证书。简单记你签给平台看用商户私钥平台签给你看用平台公钥。方向搞反了签名必然失败。提示商户私钥文件 apiclient_key.pem 绝对不能提交到代码仓库也不能打进前端包。线上环境建议放在配置中心或密钥管理服务里通过环境变量注入。1.3 请求签名的整体流程设计v3 的请求签名遵循一套固定的构造规则理解了这个规则任何语言的实现都是照葫芦画瓢。核心是把请求的关键信息拼成一个待签名串然后用商户私钥做 SHA256withRSA 签名最后把签名和相关信息放进 Authorization 头。待签名串的构造格式是这样的HTTP方法\n URL路径\n 时间戳\n 随机串\n 请求报文主体\n每一行以\n结尾最后一行也要有\n。这里有几个细节特别容易出错URL 路径要带 query 参数但不含域名请求报文主体如果是 GET 请求就是空字符串时间戳是秒级 Unix 时间戳。拼好之后用商户私钥签名再对签名结果做 Base64 编码。Authorization 头的格式是WECHATPAY2-SHA256-RSA2048 mchid...,nonce_str...,signature...,timestamp...,serial_no...这个头里的每个字段都有讲究mchid 是商户号nonce_str 是随机串和待签名串里的一致signature 是 Base64 后的签名timestamp 是时间戳serial_no 是商户证书序列号。任何一个字段对不上平台都会返回签名错误。2. 核心细节解析与实操要点2.1 待签名串构造的五个坑待签名串看着简单实际写起来坑不少我逐个说。第一个坑URL 路径带不带 query。规则是带 query但不带域名。比如请求https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi?foobar待签名串里的路径应该是/v3/pay/transactions/jsapi?foobar。很多人只写了/v3/pay/transactions/jsapi结果签名对不上。第二个坑请求主体的处理。POST 请求的主体是 JSON 字符串必须和实际发送的字节完全一致。如果你在签名时序列化了一次 JSON发送时又序列化了一次两次结果可能因为字段顺序、空格不同而不一致导致签名失败。正确做法是序列化一次存成字符串签名和发送都用这同一个字符串。第三个坑换行符。待签名串的每一行末尾都要有\n包括最后一行。少一个换行符签名就废了。这个在拼接字符串时特别容易漏。第四个坑时间戳精度。必须是秒级不是毫秒级。用毫秒级时间戳平台会认为请求过期。第五个坑随机串。每次请求都要重新生成不能复用。一般用 UUID 去掉横线或者随机生成 32 位字符串。下面是一个构造待签名串的示例Pythonimport time import uuid def build_sign_str(method, url_path, body): timestamp str(int(time.time())) nonce_str uuid.uuid4().hex sign_str f{method}\n{url_path}\n{timestamp}\n{nonce_str}\n{body}\n return sign_str, timestamp, nonce_str注意body在 GET 请求时传空字符串POST 请求时传已经序列化好的 JSON 字符串。2.2 商户私钥签名与 Authorization 头拼装拿到待签名串后用商户私钥做签名。不同语言的实现略有差异但核心都是 SHA256withRSA。以 Python 为例from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding import base64 def sign(sign_str, private_key_path): with open(private_key_path, rb) as f: private_key serialization.load_pem_private_key(f.read(), passwordNone) signature private_key.sign( sign_str.encode(utf-8), padding.PKCS1v15(), hashes.SHA256() ) return base64.b64encode(signature).decode(utf-8)这里用的是 PKCS1v15 填充不是 PSS别搞错。签名结果做 Base64 编码后拼进 Authorization 头def build_auth_header(mchid, serial_no, signature, timestamp, nonce_str): return ( fWECHATPAY2-SHA256-RSA2048 fmchid{mchid}, fnonce_str{nonce_str}, fsignature{signature}, ftimestamp{timestamp}, fserial_no{serial_no} )拼的时候注意格式字段之间用逗号分隔每个值用双引号包起来前缀WECHATPAY2-SHA256-RSA2048后面跟一个空格。这个头一旦格式错了平台直接返回 401。注意serial_no 是商户证书序列号不是平台证书序列号。这两个序列号经常被搞混导致签名验证失败。商户证书序列号可以在证书详情里看到也可以通过 openssl 命令从证书文件里提取。2.3 平台证书的下载与轮换管理平台证书是用来验签回调和加密敏感信息的必须先从平台下载。下载平台证书这个接口本身也需要签名用的是商户私钥。下载回来的证书是 PEM 格式需要解析出公钥和序列号。这里有个关键点平台证书会定期轮换不是下载一次就一劳永逸。轮换期间平台可能同时用新旧两张证书签名所以你的验签逻辑要支持多张证书。我的做法是维护一个证书列表每次验签时根据回调头里的Wechatpay-Serial找到对应的证书。def get_platform_certificate(serial): # 从本地缓存的证书列表中查找 for cert in cert_list: if cert[serial_no] serial: return cert[public_key] # 缓存里没有触发一次重新下载 refresh_certificates() # 再查一次 ...证书缓存建议加个过期时间比如 12 小时刷新一次同时在验签失败时强制刷新一次这样能兼顾性能和及时性。2.4 回调验签的完整逻辑回调验签是 v3 接入里另一个重头戏。平台在支付成功后会向你的回调地址发送一个 POST 请求请求头里带了签名信息你需要用平台公钥验证这个签名确认请求确实来自平台。验签的步骤和请求签名是对称的先从请求头里取出Wechatpay-Timestamp、Wechatpay-Nonce、Wechatpay-Signature、Wechatpay-Serial然后构造待验签串时间戳\n 随机串\n 回调报文主体\n注意这里只有三行和请求签名的五行不一样。构造好之后用Wechatpay-Serial对应的平台公钥做验签。验签通过后再解析回调报文如果里面有敏感字段比如用户信息还需要用 APIv3 密钥做 AES-256-GCM 解密。def verify_callback(headers, body, platform_public_key): timestamp headers[Wechatpay-Timestamp] nonce headers[Wechatpay-Nonce] signature headers[Wechatpay-Signature] verify_str f{timestamp}\n{nonce}\n{body}\n public_key.verify( base64.b64decode(signature), verify_str.encode(utf-8), padding.PKCS1v15(), hashes.SHA256() )验签通过后回调报文里的resource字段是加密的需要用 APIv3 密钥解密。解密用的是 AES-256-GCM密钥是 APIv3 密钥的字节nonce 和 associated_data 都在 resource 里。3. 实操过程与核心环节实现3.1 环境准备与依赖安装动手之前先把环境准备好。我以 Python 为例其他语言思路一致。需要准备的东西商户号、商户 API 证书apiclient_cert.pem 和 apiclient_key.pem、证书序列号APIv3 密钥32 位字符串一个能接收公网回调的地址本地开发可以用内网穿透工具但注意合规使用依赖库主要是cryptography和requestspip install cryptography requestscryptography负责签名、验签、AES 解密requests负责发 HTTP 请求。如果你用官方 SDK直接装对应的包就行但理解底层还是建议自己手写一遍。3.2 发起一笔 JSAPI 支付的完整流程JSAPI 支付是最常见的场景流程大致是前端调起支付后端下单返回支付参数前端唤起收银台。这里重点讲后端下单和返回参数。下单接口是/v3/pay/transactions/jsapi请求体大概长这样{ appid: 你的appid, mchid: 你的商户号, description: 测试商品, out_trade_no: 订单号, notify_url: https://你的域名/notify, amount: { total: 1, currency: CNY }, payer: { openid: 用户openid } }注意amount.total的单位是分1 就是 1 分钱。这个字段经常有人填成元导致金额错误。下单成功后平台返回一个prepay_id你需要用它再构造一组给前端的支付参数包括appId、timeStamp、nonceStr、package、signType、paySign。这里的paySign是用商户私钥对另一组待签名串做的签名格式是appId\n timeStamp\n nonceStr\n package\npackage的值是prepay_idxxx。这组参数返回给前端后前端调用wx.requestPayment唤起收银台。提示timeStamp是字符串类型不是数字。前端拿到后直接用不要做类型转换否则签名对不上。3.3 回调处理与幂等设计回调处理是支付模块里最需要小心的地方。平台会多次发送回调直到你返回成功响应所以幂等处理是必须的。我的做法是收到回调后先验签验签通过后根据订单号查库如果订单已经是支付成功状态直接返回成功不再重复处理业务逻辑。回调返回的响应体格式是{ code: SUCCESS, message: 成功 }HTTP 状态码返回 200。如果处理失败返回 500 或 4xx平台会重试。但要注意不要因为业务逻辑异常就返回失败比如库存不足这种应该记录日志后返回成功避免平台无限重试。回调报文解密后的结构大概是这样{ out_trade_no: 订单号, transaction_id: 平台交易号, trade_state: SUCCESS, amount: { total: 1, payer_total: 1 } }拿到trade_state后判断是否成功再更新订单状态。3.4 关键参数计算过程实录这里把几个关键参数的计算过程完整走一遍方便你对照。签名串构造示例假设请求是 POST/v3/pay/transactions/jsapi时间戳1700000000随机串abc123请求体是{a:1}那么待签名串是POST /v3/pay/transactions/jsapi 1700000000 abc123 {a:1}注意最后有一个空行即最后一个\n。Authorization 头示例WECHATPAY2-SHA256-RSA2048 mchid1900000001,nonce_strabc123,signaturexxxx,timestamp1700000000,serial_noyyyy回调验签串示例假设回调头时间戳1700000001随机串def456回调体{b:2}那么待验签串是1700000001 def456 {b:2}同样最后有一个空行。AES-256-GCM 解密参数keyAPIv3 密钥的 UTF-8 字节32 字节nonceresource 里的nonce字段associated_dataresource 里的associated_data字段ciphertextresource 里的ciphertext字段Base64 解码后解密解密后得到明文 JSON。4. 常见问题与排查技巧实录4.1 签名失败问题速查表签名失败是最高频的问题我把常见原因整理成表方便对照排查。报错信息可能原因排查方法401 UnauthorizedAuthorization 头格式错误检查前缀、字段名、引号、逗号签名验证失败待签名串构造错误逐行核对五行内容注意换行符签名验证失败私钥与序列号不匹配确认私钥和 serial_no 来自同一张证书签名验证失败请求体不一致签名和发送用同一个字符串请求过期时间戳精度错误用秒级时间戳检查服务器时间证书序列号错误用了平台证书序列号换成商户证书序列号排查签名问题时最有效的办法是把待签名串打印出来逐字符核对。很多时候问题就出在一个看不见的空格或者换行上。4.2 回调验签失败的排查思路回调验签失败先确认三件事平台证书是否是最新的、待验签串是否构造正确、签名是否 Base64 解码。平台证书轮换期间如果你本地缓存的是旧证书而平台用新证书签名验签就会失败。这时候需要强制刷新证书。我的做法是在验签失败时捕获异常刷新一次证书再重试如果还失败才认为是真的验签失败。待验签串的构造和请求签名不同只有三行很多人习惯性按五行构造结果必然失败。记住回调验签是三行请求签名是五行。4.3 证书轮换与过期处理平台证书有有效期过期后验签会失败。建议在代码里加一个定时任务定期检查证书有效期快过期时主动刷新。同时验签逻辑要支持多证书因为轮换期间新旧证书可能并存。商户 API 证书也有有效期过期后需要重新申请并替换。这个一般提前一个月平台会提醒别等到过期了才发现。4.4 金额与订单号处理的注意事项金额单位是分这个前面提过但还是要强调。我见过有人把 100 元写成 100结果实际支付 1 元用户乐了财务哭了。订单号要保证唯一建议用业务前缀加时间戳加随机数的方式生成。重复的订单号会导致下单失败。提示回调里的out_trade_no是你下单时传的订单号transaction_id是平台生成的交易号。对账时以transaction_id为准业务关联用out_trade_no。4.5 本地调试与日志记录技巧本地调试回调比较麻烦因为平台需要公网地址。可以用内网穿透工具把本地服务暴露出去但要注意合规使用不要用于任何违规场景。日志记录很关键建议把每次请求的待签名串、Authorization 头、响应体都记下来但不要记录私钥和 APIv3 密钥。回调处理时把验签结果、解密后的报文、业务处理结果都记下来方便出问题时回溯。我自己的习惯是给支付模块单独建一个日志文件按天切割保留 30 天。这样排查历史问题时不用翻整个应用的日志。5. 从案例到生产的几点经验把案例跑通只是第一步真正上生产还有不少细节要注意。首先是密钥管理私钥和 APIv3 密钥不能硬编码在代码里要用环境变量或密钥管理服务。其次是重试机制调用平台接口时网络抖动是常态要有合理的重试策略但注意下单接口不要盲目重试避免重复下单。再就是对账每天定时拉取平台的账单和本地订单做比对发现差异及时处理。这个在业务量上来之后特别重要能帮你发现很多隐藏问题。最后是监控告警签名失败率、回调处理失败率、证书有效期这些都要有监控出问题第一时间知道。支付无小事任何一个环节出问题都可能影响真金白银。我个人在实际操作中的体会是v3 的复杂度主要集中在前期的签名和验签理解上一旦这两块吃透后面的业务接口都是体力活。所以别急着堆业务代码先把签名验签这条链路走通后面会顺很多。另外官方文档虽然全但有些细节写得比较散建议结合 SDK 源码一起看理解会更透彻。

相关新闻

Dash-iOS 中的 NSTimer+Blocks:让 NSTimer 直接使用 Block 回调的轻量级 Category 实践指南

Dash-iOS 中的 NSTimer+Blocks:让 NSTimer 直接使用 Block 回调的轻量级 Category 实践指南

开发工具 【免费下载链接】Dash-iOS Dash for iOS was discontinued. Please check out Dash for macOS instead. 项目地址: https://gitcode.com/gh_mirrors/da/Dash-iOS 点击查看 免费下载 导读 本文围绕 Dash-iOS 仓库中引入的第三方组件 NSTimer-Blocks&#…

2026/10/15 11:52:41 阅读更多 →
Qt QSplitter核心原理与工程实践:解决面板拖拽与布局恢复

Qt QSplitter核心原理与工程实践:解决面板拖拽与布局恢复

1. 为什么需要分割器:布局管理器解决不了的面板大小分配做了几年Qt桌面应用,我越来越觉得“布局”这件事被很多人低估了。刚开始写界面时,我也喜欢用QHBoxLayout和QVBoxLayout把控件一排排摆整齐,觉得能自动伸缩就很满足了。直到某…

2026/10/15 11:52:41 阅读更多 →
2026工业具身智能移动操作机器人TOP10榜单与选型指南

2026工业具身智能移动操作机器人TOP10榜单与选型指南

1. 工业具身智能移动操作机器人的核心定义与榜单逻辑1.1 什么才算“具身智能移动操作机器人”“具身智能移动操作机器人”这个词,拆开看有三个关键词:具身智能、移动、操作。市面上很多号称“具身智能”的设备,其实只满足了其中一两个条件&am…

2026/10/15 11:52:41 阅读更多 →

最新新闻

LaTeX环境搭建:Texlive 2020与TeXstudio 4.5.3协同部署指南

LaTeX环境搭建:Texlive 2020与TeXstudio 4.5.3协同部署指南

1. 这不是“装个软件”那么简单:为什么LaTeX环境搭建值得花两小时认真对待你点开这个标题,大概率正被一篇论文、一份技术报告或毕业设计的排版问题卡在原地——Word里公式编号总对不齐,参考文献格式反复崩坏,图表跨页后标题消失&a…

2026/10/15 12:40:07 阅读更多 →
FM175XX + FreeRTOS 读卡工程详解:从移植避坑到业务链路落地

FM175XX + FreeRTOS 读卡工程详解:从移植避坑到业务链路落地

简介:面向嵌入式开发者的 APM32/STM32 RFID 读写方案,基于 FreeRTOS 集成 FM175XX 射频芯片,适合需要快速验证 TypeA 卡识别、评估识别距离优化效果的开发者。工程可直接编译,外接天线板采用双天线配置,已调通卡片 ID …

2026/10/15 12:40:07 阅读更多 →
系统辨识与建模40学时教案:从M序列设计到最小二乘的工程实践

系统辨识与建模40学时教案:从M序列设计到最小二乘的工程实践

简介:这份系统辨识教案面向自动化专业学生与相关工程技术人员,围绕从输入输出数据中建立系统模型这一核心问题,系统梳理辨识理论、方法与实验流程。内容涵盖实体与模型的概念区分、模型分类、Zadeh 辨识定义及数据、模型类、准则三要素&#…

2026/10/15 12:40:07 阅读更多 →
写博客坚持不下去?从知识复利到写作习惯的完整复盘

写博客坚持不下去?从知识复利到写作习惯的完整复盘

写了七八年的博客,中间无数次想放弃,又无数次因为某个读者的一条评论续了命。身边总有朋友问:现在短视频都把流量抢光了,谁还看长文?你怎么还能一篇篇写下去,而且没有烂尾?每次被问到这个问题&a…

2026/10/15 12:40:07 阅读更多 →
仓颉尝鲜第一步:VSCode 环境配置与 SDK 插件全流程

仓颉尝鲜第一步:VSCode 环境配置与 SDK 插件全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 12:40:07 阅读更多 →
CentOS 7 离线安装 PostgreSQL 9.5 完整实践指南

CentOS 7 离线安装 PostgreSQL 9.5 完整实践指南

1. 项目概述:为什么离线安装 PostgreSQL 9.5 在 CentOS 7 上仍值得深挖你手头有一台刚上架的生产服务器,物理隔离、无外网权限、防火墙策略严苛——这是某金融行业客户机房里最常见的“安全岛”环境;或者你正为某高校实验室的旧版教学集群做维…

2026/10/15 12:39:06 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →