error-handling - Stripe webhook 失败 - Webhook 错误:504
问题描述
Stripe webhook 失败,我认为这是因为 Stripe 没有从我的 webhook api 端点收到“成功”响应。
错误是:
Test webhook error: 504
An error occurred with your deployment
FUNCTION_INVOCATION_TIMEOUT
我使用 Nextjs 及其在 pages/api/createOrder 文件夹结构中构建来创建 api。这就是我的 createOrder webhook 的样子:
import { buffer } from "micro"
const AWS = require("aws-sdk")
AWS.config.update({
accessKeyId: process.env.MY_AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.MY_AWS_SECRET_ACCESS_KEY,
region: process.env.MY_AWS_REGION,
endpoint: process.env.MY_AWS_ENDPOINT,
})
// Establish Stripe connection
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY)
const endpointSecret = process.env.STRIPE_CREATE_ORDER_SIGNING_SECRET
const createOrder = async session => {
console.log("create order - session.id: ", session.id)
console.log(
"create order - session.metadata.userID: ",
session.metadata.userID
)
console.log(
"create order - session.amount_total / 100: ",
session.amount_total / 100
)
const docClient = new AWS.DynamoDB.DocumentClient()
let date = new Date()
// create Order
let orderParams = {
TableName: process.env.ORDER_TABLE_NAME,
Item: {
id: session.id,
userID: session.metadata.userID,
amount: session.amount_total / 100,
adID: session.metadata.adID,
createdAt: date.toISOString(),
updatedAt: date.toISOString(),
},
}
docClient.put(orderParams, function (err, data) {
if (err) {
console.log("Order put err - " + JSON.stringify(err, null, 2))
} else {
console.log("Order put Success - " + JSON.stringify(data, null, 2))
}
})
// create - TTL
const ninetyDays = 1000 * 60 * 60 * 24 * 90
const currTime = Date.now()
const ttlSeconds = Math.ceil((ninetyDays + currTime) / 1000)
// update Ad
let adParams = {
TableName: process.env.AD_TABLE_NAME,
Key: { id: session.metadata.adID },
UpdateExpression: "set paid = :paid, expdate = :expdate",
ExpressionAttributeValues: {
":paid": true,
":expdate": ttlSeconds,
},
ReturnValues: "UPDATED_NEW",
}
docClient.update(adParams, function (err, data) {
if (err) {
console.log("UPDATE Ad err - " + JSON.stringify(err, null, 2))
} else {
console.log("UPDATE Ad Success - " + JSON.stringify(data, null, 2))
}
})
}
export default async (req, res) => {
if (req.method === "POST") {
const requestBuffer = await buffer(req)
const payload = requestBuffer.toString()
const sig = req.headers["stripe-signature"]
let event
// Verify that the EVENT posted came from stripe
try {
event = stripe.webhooks.constructEvent(payload, sig, endpointSecret)
} catch (err) {
console.log("ERROR", err.message)
return res.status(400).send(`Webhook create Order error: ${err.message}`)
}
// Handle the checkout.session.completed event
if (event.type === "checkout.session.completed") {
const session = event.data.object
// Fulfill update Ad -> paid = true and ttl - expdate
return createOrder(session)
.then(() => res.status(200))
.catch(err =>
res.status(400).send(`Create Order Error - ${err.message}`)
)
}
}
// Notify Stripe that req reached api
res.status(200).json({ received: true })
}
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
}
我找到了一些解决方案来告诉 Stripe 已收到 webhook 调用,但它们都不起作用。现在我正在使用:
res.status(200).json({ received: true })
也许问题出在其他地方?我想指出 Order 已创建并且 Ad 已更新 - 因此 webhook 可以按预期工作,只是它失败了。
解决方案
经过2个月的调试,我找到了解决方案。
我认为问题在于 AWS 似乎很慢。我添加了 setTimeout 来通知 Stripe 连接成功并且它现在可以工作了!
setTimeout(() => {
// 3. Notify Stripe that event recieved.
res.json({ received: true })
}, 2000)
如果 some1 有更好的解决方案请告诉我们:)
推荐阅读
- react-native - WebView 不在摩托罗拉 G5 和 G6 上渲染大型内联 html,但适用于 iOS 和其他 Android 手机。有人遇到过这个问题吗?
- jsf - 在 p:dataTable 上使用自定义全局过滤器
- xml - 寻找黑板测验文件的文件格式
- command-line - 让 drush 和 composer 在 Visual Studio Code 终端中工作
- excel - Excel::Writer::XLSX 写入无格式日期
- java - 使用 $in Mongodb - Java 进行不区分大小写的搜索
- hp-uft - UFT OTA - 获取复制的测试集文件夹的 ID
- java - 如何为 try & catch 实现指数延迟/睡眠
- css - 如何独立于其他列或行关注一列
- python - 来自 setup.py 的 dh_python2 版本化依赖项