Skip to Content
WebhooksOverview

Webhooks Overview

Monetize.software can send you notifications any time an event happens in your app and monitor state changes for your subscribers.

Benefits

With webhooks integrated, you can:

  • Keep your backend synchronized with real-time subscription and purchase data
  • Set up automated workflows that respond to subscription events
  • Send timely communications to subscribers about billing issues or engage with them during unsubscription

Supported Events

EventDescription
payment.completedSuccessfully completed payment (one-time or first subscription payment)
subscription.createdNew subscription creation
subscription.updatedSubscription update (plan change, status change, etc.)
subscription.cancelledSubscription cancellation
refund.createdRefund creation

Webhook Structure

HTTP Headers

Every webhook request includes these headers:

Content-Type: application/json User-Agent: Monetize-Webhooks/1.0 X-Monetize-Signature: sha256=<signature>

Signature Header: The X-Monetize-Signature header is only included if you have configured a secret key for webhook verification.

Payload Structure

Each webhook notification has this JSON structure:

{ "id": "evt_1234567890_abcdef123", "type": "payment.completed", "created_at": "2024-01-15T12:30:45.000Z", "data": { "price": { "id": "cus_customer123", "unit_amount": 2000, "interval": "year" }, "customer": { "id": "cus_customer123", "email": "user@example.com" }, "user": { "id": "cus_customer123", "metadata": { "some-custom-field": "value" } }, "paywall": { "id": "123" }, "acquiring": { "id": "acq_456", "provider": "stripe" } } }

Common Fields

FieldTypeDescription
idstringUnique event identifier
typestringEvent type (e.g., “payment.completed”)
created_atstringEvent creation time in ISO 8601 format
dataobjectEvent-specific data containing information

Event-Specific Fields

Payment Events

Additional fields for payment events:

"payment": { "id": "pi_payment123", "status": "succeeded" }

Subscription Events

Additional fields for subscription events:

"subscription": { "id": "sub_subscription123", "status": "active", "current_period_start": "2024-01-15T12:30:45.000Z", "current_period_end": "2024-02-15T12:30:45.000Z" }

Refund Events

Additional fields for refund events:

"refund": { "id": "re_refund123", "reason": "requested_by_customer", "amount": 2999 }

Authentication Verification

Webhook Signature

If you have configured a secret key, each webhook will contain an X-Monetize-Signature header with an HMAC SHA256 signature of the request body.

Security: Always verify webhook signatures in production to ensure the request is genuinely from Monetize.software.

Signature Verification Examples

const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload) .digest('hex'); // Remove "sha256=" prefix from header signature = signature.replace('sha256=', ''); return crypto.timingSafeEqual( Buffer.from(expectedSignature), Buffer.from(signature) ); } // Usage const isValid = verifyWebhookSignature( req.body, req.headers['x-monetize-signature'], 'your_webhook_secret' );

Webhook Processing

Endpoint Requirements

  • HTTPS: Webhooks are only sent to HTTPS URLs
  • Response Status: Your endpoint should return HTTP status 200-299 for successful processing
  • Timeout: Response timeout is 10 seconds
  • Idempotency: Be prepared to receive duplicate events

Processing Example

const express = require('express'); const app = express(); app.use(express.json()); app.post('/webhooks/monetize', async (req, res) => { try { // Verify signature const signature = req.headers['x-monetize-signature']; if (signature && !verifyWebhookSignature( JSON.stringify(req.body), signature, 'your_secret' )) { return res.status(401).json({ error: 'Invalid signature' }); } // Parse event const event = req.body; // Process event based on type switch (event.type) { case 'payment.completed': await handlePaymentCompleted(event.data); break; case 'subscription.created': await handleSubscriptionCreated(event.data); break; case 'subscription.updated': await handleSubscriptionUpdated(event.data); break; case 'subscription.cancelled': await handleSubscriptionCancelled(event.data); break; case 'refund.created': await handleRefundCreated(event.data); break; default: console.log(`Unhandled event type: ${event.type}`); } res.status(200).json({ status: 'success' }); } catch (err) { console.error(`Webhook error: ${err}`); res.status(500).json({ error: 'Internal error' }); } }); async function handlePaymentCompleted(data) { console.log(`Payment completed: ${data.payment.id}`); // Example: Activate user access await activateUserAccess(data.user.id); } async function handleSubscriptionCreated(data) { console.log(`Subscription created: ${data.subscription.id}`); // Example: Grant premium features access await grantPremiumAccess(data.user.id); }

Retry Mechanism

The system automatically retries webhook delivery on failure:

  • Number of attempts: 5 attempts
  • Intervals: 5, 10, 20, 40, and 80 minutes
  • Retry conditions: HTTP status 5xx or connection timeout

Logging

All webhook delivery attempts are logged, including:

  • Send time - When the webhook was sent
  • HTTP response status - Response code from your endpoint
  • Response body - First 1000 characters of response
  • Error messages - Any error details
  • Attempt count - Which attempt number this was

Access Logs: Logs are available in the control panel under Settings → Webhooks → select specific webhook.

Security

Security Best Practices: Follow these guidelines to ensure secure webhook processing.

Security Guidelines

  1. Always verify the signature when using a secret key
  2. Use HTTPS for all webhook URLs
  3. Don’t log full webhook data in plain text
  4. Restrict access to webhook endpoints
  5. Validate data before processing

Limitations

LimitationValue
Maximum payload size1 MB
Timeout10 seconds
Maximum webhooks per account10
Log retention30 days

Support

If you encounter webhook issues, contact technical support providing:

  • Webhook ID - Identifier of the problematic webhook
  • Event time - When the issue occurred
  • Expected behavior - What should have happened
  • Actual behavior - What actually happened
  • Your side logs - Any relevant logs from your endpoint

Next Steps

Last updated on