Skip to content

Listen to webhooks

Montonio uses webhooks to notify your application about events in real time, such as when a payment is completed or a refund is processed. This guide covers how Montonio webhooks work, how to verify them, and how to handle them correctly.

Overview

When certain events occur – like a customer completing a payment – Montonio sends an HTTP POST request to a URL you specify (the notificationUrl). This ensures your system is updated even if the customer closes their browser before being redirected back to your store.

Montonio sends two types of webhooks to the same notificationUrl:

  • Order webhooks – Sent when the payment status of an order changes (e.g. payment completed). The request body contains an orderToken JWT. See the Orders guide, Payment links guide, and Embedded Cards guide for details.
  • Refund webhooks – Sent when the status of a refund changes (e.g. refund successful or rejected). The request body contains a refundToken JWT. See the Refunds guide for details.

Both token types are JWTs signed with your Secret Key using HS256 and are verified the same way.

How webhooks work

  1. When creating an order or payment link, you include a notificationUrl in the JWT payload.
  2. When an event occurs (e.g. a payment is completed or a refund status changes), Montonio sends an HTTP POST request to that URL.
  3. The request body contains a signed JWT – either orderToken or refundToken – with the event details.
  4. Your server verifies the JWT signature and processes the event.

Webhook source identification

IP addresses

All Montonio webhooks are sent from the following IP addresses:

  • 35.156.245.42
  • 35.156.159.169

⚠️ Allowlist these IP addresses in your firewall or WAF to ensure you receive webhook notifications. If you are using Cloudflare, see our guide on configuring Cloudflare to allow Montonio webhooks.

User-Agent

Montonio webhook requests are sent with the following User-Agent header:

MontonioWebhooks/1.0

Webhook payload

Montonio webhooks deliver their payload as a JSON object in the POST body. The field name indicates the webhook type:

Order webhook:

{
"orderToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Refund webhook:

{
"refundToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Both tokens are JWTs signed with your Secret Key. The specific fields in each token depend on the webhook type – refer to the Orders guide and Refunds guide for the decoded token contents.

Verifying webhooks

You must verify the JWT signature using your Secret Key to ensure the webhook is authentic and has not been tampered with. Never trust webhook data without verification. Both orderToken and refundToken are verified the same way.

/**
* We recommend using the jsonwebtoken package to verify
* Json Web Tokens. You can install it with npm:
* > npm install jsonwebtoken
* More information can be found at
* https://www.npmjs.com/package/jsonwebtoken
*/
import jwt from 'jsonwebtoken';
// Determine the webhook type from the POST body
const { orderToken, refundToken } = req.body;
const token = orderToken || refundToken;
try {
const decoded = jwt.verify(token, 'MY_SECRET_KEY');
if (orderToken) {
// Handle order webhook – check decoded.paymentStatus
} else if (refundToken) {
// Handle refund webhook – check decoded.refundStatus
}
} catch (error) {
// Invalid signature – reject this webhook
}

For full details on the decoded token fields and how to act on them:

Responding to webhooks

Your endpoint must respond with an HTTP status code of 200 OK or 201 Created to acknowledge receipt of the webhook. If your endpoint returns an error, we recommend responding with a JSON body – this helps Montonio troubleshoot delivery issues on your behalf.

If your endpoint does not respond with 200 or 201, Montonio will retry the webhook delivery multiple times over the next 48 hours until a successful response is received.

Testing locally

To test webhooks during local development, you can expose your local server to the internet:

  • ngrok – Creates a public tunnel to your local server.
  • webhook.site – Useful for quick troubleshooting and inspecting webhook payloads.

For a more detailed walkthrough, see our Help Center article on testing webhooks locally.

Best practices

  • Always verify the JWT signature before processing a webhook. Do not trust unverified payloads.
  • Respond quickly with a 200 or 201 status code. Process the event asynchronously if needed.
  • Handle duplicates gracefully. Due to retries, your endpoint may receive the same webhook more than once. Use the order UUID or refund UUID to deduplicate.
  • Allowlist Montonio’s IP addresses in your firewall configuration to ensure delivery.