Documentation
Guides
Webhooks

Webhooks

Listen incoming webhooks to get real-time updates. Bamotf uses webhooks to notify your application when a certain event happens in your server. Webhooks are particularly useful for asynchronous events like when a payment is confirmed on the blockchain for example.

How bamotf uses webhooks

A webhook enables bamotf to push real-time notifications to your app. The server sends notifications to your app defined as WEBHOOK_URL in your docker as a JSON payload. You can then use these notifications to execute actions in your backend systems.

Steps to receive webhooks

You can start receiving event notifications in your app using the steps in this section:

  1. Identify the events you want to monitor and the event payloads to parse.
  2. Create a webhook endpoint as an HTTP endpoint (URL) on your local server.
  3. Handle requests from bamotf by parsing each event object and returning 2xx response status codes.
  4. Test that your webhook endpoint is working properly.
  5. Deploy your webhook endpoint so it’s a publicly accessible HTTPS URL.
  6. Set your publicly accessible HTTPS URL in the WEBHOOK_URL environment variable of the server with the WEBHOOK_SECRET that you are going to use to validate the requests.

Validate requests

To make sure that the requests are coming from bamotf, you can validate the requests using the WEBHOOK_SECRET that you have set in your server. You can use the bamotf.webhooks.constructEvent method to validate the requests.

app/webhook/bamotf/route.ts
import {bamotf} from '@/utils/bamotf'
import {NextResponse} from 'next/server'
 
export async function POST(request: Request) {
  // TODO: add your secret here
  const secret = 'my-secret'
 
  const rawBody = await request.text()
  const signatureHeader = request.headers.get('x-webhook-signature') || ''
 
  const {success, parsed} = bamotf.webhooks.constructEvent(
    rawBody,
    signatureHeader,
    secret,
  )
 
  if (!success) {
    return NextResponse.json(
      {success: false, error: 'Invalid signature'},
      {status: 401, statusText: 'Unauthorized'},
    )
  }
 
  const {
    event,
    data: {paymentIntent},
  } = parsed
 
  switch (event) {
    case 'payment_intent.succeeded':
      // save this in your database
      // ...
 
      console.log(`✅ Payment intent succeeded: ${paymentIntent.id}`)
      return NextResponse.json({success: true})
 
    default:
      console.error(`Unknown event: ${event}`)
      return NextResponse.json({success: false, error: 'Unknown event'})
  }
}

All requests to the webhook endpoint are POST requests with a JSON payload in the body. The payload contains the event data. The x-webhook-signature header contains the signature for the request. The signature is computed using the WEBHOOK_SECRET that you have set in your server.

If the signature is valid, the bamotf.webhooks.constructEvent method returns an object with the following properties:

  • success - true if the signature is valid, false otherwise.
  • parsed - an object containing the event data.

Test your webhook endpoint

You can test your webhook endpoint by sending a test webhook event to your endpoint. You can do this by creating a test request. In addition to that, you can also check the Logs and events on the payment intent page of your server to see if the webhook event was received.

List of webhook events available

  • payment_intent.processing - Occurs whenever a new Transaction is detected on the Mempool.
  • payment_intent.succeeded - Occurs when the sum of all transactions for a given PaymentIntent have reached the minimum confirmations.