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.
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
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:
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:
Default status when payment is created
Owner has reviewed and confirmed the payment
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 |
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.
Link with Receipts
Payments are linked to receipts through PaymentAllocation table. Multiple payments can be combined into a single receipt (e.g., rent + utilities).
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).
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"
}
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