Stripe webhook 和原始请求正文存在问题

问题描述 投票:0回答:1

我正在在 Firebase Cloud Functions 上运行的 Node/Express.ts 后端实现 Stripe webhook 集成,并且在签名验证期间很难传递 raw req.body

我已经进行了十几次尝试和修复,我不断遇到的错误是:“Webhook 错误:Webhook 负载必须以字符串或缓冲区形式提供(https://nodejs.org/api/buffer.html )表示原始请求正文的实例是作为解析的 JavaScript 对象提供的,如果不访问原始签名的材料,则无法进行签名验证。

这是我的index.ts:

const app = express();

app.use(cors());
app.use(allowedOriginsHandler);

app.post("/api/v1/stripe/webhook/payment", express.raw({ type: '*/*' }), listenToPaymentEvents);

app.use(express.json());

app.use("/api/v1", routes);

app.use(errorLogger);
app.use(errorResponder);
app.use(failSafeHandler);

export const httpFunction = functions.https.onRequest(app);
//admin.initializeApp();

//MARKETPLACE CLOUD FUNCTIONS
//orders
export const onOrderDocumentCreateFunction = onOrderDocumentCreate;
export const onOrderStatusChangeFunction = onOrderStatusChange;

//check order products availability
export const onOrderByVendorCreateFunction = onCreateOrderByVendor;

//products (create/update subcollections)
export const onProductDocumentCreateFunction = onCreateProduct;
export const onProductDocumentUpdateFunction = onUpdateProduct;

//Update seller public info collection on seller create/update
export const onSellerCreateFunction = onCreateSeller;
export const onSellerUpdateFunction = onUpdateSeller;

export const onUserRegistrationFunction = onUserRegistration;

// Create seller products bulk upload template on seller create
// and update seller document with the template url info
export const createSellerBulkUploadTemplateFunction =
  createSellerBulkUploadTemplate;

以下是其他路由的配置:

const router = Router();


router.route("/newsletter").post(addContactToNewsletter);

router.route("/checkout").post(
  firebaseAuthenticationHandler,
  checkProductsAvailabilityHandler,
  checkProductsPriceChangesHandler,
  lockProductsHandler,
  checkout
);

router.route("/order/vendor/cancel/:id").put(
  firebaseAuthenticationHandler,
  orderCancelledByVendor
);

router.route("/order/buyer/cancel").post(orderCancelledByBuyer);

router.route("/order/vendor/processing/:id").put(
  firebaseAuthenticationHandler,
  updateOrderToProcessing
);

export default router;

这是处理 webhook 的控制器:

dotenv.config();
const stripePaymentIntentWebhookEndpointSecret =
  process.env.STRIPE_PAYMENT_INTENT_WEBHOOK_ENDPOINT_SECRET ?? "";

export const listenToPaymentEvents: RequestHandler = async (req, res) => {
  const sig = req.headers["stripe-signature"];

  if (!sig) {
    console.log("Missing Stripe signature");
    res.status(400).send("Missing Stripe signature");
    return;
  }

  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      stripePaymentIntentWebhookEndpointSecret
    );

    switch (event.type) {
      case "payment_intent.payment_failed": {
        const paymentIntentPaymentFailed = event.data.object;
        console.log(paymentIntentPaymentFailed);
        break;
      }
      case "payment_intent.succeeded": {
        const paymentIntentSucceeded = event.data.object;
        await handlePaymentIntentSuccess(paymentIntentSucceeded);
        break;
      }
      default: {
        console.log(`Unhandled event type ${event.type}`);
      }
    }

    res.status(200).send("Event received");
  } catch (error) {
    if (error instanceof Error) {
      res.status(500).send(`Webhook Error: ${error.message}`);
    } else {
      res.status(500).send("Webhook Error: An unexpected error occurred");
    }
  }
};

我做错了什么?

express stripe-payments webhooks
1个回答
0
投票

我的猜测是

app.use(express.json());
中间件,因为错误消息提到内容是 JSON 而不是原始字符串。我会删除该行,看看您是否收到相同的错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.