Home Library Payments

Payments

Recording and tracking payments for properties

Overview

The payments module allows you to record payments for utility services and maintenance staff work. Each payment is linked to a property and can have an attached receipt.

Payment Tracking

Record payments with amount, date and expense type

Receipt Upload

Attach PDF, JPG or PNG files as payment confirmation

Owner Confirmation

Owner can confirm or reject the payment

Multi-Currency Support

Payments automatically convert to property country currency when different from payment currency.

Payment Architecture

Payments support two types of charges: utility expenses and rent. Each payment is linked to exactly one charge type.

Utilities / expenses
Payment
ExpenseChargeBilling period for an expense
PropertyExpenseRecurring expense configuration
ExpenseProviderService provider or recipient user
Rent
Payment
RentalChargeMonthly rent billing record
ContractRental agreement with tenant
Data Integrity: Each payment must be linked to either an expense charge (utilities) or a rental charge (rent). Both types cannot be set simultaneously.

Recipient Types

A payment can be addressed to one of two recipient types:

Service Provider

Utility service company (power company, gas company, water utility, etc.)

User

Maintenance staff (with MAINTENANCE role) for work performed

Recipient Fallback: The system first tries to get the recipient from PropertyExpense → ExpenseProvider. If not found, it falls back to ExpenseCharge → ServiceProvider for backward compatibility.

Currency Conversion

When viewing a payment, if the payment currency differs from the property's country official currency, the amount is automatically displayed in both currencies:

150.00 €
(7,521.66 ₴)

Conversion uses daily exchange rates from the National Bank of Ukraine with EUR as the base currency.

Supported Country Currencies

  • UA (Ukraine) → UAH (₴)
  • PL (Poland) → PLN (zł)
  • MD (Moldova) → MDL (L)
  • RO (Romania) → RON (lei)
  • CZ (Czech Republic) → CZK (Kč)
  • Eurozone countries → EUR (€) - no conversion needed

Confirmation Statuses

The owner or their agent can set the payment confirmation status:

Not specified

Default status when payment is created

Confirmed

Owner has reviewed and confirmed the payment

Rejected

Owner has rejected the payment as incorrect

Payment Visibility

Who sees payments depends on the user's role on the property:

Role Can See
LANDLORD / LANDLORD_AGENT All payments (active and inactive)
TENANT / TENANT_AGENT Own payments + active payments by others
MAINTENANCE Only payments where they are the recipient
Inactive Payments Inactive payments (is_active=false) are visible only to the author or property owner/agent.

File Upload

You can attach a receipt to a payment. Supported formats:

  • PDF - documents
  • JPG, JPEG, PNG - images
  • HEIC - iPhone photos (converted to JPG)

Files are stored in S3 cloud storage with a unique path for each payment.

Secure File Access: All payment files use HMAC-signed secure URLs to prevent unauthorized access. Direct S3 URLs are never exposed to clients.

Link with Receipts

Payments are linked to receipts through PaymentAllocation table. Multiple payments can be combined into a single receipt (e.g., rent + utilities).

Payment Outgoing payment from tenant
PaymentAllocation Links payment to receipt with allocated amount
Receipt Incoming payment confirmation from landlord

Receipt Combining

One receipt can combine multiple payments (e.g., rent + utilities in a single receipt). Each payment is linked to the receipt with the allocated amount.

Multi-Currency Allocation

Allocation amounts can differ from payment/receipt amounts when currencies are different (automatic conversion).

Learn More: For detailed information about receipts, see the Receipts.

REST API

Payments are available via REST API with JWT authorization:

GET    /api/v1/payments                              - My payments
GET    /api/v1/properties/{id}/payments              - Property payments
POST   /api/v1/properties/{id}/payments              - Create payment
GET    /api/v1/properties/{id}/payments/{pid}        - Payment details
PUT    /api/v1/properties/{id}/payments/{pid}        - Update payment
DELETE /api/v1/properties/{id}/payments/{pid}        - Delete payment
POST   /api/v1/properties/{id}/payments/{pid}/confirm - Confirm
POST   /api/v1/properties/{id}/payments/{pid}/reject  - Reject

Create Request Example

Utilities / expenses (utilities)

{
  "payment_date": "2026-01-15",
  "amount": "150.50",
  "currency_id": 1,
  "expense_charge_id": 42,
  "contract_id": 5,
  "payer_user_id": 10,
  "notes": "January electricity payment"
}

Rent (rent)

{
  "payment_date": "2026-02-05",
  "amount": "25000.00",
  "currency_id": 3,
  "rental_charge_id": 34,
  "contract_id": 31,
  "payer_user_id": 13,
  "notes": "February rent"
}
Required Fields: payment_date, amount, currency_id are always required. Provide exactly one of: expense_charge_id (utilities) or rental_charge_id (rent).

Example Response

{
  "data": {
    "id": 1,
    "payment_type": "expense",
    "property_id": 5,
    "property_name": "Apartment Kyiv",
    "payment_date": "2026-01-15",
    "amount": "1500.00",
    "amount_formatted": "1,500.00 ₴",
    "currency": { "id": 3, "code": "UAH", "symbol": "₴" },
    "expense_type": { "id": 2, "code": "ELECTRICITY", "name_key": "expense_type.electricity" },
    "rental_charge": null,
    "service_provider": { "id": 3, "name": "Kyivenergo" },
    "recipient_user": null,
    "is_active": true,
    "owner_confirmation": "CONFIRMED",
    "has_file": true,
    "file_url": "https://llm.com/file/...",
    "file_name": "receipt.pdf"
  }
}

Rental payment response

{
  "data": {
    "id": 500,
    "payment_type": "rental",
    "property_id": 5,
    "payment_date": "2026-02-05",
    "amount": "25000.00",
    "currency": { "id": 3, "code": "UAH", "symbol": "₴" },
    "expense_type": null,
    "rental_charge": {
      "id": 34,
      "charge_date": "2026-03-05",
      "period_start": "2026-02-05",
      "period_end": "2026-03-04",
      "rental_days": 28,
      "amount": "25000.00"
    },
    "service_provider": null,
    "is_active": true,
    "owner_confirmation": "CONFIRMED"
  }
}

API Notes

  • payment_type field indicates "expense" or "rental"
  • expense_charge_id links payment to a billing period
  • rental_charge_id links payment to a rent billing period
  • expense_charge_id and rental_charge_id are mutually exclusive
  • Use payment_type=rental or payment_type=expense to filter by type
  • Country currency conversion is automatic on frontend display
  • file_url uses HMAC-signed secure URLs with limited lifetime

Swagger / OpenAPI

Full API documentation with testing capability is available at /api/v1/doc