Models

All models are in django_athm.models.

Payment

Payment transaction from ATH Móvil.

Fields

Field Type Description
ecommerce_id UUID Primary key - ATH Móvil transaction ID
reference_number str Unique reference (populated on completion)
daily_transaction_id str ATH Móvil daily transaction ID
status str Payment status
total Decimal Total amount
subtotal Decimal Subtotal before tax
tax Decimal Tax amount
fee Decimal ATH Móvil processing fee
net_amount Decimal Net amount after fees
total_refunded_amount Decimal Total amount refunded
customer_name str Customer name
customer_phone str Customer phone
customer_email str Customer email
client ForeignKey Associated Client record
metadata_1 str Custom metadata (max 40 chars)
metadata_2 str Custom metadata (max 40 chars)
message str Optional message
business_name str Business name
transaction_date datetime Transaction completion date
created_at datetime Record creation timestamp
updated_at datetime Last modification timestamp

Status Choices

class Status(models.TextChoices):
    OPEN = "OPEN"           # Awaiting customer confirmation
    CONFIRM = "CONFIRM"     # Awaiting authorization
    COMPLETED = "COMPLETED" # Successfully completed
    CANCEL = "CANCEL"       # Cancelled
    EXPIRED = "EXPIRED"     # Expired

Properties

payment.is_successful      # True if COMPLETED
payment.is_refundable      # True if completed with refundable amount
payment.refundable_amount  # Decimal amount available for refund

Query Examples

from django_athm.models import Payment

# Completed payments
Payment.objects.filter(status=Payment.Status.COMPLETED)

# Refundable payments
from django.db.models import F
Payment.objects.filter(
    status=Payment.Status.COMPLETED,
    total__gt=F("total_refunded_amount")
)

# Payment with refunds
payment = Payment.objects.prefetch_related("refunds").get(ecommerce_id=uuid)

# Date range filter
from datetime import datetime
Payment.objects.filter(
    created_at__gte=datetime(2025, 1, 1),
    created_at__lte=datetime(2025, 1, 31)
)

Refund

Refund for a payment.

Fields

Field Type Description
id UUID Primary key
payment ForeignKey Related Payment
reference_number str Unique refund reference
daily_transaction_id str ATH Móvil daily transaction ID
amount Decimal Refund amount
message str Refund message (max 50 chars)
status str Status (always "COMPLETED")
customer_name str Customer name
customer_phone str Customer phone
customer_email str Customer email
client ForeignKey Associated Client record
transaction_date datetime Refund transaction date
created_at datetime Record creation timestamp

Query Examples

from django_athm.models import Refund

# Refunds for a payment
payment.refunds.all()

# Recent refunds
from datetime import datetime
Refund.objects.filter(created_at__gte=datetime(2025, 1, 1))

WebhookEvent

Webhook event received from ATH Móvil.

Fields

Field Type Description
id UUID Primary key
idempotency_key str Unique key for deduplication
event_type str Event type
remote_ip str IP address of webhook request
payload JSON Raw JSON payload
processed bool Whether processed successfully
payment ForeignKey Associated Payment (if any)
refund ForeignKey Associated Refund (if any)
created_at datetime Record creation timestamp
updated_at datetime Last modification timestamp

Event Types

class Type(models.TextChoices):
    SIMULATED = "simulated"
    PAYMENT_RECEIVED = "payment"
    DONATION_RECEIVED = "donation"
    REFUND_SENT = "refund"
    ECOMMERCE_COMPLETED = "ecommerce_completed"
    ECOMMERCE_CANCELLED = "ecommerce_cancelled"
    ECOMMERCE_EXPIRED = "ecommerce_expired"
    UNKNOWN = "unknown"

Client

Customer record identified by phone number. Automatically created/updated when processing webhooks or syncing transactions.

Fields

Field Type Description
id UUID Primary key
phone_number str Unique phone (normalized to digits)
name str Customer name
email str Customer email
created_at datetime Record creation timestamp
updated_at datetime Last modification timestamp

Query Examples

from django_athm.models import Client

# Client by phone
client = Client.objects.get(phone_number="7871234567")

# Client's payments and refunds
client.payments.all()
client.refunds.all()

# Repeat customers
from django.db.models import Count
Client.objects.annotate(
    payment_count=Count("payments")
).filter(payment_count__gt=1)