跳到正文

支付插件的安装包里不该有 API 密钥

2026年8月16日 2 分钟读完 Paymos Tech Paymos Tech
一排一模一样的合着的盒子旁边,敞着一个空盒子,一条虚线平着穿过它们

要点速览

支付插件的安装包里不该有 API 密钥,Paymos 的包也确实没有:这个压缩包对每个商户 都是同一个文件,不含 API key、API secret、项目 ID、webhook secret、OAuth 令牌 或设备码。安装之后也不用手工补:连接店铺是一次授权,密钥、webhook 和项目绑定 都在这一步里配好。按商户单独打包的做法,是用「把一个可用的密钥写进文件」换来 更短的安装流程,而这个文件之后会进备份、工单附件和代码仓库。两步检查——一次 搜索和一次校验和——就能看出你拿到的是哪一种。

Paymos 的插件包里没有凭据。商户为 WooCommerce、Magento 2 或者另外六个官方插件下载的压缩包,和其他商户下载的是同一个;里面没有 API key、API secret、项目 ID、webhook secret、OAuth 令牌,也没有设备码。下载这个动作不连接任何东西。

后面的步骤也不会把它们塞进去。连接店铺是一次授权,密钥、webhook 和项目绑定都在这一步里配好,然后在店铺自己这一侧加密保存。

把压缩包留空不是细节,正是这件事的重点。按商户单独打包、密钥已经写在里面的文件,本身就是一份可用的凭据——而文件是会跑的:跑进下载目录、跑进每晚的备份、跑进工单附件,跑进那个装着站点主题的代码仓库。

找外包或者代运营的店铺尤其容易碰上。「这个插件发我一份」听起来只是传个文件;包里要是带着密钥,同一句话的意思就变成了把账户交出去。

装插件是 WooCommerce 文档和它旁边七篇的事,选哪一个是插件总览的事。这篇写在两者下面:一个插件包能装下什么,Paymos 的包里装了什么,以及怎么核实别人递给你的那一个。

支付插件的安装包里装着什么?

支付插件的安装包是一个代码压缩包——CMS 要安装的那个扩展,加上向店铺描述它的那些文件。里面的内容对每个下载的人都一样,没有哪一部分是为下载它的那个商户准备的。

值得把它打开看一眼的原因,是一套能跑起来的接入最终需要的东西:一个 API key、一个 API secret、一个项目绑定,和一个 webhook secret。所以网关在这里有一个选择:这些东西什么时候存在——在打包时写进文件,还是在连接时再配。

Paymos 把这个选择放在连接那一刻。下载路由提供的是一个静态文件,不是按账户临时拼装的包;这就是为什么压缩包对每个商户都一样,也不含上面那几类凭据中的任何一种。

两种做法的差别在于压缩包是什么东西。打包时写进去的密钥,把这个文件变成了一份机密;连接时才配的密钥,让文件保持为代码,机密在店铺自己那一侧生成。

为什么有的网关会把密钥写进下载包?

网关把凭据写进下载包,是为了把安装的活从商户身上拿掉。它的前提是两件事必然连在一起——一家什么都不用配的店铺,肯定是拿到了一个早就知道自己属于谁的文件。

这条捷径的代价由压缩包来付。把一把密钥写进插件包,就是把它从代码变成了持有即生效的凭据:拿到文件的人就等于拿到了它对应的那个账户,而拿到一个文件的门槛非常低。

写死密钥的包还把两件事压成了一件。拿代码不需要账户,谁都可以重复拿;连接一家店铺是要认证的,而且只发生一次。带密钥的压缩包把这两件事合成了同一件。

MITRE 把这种一般形态编在 CWE-798,Use of Hard-coded Credentials——「产品中含有硬编码的凭据,例如口令或加密密钥」。它的经典情形是所有安装共用一个机密;按商户打包把这一点反过来,给每个文件配一把自己的,却保留了要害的那部分:一个可用的机密,静静躺在一个可以分发的文件里。

插件包下载之后会去哪些地方?

插件包不会停在它落地的位置。下载目录只是若干站里的第一站,而后面那些站点在设立的时候,没有一个是把凭据考虑在内的:

  • 笔记本上的下载目录,没有加密,在有人清理之前一直躺着。
  • 每晚一次的站点备份,以及这份备份产生的每一个还原点。
  • 工单附件——商户把「那个插件」发给正在帮他看问题的人的那一刻。
  • 纳入版本管理的站点仓库,就放在主题旁边。
  • 外包同事的电脑,因为把文件转过去是交接工作最快的方式。

对一个不含凭据的压缩包,这五处都不算事:文件里是公开的字节,什么都不泄露。对一个写进了密钥的压缩包,这五处每一处都是一次泄露,而商户手里没有一份「发生过几次」的记录。

这份清单真正麻烦的地方在于不可撤回。删掉一份备份,收不回从它还原出来的副本;撤回一个工单附件,也撤不回已经下载过它的人。凭据从一开始就不在里面时,这些问题一个都不会提出来。

怎么核实别人给你的这个包?

核实一个插件包的方法,是在它进入站点之前解开来搜一遍。三条命令就能把问题问完,而且都不需要网关配合。

# 1. 在包进入店铺之前先解开
unzip -q plugin.zip -d pkg

# 2. 搜一遍所有长得像可用凭据的东西
grep -rIn -iE 'api[_-]?key|secret|token|client_id|device_code' pkg

# 3. 算哈希,再和同一版本的第二次下载比对
shasum -a 256 plugin.zip

第二步里的 -i 是真在干活:一个常量写成 API_KEYApiKey 的概率不比 api_key 低,区分大小写的搜索会从两者旁边走过去。拿这条模式跑公开的 Paymos WooCommerce 源码,带 -i 返回 65 行,不带返回 63 行。

这些命中要当成字段名、标签和翻译文案来读,不是当成结论。在那棵源码树里,其中三十八行落在 tests/ 下面,那里像 'api_key' => 'pk_test_1234567890' 这样的写法本来就是占位;真正要停下来看的,是测试目录之外带着真实值的那一条。

搜索只能给出提示,校验和才能定案。换一台机器把同一个版本再下载一次,也算一遍哈希:对每个商户都相同的压缩包会两次给出同一个哈希,按商户拼装的包做不到。

包里是空的,插件的密钥从哪来?

插件的密钥来自一次授权。装好这个版本,在店铺后台点 Connect Paymos,在打开的 Paymos 标签页里确认这次请求——剩下的由连接这一步配好:

  • 密钥。 复用商户当前生效的收款密钥,没有就新建一个;沙盒和正式一起配好,所以之后把插件切到正式环境不需要重新连接。
  • webhook。 账单 webhook 由平台自己注册,只有回调地址、类别和项目三者都一致时才复用已有的那个,同一地址上冲突的 webhook 绝不做静默覆盖。
  • 项目。 在插件里根本不选——绑定的是控制台里当前打开的那个项目,整条流程里没有第二个项目选择器。

于是「为了省事」这个论点自己回答了自己。按商户打包,是拿一个写进文件的机密换来更短的安装流程;而用这种方式连接的店铺,同样什么都没配,它装进去的那个文件里也仍然什么都没有。

为什么一个包能给所有商户用?

一个包能给所有商户用,是因为插件是代码,而代码里面没有账户。各个 CMS 平台假设的正是这一点,它们的分发规则也是围着这一点写的。

WordPress 把这个假设写成了目录规则:「WordPress.org 分发的插件版本只有目录里的那一个」。一个版本一个产物、发给所有人,是 CMS 期待插件抵达时的形态——不管由哪条渠道送达。

按商户拼装的包塞不进这样的渠道。这种文件没法作为一个发布版本公开,没法和一个公共版本对照,也没法在版本之间做差异比对,因为根本不存在唯一一个已发布的版本可以拿来比。

Paymos 的八个官方插件按公开发布下载分发,一个平台一个版本一个包。每次发布为 WooCommerce 和 WHMCS、OpenCart 和 PrestaShop、Magento 2 和 Shopware 6、CS-Cart 和 Easy Digital Downloads 各产出一个压缩包。

不带密钥的包让哪些操作变简单?

一个不含凭据的包,让三件很平常的操作不至于变成泄露:把文件发给别人、轮换一把密钥、替换插件。这三件事在普通的一周里都会发生。

把文件交给开发、外包或者同事,什么都不会泄露,因为 Paymos 的压缩包就是别人手里已经有的那一个。会移动的那个东西,不是能授予访问权限的那个东西。

轮换凭据也不需要重新下载。密钥和压缩包是两个独立的对象,所以轮换之后整套操作就是把店铺重新连接一次;webhook secret 的轮换还带一个过渡期,当前密钥和上一把密钥签出来的签名都接受。

OWASP 把轮换放在同一个位置:「你应当定期轮换机密,这样被盗的凭据只能在很短的时间内可用」。一次得先重新下载插件才能开始的轮换,就是一次会被一直往后拖的轮换。

空包又证明不了什么?

一个不含凭据的压缩包只证明一件事:这个文件里没有带着机密。它留下两个问题没答,而这两个都比它答掉的那个更重要。

第一个是存储。凭据到了店铺那边,总得有个东西把它存下来,怎么存是另一个属性、另一个答案——Paymos 插件把这些值加密存在店铺自己一侧,从不返回给浏览器,也不提供手工修改的入口。

第二个是运行时。压缩包是代码的一张快照,所以读一个插件的压缩包,看到的是它做什么,不是它在一家有真实账单在跑的店铺上实际做了什么。

存储和运行时都值得一个答案,而校验和一个都解决不了。翻压缩包是便宜的那一步:在装任何东西之前花几分钟,把一整类暴露方式挡在外面。

这个密钥本身该有多窄?

递到 CMS 手里的凭据,应该是能干完这件事的最窄的那一份,因为店铺是一台共享的机器,插件目录里的东西,任何有后台权限的人都读得到。Paymos 的做法在这个问题被提出之前就先把它收窄了。

连接这一步配的是一份收款凭据,而收款和转出是两套凭据,所以一个收银插件从来不会拿到那把能把钱转走的。沙盒和正式也在同一套 API 契约上用两套凭据,所以店铺拿去测试的那把,不是收真实付款的那把。

一份 Paymos 凭据可以带最多 50 条 IP 白名单,把它钉在店铺实际运行的那些地址上。从别处递上来的同一份凭据会被拒绝,所以从备份里捞出来的密钥,不是一把能用的密钥。

Merchant API 的认证是 HMAC-SHA256 请求签名,不是持有即生效的令牌,所以这份机密是用来签请求的,不会跟着请求一起发出去。API 密钥那一页把整套凭据模型讲完了。

装插件之前该问哪几个问题?

四个问题就能把一个支付插件怎么处理凭据问清楚,而且四个都能在文件进入站点之前回答。

  1. 这个压缩包对所有人都一样吗?给自己的下载算个哈希,再从另一台机器取同一个版本,对一遍。
  2. 包里有没有一个可用的值?在解开的文件里搜像凭据的字符串;字段名和测试数据不算结论。
  3. 装好之后插件把凭据放在哪里?这该写在文档里,不该出现在一条客服回复里。
  4. 它手里那份凭据有多窄?一个带着转出权限的收银插件,拿的比这份活需要的多。

这四个问题没有一个称得上安全审计;但合起来,它们排掉了那种没有补救步骤的故障:一个机密已经被复制到了没人记过账的地方。

插件只是从店铺通向收款通道的一条路,在网站上收加密货币的其他做法讲的是其余几条。不管店铺走哪一条,它的凭据都该从那里开始,而不是从一个已经跑过好几个地方的文件里开始。

支付插件需要的凭据,分别从哪里来(2026年8月)
凭据是否写在下载包里不在包里的话从哪来
API key没有连接那一步配好,沙盒和正式一起
API secret没有连接那一步配好,在店铺侧加密存储
项目 ID没有按控制台里打开的项目绑定,插件里不选
webhook secret没有随平台注册的 webhook 一起生成
OAuth 令牌或设备码没有短时有效,连接过程中用掉即丢弃

常见问题

Paymos 插件下载包里有我的 API key 吗?

没有。压缩包里不含 API key、API secret、项目 ID、webhook secret、OAuth 令牌 或设备码。这些是在连接店铺之后,由一次授权配好的。

装完插件之后我要配置什么?

什么都不用配。连接就是店铺后台里的一个按钮,加上在 Paymos 标签页里点一次确认; 密钥、webhook 和项目绑定都在这一步里完成。

每个商户拿到的插件文件不一样吗?

一样。下载的包对每个商户都是同一个,所以同一个版本下载两次,字节相同,校验和 也相同。

装好之后,Paymos 插件把凭据存在哪里?

存在店铺自己这一侧,加密保存,并且不会返回给浏览器。凭据跟着店铺走,不在分发 的压缩包里,所以换一个压缩包不会搬动任何一份凭据。

怎么检查一个插件包里有没有凭据?

把压缩包解开,搜一遍像凭据的字符串,再对文件做一次哈希,和同一版本的第二次 下载比对。结果里出现字段名是正常的,出现真实值不正常;测试目录下的命中是 测试数据。

下载插件会把我的店铺连上 Paymos 吗?

不会。下载只搬运代码。店铺是在另一个步骤里连接的,由店铺后台发起的一次授权 完成。

插件最后手里拿着哪一种凭据?

一份收款凭据,在连接时从商户当前生效的收款密钥推导,没有就新建一个。收款和 转出是两套凭据,所以插件从来不会拿到那把能把钱转走的。

什么时候不该用翻查安装包这件事

  • 如果你的问题是店铺装好之后怎么保管这把密钥,翻压缩包回答不了。一个不含凭据的 文件说明不了存储方式,去读插件的凭据存储文档。
  • 如果接入的是你自己写的 REST API 代码,不是打包的插件,那就没有压缩包可查。 该审的是部署路径:环境变量、CI 变量、配置文件。
  • 如果你要的是一份连服务器自己都读不回来的凭据,跑在自己主机上的插件不是该找的 地方。店铺能递给 API 的东西,店铺就能保存;真正管用的是密钥外面的控制,比如 IP 白名单。
  • 如果这家网关根本不提供下载,扩展是从它自己的后台装进去的,校验和这一步没有可 比对的对象。那就问清凭据被写到哪里,以及还有谁能读到那个位置。

参考来源

  1. 1. CWE-798: Use of Hard-coded Credentials (accessed 2026-08-16)
  2. 2. OWASP Secrets Management Cheat Sheet (accessed 2026-08-16)
  3. 3. WordPress Plugin Directory guidelines (accessed 2026-08-16)
  4. 4. Paymos 文档 — WooCommerce 插件 (accessed 2026-08-16)

最近复核:2026年8月16日

#cms-插件#api-密钥#插件安全#凭据存储
分享