Webhooks

Receive real-time notifications about payment events to keep your systems in sync.

Last updated: June 24, 2023
Next: Payment Buttons

Overview

ZenPay webhooks provide a way for your application to receive real-time notifications when payment events occur. Instead of polling our API for updates, webhooks push notifications to your server whenever events happen, enabling you to automatically respond to payment status changes, refunds, disputes, and more.

Real-time Updates

Get instant notifications about payment events.

No polling required
Immediate event delivery
Keep local systems in sync

Secure Delivery

Enhanced security for your webhook endpoints.

HTTPS-only delivery
Signature verification
Replay attack prevention

Flexible Integration

Easy integration with any backend system.

Structured JSON payloads
Language-agnostic implementation
SDK support for major languages

Reliable Delivery

Ensures all events reach your application.

Automatic retries
Webhook logs for debugging
Event history for 30 days

Setting Up Webhooks

Follow these steps to configure webhooks for your ZenPay account:

1

Create a Webhook Endpoint

First, create an endpoint on your server that can receive POST requests from ZenPay:

  • The endpoint must be publicly accessible over HTTPS
  • It should accept JSON payloads in the request body
  • It should return a 2xx status code to acknowledge receipt
2

Register Your Endpoint

Add your webhook endpoint to your ZenPay account:

  • Go to Dashboard → Developers → Webhooks → Add Endpoint
  • Enter your endpoint URL
  • Select the events you want to receive notifications for
  • Generate a webhook secret for signature verification
3

Verify Webhook Signatures

Implement signature verification in your endpoint code:

  • Extract the Zenpay-Signature header from incoming requests
  • Use your webhook secret to verify the signature
  • Reject requests with invalid signatures to prevent spoofing
4

Handle Webhook Events

Process the webhook payload and update your systems accordingly:

  • Parse the JSON payload to extract event details
  • Check the event_type field to determine the appropriate action
  • Update order status, trigger emails, or perform other business logic
  • Implement idempotency to handle potential duplicate events

Event Types

ZenPay webhooks support the following event types:

Event TypeDescriptionWhen It's Triggered
payment.createdA new payment has been createdWhen a customer initiates a payment
payment.pendingPayment is awaiting confirmationWhen payment is detected but not yet confirmed
payment.completedPayment has been completed successfullyWhen payment receives required confirmations
payment.failedPayment attempt has failedWhen payment expires or is rejected
payment.refundedPayment has been refundedWhen a refund is processed
checkout.completedCheckout process completedWhen customer completes the checkout flow
checkout.abandonedCheckout was started but not completedWhen checkout expires without payment
subscription.createdNew subscription has been createdWhen a customer subscribes to a plan
subscription.updatedSubscription details have changedWhen subscription plan or status changes
subscription.canceledSubscription has been canceledWhen a subscription is terminated

Webhook Payload

Each webhook notification contains a JSON payload with information about the event:

Example Payment Completed Webhook Payload
{
  "id": "evt_5f7e243e8b9c4",
  "type": "payment.completed",
  "created": 1626285966,
  "data": {
    "object": {
      "id": "pay_6g8h354f9c0d5",
      "amount": "99.99",
      "currency": "USD",
      "crypto_amount": "0.00312",
      "crypto_currency": "BTC",
      "status": "completed",
      "customer": {
        "email": "customer@example.com",
        "name": "John Doe"
      },
      "metadata": {
        "order_id": "ORD-12345",
        "product_id": "PRD-6789"
      },
      "created": 1626285900,
      "updated": 1626285966,
      "transaction_hash": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
      "confirmation_count": 6,
      "checkout_session_id": "cs_7h9i465g0d1e6"
    }
  }
}

Signature Verification

To ensure webhooks are coming from ZenPay and haven't been tampered with, you should verify the signature:

Node.js Signature Verification Example
// Using the ZenPay Node.js SDK
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();

// Use raw body parser for webhook signature verification
app.use('/webhooks/zenpay', 
  bodyParser.raw({ type: 'application/json' }),
  (req, res) => {
    const payload = req.body;
    const signature = req.headers['zenpay-signature'];
    const webhookSecret = 'whsec_your_webhook_secret';
    
    // Verify signature
    const expectedSignature = crypto
      .createHmac('sha256', webhookSecret)
      .update(payload)
      .digest('hex');
    
    // Check if signatures match
    if (signature !== expectedSignature) {
      console.error('Invalid signature');
      return res.status(400).send('Invalid signature');
    }
    
    // Parse the payload
    const event = JSON.parse(payload);
    
    // Handle different event types
    switch (event.type) {
      case 'payment.completed':
        // Update order status, send confirmation email, etc.
        const paymentId = event.data.object.id;
        const amount = event.data.object.amount;
        const currency = event.data.object.currency;
        console.log(`Payment ${paymentId} completed: ${amount} ${currency}`);
        break;
        
      case 'payment.failed':
        // Handle failed payment
        console.log(`Payment ${event.data.object.id} failed`);
        break;
        
      // Handle other event types
      
      default:
        console.log(`Unhandled event type: ${event.type}`);
    }
    
    // Return a response to acknowledge receipt of the webhook
    res.status(200).send('Webhook received');
  }
);

app.listen(3000, () => console.log('Webhook server running on port 3000'));

Webhook Testing

Before relying on webhooks in production, test your implementation thoroughly:

Testing Options

  • 1

    Webhook Tester - Use the webhook tester in your ZenPay dashboard to send test events to your endpoint without creating actual payments.

  • 2

    Local Development - For local testing, use tools like ngrok or localtunnel to create a public URL that forwards to your local server.

  • 3

    Test Mode Transactions - Create test payments in your ZenPay test environment to trigger real webhook events.

  • 4

    Replay Events - Use the webhook logs in your dashboard to replay previous events for testing your handler logic.

Best Practices

Follow these recommendations to ensure reliable webhook processing:

Implementation Recommendations

  • 1

    Return quickly - Respond to webhooks with a 2xx status code as soon as possible, ideally under 500ms. Process the event asynchronously if needed.

  • 2

    Implement idempotency - Design your webhook handler to safely process the same event multiple times without causing duplicate operations.

  • 3

    Monitor webhook deliveries - Regularly check the webhook logs in your dashboard to ensure events are being delivered and processed correctly.

  • 4

    Use a queue system - For high-volume applications, consider using a message queue to buffer webhook events before processing.

  • 5

    Set up alerting - Configure alerts for webhook failures or delays to quickly identify and resolve issues.

Troubleshooting

If you're experiencing issues with webhooks, check these common problems:

Common Issues

1

Webhook Secret Mismatch

Ensure that the webhook secret used for signature verification matches the one in your ZenPay dashboard. If you've regenerated your webhook secret, you'll need to update your code.

2

Endpoint Not Responding

Check if your server is accessible and responding to webhook requests. ZenPay expects a 2xx response within a certain timeout period, or it will retry the webhook.

3

Firewall or Security Issues

Make sure your firewall allows incoming connections from ZenPay's IP ranges. Consider whitelisting ZenPay's IP addresses if you're using IP-based filtering.

4

Incorrect Content Type

ZenPay sends webhooks with Content-Type: application/json. Ensure your endpoint correctly handles this content type and properly parses the JSON payload.

Next Steps

Now that you've set up webhooks, explore these related features:

Payment Buttons

Add simple payment buttons to your website

API Reference

Browse the complete API documentation

Was this helpful?