Related to Stripe integration in directus #25371
Replies: 2 comments
|
Heya! Right now the JSON parsing middleware runs before custom endpoints or hooks are registered: Lines 193 to 205 in 7532b2b Lines 323 to 326 in 7532b2b so there's no way to access the raw body from a custom endpoint. That being said — while a little hackier — you can use the This allows you to setup any route handling that skips over any of the system logic, for example: export default ({ init }) => {
init('middleware.before', (app) => {
app.use((req, res, next) => {
if (req.path === '/my-stripe-endpoint') {
// Execute custom stripe logic
} else {
// Continue in the normal routing stack
next();
}
});
});
}; |
|
i have to create a hook something and include this code...? what will be flow like can you explain small flow how can i setup this so that i can integrate stripe very easily... |
Uh oh!
There was an error while loading. Please reload this page.
Summary
I'm trying to implement Stripe webhooks directly within a Directus endpoint (without using a separate Express server). The goal is to listen for events like payment_intent.succeeded, verify the Stripe signature, and update a related Directus collection.
The issue I'm facing is:
Stripe requires access to the raw request body (Buffer) to verify the signature.
But inside Directus, req.body is already parsed into a JavaScript object — meaning the raw body is no longer available, and verification fails with:
❌ Webhook payload must be provided as a string or a Buffer
Here’s what I tried:
Created a middleware hook in extensions/hooks/stripe-raw-body/index.js to use express.raw() for the /stripe-webhooks route:

export default ({ app }) => {
app.use('/stripe-webhooks', express.raw({ type: 'application/json' }));
};
In the endpoint (extensions/endpoints/stripe-webhooks/index.js), I’m calling stripe.webhooks.constructEvent(req.body, signature, webhookSecret).
But the raw body still seems unavailable, and Stripe throws a signature verification error.
I would really appreciate help with:
Ensuring the raw body is preserved correctly inside a Directus endpoint
Any guidance on proper middleware hook order or limitations within Directus that might prevent this from working
Directus version: 11.8.0
Fronted: React Native
Thank you for your support!
Basic Example
No response
Motivation
I'm building a tipping/payment feature in a React Native app that connects to a Directus backend. Payments are handled via Stripe, and I need to know when a payment succeeds in order to update related records in Directus (like marking a tip as "paid").
To do this securely, Stripe recommends using webhooks — which require the backend to verify incoming requests using Stripe's constructEvent method. This method strictly requires the raw request body (a Buffer), not a parsed JSON object.
Currently, when Stripe sends the webhook to a Directus endpoint, the body is already parsed by the time it reaches the handler, making signature verification impossible. This breaks a critical step in Stripe's recommended flow and leaves the system unable to trust or process payment success notifications.
Use cases this supports:
Securely processing Stripe payments in apps using Directus as the backend
Enabling any Stripe-integrated workflows (subscriptions, purchases, etc.) within Directus
Avoiding the need for a separate backend service just to handle raw body webhooks
Expected outcome:
To make it possible to reliably receive, verify, and process Stripe webhooks inside Directus by preserving access to the raw body buffer in a specific route (/stripe-webhooks).
This would eliminate the need for a parallel Express server and enable Directus users to natively integrate Stripe in secure, production-ready ways.
Detailed Design
The goal is to support Stripe webhook signature verification within Directus by ensuring the raw request body (Buffer) is available for a specific endpoint, such as /stripe-webhooks.
Stripe requires the exact byte-for-byte raw body to compute and verify webhook signatures. However, Directus automatically parses incoming requests using express.json(), which consumes the body stream and replaces req.body with a parsed object — making verification impossible.
To fix this within Directus:
✅ Middleware Hook (express.raw() applied only to /stripe-webhooks)
A middleware hook is created under extensions/hooks/stripe-raw-body/index.js, which ensures that the raw body is preserved for the Stripe route only:
js
Copy
Edit
import express from 'express';
export default ({ app }) => {
console.log('[HOOK] Attaching raw body middleware for /stripe-webhooks...');
app.use('/stripe-webhooks', express.raw({ type: 'application/json' }));
};
This must be registered before any endpoint processing.
express.raw() is used only for /stripe-webhooks, to avoid breaking the rest of the API.
✅ Endpoint Implementation (/extensions/endpoints/stripe-webhooks/index.js)
A custom endpoint receives the webhook from Stripe and verifies the signature using the raw body:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
export default function registerEndpoint(router) {
router.post('/', async (req, res) => {
const signature = req.headers['stripe-signature'];
});
}
🧪 Example Use Case
A mobile app calls a /create-payment-intent endpoint to initiate a tip. Stripe sends a webhook to /stripe-webhooks. This webhook:
Is received by Directus
Bypasses JSON parsing via the hook
Retains req.body as a Buffer
Is verified using Stripe’s official method
Triggers logic to update the tip record
🧩 Corner Cases & Considerations:
If express.json() is run before express.raw(), the raw body is lost and verification fails.
This setup is scoped only to the /stripe-webhooks path to avoid affecting Directus internals.
Care must be taken not to apply express.raw() globally, or it will break all other endpoints.
If Stripe changes their webhook requirements (e.g. new signature formats), Directus upgrades might need revalidation.
Requirements List
Should Have:
-A : Clear documentation or guidelines for users needing raw body support for webhooks (e.g., Stripe, GitHub)
Could Have: Reliable verification using stripe.webhooks.constructEvent()
Won't Have:
Drawbacks
N/A
Alternatives
N.A
Adoption Strategy
N/A
Unresolved Questions
No response
All reactions