Documentation Index Fetch the complete documentation index at: https://mintlify.com/PhemiT/vaniykeempire-api/llms.txt
Use this file to discover all available pages before exploring further.
Secure webhook endpoint that receives events from Stripe when payment status changes. This endpoint handles payment intent success and failure events, updating the Purchase record status accordingly.
Important Notes
This endpoint requires raw request body parsing and must be placed before the express.json() middleware in your Express application. The Stripe signature verification requires access to the raw request body.
This endpoint is called by Stripe servers, not by your frontend application. Configure this webhook URL in your Stripe Dashboard under Developers → Webhooks.
Webhook Configuration
In Stripe Dashboard, go to Developers → Webhooks
Click “Add endpoint”
Enter URL: https://api.vaniykempire.com/api/payments/webhook
Select events to listen for:
payment_intent.succeeded
payment_intent.payment_failed
Copy the webhook signing secret to STRIPE_WEBHOOK_SECRET environment variable
Signature Verification
The endpoint verifies webhook authenticity using Stripe’s signature verification:
const sig = req . headers [ 'stripe-signature' ];
const event = stripe . webhooks . constructEvent (
req . body ,
sig ,
process . env . STRIPE_WEBHOOK_SECRET
);
Handled Events
payment_intent.succeeded
Fired when a payment successfully completes. The webhook handler:
Finds the Purchase record by stripePaymentIntentId
Updates Purchase status to completed
Logs the successful payment
payment_intent.payment_failed
Fired when a payment fails (card declined, insufficient funds, etc.). The webhook handler:
Finds the Purchase record by stripePaymentIntentId
Updates Purchase status to failed
Logs the failed payment
Stripe webhook signature for verifying the request authenticity. Automatically added by Stripe.
Should be application/json
Request Body
The raw Stripe event object. Common fields include:
Unique identifier for the event (e.g., evt_1MtwBwLkdIwHu7ix28a3tqPa)
Event type (e.g., payment_intent.succeeded, payment_intent.payment_failed)
Event data containing the payment intent object Show data.object properties
Payment intent ID (e.g., pi_3MtwBwLkdIwHu7ix28a3tqPa)
Three-letter ISO currency code (e.g., usd)
Custom metadata attached when creating payment intent MongoDB ObjectId of purchased content
MongoDB ObjectId of purchasing user
Title of purchased content
Response
Always returns true to acknowledge receipt of the webhook
Error Handling
If signature verification fails, returns:
Status Code : 400
Body : Webhook Error: <error message>
cURL (Simulated)
Testing Webhooks Locally
# This is how Stripe calls your webhook
curl -X POST https://api.vaniykempire.com/api/payments/webhook \
-H "stripe-signature: t=1678886400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd" \
-H "Content-Type: application/json" \
-d '{
"id": "evt_1MtwBwLkdIwHu7ix28a3tqPa",
"type": "payment_intent.succeeded",
"data": {
"object": {
"id": "pi_3MtwBwLkdIwHu7ix28a3tqPa",
"amount": 2999,
"currency": "usd",
"status": "succeeded",
"metadata": {
"contentId": "507f191e810c19729de860ea",
"userId": "507f1f77bcf86cd799439011",
"contentTitle": "Advanced React Patterns"
}
}
}
}'
200 Success
400 Verification Failed
Security Best Practices
Always verify webhook signatures - Prevents unauthorized requests from spoofing Stripe
Use raw body parsing - Required for signature verification
Store webhook secret securely - Use environment variables, never commit to git
Implement idempotency - Handle duplicate webhook events gracefully
Return 200 quickly - Stripe will retry if endpoint times out
Webhook Retry Logic
Stripe automatically retries failed webhooks:
If endpoint returns non-2xx status code
If endpoint times out (after 30 seconds)
Retries for up to 3 days with exponential backoff
View retry attempts in Stripe Dashboard
Testing
Local Development
# Install Stripe CLI
stripe login
# Forward webhooks to local server
stripe listen --forward-to localhost:3000/api/payments/webhook
# Trigger test events
stripe trigger payment_intent.succeeded
stripe trigger payment_intent.payment_failed
Test Mode
Use Stripe test mode webhook endpoints with test API keys to safely test without affecting production data.
Troubleshooting
Issue Solution Signature verification fails Ensure raw body parsing is enabled and webhook secret is correct Purchase not found Check that payment intent was created through your API Webhooks not received Verify webhook URL is correct in Stripe Dashboard Duplicate events Implement idempotency using event ID
Environment Variables
Webhook signing secret from Stripe Dashboard. Format: whsec_...
Implementation Notes
Middleware: express.raw({ type: 'application/json' })
Must be registered before express.json() middleware
Unhandled event types are logged but don’t cause errors
Purchase updates are wrapped in try-catch to prevent webhook failures
Source: src/controllers/paymentController.js:64-130
Route configuration: src/routes/paymentRoutes.js:7-11