Investment Deposits
A term deposit whose return depends on what the pooled funds actually earned. The depositor and the account-keeper agree a split of profit; the depositor bears the loss.
That is the trade. In exchange for no guaranteed rate, the depositor gets a share of results that may be better than a rate — and may be nothing at all. The API keeps the two apart everywhere it can: there is no rate field, indicative_rate is explicitly labelled as a look at past periods, and record_loss reduces the depositor's balance while leaving the keeper's side untouched.
Base path: /api/v1/pfp/investment-deposits · Religious reading: Mudaraba deposit
Two forms
investment_type | Where the money goes |
|---|---|
general (default) | The general investment pool |
restricted | Only the fields named in investment_restrictions |
Statuses
pending ──activate──> active ──mature──> matured ──close──> closed
│ │
│ └──renew──> active
│
└──withdraw──> withdrawn ──close──> closed
| Status | Meaning |
|---|---|
pending | Application recorded, money not yet accepted |
active | Open; profit and loss are recorded against it |
matured | The term has run |
withdrawn | Taken out early |
closed | Money paid out. Terminal |
Open a deposit
POST /api/v1/pfp/investment-deposits
{
"customer_id": "8f2a1c44-0b6e-4d51-9a3f-1c8e5b7d2a90",
"region": "RU",
"currency": "RUB",
"initial_amount": "50000000",
"term_months": 12,
"profit_sharing_ratio": { "bank": 20, "customer": 80 },
"investment_type": "general",
"distribution_frequency": "quarterly",
"indicative_rate": 7,
"early_withdrawal_allowed": true,
"early_withdrawal_penalty_percent": 50,
"auto_renewal": false
}
| Field | Type | Required | Notes |
|---|---|---|---|
customer_id | uuid | ✅ | The depositor |
region | string | ✅ | Deposit region |
currency | string | ✅ | ISO 4217 |
initial_amount | string | ✅ | Minor units, above zero |
term_months | integer | ✅ | 1–120 |
profit_sharing_ratio | object | ✅ | {"bank": n, "customer": m}, whole percent, must sum to 100 |
investment_type | enum | — | general (default) | restricted |
investment_restrictions | array | — | Fields the money may go into, for restricted |
distribution_frequency | enum | — | monthly | quarterly | semi_annually | at_maturity |
indicative_rate | integer | — | Whole percent — see below |
early_withdrawal_allowed | boolean | — | Gates the early-withdrawal transition |
early_withdrawal_penalty_percent | integer | — | 0–100. Applies to the depositor's accrued share, not to the deposit |
auto_renewal | boolean | — | |
account_id, product_id, opened_by, metadata | — | — |
indicative_rate is not a rate
It records what comparable periods have returned. It is not promised, not accrued, and not used in any calculation the platform performs — nothing reads it back.
Show it to a depositor only with the word "indicative" attached, and never in the position where a fixed-rate product would show its rate. A number in that position is read as a commitment regardless of the label beside it, and a commitment is precisely what this product does not make.
distribution_frequency: "at_maturity" means exactly that — the first and only distribution date is the maturity date, not a step along the calendar.
Activate
POST /api/v1/pfp/investment-deposits/{id}/activate
{
"compliance_review": {
"approved_by": "Product Committee, minutes 22/2026"
}
}
pending → active. Sets the opening date, the maturity date and the first distribution date.
The body is optional in the secular reading. If you send a compliance_review, it is validated — approved_by must be present and non-blank. In the religious reading the conclusion is required, and activation without one fails.
Unlike the contract products, there is no separate submit/review pair here: the conclusion, if any, is attached at the moment of opening.
Profit and loss
Distribute profit
POST /api/v1/pfp/investment-deposits/{id}/profit
{ "gross_profit": "1200000", "period_end_date": "2026-12-31" }
Only from active. Split by profit_sharing_ratio; the depositor's share is added to current_value and to customer_profit_share, the keeper's to bank_profit_share. Recorded in profit_distributions:
{
"profit_distributions": [
{
"date": "2026-12-31",
"gross_profit": "1200000",
"customer_share": "960000",
"bank_share": "240000"
}
]
}
period_end_date is optional and defaults to today.
Zero is a legitimate report. A period that earned nothing still closes and still advances the next distribution date. Negative is refused — that is a loss, and it has its own transition.
Record a loss
POST /api/v1/pfp/investment-deposits/{id}/loss
{ "amount": "300000", "period_end_date": "2027-03-31" }
Reduces current_value — the depositor's money. The keeper's side is untouched, because the keeper put in no money: what it loses is the work.
Zero is refused here. period_end_date is optional and defaults to today.
Ending the deposit
Maturity
POST /api/v1/pfp/investment-deposits/{id}/mature
No body. active → matured, and only if the maturity date has actually arrived. A twelve-month deposit cannot be matured today; the depositor would lose the distributions still due.
Renew
POST /api/v1/pfp/investment-deposits/{id}/renew
{ "term_months": 24, "profit_sharing_ratio": { "bank": 25, "customer": 75 } }
Only from matured; both fields are optional and default to the existing terms. What accumulated becomes the new principal, and the deposit returns to active.
A new ratio is validated exactly as at opening — it must still sum to 100. A renewed deposit closes at its new maturity, like any other.
Early withdrawal
POST /api/v1/pfp/investment-deposits/{id}/withdraw
{ "closed_by": "branch-kzn-04" }
Only from active, and only if early_withdrawal_allowed was set at opening. Otherwise the request is refused:
{
"error": "unprocessable_entity",
"details": {
"early_withdrawal_allowed": ["досрочное снятие условиями не предусмотрено"]
}
}
The penalty is taken from the depositor's accrued profit share, not from the deposit itself:
penalty = customer_profit_share × early_withdrawal_penalty_percent / 100
final_value = max(current_value − penalty, 0)
What was put in is not cut by withdrawing early — only what was earned on it is. With early_withdrawal_penalty_percent: 50 and an accrued share of 960 000, the penalty is 480 000; the principal stays whole.
The breakdown is written to metadata.early_withdrawal:
{
"early_withdrawal": {
"penalty_amount": "480000",
"penalty_percent": "50",
"final_value": "50480000"
}
}
Close
POST /api/v1/pfp/investment-deposits/{id}/close
{ "closed_by": "branch-kzn-04" }
From matured or withdrawn. Sets closed_at. Terminal — a closed deposit cannot be closed again, and its closing date cannot be overwritten.
List and read
GET /api/v1/pfp/investment-deposits
| Query parameter | Values |
|---|---|
status | pending | active | matured | withdrawn | closed |
region | deposit region |
type | general | restricted |
customer_id | uuid |
env | test | prod |
GET /api/v1/pfp/investment-deposits/{id}