Webhook Setup
Real-time Event Notifications Learn how to set up webhooks to receive instant notifications when events occur in your Notch Pay account, enabling you to automate your business processes and provide a better customer experience.
What are Webhooks?
Webhooks are HTTP callbacks that notify your application when events happen in your Notch Pay account. Instead of your application constantly polling the Notch Pay API for updates, webhooks push events to your application as they happen.
Think of webhooks as a “phone call” from Notch Pay to your application, rather than your application repeatedly “calling” Notch Pay to check for updates.
Why Use Webhooks? Real-time updates - Get notified immediately when events occurReduced API calls - No need to constantly poll for updatesAutomation - Trigger workflows automaticallyBetter user experience - Update your UI in real-time
Implementation Overview
Create a Webhook Endpoint
Set up an endpoint on your server that can receive HTTP POST requests from Notch Pay.
Register Your Endpoint
Add your webhook URL to your Notch Pay account and select which events you want to receive.
Implement Signature Verification
Verify that incoming webhook requests are actually from Notch Pay by checking the signature.
Process Webhook Events
Handle the different types of events and update your systems accordingly.
Test Your Implementation
Use the Notch Pay dashboard to send test events to your webhook endpoint.
Common Use Cases
Order Management Automatically update order status when a payment is completed, failed, or refunded. Trigger fulfillment processes and notify customers about their order status.
Customer Communications Send confirmation emails, SMS notifications, or in-app messages to customers when their payments are processed or transfers are completed.
Inventory Management Update your inventory systems automatically when products are purchased. Trigger reordering processes when stock levels fall below thresholds.
Analytics & Reporting Track payment success rates, monitor failed payments, and analyze customer payment patterns. Log events for audit trails and compliance reporting.
Setting Up Your Webhook Endpoint
Your webhook endpoint should:
Accept HTTP POST requests
Parse JSON request bodies
Respond with a 2xx status code (preferably 200 OK)
Process the webhook data asynchronously if needed
Node.js (Express)
PHP
Python (Flask)
const express = require ( 'express' );
const app = express ();
// Parse JSON request bodies
app . use ( express . json ());
app . post ( '/webhooks/notchpay' , ( req , res ) => {
// Return a 200 response immediately
res . status ( 200 ). send ( 'Webhook received' );
// Process the webhook asynchronously
const event = req . body ;
processWebhook ( event );
});
function processWebhook ( event ) {
const eventType = event . type ;
const eventData = event . data ;
switch ( eventType ) {
case 'payment.complete' :
// Handle completed payment
console . log ( `Payment ${ eventData . id } completed` );
break ;
case 'payment.failed' :
// Handle failed payment
console . log ( `Payment ${ eventData . id } failed` );
break ;
// Handle other event types
}
}
app . listen ( 3000 , () => {
console . log ( 'Webhook server running on port 3000' );
});
<? php
// Get the request body
$input = file_get_contents ( 'php://input' );
$event = json_decode ( $input , true );
// Return a 200 response immediately
http_response_code ( 200 );
header ( 'Content-Type: application/json' );
echo json_encode ([ 'status' => 'received' ]);
// Process the webhook asynchronously
if ( function_exists ( 'fastcgi_finish_request' )) {
fastcgi_finish_request ();
}
// Process the webhook
$eventType = $event [ 'type' ];
$eventData = $event [ 'data' ];
switch ( $eventType ) {
case 'payment.complete' :
// Handle completed payment
error_log ( "Payment { $eventData ['id']} completed" );
break ;
case 'payment.failed' :
// Handle failed payment
error_log ( "Payment { $eventData ['id']} failed" );
break ;
// Handle other event types
}
from flask import Flask, request, jsonify
import threading
app = Flask( __name__ )
@app.route ( '/webhooks/notchpay' , methods = [ 'POST' ])
def webhook ():
# Return a 200 response immediately
event = request.json
# Process the webhook asynchronously
threading.Thread( target = process_webhook, args = (event,)).start()
return jsonify({ 'status' : 'received' }), 200
def process_webhook ( event ):
event_type = event[ 'type' ]
event_data = event[ 'data' ]
if event_type == 'payment.complete' :
# Handle completed payment
print ( f "Payment { event_data[ 'id' ] } completed" )
elif event_type == 'payment.failed' :
# Handle failed payment
print ( f "Payment { event_data[ 'id' ] } failed" )
# Handle other event types
if __name__ == '__main__' :
app.run( port = 3000 )
Registering Your Webhook
Using the Dashboard
Using the API
Log in to your Notch Pay Business suite
Navigate to Settings > Webhooks
Click “Add Endpoint”
Enter your webhook URL (e.g., https://example.com/webhooks/notchpay)
Select the events you want to receive
Click “Save” to create the webhook
curl https://api.notchpay.co/webhooks \
-H "Authorization: YOUR_PUBLIC_KEY" \
-H "X-Grant: YOUR_PRIVATE_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/notchpay",
"events": ["payment.complete", "payment.failed"],
"description": "Payment notifications for my e-commerce site"
}'
For more details, see the Webhooks API Reference .
Key Webhook Events
Event Description payment.createdTriggered when a payment is created payment.completeTriggered when a payment is successfully completed payment.failedTriggered when a payment fails payment.canceledTriggered when a payment is canceled payment.expiredTriggered when a payment expires
Event Description transfer.createdTriggered when a transfer is created transfer.completeTriggered when a transfer is successfully completed transfer.failedTriggered when a transfer fails
Event Description customer.createdTriggered when a customer is created customer.updatedTriggered when a customer is updated customer.deletedTriggered when a customer is deleted
Securing Your Webhooks
Always verify webhook signatures to ensure they’re coming from Notch Pay and not from an attacker.
const crypto = require ( 'crypto' );
function verifySignature ( payload , signature , secret ) {
const hmac = crypto . createHmac ( 'sha256' , secret );
const calculatedSignature = hmac . update ( payload ). digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( calculatedSignature , 'hex' ),
Buffer . from ( signature , 'hex' )
);
}
app . post ( '/webhooks/notchpay' , express . raw ({ type: 'application/json' }), ( req , res ) => {
const signature = req . headers [ 'x-notch-signature' ];
const payload = req . body . toString ();
if ( ! verifySignature ( payload , signature , 'your_webhook_secret' )) {
return res . status ( 400 ). send ( 'Invalid signature' );
}
const event = JSON . parse ( payload );
// Process the event
res . status ( 200 ). send ( 'Webhook received' );
});
<? php
function verifySignature ( $payload , $signature , $secret ) {
$calculatedSignature = hash_hmac ( 'sha256' , $payload , $secret );
return hash_equals ( $calculatedSignature , $signature );
}
$payload = file_get_contents ( 'php://input' );
$signature = $_SERVER [ 'HTTP_X_NOTCH_SIGNATURE' ];
if ( ! verifySignature ( $payload , $signature , 'your_webhook_secret' )) {
http_response_code ( 400 );
echo 'Invalid signature' ;
exit ;
}
$event = json_decode ( $payload , true );
// Process the event
import hmac
import hashlib
def verify_signature ( payload , signature , secret ):
calculated_signature = hmac.new(
secret.encode( 'utf-8' ),
payload.encode( 'utf-8' ),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(calculated_signature, signature)
@app.route ( '/webhooks/notchpay' , methods = [ 'POST' ])
def webhook ():
payload = request.data.decode( 'utf-8' )
signature = request.headers.get( 'X-Notch-Signature' )
if not verify_signature(payload, signature, 'your_webhook_secret' ):
return 'Invalid signature' , 400
event = json.loads(payload)
# Process the event
return jsonify({ 'status' : 'received' }), 200
Testing Your Implementation
Test in the Dashboard
Use the “Test” button in your Notch Pay dashboard to send test events to your webhook endpoint.
Test Locally with Tunneling
For local development, use tools like ngrok to expose your local server to the internet: # Start your local server (e.g., on port 3000)
npm start
# In another terminal, start ngrok
ngrok http 3000
Use the generated URL (e.g., https://abc123.ngrok.io/webhooks/notchpay) as your webhook endpoint.
Check Webhook Logs
Monitor your webhook delivery logs in the Notch Pay dashboard to ensure events are being delivered successfully.
Best Practices
Respond Quickly Return a 200 response as soon as possible, then process the webhook asynchronously to avoid timeouts.
Verify Signatures Always verify webhook signatures to ensure they come from Notch Pay.
Handle Duplicates Design your webhook handler to be idempotent, as the same event might be delivered multiple times.
Implement Logging Log all webhook events for debugging and auditing purposes.
Handle Retries Be prepared for Notch Pay to retry failed webhook deliveries with exponential backoff.
Monitor Performance Monitor your webhook endpoint’s performance to ensure it can handle the volume of events.
Next Steps
Secure Your Webhooks Now that you’ve set up your webhook endpoint, it’s important to secure it by verifying webhook signatures. This ensures that webhook events are actually coming from Notch Pay and not from a malicious source.
Explore the complete Webhooks API reference documentation for detailed information about endpoints and parameters.
View API Reference Our SDKs provide built-in support for webhook signature verification and event handling.
Explore SDKs Having issues with your webhooks? Check our troubleshooting guide for common problems and solutions.
Troubleshooting Guide