Signals
The django_midtrans.signals module provides Django signals dispatched during payment lifecycle events.
All signals send sender and keyword arguments. Connect handlers to react to payment state changes.
Payment Signals
payment_received
Dispatched when a new pending payment is created.
from django_midtrans.signals import payment_received
@receiver(payment_received)
def on_payment_received(sender, payment, notification, **kwargs):
print(f"New payment: {payment.order_id}")
Argument |
Type |
Description |
|---|---|---|
|
|
The payment instance. |
|
|
The notification that triggered this signal. |
payment_settled
Dispatched when a payment is successfully settled or captured.
from django_midtrans.signals import payment_settled
@receiver(payment_settled)
def on_payment_settled(sender, payment, notification, **kwargs):
# Fulfill the order
order = Order.objects.get(midtrans_order_id=payment.order_id)
order.status = "paid"
order.save()
payment_denied
Dispatched when a payment is denied (fraud or bank rejection).
from django_midtrans.signals import payment_denied
@receiver(payment_denied)
def on_payment_denied(sender, payment, notification, **kwargs):
send_payment_denied_email(payment.customer_email)
payment_cancelled
Dispatched when a payment is cancelled.
payment_expired
Dispatched when a payment expires (not paid within time limit).
payment_refunded
Dispatched when a payment is refunded (full or partial).
payment_failed
Dispatched when a payment fails.
Invoice Signals
invoice_created
Dispatched when a new invoice is created.
invoice_paid
Dispatched when an invoice is paid.
invoice_voided
Dispatched when an invoice is voided.
Subscription Signals
subscription_created
Dispatched when a new subscription is created.
subscription_charged
Dispatched when a subscription charge is processed.
subscription_disabled
Dispatched when a subscription is disabled.
subscription_cancelled
Dispatched when a subscription is cancelled.
Signal Handler Example
# myapp/signals.py
from django.dispatch import receiver
from django_midtrans.signals import (
payment_settled,
payment_expired,
payment_refunded,
)
@receiver(payment_settled)
def handle_payment_success(sender, payment, notification, **kwargs):
"""Send confirmation email and fulfill order."""
from myapp.models import Order
from myapp.tasks import send_confirmation_email
order = Order.objects.get(payment_order_id=payment.order_id)
order.mark_as_paid()
send_confirmation_email.delay(order.id)
@receiver(payment_expired)
def handle_payment_expired(sender, payment, notification, **kwargs):
"""Release reserved stock."""
from myapp.models import Order
order = Order.objects.get(payment_order_id=payment.order_id)
order.release_stock()
@receiver(payment_refunded)
def handle_refund(sender, payment, notification, **kwargs):
"""Notify customer of refund."""
from myapp.tasks import send_refund_email
send_refund_email.delay(payment.customer_email, str(payment.refund_amount))
Register in your AppConfig.ready():
# myapp/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = "myapp"
def ready(self):
import myapp.signals # noqa: F401
Complete Signal Reference
Signal |
Trigger |
Arguments |
|---|---|---|
|
New pending payment via webhook |
|
|
Payment settled/captured |
|
|
Payment denied |
|
|
Payment cancelled |
|
|
Payment expired |
|
|
Payment refunded |
|
|
Payment failed |
|
|
Invoice created |
|
|
Invoice paid |
|
|
Invoice voided |
|
|
Subscription created |
|
|
Subscription charged |
|
|
Subscription disabled |
|
|
Subscription cancelled |
|