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:
| Action | Events to expect |
|---|---|
| Create a checkout session | checkout.created, transaction.created |
| Pay on the hosted page | payment.succeeded, checkout.completed, transaction.completed |
| A payment that fails | payment.failed |
| Expire a checkout session | checkout.expired |
| Refund a payment | refund.succeeded or refund.failed |
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:
#!/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.