Skip to content

Implement Invoice model #38

Description

@codebestia

The Python Invoice model must be a faithful mirror of the Soroban smart contract struct. There are no line items — the contract models an invoice as a single description + amount + token tuple. All monetary fields (amount, amount_paid, amount_refunded) map to Python Decimal (from i128). All timestamp fields (date_created, date_paid, expires_at) map to Python datetime (converted from u64 Unix timestamps). The id field is the u64 on-chain invoice ID, mapped to Python int.

Proposed Steps:

  • Create src/shade/models/invoice.py.
  • Define InvoiceStatus as a StrEnum with values: pending, paid, expired, partially_paid, refunded.
  • Define Invoice(ShadeObject) with fields: id: int, description: str, amount: Decimal, token: str, status: InvoiceStatus, merchant_id: int, payer: Optional[str], date_created: datetime, date_paid: Optional[datetime], amount_paid: Decimal, amount_refunded: Decimal, expires_at: Optional[datetime].
  • Add computed properties: is_paid: bool, is_expired: bool, outstanding: Decimal.
  • Write _from_contract_dict(data: dict) classmethod for u64 → int and i128 → Decimal conversions.

Acceptance Criteria:

  • Invoice.from_dict(contract_response) populates all fields correctly.
  • invoice.amount is a Decimal, not an int or float.
  • invoice.date_created is a datetime, not an int.
  • invoice.payer is None for an unpaid invoice.
  • invoice.is_expired returns True when expires_at is in the past.
  • invoice.outstanding equals amount - amount_paid for a partially paid invoice.
  • The model has no line_items, customer_email, payment_url, or total fields.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions