生产环境调用Stripe create-checkout-session返回400错误本地运行正常
问题根因
你遇到的问题是生产环境IIS + iisnode托管时,Express的JSON请求体解析异常,导致传入Stripe的参数被错误转换/丢失,核心有两个触发点:
- 从Stripe日志可看到所有数组类型参数都被转成了索引为键的对象(比如
payment_method_types本来是数组,变成了{"0": "card", "1": "sepa_debit"}格式),line_items属于复杂数组结构,直接在解析阶段丢失 - 本地运行时Node直接接收请求不会触发该问题,IIS默认的请求过滤/参数转换会修改POST请求体,和Express的JSON解析中间件配置不匹配时就会出现参数丢失
解决方案
按优先级依次排查验证:
- 调整Express的JSON解析中间件配置
确保你在所有路由注册前就启用了JSON解析,同时配置足够大的请求体限制,避免iisnode默认截断超出大小的请求体:
// 必须放在所有路由注册之前,不要放在路由定义之后 app.use(express.json({ limit: '1mb' }));
- 修改iisnode对应的web.config配置
禁用IIS默认的请求体解析逻辑,把原始请求体直接转发给Node进程:
<configuration> <system.webServer> <handlers> <add name="iisnode" path="你的入口文件.js" verb="*" modules="iisnode" /> </handlers> <iisnode enableXFF="true" promoteServerVars="HTTP_*" /> <security> <requestFiltering> <requestLimits maxAllowedContentLength="1048576" /> </requestFiltering> </security> <httpErrors existingResponse="PassThrough" /> </system.webServer> </configuration>
- 添加日志验证参数完整性
在调用Stripe接口前打印完整参数,确认生产环境下line_items是否正常存在:
app.post('/create-checkout-session', async (req, res) => { const cartData = req.body // 加这行日志,后续去iisnode的日志目录查看输出即可确认参数是否丢失 console.log('传入Stripe的完整参数:', JSON.stringify({ payment_method_types: ['card', 'sepa_debit'], shipping_rates: ['shr_1Jmh85AuqIBxGbL5Z7JbTJaV'], shipping_address_collection: { allowed_countries: ['FI'] }, line_items: [{ price_data: { currency: "eur", product_data: { name: "Product 1", description: "Further info here" }, unit_amount: 6800 }, quantity: 2 }], phone_number_collection: { enabled: true }, mode: 'payment', success_url: `${stripeUrl}/myynti/success?true&session_id={CHECKOUT_SESSION_ID}`, cancel_url: `${stripeUrl}/myynti/cancel` })) try { // 原有Stripe调用逻辑 } catch (e) { // 原有错误处理逻辑 } });
内容的提问来源于stack exchange,提问作者M.Y.
相关产品推荐
相关产品推荐

