Register Webhook Endpoint
This guide explains how to register and manage webhook endpoints in ZoPay. You can register endpoints through the dashboard or via the API.
Prerequisites
- A server endpoint that accepts HTTP POST requests
- HTTPS URL (required for production, HTTP allowed for local testing)
- Endpoint must be publicly accessible (not behind a firewall)
- Ability to verify HMAC signatures
- Endpoint must respond within 30 seconds
- Ability to capture raw request body (before JSON parsing) for signature verification
Registering via Dashboard
The easiest way to register a webhook endpoint is through the ZoPay dashboard:
- Navigate to Dashboard → Webhooks
- Click "Add Endpoint" button
- Enter your webhook URL (must be HTTPS in production)
- All 6 events are automatically selected (required)
- Click "Create Endpoint"
- Save your webhook secret - it's only shown once!
Important: The webhook secret is only returned once during registration. Make sure to save it securely - you'll need it to verify webhook signatures. If you lose it, you'll need to create a new endpoint.
Registering via API
You can also register webhook endpoints programmatically using the API:
Endpoint
POST /merchant/v1/webhooks/endpoints
Request Body
1{
2 "url": "https://your-server.com/webhooks/zopay",
3 "events": [
4 "payment.succeeded",
5 "payment.failed",
6 "payout.completed",
7 "payout.failed",
8 "refund.completed",
9 "settlement.generated"
10 ]
11}Response
1{
2 "endpoint": {
3 "id": "550e8400-e29b-41d4-a716-446655440000",
4 "merchantId": "merchant-uuid",
5 "url": "https://your-server.com/webhooks/zopay",
6 "enabled": true,
7 "events": [
8 "payment.succeeded",
9 "payment.failed",
10 "payout.completed",
11 "payout.failed",
12 "refund.completed",
13 "settlement.generated"
14 ],
15 "secret": "whsec_abc123def456...",
16 "createdAt": "2026-01-18T23:30:00.000Z"
17 }
18}Save the Secret: The secret field in the response is your webhook signing secret. Store it securely in your environment variables or secret management system. You'll use this to verify that webhook requests are actually from ZoPay.
Required Events
When registering a webhook endpoint, you must include all 6 required events:
payment.succeeded- Payment completed successfullypayment.failed- Payment failedpayout.completed- Payout sent successfullypayout.failed- Payout failedrefund.completed- Refund processedsettlement.generated- Settlement created
You cannot register a webhook endpoint with only a subset of events. All 6 events are required to ensure you receive all transaction notifications.
URL Requirements
- Production: Must use HTTPS (HTTP is not allowed)
- Sandbox/Local: HTTP is allowed for testing only
- URL must be publicly accessible (not localhost in production, not behind a firewall)
- URL must accept POST requests
- Endpoint should respond within 30 seconds
Example URLs:
- ✅
https://api.yourstore.com/webhooks/zopay - ✅
https://yourstore.com/api/webhooks/zopay - ❌
http://localhost:3000/webhooks(HTTP not allowed in production) - ❌
https://192.168.1.100/webhooks(Not publicly accessible)
Updating an Endpoint
You can update an existing webhook endpoint to change its URL, enable/disable it, or update events:
Endpoint
PUT /merchant/v1/webhooks/endpoints/:id
Request Body
1{
2 "url": "https://new-server.com/webhooks/zopay",
3 "enabled": true,
4 "events": [
5 "payment.succeeded",
6 "payment.failed",
7 "payout.completed",
8 "payout.failed",
9 "refund.completed",
10 "settlement.generated"
11 ]
12}All fields are optional, but if you update events, you must include all 6 required events.
Listing Endpoints
Get all webhook endpoints for your merchant account:
Endpoint
GET /merchant/v1/webhooks/endpoints
Response
1{
2 "endpoints": [
3 {
4 "id": "550e8400-e29b-41d4-a716-446655440000",
5 "url": "https://your-server.com/webhooks/zopay",
6 "enabled": true,
7 "events": [...],
8 "createdAt": "2026-01-18T23:30:00.000Z"
9 }
10 ]
11}Note: The secret is not included in the list response. To retrieve the secret for an existing endpoint, use the GET /merchant/v1/webhooks/endpoints/:id endpoint.
Getting Endpoint Details
Get detailed information about a specific endpoint, including the secret:
Endpoint
GET /merchant/v1/webhooks/endpoints/:id
Response
1{
2 "endpoint": {
3 "id": "550e8400-e29b-41d4-a716-446655440000",
4 "url": "https://your-server.com/webhooks/zopay",
5 "enabled": true,
6 "events": [...],
7 "secret": "whsec_abc123def456...",
8 "createdAt": "2026-01-18T23:30:00.000Z",
9 "updatedAt": "2026-01-18T23:35:00.000Z"
10 }
11}Enabling and Disabling Endpoints
You can temporarily disable a webhook endpoint without deleting it. Disabled endpoints will not receive webhook deliveries:
1PUT /merchant/v1/webhooks/endpoints/:id
2{
3 "enabled": false
4}To re-enable the endpoint, set enabled: true.
Testing Your Endpoint
After registering your endpoint, you can test it using several methods:
Method 1: Test Transaction
- Make a test transaction in sandbox mode
- Check the webhook deliveries in your ZoPay dashboard
- Verify that your server receives the webhook
- Confirm that signature verification works
- Check your server logs for webhook processing
Method 2: Test Endpoint (if available)
Some implementations provide a test endpoint to verify your webhook handler is accessible:
1# Test if webhook endpoint is accessible
2curl -X GET https://your-domain.com/api/webhooks/test
3
4# Expected response:
5{
6 "message": "Webhook endpoint is accessible",
7 "endpoint": "/api/webhooks/zopay",
8 "method": "POST",
9 "status": "ready"
10}Method 3: Manual Testing with curl
You can test your endpoint manually, but note that signature verification will fail without a proper signature from ZoPay:
1# Basic connectivity test (signature will fail)
2curl -X POST https://your-domain.com/api/webhooks/zopay \
3 -H "Content-Type: application/json" \
4 -H "X-Zo-Event: payment.succeeded" \
5 -H "X-Zo-Delivery-Id: test-123" \
6 -H "X-Zo-Timestamp: 1769164241000" \
7 -H "X-Zo-Signature: test-signature" \
8 -d '{"event":"payment.succeeded","data":{"transaction_id":"test"}}'Note: Real webhooks must come from ZoPay with proper HMAC-SHA256 signatures. Manual testing with curl will fail signature verification, but you can verify that your endpoint is accessible and returns appropriate error messages.
Verification Checklist
- ✅ Webhook endpoint is publicly accessible (HTTPS)
- ✅ Environment variables are set correctly
- ✅ Webhook secret is configured
- ✅ Test endpoint returns success (if available)
- ✅ Webhook logs appear in your monitoring system
- ✅ Signature verification works (test with invalid signature)
- ✅ Idempotency works (test duplicate delivery ID)
- ✅ All 6 event types are handled
Local Testing: Use a tool like ngrok to expose your local server for testing. Run ngrok http 3000 and use the provided HTTPS URL for your webhook endpoint. This allows you to test webhook signature verification locally before deploying to production.
Your Webhook Secret
When you register a webhook endpoint, ZoPay generates a unique webhook secret (64-character hex string). This secret is:
- Shown only once when you create the endpoint
- Used to verify signatures - store it securely
- Different for each endpoint - if you have multiple endpoints, each has its own secret
Critical: Store your webhook secret securely (environment variable, secrets manager, etc.). Never commit it to code or version control. If you lose it, you'll need to create a new endpoint.
Configuration Requirements
After registering your webhook endpoint, you need to configure your server with the webhook secret:
Environment Variables
Store your webhook secret in an environment variable:
1# .env.local or production environment
2ZITOPAY_WEBHOOK_SECRET=your_64_character_hex_string_from_zopaySecurity Warning: Never commit your webhook secret to version control. Always use environment variables or a secrets management service. Never expose the secret in client-side code or logs.
Endpoint Requirements
- HTTPS Only: Webhook endpoint must be publicly accessible via HTTPS (HTTP only for local testing)
- Public URL: Cannot be localhost or private IP address in production
- Response Time: Must respond within 30 seconds
- Status Code: Must return 200 OK for successful receipt
- Raw Body Access: Must be able to access raw request body (before JSON parsing) for signature verification
Best Practices
- Save your secret securely: Store it in environment variables or a secret management system
- Use HTTPS in production: Never use HTTP for production webhooks
- Test thoroughly: Test your endpoint with sandbox transactions before going live
- Monitor deliveries: Regularly check webhook delivery status in the dashboard
- Handle all events: Make sure your webhook handler can process all 6 event types
- Implement idempotency: Use delivery IDs to prevent duplicate processing
- Log everything: Log all webhook receipts for debugging and auditing
- Respond quickly: Return 200 OK within 30 seconds, process events asynchronously
Next Steps
- Learn about Webhook Events and their payloads
- Understand Webhook Security and signature verification
- View Your Webhook Endpoints in the dashboard