Skip to content

Instantly share code, notes, and snippets.

@imlautaro
Created March 18, 2024 00:05
Show Gist options
  • Save imlautaro/921df50e4a60939ddfe351e6d0a2ffb9 to your computer and use it in GitHub Desktop.
Save imlautaro/921df50e4a60939ddfe351e6d0a2ffb9 to your computer and use it in GitHub Desktop.
MercadoPago Webhook Handler for Nuxt
import crypto from 'crypto'
import type { EventHandler, EventHandlerRequest } from 'h3'
export const defineMPWebhookHandler = <T extends EventHandlerRequest, D>(
handler: EventHandler<T, D>
): EventHandler<T, D> => {
return defineEventHandler<T>(async event => {
const runtimeConfig = useRuntimeConfig()
if (!runtimeConfig.mercadopago.webhookSecret) {
console.error('❌ Error: No webhook secret provided')
setResponseStatus(event, 500)
return { message: 'Internal Server Error' }
}
const body = await readBody(event)
if (!body) {
setResponseStatus(event, 400)
return { message: 'Missing body' }
}
if (!body.data.id) {
setResponseStatus(event, 400)
return { message: 'Missing id' }
}
const signature = getHeader(event, 'x-signature')
if (!signature) {
setResponseStatus(event, 400)
return { error: 'Missing signature' }
}
const requestId = getHeader(event, 'x-request-id')
if (!requestId) {
setResponseStatus(event, 400)
return { error: 'Missing request id' }
}
const ts = signature.split(',')[0].split('=')[1]
const v1 = signature.split(',')[1].split('=')[1]
if (!ts || !v1) {
setResponseStatus(event, 400)
return { error: 'Invalid signature' }
}
const template = `id:${body.data.id};request-id:${requestId};ts:${ts};`
const cyphedSignature = crypto
.createHmac('sha256', runtimeConfig.mercadopagoWebhookSecret)
.update(template)
.digest('hex')
if (cyphedSignature !== v1) {
setResponseStatus(event, 400)
return { error: 'Invalid signature' }
}
return await handler(event)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment