电脑网站支付沙盒环境报错 missing-signature-config 如何解决?
结论
missing-signature-config 表示支付请求指定了某种签名算法,例如 RSA2,但沙盒应用后台没有配置与之匹配的应用公钥或应用公钥证书。
请确保以下三处配置一致:
- 请求中的
app_id属于当前沙盒应用; - 程序使用应用私钥生成签名;
- 沙盒应用后台保存了与该私钥配对的应用公钥,并且
sign_type与后台配置一致。
最常见的正确组合是:应用后台配置 RSA2 应用公钥,代码配置对应的 RSA2 应用私钥,请求参数使用 sign_type=RSA2。
错误原因
支付宝会根据请求中的 app_id 和 sign_type 查找应用的验签配置。找不到对应的公钥或证书时,支付宝无法验证请求签名,因此返回:
missing-signature-config
应用未配置对应签名算法的公钥或者证书
常见原因有:
- 只在本地生成了密钥,没有将应用公钥配置到沙盒应用后台;
- 后台配置的是 RSA,请求使用的却是
RSA2,或反过来; - 程序使用了另一套应用私钥,与后台保存的应用公钥不匹配;
- 使用正式环境应用的
app_id请求沙盒网关; - 将支付宝公钥误当成应用公钥上传;
- 代码启用了证书模式,后台却没有配置对应的应用公钥证书;
- 密钥配置已经修改,但程序仍在读取旧配置或旧密钥文件。
还要分清三种密钥的用途:
- 应用私钥:保存在商户服务器中,用来对请求签名,不能上传或泄露。
- 应用公钥:配置到支付宝开放平台,供支付宝验证商户请求。
- 支付宝公钥:配置在商户程序中,用来验证支付宝返回的数据和异步通知。
解决步骤
1. 确认使用的是沙盒应用和沙盒网关
检查代码中的 app_id,确认它是当前沙盒应用的 App ID,而不是正式应用的 App ID。
沙盒网关通常配置为:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
具体地址以当前支付宝开放平台沙盒页面及所用 SDK 的说明为准。
2. 生成一对应用密钥
建议使用支付宝开放平台提供的密钥工具生成 RSA2 密钥。生成后会得到:
应用私钥
应用公钥
两者必须由同一次操作生成,组成完整的一对密钥。
如果使用 OpenSSL 自行生成密钥,需要确认密钥格式符合 SDK 的要求。例如,下面的命令会生成一个 2048 位 RSA 私钥及其公钥:
openssl genrsa -out app_private_key.pem 2048
openssl rsa -in app_private_key.pem -pubout -out app_public_key.pem
不同语言的 SDK 对 PKCS#1、PKCS#8 和 PEM 头尾的要求可能不同,不能只通过文件扩展名判断格式。
3. 将应用公钥配置到沙盒应用
进入支付宝开放平台中的对应沙盒应用,在开发设置或接口加签方式中配置应用公钥。控制台调整后,入口名称可能发生变化,请确认当前操作的是正确的沙盒应用。
选择与代码一致的签名方式,通常为:
RSA2
然后填写或上传刚生成的应用公钥。
此处需要配置的是:
应用公钥
不要上传应用私钥,也不要将支付宝公钥填到应用公钥的位置。
保存成功后,平台通常会提供或显示支付宝公钥。将它保存到程序配置中,用于验签。
4. 检查程序中的签名配置
以 Java SDK 的普通公钥模式为例:
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do"
);
alipayConfig.setAppId("沙盒应用APP_ID");
alipayConfig.setPrivateKey("应用私钥");
alipayConfig.setFormat("json");
alipayConfig.setCharset("UTF-8");
alipayConfig.setAlipayPublicKey("沙盒环境对应的支付宝公钥");
alipayConfig.setSignType("RSA2");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
发起电脑网站支付请求时:
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl("https://example.com/alipay/return");
request.setNotifyUrl("https://example.com/alipay/notify");
request.setBizContent("""
{
"out_trade_no": "ORDER_202609130001",
"total_amount": "0.01",
"subject": "沙盒支付测试",
"product_code": "FAST_INSTANT_TRADE_PAY"
}
""");
AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
if (response.isSuccess()) {
String paymentForm = response.getBody();
} else {
System.out.println(response.getCode());
System.out.println(response.getSubCode());
System.out.println(response.getSubMsg());
}
如果使用旧版 Java SDK 的构造方式,配置原则不变:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do",
"沙盒应用APP_ID",
"应用私钥",
"json",
"UTF-8",
"沙盒环境对应的支付宝公钥",
"RSA2"
);
不同 SDK 版本的类名和初始化方式可能不同,请以项目实际依赖的版本为准。
5. 验证公私钥是否匹配
如果后台已经配置应用公钥,但错误依然存在,应重点检查代码中的应用私钥是否与该公钥配对。
可以通过 OpenSSL 从私钥中提取公钥:
openssl rsa \
-in app_private_key.pem \
-pubout \
-out public_key_from_private.pem
再将 public_key_from_private.pem 与后台配置的应用公钥进行比较。比较时可以忽略 PEM 头尾和换行,但 Base64 主体必须一致。
6. 重新加载配置后再测试
更换密钥后,要确认正在运行的应用已经加载新配置。必要时重启应用,并检查:
- 环境变量是否已经更新;
- 配置中心是否仍保存着旧私钥;
- 容器或服务器是否挂载了旧密钥文件;
- 是否存在多套沙盒配置,导致程序读取了错误的一套;
- 请求中的
app_id和sign_type是否与预期一致。
使用证书模式时怎么处理
如果项目明确使用证书模式,代码通常需要配置:
- 应用私钥;
- 应用公钥证书;
- 支付宝公钥证书;
- 支付宝根证书。
Java SDK 的配置形式通常如下:
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do"
);
alipayConfig.setAppId("沙盒应用APP_ID");
alipayConfig.setPrivateKey("应用私钥");
alipayConfig.setFormat("json");
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
alipayConfig.setAppCertPath("/path/to/appCertPublicKey.crt");
alipayConfig.setAlipayPublicCertPath("/path/to/alipayCertPublicKey_RSA2.crt");
alipayConfig.setRootCertPath("/path/to/alipayRootCert.crt");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
证书模式除了要在代码中配置证书文件路径,还需要在开放平台完成相应的证书签名配置。沙盒是否支持项目所需的证书接入方式,以当前沙盒控制台提供的选项为准。
如果项目原本采用普通公钥模式,不必为了处理这个错误而混用证书配置。选择一种模式,并确保后台和代码的配置一致即可。
排查清单
重新发起支付前,可以逐项检查:
app_id是沙盒应用的 App ID;- 请求发送到沙盒网关;
- 后台配置的是应用公钥,不是支付宝公钥;
- 代码保存的是应用私钥,不是应用公钥;
- 应用公钥和应用私钥属于同一对密钥;
- 后台签名方式与代码中的
RSA2一致; - 没有混用普通公钥模式和证书模式;
- 配置修改后,运行中的程序已经重新加载;
- 没有交叉使用正式环境和沙盒环境的密钥。
完成这些配置后,支付宝就能根据 app_id 找到 RSA2 对应的验签材料,missing-signature-config 错误通常会随之消失。如果问题仍然存在,请记录实际请求中的 app_id、sign_type、网关地址和支付宝返回的完整错误信息,同时注意不要在日志或工单中暴露应用私钥。
备注:内容仅供参考。