Skip to content

Webhook Integration

Mehmet Celik edited this page May 19, 2025 · 1 revision

Webhooks allow external applications to receive real-time, secure notifications from Wapy.dev. When enabled, your application will be notified of important events such as payment reminders.

The reference implementation for handling webhooks can be found in the file: src/app/api/webhook/route.js

Enable Webhook

To enable webhook notifications:

  • Navigate to the Account page.

  • Click the Configure Webhook link.

image

  • Enter your Webhook URL into the input box.

image

  • Click Save.

Once clicked, the URL will go through the verification process. When successfully verified, Wapy.dev will begin sending signed event payloads to your endpoint for the selected subscriptions, the same way push or email notifications are configured.

image

Webhook Verification

To ensure your endpoint is ready to receive events, Wapy.dev will send a verification request when the webhook is configured.

Verification Process

  • HTTP Method: POST

  • Payload: A JSON with a token signed with your SUBSCRIPTION_JWT_SECRET key.

{
  "token": "XXXXXXXXXXXXXXXXXXXXXXXXXX"
}
  • Decoded Token Content:
{
  "event": "verify"
}

Required Response

Your server must:

  • Decode and verify the JWT using the shared secret (SUBSCRIPTION_JWT_SECRET).

  • If the signature is valid and the event is verify, respond with:

{
  "success": true
}
  • HTTP Status Code: 200 OK

Webhook Events

All event requests are sent via HTTP POST and are signed JWT tokens. Your application must verify the signature using the shared secret.

If verification is successful, respond with HTTP 200 OK and a JSON body:

{
  "success": true
}

Events

  • verify

Sent to confirm that your webhook endpoint is active and functional.

  • payment_due_now
  • payment_due_upcoming

Notifies your application of a payment that is currently due or upcoming. Example payload:

{
  "event": "payment_due_now", // or "payment_due_upcoming"
  "price": "XX.XX",
  "currency": "USD",
  "paymentDate": "2025-06-01T12:00:00Z",
  "untilDate": "2025-06-10T23:59:59Z",
  "timezone": "Europe/Helsinki",
  "url": "https://link-to-payment.com",
  "notes": "Your Notes Here",
  "title": "Subscription Payment Due",
  "message": "Your subscription is due for renewal.",
  "markAsPaidUrl": "https://yourdomain.com/api/payments/mark-paid",
  "siteUrl": "https://yourdomain.com"
}

Example Implementations

Python

# pip pip install fastapi uvicorn python-jose
# To start the server, run:
# uvicorn webhook:app --reload

from fastapi import FastAPI, Request, HTTPException
from jose import jwt, JWTError
import os

app = FastAPI()

SUBSCRIPTION_JWT_SECRET = os.getenv("SUBSCRIPTION_JWT_SECRET", "your-secret-key")

@app.post("/webhook")
async def handle_webhook(request: Request):
    try:
        body = await request.json()
        token = body.get("token")

        if not token:
            raise HTTPException(status_code=400, detail="Missing token")

        # Decode and verify the JWT token
        data = jwt.decode(token, SUBSCRIPTION_JWT_SECRET, algorithms=["HS256"])

        event_type = data.get("event")
        if not event_type:
            raise HTTPException(status_code=401, detail="Invalid token")

        # Handle different webhook events
        if event_type == "verify":
            # Process verification request
            print("Webhook verification requested")
            return {"success": True}

        elif event_type == "payment_due_now":
            print("Payment is due now:", data.get("title"), data.get("message"))
            # You can access fields like:
            # data["markAsPaidUrl"], data["url"], data["paymentDate"], etc.
            return {"success": True}

        elif event_type == "payment_due_upcoming":
            print("Upcoming payment:", data.get("title"), data.get("message"))
            return {"success": True}

        else:
            print("Unhandled event type:", event_type)
            raise HTTPException(status_code=400, detail="Unhandled event type")

    except JWTError as e:
        print("JWT verification failed:", str(e))
        raise HTTPException(status_code=401, detail="Token verification failed")
    except Exception as e:
        print("Error processing webhook:", str(e))
        raise HTTPException(status_code=500, detail="Internal server error")

Topics

Getting Started
Learn how to install the application with Docker.

Environment Variables
Learn how to configure the application.

Single Sign-On (SSO) Alternatives
Find detailed instructions on how to configure login with Keycloak or Authentik.

Self‐Hosting without SMTP Email Server
Find detailed instructions on how to set up and configure Mailpit as a local SMTP server for self-hosted environments.

Webhook Integration
Find detailed instructions on how to use webhook.

Disable New User Registration
Learn how to disable new user registration.

Building Docker Image
Learn how to build the Docker image locally.

Database Backup and Restore
Find detailed instructions on how to back up and restore the database, including automation tips.

Clone this wiki locally