向Stripe发送JSON对象请求时返回未知参数错误如何解决
错误原因
- 请求头与请求体格式不匹配:代码中设置
Content-Type为application/x-www-form-urlencoded,但实际提交的是JSON.stringify序列化后的JSON字符串,Stripe服务端无法正确解析参数,会把整个JSON串识别为一个未知的参数名,直接触发parameter_unknown报错。 - 异步逻辑未等待执行:handler函数标记了
async但未对fetch请求加await,函数会在fetch请求完成前就执行结束,导致出现API resolved without sending a response的警告,同时try/catch也无法捕获fetch链路抛出的错误。 - 冗余实现逻辑:已经引入官方Stripe SDK的前提下,完全不需要手动封装fetch请求调用Stripe接口,官方SDK已经处理了鉴权、参数序列化、错误捕获等逻辑,手写fetch反而容易出现格式错误。
修复方案
最优方案:使用Stripe官方SDK调用接口
直接用已经初始化的stripe实例调用对应方法,不需要手写fetch,代码更简洁也不会出现格式错误:
import Stripe from 'stripe'; import { NextApiRequest, NextApiResponse } from 'next'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: '2020-08-27' }); export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === 'POST') { try { // 直接调用sdk的products.create方法,参数直接传对象即可,sdk会自动处理序列化 const product = await stripe.products.create({ name: req.body.name }); res.status(200).json(product); } catch (err) { res.status(err.statusCode || 500).json(err.message); } } else { res.setHeader('Allow', 'POST'); res.status(405).end('Method Not Allowed'); } }
若坚持使用fetch调用的修复方案
如果一定要手动写fetch,需要修改两个点:把Content-Type改成和请求体匹配的application/json,同时给fetch加await保证异步逻辑执行顺序:
import Stripe from 'stripe'; import { NextApiRequest, NextApiResponse } from 'next'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: '2020-08-27' }); export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === 'POST') { try { const name = { name: req.body.name }; // 加await,让异步逻辑等待执行完成 const response = await fetch(`${process.env.BASE_URL}/v1/products`, { method: 'POST', body: JSON.stringify(name), headers: { 'Accept': 'application/json', // 修正Content-Type和请求体格式匹配 "Content-Type": 'application/json', Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`, } }); const data = await response.json(); console.log(data); res.status(200).json(data); } catch (err) { res.status(err.statusCode || 500).json(err.message); } } else { res.setHeader('Allow', 'POST'); res.status(405).end('Method Not Allowed'); } }
内容的提问来源于stack exchange,提问作者Arturs Radionovs
相关产品推荐
相关产品推荐

