Best practices

Use the raw request body

Always verify the signature using the raw request body.

Do not verify the signature using a parsed JSON object.

Incorrect:

<span><span style="color: undefined">JSON.parse(body)</span></span>
<span><span style="color: undefined">JSON.stringify(parsedBody)</span></span>
<span><span style="color: undefined">Verify signature using the new JSON string</span></span>
<span><span style="color: undefined"></span></span>

Correct:

<span><span style="color: undefined">Read raw body exactly as received</span></span>
<span><span style="color: undefined">Verify signature</span></span>
<span><span style="color: undefined">Then parse JSON</span></span>
<span><span style="color: undefined"></span></span>

Use constant-time comparison

Use a secure comparison function when comparing signatures.

Recommended functions:

LanguageFunction
Node.jscrypto.timingSafeEqual
Pythonhmac.compare_digest
PHPhash_equals

Store processed event IDs

Webhook events can be delivered more than once.

Always store processed event IDs and avoid processing the same event twice.

Example database table:

<span><span style="color: undefined">webhook_event_id</span></span>
<span><span style="color: undefined">processed_at</span></span>
<span><span style="color: undefined">event_type</span></span>
<span><span style="color: undefined"></span></span>

Do not expose the webhook secret

Never expose your webhook signing secret in:

  • frontend code;
  • mobile applications;
  • public repositories;
  • logs;
  • error reports;
  • browser JavaScript.

The webhook secret must remain on your backend server only.

Rotate your webhook secret if needed

If your webhook secret is compromised, rotate it from your MeSomb dashboard.

During rotation, MeSomb may temporarily sign events with both the old and new secrets to avoid breaking your integration.