Stripe支付初始化失败求助:StripeInvalidRequestError报错排查
环境信息
- Node.js版本:v18.7.0
- NPM版本:8.4.1
后端代码(Stripe_api.js)
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); export default async (req, res) => { const { items, email } = req.body; const transformedItems = items.map(item => ({ description: item.description, quantity: 1, price_data: { currency: 'GBP', unit_amount: item.price * 100, product_data: { name: item.title, images:[item.image] } }, })); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], shipping_rates: ['shr_1Lo5yeSJ4Tf************'], shipping_address_collection: { allowed_countries: ['GB', 'US', 'CA'], }, line_items: transformedItems, mode: 'payment', success_url: `${process.env.HOST}/success`, cancel_url: `${process.env.HOST}/checkout`, metadata: { email, images: JSON.stringify(items.map((item)=> item.image)) }, }); res.status(200).json({ id: session.id}); };
前端代码(checkout.js)
function Checkout() { const items = useSelector(selectItems); const total = useSelector(selectTotal); const [session] = useSession(); const createCheckoutSession = async() => { const stripe = await stripePromise; //checkout session const checkoutSession = await axios.post( '/api/Stripe/create-checkout-session', { items: items, email: session.user.email, } ); const result = await stripe.redirectToCheckout({ sessionId: checkoutSession.data.id, }); if (result.error) { alert(result.error.message); } } return ( <div className="bg-gray-100"> <Header /> <main className="lg:flex max-w-screen-2xl mx-auto"> {/* Left*/} <div> <div className="flex flex-col p-5 space-y-10 bg-white"> <h1 className="text-3xl border-b pb-4"> {items.length === 0 ? "Your Amazon Basket is empty" : "Shopping Basket"} </h1> {items.map((item, i) => ( <CheckoutProduct key={i} id={item.id} title={item.title} rating={item.rating} price={item.price} description={item.description} category={item.category} image={item.image} hasPrime={item.hasPrime} /> ))} </div> </div> <div> {items.length > 0 && ( <> <h2 className="whitespace-nowrap"> Subtotal ({items.length} items): <span className="font-bold"> <Currency quantity={total} currency="GBP" /> </span> </h2> <button role="link" onClick = {createCheckoutSession} disabled={!session} className={`button mt-2 ${! !session && "from-gray-300 to-gray-500 border-gray-200 text-gray-300 cursor-not-allowed" }`} > {!session ? "Sign in to checkout" : "Proceed to checkout"} </button> </> )} </div> </main> </div> ); } export default Checkout;
验证通过的Items数据
[{ id: 2, title: 'Mens Casual Premium Slim Fit T-Shirts ', price: 22.3, description: 'Slim-fitting style, contrast raglan long sleeve, three-button henley placket, light weight & soft fabric for breathable and comfortable wearing. And Solid stitched shirts with round neck made for durability and a great fit for casual fashion wear and diehard baseball fans. The Henley style round neckline includes a three-button placket.', category: "men's clothing", image: 'https://****/****/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg', hasPrime: false }]
触发的报错信息
StripeInvalidRequestError: 当前API版本不允许使用
line_items.amount、line_items.currency、line_items.name、line_items.description或line_items.images字段,请使用line_items.price或line_items.price_data。错误堆栈:
at StripeError.generate (C:\Users\shikshgu\shopping site\Amazon\node_modules\stripe\lib\Error.js:36:16)
at res.toJSON.then.StripeAPIError.message (C:\Users\shikshgu\shopping site\Amazon\node_modules\stripe\lib\StripeResource.js:201:35)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)错误详情:
type: 'StripeInvalidRequestError',
raw: {
message: '当前API版本不允许使用line_items.amount、line_items.currency、line_items.name、line_items.description或line_items.images字段,请使用line_items.price或line_items.price_data。',
type: 'invalid_request_error',
headers: {
server: 'nginx',
date: 'Sat, 15 Oct 2022 06:28:18 GMT',
'content-type': 'application/json',
'content-length': '470',
connection: 'keep-alive',
'access-control-allow-credentials': 'true',
'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE',
'access-control-allow-origin': '*',
'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
'access-control-max-age': '300',
'cache-control': 'no-cache, no-store',
'idempotency-key': '849332d0-1d08-4052-bc3a-3c92b503d4cd',
'original-request': 'req_28SN2DhsGvhHVF',
'request-id': 'req_28SN2DhsGvhHVF',
'stripe-should-retry': 'false',
'stripe-version': '2022-08-01',
'strict-transport-security': 'max-age=63072000; includeSubDomains; preload'
},
statusCode: 400,
requestId: 'req_28SN2DhsGvhHVF'
},
rawType: 'invalid_request_error',
code: undefined,
doc_url: undefined
问题原因与修复方案
问题原因
你已经使用了price_data字段,但错误地将description放在了line_item的根层级。在Stripe API 2022-08-01版本中,line_items的根层级不允许直接设置description,必须将其移到price_data.product_data内部。
修复代码
修改后端transformedItems的映射逻辑,把description从根层级移到product_data中:
const transformedItems = items.map(item => ({ quantity: 1, price_data: { currency: 'GBP', unit_amount: item.price * 100, product_data: { name: item.title, description: item.description, // 移到这里 images:[item.image] } }, }));
这样修改后,就符合Stripe当前API版本的要求,不会再触发该错误。
内容的提问来源于stack exchange,提问作者Shikshit

