#error-handling #next.js #timeout #stripe-payments
Вопрос:
Stripe webhook терпит неудачу, и я предполагаю, что это связано с тем, что Stripe не получает ответ «успешно» от моей конечной точки api webhook.
Ошибка заключается в:
Test webhook error: 504
An error occurred with your deployment
FUNCTION_INVOCATION_TIMEOUT
Я использую Nextjs и его сборку в структуре папок pages/api/CreateOrder для создания api. Вот как выглядит мой веб-крючок CreateOrder:
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,
},
}
Я нашел несколько решений, как сообщить полосе, что вызов webhook был получен, но ни одно из них не сработало. Прямо сейчас я использую:
res.status(200).json({ received: true })
Может быть, проблема кроется где-то в другом месте?
Я хочу отметить, что заказ создан и объявление обновлено — так что веб-крючок работает так, как ожидалось, за исключением того, что он выходит из строя.
Комментарии:
1. Сообщение об ошибке, по-видимому, связано с вызовом метода webhook. Вы уверены, что эти 2 строки будут соответствовать тексту запроса? const requestBuffer = буфер ожидания(запрос) const полезная нагрузка = requestBuffer.toString()
2. Можете ли вы определить проблему, добавив ведение журнала в свой код, запустить веб-браузер, посмотреть, как далеко он продвинется в зависимости от того, что регистрируется, а затем обновить свой вопрос более подробной информацией о том, где происходит сбой?
Ответ №1:
После 2 месяцев отладки я нашел решение.
Я думаю, проблема заключалась в том, что AWS, похоже, работает МЕДЛЕННО. Я добавил setTimeout для уведомления Stripe о том, что соединение было успешным, и теперь оно работает!
setTimeout(() => {
// 3. Notify Stripe that event recieved.
res.json({ received: true })
}, 2000)
Если у some1 есть лучшее решение, пожалуйста, сообщите нам 🙂