H5支付宝手机网站支付如何更换商户号及生成.pem文件
结论
只替换 APPID 通常无法完成商户切换。还要更换新应用对应的商户私钥、支付宝公钥或应用证书,并确认新商户下的应用已经开通”手机网站支付”能力。
ali_private_key.pem 不是从支付宝下载的,而是由商户在本地生成并妥善保管。由该私钥导出的应用公钥需要配置到支付宝开放平台。如果项目采用证书模式,还要为新应用重新申请应用公钥证书,同时替换支付宝公钥证书和支付宝根证书。
.pem 文件名并非支付宝的统一规范,不能只凭文件名判断用途。应先检查支付配置和 SDK 初始化代码,确认项目使用的是”普通公钥模式”还是”证书模式”。
先确认当前使用的密钥模式
先找到支付宝客户端的初始化位置。
如果配置中包含以下字段,通常使用的是普通公钥模式:
app_id
merchant_private_key
alipay_public_key
sign_type
gateway_url
如果包含以下字段,通常使用的是证书模式:
app_id
merchant_private_key
app_cert_path
alipay_cert_path
alipay_root_cert_path
部分旧项目的字段或文件名称可能不同,例如:
ali_private_key.pem
ali_public_key.pem
alipay_public_key.pem
cacert.pem
文件可以自行命名。判断其用途,要看代码将文件内容传给了哪个配置项,不要看到四个 .pem 文件就直接逐一覆盖。
普通公钥模式如何更换
普通公钥模式涉及以下密钥:
- 商户应用私钥:保存在服务器上,用于为支付请求签名。
- 商户应用公钥:由私钥导出,配置到支付宝开放平台。
- 支付宝公钥:从支付宝开放平台获取,保存在服务器上,用于验证支付宝响应和异步通知的签名。
切换步骤如下:
- 登录新商户对应的支付宝开放平台账号。
- 确认目标应用的
APPID,并检查该应用是否已开通手机网站支付能力。 - 在安全的本地环境中生成新的 RSA2 密钥对。
- 将生成的应用公钥配置到新应用的接口加签方式中。
- 从开放平台取得与该应用匹配的支付宝公钥。
- 替换服务器上的商户私钥和支付宝公钥。
- 修改
APPID,以及项目中可能存在的seller_id、PID 等商户标识。 - 使用新商户测试下单、同步跳转和异步通知验签。
生成 ali_private_key.pem
建议使用支付宝开放平台提供的密钥工具生成 RSA2 密钥。工具会生成应用私钥和应用公钥,其中应用私钥用于服务器签名,可以保存为 ali_private_key.pem,但文件名并非强制要求。
也可以使用 OpenSSL。以下命令会生成一把 2048 位 RSA 私钥:
openssl genrsa -out ali_private_key.pem 2048
导出对应的公钥:
openssl rsa \
-in ali_private_key.pem \
-pubout \
-out ali_public_key.pem
三个文件或密钥的用途如下:
ali_private_key.pem -> 服务器保存,用于请求签名
ali_public_key.pem -> 配置到支付宝开放平台
支付宝公钥 -> 从开放平台获取,用于验签
上传到支付宝开放平台的是应用公钥,不是私钥。ali_private_key.pem 不得上传,也不能提交到公开代码仓库或发送给无关人员。
PKCS#1 与 PKCS#8 格式
不同语言、不同版本的支付宝 SDK 对私钥格式的要求可能不同。除了 .pem 后缀,还要检查文件头和 SDK 的配置说明。
PKCS#1 私钥通常以以下内容开头:
-----BEGIN RSA PRIVATE KEY-----
PKCS#8 私钥通常以以下内容开头:
-----BEGIN PRIVATE KEY-----
如果 SDK 要求使用 PKCS#8,可以执行以下转换:
openssl pkcs8 \
-topk8 \
-inform PEM \
-in ali_private_key.pem \
-outform PEM \
-nocrypt \
-out ali_private_key_pkcs8.pem
不要通过手工删除文件头、文件尾或换行来”转换格式”。有些 SDK 配置项要求填写不含 PEM 头尾的纯 Base64 内容,有些则支持完整的 PEM 文件,具体应以项目所用 SDK 的参数要求为准。
证书模式如何处理
如果代码中配置了应用证书、支付宝公钥证书和支付宝根证书,项目很可能使用的是证书模式。这种情况下,只生成普通 RSA 密钥对还不够。
证书模式一般需要:
- 商户应用私钥。
- 应用公钥证书。
- 支付宝公钥证书。
- 支付宝根证书。
典型配置如下:
<?php
$aop = new AopCertClient();
$aop->appId = '新应用APPID';
$aop->rsaPrivateKey = file_get_contents(
__DIR__ . '/cert/ali_private_key.pem'
);
$appCertPath = __DIR__ . '/cert/appCertPublicKey_新APPID.crt';
$alipayCertPath = __DIR__ . '/cert/alipayCertPublicKey_RSA2.crt';
$rootCertPath = __DIR__ . '/cert/alipayRootCert.crt';
$aop->appCertSN = $aop->getCertSN($appCertPath);
$aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
$aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);
$aop->signType = 'RSA2';
具体的类名和属性取决于项目使用的 SDK 版本,并非所有 PHP SDK 都采用完全相同的接口。
证书模式通常按以下步骤处理:
- 为新应用生成新的应用密钥。
- 按照支付宝开放平台的证书申请流程提交应用公钥或 CSR。
- 下载新应用的应用公钥证书。
- 下载对应的支付宝公钥证书和支付宝根证书。
- 替换项目中的证书文件。
- 重新计算证书序列号,或交由 SDK 自动计算。
- 使用新应用进行联调。
证书文件通常使用 .crt 后缀,但旧项目也可能把证书内容保存为 .pem 文件,所以仍要根据文件内容和代码用途判断。
普通公钥模式配置示例
以下只是结构示例,字段名称要与当前项目使用的 SDK 对应:
<?php
$config = [
'app_id' => '新应用APPID',
'sign_type' => 'RSA2',
'charset' => 'UTF-8',
'gateway_url' => 'https://openapi.alipay.com/gateway.do',
// 新商户应用私钥
'merchant_private_key' => file_get_contents(
__DIR__ . '/cert/ali_private_key.pem'
),
// 新应用安全配置页面显示的支付宝公钥
'alipay_public_key' => file_get_contents(
__DIR__ . '/cert/alipay_public_key.pem'
),
'return_url' => 'https://example.com/alipay/return',
'notify_url' => 'https://example.com/alipay/notify',
];
发起手机网站支付时,通常仍使用以下接口:
alipay.trade.wap.pay
如果旧代码中硬编码了商户标识,也要一并检查:
seller_id
pid
partner
app_id
较新的开放平台接口主要通过 APPID 标识应用,但旧接口或旧业务代码中可能仍保留 partner、PID 或 seller_id。这些值不能继续指向原商户。
异步通知验签也必须更换
商户切换后,支付通知验签很容易被遗漏。发起支付时已经使用新私钥,并不表示回调验签配置也已更新。
普通公钥模式应使用新应用对应的支付宝公钥验签:
<?php
$verified = $aop->rsaCheckV1(
$_POST,
$newAlipayPublicKey,
'RSA2'
);
if (!$verified) {
http_response_code(400);
exit('failure');
}
验签通过后,仍要核对以下字段:
app_id
out_trade_no
trade_no
total_amount
seller_id
trade_status
尤其要确认通知中的 app_id、金额和订单号与本地订单一致,不能只根据 trade_status 更新订单。
还需要检查的配置
除密钥外,至少还要检查以下事项:
- 新商户应用是否已经签约并开通手机网站支付。
- 应用是否处于可用状态,正式环境不能误用沙箱
APPID。 gateway_url是否与正式环境或沙箱环境匹配。sign_type是否统一为RSA2。notify_url和return_url是否仍然有效。- 域名、应用授权及相关产品配置是否需要在新应用下重新设置。
- 旧代码是否缓存了
APPID、私钥、支付宝公钥或证书序列号。 - Web 服务器或 PHP-FPM 等运行账户是否有权读取新密钥文件。
- 新私钥文件是否设置了严格的访问权限。
- 数据库或环境变量中是否仍保留旧商户的 PID、
seller_id、授权令牌等信息。 - 如果存在服务商代商户调用,还要检查
app_auth_token,不要混淆普通商户直连与第三方应用授权。
不建议直接沿用旧 .pem 文件
旧支付宝公钥通常对应旧应用的安全配置,继续使用往往会导致验签失败。旧商户私钥即使仍能读取,只要它与新应用中配置的应用公钥不匹配,请求签名就会失败。
只有明确掌握旧密钥的来源,确认新应用已经配置同一把应用公钥,并完成安全评估后,才可能复用原密钥。实际迁移时,为新应用生成独立密钥通常更稳妥。切换完成后,再安全归档或撤销旧密钥。
如果暂时无法确定四个 .pem 文件的用途,应从 SDK 初始化代码反向查找每个文件对应的配置项。只凭文件名替换风险较大。配置完成后,至少要验证支付下单、支付页面跳转、同步返回、异步通知验签、订单状态更新和退款等完整链路。
备注:内容仅供参考。
