Quick Start
Get a payment running in 5 minutes.
1. Add to INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
# Optional: Unfold admin (must be BEFORE django.contrib.admin)
"unfold",
"unfold.contrib.filters",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# Required third-party
"rest_framework",
"django_celery_beat", # Optional: only if using Celery Beat
# The package
"django_midtrans",
]
2. Configure Midtrans Settings
# settings.py
import os
MIDTRANS = {
"SERVER_KEY": os.environ.get("MIDTRANS_SERVER_KEY", ""),
"CLIENT_KEY": os.environ.get("MIDTRANS_CLIENT_KEY", ""),
"MERCHANT_ID": os.environ.get("MIDTRANS_MERCHANT_ID", ""),
"IS_PRODUCTION": False,
"NOTIFICATION_URL": os.environ.get("MIDTRANS_NOTIFICATION_URL", ""),
}
3. Add URL Routes
# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("api/midtrans/", include("django_midtrans.urls")),
]
4. Run Migrations
python manage.py migrate django_midtrans
This creates 7 database tables:
midtrans_payment— Payment recordsmidtrans_paymentitem— Line items for each paymentmidtrans_notification— Webhook notification audit logmidtrans_invoice— Invoice recordsmidtrans_invoiceitem— Invoice line itemsmidtrans_subscription— Recurring payment subscriptionsmidtrans_refund— Refund records
5. Create Your First Payment
from django_midtrans.services import PaymentService
service = PaymentService()
# Create a Bank Transfer (BCA Virtual Account) payment
payment = service.create_charge(
payment_type="bank_transfer",
gross_amount=150000,
order_id="ORDER-001",
bank="bca",
customer_details={
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"phone": "081234567890",
},
item_details=[
{
"id": "ITEM-1",
"name": "T-Shirt",
"price": 150000,
"quantity": 1,
},
],
)
# The payment is now created in Midtrans and stored in your database
print(payment.order_id) # "ORDER-001"
print(payment.va_number) # "1234567890123456"
print(payment.transaction_status) # "pending"
print(payment.is_pending) # True
print(payment.expiry_time) # datetime when VA expires
6. Handle Webhook Notifications
When the customer pays, Midtrans will send a webhook notification to your NOTIFICATION_URL. The package handles this automatically:
# your_app/signals.py
from django.dispatch import receiver
from django_midtrans.signals import payment_settled
@receiver(payment_settled)
def handle_payment_success(sender, notification, payload, **kwargs):
order_id = payload.get("order_id")
# Update your order status, send email, etc.
print(f"Payment settled for order {order_id}!")
Make sure to import this in your app’s apps.py:
# your_app/apps.py
from django.apps import AppConfig
class YourAppConfig(AppConfig):
name = "your_app"
def ready(self):
import your_app.signals # noqa
Next Steps
Configuration — Full configuration reference
Payment Methods — All payment methods with examples
Webhook Notifications — Webhook setup and handling
Signals Reference — All available lifecycle signals
Celery & Async Tasks — Async tasks and periodic scheduling