简体   繁体   English

Node/Express API 在本地运行,但在 AWS Lambda 调用 API 时挂断

[英]Node/Express API runs locally but hangs up on API call in AWS Lambda

I have an Express API setup which works fine locally.我有一个 Express API 设置,可以在本地正常工作。 However, when deployed to AWS Lambda it chokes/hangs on a call to an Authorize.net API and the Lambda function closes.但是,当部署到 AWS Lambda 时,它会阻塞/挂起对 Authorize.net API 和 Lambda ZC1C4145268E68394D 的调用关闭。 Lambda/Cloudwatch logs don't indicate an error of any kind. Lambda/Cloudwatch 日志不表示任何类型的错误。

  • CORS is installed and enabled on the Express app, so I don't think that is the problem CORS 已在 Express 应用程序上安装并启用,所以我认为这不是问题

Completely at a loss.完全无所适从。

Any help is appreciated.任何帮助表示赞赏。

authnet-api.js authnet-api.js

const axios = require('../config/axios')
const loginId = process.env.AUTHORIZENET_LOGIN_ID
const transactionKey = process.env.AUTHORIZENET_TRANSACTION_KEY

class AuthNetAPI {
  constructor() {
    this.headers = { headers: { 'Content-Type': 'application/json' } }
  }
  async getTransactionDetails(transactionId) {
    return axios.authNetAxios.post(
      '/',
      {
        getTransactionDetailsRequest: {
          merchantAuthentication: {
            name: loginId,
            transactionKey: transactionKey,
          },
          transId: transactionId,
        },
      },
      this.headers
    )
  }
}
module.exports = new AuthNetAPI()

webhook controller网络挂钩 controller

const moment = require('moment')
const AuthNetAPI = require('../lib/authnet-api')
const helpers = require('../utils/helpers')


module.exports.makeWebhookPayment = async (req, res, next) => {
  try {
    const rawBodyString = req.rawBody
    const notificationBody = req.body
    const authNetHash = req.header('X-ANET-Signature')
    const clientHash = await helpers.generateHash(rawBodyString)
    const timestamp = Date.now()
    const batch = `AuthorizeNet_Phone ${moment(timestamp).format('M/D/YYYY')}`
    const documentDate = moment(timestamp).format()

    if (authNetHash === clientHash) {
      res.sendStatus(200)
      const transactionId = req.body.payload.id

      console.log(transactionId) // this logs out.

      const transactionResult = await AuthNetAPI.getTransactionDetails(
        transactionId
      ) // this API call closes the Lambda function with no error

      const transaction = transactionResult.data.transaction
      // console.log(transaction) // this does not log out, obviously.

     ...// remainder of code
 
  } catch (error) {
    next(error)
  }
}

index.js (express app wrapped with serverless-http handler) index.js(使用 serverless-http 处理程序包装的快速应用程序)

const serverless = require('serverless-http')
const app = require('./src/config/express')

process.env.ENVIRONMENT === 'production'
  ? (module.exports.handler = serverless(app))
  : app.listen(3000, () => {
      console.log('listening on port 3000')
    })

module.exports.handler = serverless(app)

The Authorize.net Webhooks API requires a response status of 200 when the webhook notification is received. Authorize.net Webhook API 要求收到 webhook 通知时的响应状态为 200。 Failure to do so may result in repeated notification retries and webhook inactivation.不这样做可能会导致重复通知重试和 webhook 停用。

My particular problem had to do with res.sendStatus(200) .我的特殊问题与res.sendStatus(200)有关。 This was returning the response to API Gateway and effectively closing the Lambda function.这是返回对 API 网关的响应并有效地关闭 Lambda function。 The solution was to replace res.sendStatus(200) with res.status(200) .解决方案是将res.sendStatus(200)替换为res.status(200)

const moment = require('moment')
const AuthNetAPI = require('../lib/authnet-api')
const helpers = require('../utils/helpers')


module.exports.makeWebhookPayment = async (req, res, next) => {
  try {
    res.status(200)
    const rawBodyString = req.rawBody
    const notificationBody = req.body
    const authNetHash = req.header('X-ANET-Signature')
    const clientHash = await helpers.generateHash(rawBodyString)
    const timestamp = Date.now()
    const batch = `AuthorizeNet_Phone ${moment(timestamp).format('M/D/YYYY')}`
    const documentDate = moment(timestamp).format()

    if (authNetHash === clientHash) {
      const transactionId = req.body.payload.id

      console.log(transactionId)

      const transactionResult = await AuthNetAPI.getTransactionDetails(
        transactionId
      ) 

      const transaction = transactionResult.data.transaction

     ...// remainder of code
 
  } catch (error) {
    next(error)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM