Skip to content
Merxian

Webhooks

Test webhooks

Test your webhook endpoint in sandbox with real events, then test the cases that real traffic produces less often, such as duplicates and events out of order.

On this page

Set up a sandbox endpoint#

Add an endpoint in the sandbox environment of the dashboard. See Configure an endpoint. Store its signing secret as your sandbox secret.

In sandbox, the URL can use http. The URL must be one that Merxian can reach.

The dashboard cannot send a test event yet. Trigger real sandbox events instead.

Trigger real events#

Use a sandbox API key and run the flows that your integration uses:

The events can arrive in any order. See Test scenarios for the full list of flows to test.

Test signature verification#

Store the raw body and the headers of one sandbox delivery. Then sign the body yourself and send it to your local endpoint. This script signs a body with your sandbox secret and a current timestamp:

send-signed.sh
#!/usr/bin/env bash
# Usage: ./send-signed.sh body.json http://localhost:3000/webhooks/merxian
set -euo pipefail

BODY_FILE="$1"
URL="$2"
SECRET="${MERXIAN_WEBHOOK_SECRET:?Set the sandbox signing secret}"

TIMESTAMP=$(date +%s)
KEY_HEX=$(printf '%s' "${SECRET#whsec_}" | base64 -d | xxd -p -c 256)
SIGNATURE=$(printf '%s.' "$TIMESTAMP" | cat - "$BODY_FILE" \
  | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$KEY_HEX" | sed 's/^.* //')

curl -sS -X POST "$URL" \
  -H "Content-Type: application/json" \
  -H "Merxian-Signature: t=$TIMESTAMP,v1=$SIGNATURE" \
  --data-binary "@$BODY_FILE" \
  -w '\n%{http_code}\n'

Check these cases:

Case How Expected result
Valid signature Run the script as it is. 200
Wrong secret Set MERXIAN_WEBHOOK_SECRET to another value. 400
Changed body Change one character in the body file after you sign it. 400
Old timestamp Set TIMESTAMP to a value more than 5 minutes ago. 400
Missing header Remove the Merxian-Signature header. 400

Use --data-binary, not -d. The -d option removes line breaks, so the bytes that you send differ from the bytes that you signed.

Test duplicates#

Send the same body twice, with the same event id. Your system must apply the effect once. For example, it must mark the transaction as paid once and send one confirmation email.

Test ordering#

Send two events for one payment in the reverse order. For example, send payment.succeeded first and payment.processing second. The final state in your system must be “paid”.

Test slow processing#

Make your processing slow on purpose, for example with a 15-second delay. Your endpoint must still answer within 10 seconds. If it does not, Merxian retries, and you get a duplicate delivery.

Try refund, payment.succeeded,POST /v1/transactions, orIdempotency-Key.