使用node-fetch生成Apple Pay PaymentSession时证书报错问题
解决Apple Pay Payment Session请求的证书相关错误
问题分析与分步解决
1. 解决PEM格式错误(ERR_OSSL_PEM_NO_START_LINE)
你已经通过openssl x509 -inform der -in merchant_id.cer -out merchant_id.pem将DER格式证书转成了PEM,但代码里仍然在读取原有的merchant_id.cer文件,这是导致格式错误的核心原因。Node.js的https.Agent要求cert参数必须是PEM格式的文本内容,所以需要修改代码中的证书路径。
2. 解决SSL证书要求错误(ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED)
Apple Pay的Payment Session接口要求双向TLS认证,你只提供了证书,没有配置对应的私钥。Apple网关需要验证你的身份,必须同时提供证书和匹配的私钥才能通过认证。
修正后的代码
import express from "express" import fs from "fs" import fetch from "node-fetch" import https from "https" const app = express() app.get('/', function (req, res) { const html = fs.readFileSync('index.html', 'utf8') res.send(html) }) app.get('/paymentSession', async function(req, res) { const httpsAgent = new https.Agent({ // 生产环境请移除该配置,确保证书链有效 rejectUnauthorized: false, cert: fs.readFileSync('merchant_id.pem', 'utf8'), // 改为转换后的PEM证书 key: fs.readFileSync('merchant_id.key', 'utf8') // 添加对应的私钥文件 }) try { const response = await fetch('https://apple-pay-gateway.apple.com/paymentservices/paymentSession', { method: 'POST', headers: { 'content-type': 'application/json' }, agent: httpsAgent, body: JSON.stringify({ merchantIdentifier: 'merchant.com.xxx.xxx', displayName: 'xxx', initiative: 'web', initiativeContext: 'xxx.com' // 确保是不带http/https的域名 }) }) console.log('响应状态:', response.status) const text = await response.text() console.log('响应内容:', text) res.json({ status: response.status, data: text }) } catch (err) { console.error('请求失败:', err) res.status(500).json({ error: err.message }) } }) app.listen(3000, () => { console.log('服务运行在http://localhost:3000') })
关键注意事项
- 私钥获取:
merchant_id.key是你当初生成CSR(证书签名请求)时本地保存的私钥文件。如果你的私钥是PKCS#12格式(.p12文件),需要用以下命令转成PEM格式:openssl pkcs12 -in merchant_id.p12 -nocerts -out merchant_id.key -nodes - 证书匹配:确保
merchant_id.pem和merchant_id.key是一一对应的,证书是用该私钥生成的CSR向Apple申请的。 - 参数验证:
merchantIdentifier必须与Apple开发者后台配置的商户ID完全一致;initiativeContext必须是你的网站域名(不能包含http://或https://)。 - 生产环境配置:移除
rejectUnauthorized: false,确保你的服务器信任Apple的根证书,避免安全风险。
内容的提问来源于stack exchange,提问作者Ajouve
相关产品推荐
相关产品推荐

