Node.js集成Stripe支付时出现await语法错误求助
解决"await is only valid in async function"错误及Stripe示例代码修复
错误原因
await关键字只能在标记为async的函数内部使用,你写的const calculation = await stripe.tax.calculations.create({...})直接放在全局作用域里,不属于任何async函数,所以Node.js会抛出该错误。
修复你的server.js代码
场景1:每次创建Payment Intent时计算税费(推荐)
税费计算通常和具体支付请求绑定,把计算逻辑放到/prepare-payment-sheet的async路由处理函数里,能保证每次请求生成对应税费结果并传入Payment Intent:
const stripe = require('stripe')('sk_test_', { apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;' }); const express = require('express'); const app = express(); app.use(express.json()); app.post('/prepare-payment-sheet', async (req, res) => { try { // 1. 生成税费计算结果 const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_99999999', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }); // 2. 创建客户、临时密钥和支付意向 const customer = await stripe.customers.create(); const ephemeralKey = await stripe.ephemeralKeys.create( { customer: customer.id }, { apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;' } ); const paymentIntent = await stripe.paymentIntents.create({ amount: 1099, currency: 'usd', customer: customer.id, automatic_payment_methods: { enabled: true, }, async_workflows: { inputs: { tax: { calculation: calculation.id, // 使用实际生成的税费计算ID }, }, }, }); console.log(req.body) console.log(paymentIntent) // 修复res.body不存在的错误,改为打印支付意向信息 res.json({ paymentIntentID: paymentIntent.id, clientSecret: paymentIntent.client_secret, ephemeralKey: ephemeralKey.secret, customer: customer.id, publishableKey: 'pk_test_' }); } catch(e) { res.status(400).json({ error: { message: e.message }}); } }); app.post('/update-payment-sheet', async (req, res) => { try { const paymentIntent = await stripe.paymentIntents.update( req.body.paymentIntentID, { amount: req.body.amount, } ); console.log(req.body) console.log(paymentIntent) res.json({}); } catch(e) { res.status(400).json({ error: { message: e.message }}); } }); app.listen(3000, () => console.log('Running now on port 3000')); app.get('/', (req,res) => res.json('My API is running'))
额外说明:
- 初始化Stripe时添加了beta版本API参数,确保和后续接口调用版本一致
- 替换了占位符
{{CALCULATION_ID}}为实际生成的calculation.id - 给
/update-payment-sheet添加了try-catch,避免未捕获异常导致服务器崩溃
场景2:全局初始化时计算税费(仅测试用)
如果只是测试需求,想在服务启动时生成一次税费计算ID,可以用自执行async函数包裹全局逻辑:
const stripe = require('stripe')('sk_test_', { apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;' }); const express = require('express'); const app = express(); app.use(express.json()); // 自执行async函数处理全局await逻辑 (async () => { try { const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_99999999', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }); global.calculationId = calculation.id; // 存到全局变量后续使用 console.log('税费计算ID:', calculation.id); } catch(e) { console.error('全局税费计算失败:', e.message); } })(); // 后续路由中可通过global.calculationId替换{{CALCULATION_ID}} // ... 其余路由代码不变
修复Stripe官网示例代码
官网示例同样把await用在了全局作用域,只需用自执行async函数包裹即可:
// Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')( 'sk_test_', {apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;'} ); // 自执行async函数包裹逻辑 (async () => { try { const paymentIntent = await stripe.paymentIntents.create({ amount: 1000, currency: 'usd', automatic_payment_methods: { enabled: true, }, async_workflows: { inputs: { tax: { calculation: '{{CALCULATION_ID}}', // 替换为实际税费计算ID }, }, }, }); console.log('支付意向ID:', paymentIntent.id); } catch(e) { console.error('创建支付意向失败:', e.message); } })();
内容的提问来源于stack exchange,提问作者user1233894
相关产品推荐
相关产品推荐

