Сбой веб-крючка Stripe — Ошибка веб-крючка: 504

#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 есть лучшее решение, пожалуйста, сообщите нам 🙂