Test Webhook Endpoints

Overview

Once you've added an endpoint, you'll want to make sure it's working correctly before relying on it in production. Testing your webhook implementation is crucial for ensuring reliable event processing.

Using the Dashboard Testing Feature

Send Test Events

The "Testing" tab in your webhook dashboard lets you send test events to your endpoint:

  1. Navigate to your endpoint in the webhook dashboard
  2. Click the "Testing" tab
  3. Select an event type (e.g., chargeback.created)
  4. Click "Send Test Event"

After sending an example event, you can click into the message to view:

  • The complete message payload that was sent
  • All delivery attempts made
  • Whether each attempt succeeded or failed
  • Response codes and timing information
  • Any error messages from failed attempts

Test Event Payloads

Here are sample test payloads you can expect:

Test chargeback.created Event

{
  "event": "chargeback.created",
  "timestamp": "2024-08-20T10:30:45.123Z",
  "data": {
    "id": "test-chargeback-uuid-12345",
    "chargebackId": "TEST_CB_001",
    "psp": "stripe",
    "currency": "USD",
    "amount": 149.99,
    "postingDate": "2024-08-20T08:15:30.000Z",
    "transactionCreatedDate": "2024-08-10T14:22:18.000Z",
    "dueDate": "2024-09-03T23:59:59.000Z",
    "pspStatus": "needs_response",
    "status": "waiting_for_data",
    "lifecycleStage": "chargeback",
    "transactionId": "test_txn_abc123",
    "arn": "74537604221234567890123",
    "externalTransactionIdentifier": "TEST-ORD-2024-001",
    "merchantReferenceName": "test_merchant_account",
    "reasonCode": "4855",
    "reason": "Goods/Services Not Provided",
    "cardScheme": "VISA",
    "enrichmentRatio": 0.65
  },
  "webhookId": "test-webhook-delivery-uuid",
  "merchantUuid": "test-merchant-uuid-12345"
}

Local Development Testing

Using ngrok for Local Testing

If you're developing locally, you can use ngrok to expose your local server:

# Install ngrok if you haven't already
npm install -g @ngrok/ngrok

# Start your local server (e.g., NestJS on port 3000)
npm run start:dev

# In another terminal, expose your local server
ngrok http 3000

# Use the ngrok HTTPS URL as your webhook endpoint
# Example: https://abc123.ngrok.io/webhooks/chargebacks

Testing with curl

You can also manually test your endpoint using curl with a sample payload:

curl -X POST https://your-endpoint.com/webhooks/chargebacks \
  -H "Content-Type: application/json" \
  -H "webhook-id: msg_test123" \
  -H "webhook-timestamp: 1692531045" \
  -H "webhook-signature: v1,test-signature-here" \
  -d '{
    "event": "chargeback.created",
    "timestamp": "2024-08-20T10:30:45.123Z",
    "data": {
      "id": "test-chargeback-uuid",
      "chargebackId": "TEST_CB_001",
      "psp": "stripe",
      "currency": "USD",
      "amount": 149.99,
      "status": "waiting_for_data"
    },
    "webhookId": "test-webhook-id",
    "merchantUuid": "test-merchant-uuid"
  }'

NestJS Testing Example

Here's how you can write unit tests for your webhook controller:

import { Test, TestingModule } from '@nestjs/testing';
import { WebhookController } from './webhook.controller';
import { WebhookService } from './webhook.service';

describe('WebhookController', () => {
  let controller: WebhookController;
  let service: WebhookService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [WebhookController],
      providers: [
        {
          provide: WebhookService,
          useValue: {
            processChargebackCreated: jest.fn(),
            processChargebackUpdated: jest.fn(),
            verifySignature: jest.fn().mockReturnValue(true),
          },
        },
      ],
    }).compile();

    controller = module.get<WebhookController>(WebhookController);
    service = module.get<WebhookService>(WebhookService);
  });

  describe('handleWebhook', () => {
    it('should process chargeback.created event', async () => {
      const mockEvent = {
        event: 'chargeback.created',
        timestamp: '2024-08-20T10:30:45.123Z',
        data: {
          id: 'test-id',
          chargebackId: 'TEST_CB_001',
          psp: 'stripe',
          currency: 'USD',
          amount: 149.99,
          status: 'waiting_for_data',
        },
        webhookId: 'test-webhook-id',
        merchantUuid: 'test-merchant-uuid',
      };

      const mockHeaders = {
        'webhook-id': 'msg_test123',
        'webhook-timestamp': '1692531045',
        'webhook-signature': 'v1,test-signature',
      };

      const result = await controller.handleWebhook(mockEvent, mockHeaders);
      
      expect(result).toEqual({ received: true });
      expect(service.processChargebackCreated).toHaveBeenCalledWith(mockEvent.data);
    });

    it('should handle unknown event types gracefully', async () => {
      const mockEvent = {
        event: 'unknown.event',
        timestamp: '2024-08-20T10:30:45.123Z',
        data: {},
        webhookId: 'test-webhook-id',
        merchantUuid: 'test-merchant-uuid',
      };

      const result = await controller.handleWebhook(mockEvent, {});
      
      expect(result).toEqual({ received: true });
    });
  });
});

Integration Testing

End-to-End Testing Flow

  1. Set up test environment with a test webhook endpoint
  2. Configure webhook in your test/staging dashboard
  3. Trigger actual events in your test environment
  4. Verify webhook delivery and processing
  5. Check downstream effects (database updates, notifications, etc.)

Test Checklist

Before going to production, verify:

  • Endpoint responds correctly to all event types
  • Signature verification is working properly
  • Error handling works for malformed payloads
  • Timeout handling responds within 15 seconds
  • Idempotency handles duplicate events correctly
  • Logging captures all necessary information
  • Database operations complete successfully
  • Downstream integrations are triggered properly

Common Testing Scenarios

Success Cases

  • Valid chargeback.created event processing
  • Valid chargeback.updated event processing
  • Proper signature verification
  • Quick response times (< 15 seconds)

Error Cases

  • Invalid JSON payload
  • Missing required fields
  • Invalid signature
  • Network timeouts
  • Database connection failures
  • Downstream service failures

Edge Cases

  • Very large payloads
  • Special characters in chargeback data
  • Duplicate webhook deliveries
  • Out-of-order event delivery

Debugging Failed Tests

When tests fail, check:

  1. Response status codes - Are you returning 2xx for success?
  2. Response timing - Are you responding within 15 seconds?
  3. Signature verification - Is your signature validation correct?
  4. Payload parsing - Are you handling the JSON correctly?
  5. Error logs - What do your application logs show?
  6. Network connectivity - Can our servers reach your endpoint?

The webhook dashboard provides detailed logs and retry information to help you debug issues quickly.