A Django app for handling Razorpay Instant Payment Notification (IPN) webhook events, designed to manage payment, order, and subscription notifications seamlessly with support for signal-based event tracking.
Install the package via pip:
bash
pip install razorpay-ipn-django-handler
In your Django settings.py
, add razorpay_ipn_django_handler
:
python
INSTALLED_APPS = [
...,
"razorpay_ipn_django_handler",
]
In your project’s urls.py
, include the app’s URL configuration for webhook notifications:
```python from django.urls import path, include
urlpatterns = [ ..., path("payment/razorpay/", include("razorpayipndjango_handler.urls")), ] ```
For example, if your server is https://yourdomain.com
, Razorpay notifications will be processed at https://yourdomain.com/payment/razorpay/webhook/
.
Note: Customize the
"payment/razorpay/"
URL to suit your structure if needed.
Add your Razorpay credentials in settings.py
using environment variables:
python
RAZORPAY_WEBHOOK_SECRET = "your_webhook_secret_here"
RAZORPAY_API_KEY = "your_api_key_here"
RAZORPAY_API_SECRET = "your_api_secret_here"
Replace the placeholders with your actual credentials from the Razorpay Dashboard.
Run migrations to create the necessary database tables:
bash
python manage.py makemigrations
python manage.py migrate
The app provides signals for handling valid and invalid IPN events, allowing custom processing based on event types.
In one of your app files, such as signals.py
, register handlers for IPN events:
```python from django.dispatch import receiver from razorpayipndjangohandler.signals import validrazorpayipnreceived, invalidrazorpayipnreceived from razorpayipndjangohandler.models import RazorpayIPN
@receiver(validrazorpayipnreceived) def handlevalid_ipn(sender, instance, **kwargs): print("Received valid IPN event:", instance.event) # Process the IPN instance as needed
@receiver(invalidrazorpayipnreceived) def handleinvalid_ipn(sender, **kwargs): print("Invalid IPN received") # Log or handle invalid IPN events ```
Here, instance
provides a RazorpayIPN
object containing event data like event_type
, payment_id
, and other Razorpay IPN-related information.
The following models are included to manage event data and related details effectively:
Represents an IPN event with fields to track event type, account ID, signature verification, and related details.
Tracks payment details including amount, status, method, and optional metadata such as UPI, card, or wallet details.
Captures subscription events, including plan ID, quantity, status, schedule changes, and metadata.
Records refund details, including refund amount, status, batch ID, and additional notes.
Stores order-specific details such as amount, status, receipt number, and custom notes.
These models make it easier to track Razorpay events, allowing you to link each IPN event to associated payments, subscriptions, refunds, and orders as per your requirements.
To verify a Razorpay webhook signature, use the verify_signature
method on a RazorpayIPN
instance:
python
ipn_instance = RazorpayIPN.objects.create(payload=payload_data)
signature_valid = ipn_instance.verify_signature(body=request_body, signature=header_signature)
if signature_valid:
# Process the event
else:
# Handle invalid signature
In your signal handler, you can access the event data for custom processing:
python
@receiver(valid_razorpay_ipn_received)
def process_payment_event(sender, instance, **kwargs):
if instance.event_type == 'payment.authorized':
# Add logic to handle authorized payment events
elif instance.event_type == 'subscription.activated':
# Add logic to handle subscription activation
We welcome contributions to enhance the functionality of this library. Feel free to open issues, suggest features, or submit pull requests on GitHub.
This project is licensed under the MIT License. See the LICENSE file for more details.
I am [Arpan Sahu], a developer specializing in web development, payment integrations, and more. Feel free to check out my portfolio to learn more about my work:
If you have any questions or are interested in collaborating, please reach out via my portfolio contact form or directly through LinkedIn.