使用Firebase Functions创建Stripe Ephemeral Key时遇内部错误排查
问题场景
我按照教程使用firebase-functions创建Stripe Ephemeral Key,对应的Node.js代码如下:
exports.createEphemeralKey = functions.https.onCall(async (data, context) => { const customerId = data.customer_id; const stripeVersion = data.stripe_version; const uid = context.auth.uid; if (uid === null) { console.log('Illegal access attempt due to unauthenticated attempt.') throw new functions.https.HttpsError('internal', 'Illegal access attempt'); } return stripe.ephemeralKeys.create( { customer: customerId }, { stripe_version: stripeVersion } ).then((key) => { return key }).catch( (err) => { functions.logger.log('Error creating ephemeral key', err) throw new functions.https.HttpsError('internal', 'Unable to create ephemeral key: ' + err) }); });
运行后Xcode立即报错:
Error Domain=com.firebase.functions Code=13 "INTERNAL" UserInfo={NSLocalizedDescription=INTERNAL}
点击「管理我的信用卡」触发Stripe Payment Sheet时,页面一直显示「Loading...」无法加载。已验证Swift代码无问题,customerID通过Xcode打印确认正常,怀疑是stripeVersion或其他后端问题导致。
排查修复方案
检查Stripe版本兼容性:
前端传递的stripe_version必须与后端Stripe SDK版本兼容。Stripe临时密钥要求客户端SDK版本和服务端API版本匹配,比如前端用Stripe iOS SDK v23.0.0时,对应API版本通常是2023-10-16。可以在Stripe控制台查看账号默认API版本,或者在后端初始化Stripe时显式指定兼容版本:const stripe = require('stripe')('你的API密钥', { apiVersion: '2023-10-16', // 与前端SDK匹配的版本 });完善错误日志定位问题:
当前日志仅打印错误对象,建议输出更详细的错误信息,方便排查具体原因:.catch( (err) => { functions.logger.error('创建临时密钥失败', { errorMsg: err.message, errorType: err.type, rawError: err.raw, stripeVersion, customerId }); throw new functions.https.HttpsError('internal', '无法创建临时密钥'); });之后去Firebase控制台的Functions日志中查看完整错误详情,比如版本不兼容、customerId权限问题、API密钥权限不足等。
验证Stripe API密钥权限:
确认初始化Stripe用的sk_开头密钥拥有创建临时密钥的权限,确保密钥处于活跃状态且未被限制权限。简化代码逻辑:
统一使用async/await写法,代码更清晰且便于排查:exports.createEphemeralKey = functions.https.onCall(async (data, context) => { const customerId = data.customer_id; const stripeVersion = data.stripe_version; const uid = context.auth.uid; if (!uid) { functions.logger.warn('未授权访问尝试'); throw new functions.https.HttpsError('unauthenticated', '请先登录'); } try { const key = await stripe.ephemeralKeys.create( { customer: customerId }, { stripe_version: stripeVersion } ); return key; } catch (err) { functions.logger.error('创建临时密钥失败', { err, stripeVersion, customerId }); throw new functions.https.HttpsError('internal', '无法创建临时密钥'); } });这里将未授权错误的类型改为
unauthenticated,更符合Firebase的错误规范。
内容的提问来源于stack exchange,提问作者iosBeginner Guy

