Models

All models use UUIDv4 primary keys and include created_at/updated_at timestamps via the TimeStampedModel abstract base class.

Plan

Defines a subscription plan with pricing and billing schedule.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

name

CharField(255)

Plan display name

slug

SlugField (unique)

URL-friendly identifier, used as lookup field

description

TextField

Plan description

price

DecimalField(12,2)

Price per interval

currency

CharField(3)

Currency code (default: IDR)

interval

PositiveIntegerField

Number of interval units (default: 1)

interval_unit

CharField(10)

day, week, or month

trial_period_days

PositiveIntegerField

Trial duration in days (default: 0)

max_cycles

PositiveIntegerField

Max billing cycles, 0 = unlimited

status

CharField(10)

active, inactive, or archived

features

JSONField

Dict of feature flags/limits

metadata

JSONField

Arbitrary metadata

sort_order

PositiveIntegerField

Display ordering

Ordering: sort_order, price


Subscription

Represents a user’s subscription to a plan, synced with Midtrans.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

user

ForeignKey(User)

Subscriber (CASCADE)

plan

ForeignKey(Plan)

Associated plan (PROTECT)

status

CharField(20)

See status choices below

payment_type

CharField(20)

Payment method used

midtrans_subscription_id

CharField(255)

Midtrans subscription ID for native recurring

midtrans_token

CharField(500)

Saved card token or GoPay account ID

current_period_start

DateTimeField

Start of current billing period

current_period_end

DateTimeField

End of current billing period

trial_end

DateTimeField

Trial period end date

billing_cycle_count

PositiveIntegerField

Number of completed billing cycles

next_billing_date

DateTimeField

When next charge will be created

cancel_at_period_end

BooleanField

Cancel when current period ends

cancelled_at

DateTimeField

When cancellation was requested

cancellation_reason

TextField

Reason for cancellation

customer_first_name

CharField(100)

Customer first name for Midtrans

customer_last_name

CharField(100)

Customer last name

customer_email

EmailField

Customer email

customer_phone

CharField(20)

Customer phone

metadata

JSONField

Arbitrary metadata

Subscription Status Choices

Status

Description

pending

Created, awaiting first payment

trialing

In free trial period

active

Active and paid

past_due

Payment failed, in grace period

paused

Temporarily paused by user/admin

cancelled

Permanently cancelled

expired

Expired (max cycles reached or grace period ended)

Subscription Payment Types

credit_card, gopay, bank_transfer, echannel (Mandiri Bill), qris, shopeepay, wallet

Computed Properties

  • is_activeTrue if status is active or trialing

  • is_in_grace_periodTrue if past_due and within GRACE_PERIOD_DAYS

  • has_accessTrue if is_active or is_in_grace_period


Payment

Individual payment transaction tracked via Midtrans Core API.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

subscription

ForeignKey(Subscription)

Related subscription (nullable for standalone payments)

user

ForeignKey(User)

Payer

order_id

CharField(255)

Unique Midtrans order ID (e.g., SUB-A1B2C3D4E5F6)

midtrans_transaction_id

CharField(255)

Midtrans transaction ID

payment_type

CharField(30)

Payment method

status

CharField(20)

Transaction status from Midtrans

fraud_status

CharField(20)

Fraud detection result

gross_amount

DecimalField(12,2)

Total charge amount

currency

CharField(3)

Currency code

refund_amount

DecimalField(12,2)

Amount refunded

payment_details

JSONField

VA numbers, QR URLs, redirect URLs

transaction_time

DateTimeField

When Midtrans created the transaction

settlement_time

DateTimeField

When payment was settled

expiry_time

DateTimeField

When payment expires

midtrans_response

JSONField

Full Midtrans API response

is_retry

BooleanField

Whether this is a retry charge

retry_count

PositiveIntegerField

Retry attempt number

metadata

JSONField

Arbitrary metadata

Payment Status Choices

pending, capture, settlement, deny, cancel, expire, refund, partial_refund, authorize, failure

Computed Properties

  • is_successfulTrue if settlement or capture

  • is_paidTrue if settlement or (capture + fraud_status == "accept")


Invoice

Invoice generated for each billing cycle.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

invoice_number

CharField(50)

Unique number (e.g., INV-202501-00001)

subscription

ForeignKey(Subscription)

Related subscription

payment

OneToOneField(Payment)

Related payment (nullable)

user

ForeignKey(User)

Invoice recipient

status

CharField(10)

draft, issued, paid, void, overdue, refunded

subtotal

DecimalField(12,2)

Pre-tax amount

tax_amount

DecimalField(12,2)

Tax amount

discount_amount

DecimalField(12,2)

Discount amount

total_amount

DecimalField(12,2)

Final total

currency

CharField(3)

Currency code

issue_date

DateField

Date invoice was issued

due_date

DateField

Payment due date

paid_date

DateField

Date payment was received

period_start

DateTimeField

Billing period start

period_end

DateTimeField

Billing period end

notes

TextField

Invoice notes

void_reason

TextField

Reason for voiding


InvoiceItem

Line item on an invoice.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

invoice

ForeignKey(Invoice)

Parent invoice

description

CharField(500)

Item description

quantity

PositiveIntegerField

Quantity (default: 1)

unit_price

DecimalField(12,2)

Price per unit

total_price

DecimalField(12,2)

Auto-calculated: quantity × unit_price


WebhookLog

Logs every incoming Midtrans webhook notification.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

order_id

CharField(255)

Order ID from notification

midtrans_transaction_id

CharField(255)

Midtrans transaction ID

transaction_status

CharField(30)

Status from Midtrans

payment_type

CharField(30)

Payment type

fraud_status

CharField(20)

Fraud detection result

gross_amount

CharField(30)

Amount (as string from Midtrans)

signature_key

TextField

SHA-512 signature from Midtrans

status

CharField(20)

Processing status: received, processed, failed, invalid, duplicate

raw_payload

JSONField

Full webhook payload

error_message

TextField

Error details if processing failed

ip_address

GenericIPAddressField

Sender IP

processed_at

DateTimeField

When processing completed


NotificationLog

Logs outgoing notifications (email, in-app) sent to users.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

user

ForeignKey(User)

Recipient user

subscription

ForeignKey(Subscription)

Related subscription (nullable)

payment

ForeignKey(Payment)

Related payment (nullable)

notification_type

CharField(30)

Type (see choices below)

channel

CharField(10)

email, webhook, or in_app

status

CharField(10)

queued, sent, failed, skipped

subject

CharField(500)

Message subject

body

TextField

Message body

recipient

CharField(255)

Recipient address

error_message

TextField

Error details

sent_at

DateTimeField

When notification was sent

Notification Types

payment_success, payment_failed, payment_pending, subscription_created, subscription_activated, subscription_cancelled, subscription_expired, subscription_renewed, subscription_paused, subscription_resumed, invoice_issued, invoice_paid, invoice_overdue, expiry_reminder, payment_retry, refund_processed


Wallet

User wallet for holding balance used to pay subscriptions.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

user

OneToOneField(User)

Wallet owner

balance

DecimalField(15,2)

Current balance

currency

CharField(3)

Currency code

is_active

BooleanField

Whether wallet is active

Computed Properties

  • has_sufficient_balanceTrue if balance > 0

  • can_afford(amount)True if is_active and balance >= amount


WalletTransaction

Record of every wallet balance change.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

wallet

ForeignKey(Wallet)

Parent wallet

transaction_type

CharField(30)

top_up, subscription_payment, refund, adjustment

amount

DecimalField(15,2)

Positive = credit, negative = debit

balance_before

DecimalField(15,2)

Balance before transaction

balance_after

DecimalField(15,2)

Balance after transaction

reference_type

CharField(50)

Related object type (topup, subscription, payment)

reference_id

CharField(255)

UUID of related object

description

CharField(500)

Human-readable description


TopUp

Top-up request linked to a Midtrans payment for crediting wallet.

Field

Type

Description

id

UUIDField (PK)

Auto-generated UUID

wallet

ForeignKey(Wallet)

Target wallet

user

ForeignKey(User)

Requester

amount

DecimalField(15,2)

Top-up amount

payment_type

CharField(20)

Payment method

status

CharField(20)

pending, success, failed, expired

order_id

CharField(255)

Unique Midtrans order ID (e.g., TOPUP-A1B2C3D4E5F6)

midtrans_transaction_id

CharField(255)

Midtrans transaction ID

payment_details

JSONField

VA numbers, QR URLs

midtrans_response

JSONField

Full Midtrans response


Entity Relationship Diagram

See Architecture Diagrams for the full ER diagram of all models.