Investment Participation Flow
Complete user journey from strategy discovery to active investment management.
Overview
The investment flow includes:
- Strategy discovery and research
- Participation initiation
- Multi-step participation process
- Payment and confirmation
- Portfolio management
- Returns tracking and maturity handling
Main Flow Diagram
Step Details
1. Strategy Discovery
Endpoint: GET /strategies
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| category | string | Category slug |
| riskLevel | string | LOW, MEDIUM, HIGH, VERY_HIGH |
| minAmount | number | Minimum investment filter |
| maxReturn | number | Maximum expected return filter |
| duration | string | SHORT (< 6mo), MEDIUM (6-12mo), LONG (> 12mo) |
| sort | string | popular, newest, return_desc, min_amount_asc |
| page | number | Page number |
| limit | number | Items per page |
Strategy List Item:
{
"id": "uuid",
"name": "Commercial Real Estate Fund",
"slug": "commercial-real-estate-fund",
"shortDescription": "Diversified portfolio of commercial properties",
"riskLevel": "MEDIUM",
"minAmount": 50000.00,
"expectedReturnMin": 12.0,
"expectedReturnMax": 18.0,
"durationMonths": 24,
"imageUrl": "https://cdn.../strategy.jpg",
"participantsCount": 245,
"totalInvested": 15000000.00,
"status": "ACTIVE"
}2. Strategy Details
Endpoint: GET /strategies/{slug}
Response:
{
"id": "uuid",
"name": "Commercial Real Estate Fund",
"slug": "commercial-real-estate-fund",
"shortDescription": "Diversified portfolio of commercial properties",
"description": "Full HTML description with investment thesis...",
"terms": "Full terms and conditions...",
"riskLevel": "MEDIUM",
"riskDisclosure": "Investment risks description...",
"minAmount": 50000.00,
"maxAmount": 5000000.00,
"durationMonths": 24,
"expectedReturnMin": 12.0,
"expectedReturnMax": 18.0,
"payoutSchedule": "QUARTERLY",
"earlyWithdrawalAllowed": true,
"earlyWithdrawalPenalty": 5.0,
"documents": [
{
"name": "Investment Memorandum",
"type": "PDF",
"url": "https://cdn.../memorandum.pdf"
},
{
"name": "Risk Disclosure Statement",
"type": "PDF",
"url": "https://cdn.../risk-disclosure.pdf"
}
],
"participationSteps": [
{
"stepNumber": 1,
"title": "Select Investment Amount",
"stepType": "FORM",
"isRequired": true
},
{
"stepNumber": 2,
"title": "Review Terms & Risk Disclosure",
"stepType": "CONFIRMATION",
"isRequired": true
},
{
"stepNumber": 3,
"title": "Payment",
"stepType": "PAYMENT",
"isRequired": true
}
],
"category": {
"id": "uuid",
"name": "Real Estate",
"slug": "real-estate"
},
"stats": {
"participantsCount": 245,
"totalInvested": 15000000.00,
"averageInvestment": 61224.49
},
"status": "ACTIVE",
"publishedAt": "2024-01-01T00:00:00Z"
}3. Start Participation
Endpoint: POST /strategies/{id}/participate
Eligibility Requirements:
| Requirement | Check |
|---|---|
| User authenticated | Valid JWT token |
| Email verified | user.email_verified_at IS NOT NULL |
| KYC approved | kyc_verification.status = 'APPROVED' |
| KYC level sufficient | Based on investment amount |
| No pending participation | For same strategy |
KYC Level Requirements:
| KYC Level | Max Investment |
|---|---|
| BASIC | Not allowed |
| STANDARD | 1,000,000 RUB |
| ENHANCED | Unlimited |
Response:
{
"participationId": "uuid",
"strategyId": "uuid",
"currentStep": 1,
"totalSteps": 3,
"status": "IN_PROGRESS",
"nextStep": {
"stepNumber": 1,
"title": "Select Investment Amount",
"stepType": "FORM",
"config": {
"minAmount": 50000,
"maxAmount": 5000000,
"currency": "RUB",
"suggestedAmounts": [50000, 100000, 250000, 500000]
}
}
}4. Step 1: Select Amount
Endpoint: POST /participations/{id}/steps/1
Request:
{
"amount": 100000.00,
"currency": "RUB"
}Validation Rules:
| Rule | Constraint |
|---|---|
| Amount | >= strategy.min_amount |
| Amount | <= strategy.max_amount (if set) |
| Amount | <= user's KYC level limit |
| Currency | Must match strategy currency |
Error Scenarios:
| Scenario | Error Code | Message |
|---|---|---|
| Below minimum | BELOW_MINIMUM | "Minimum investment is X RUB" |
| Above maximum | ABOVE_MAXIMUM | "Maximum investment is X RUB" |
| KYC limit exceeded | KYC_LIMIT_EXCEEDED | "Upgrade KYC for larger investments" |
5. Step 2: Review Terms
Endpoint: POST /participations/{id}/steps/2
Request:
{
"acceptTerms": true,
"acceptRiskDisclosure": true,
"acknowledgeNoGuarantee": true,
"confirmOwnFunds": true
}Required Acknowledgments:
| Field | Description |
|---|---|
| acceptTerms | Accept investment terms |
| acceptRiskDisclosure | Acknowledge risk disclosure |
| acknowledgeNoGuarantee | Understand returns not guaranteed |
| confirmOwnFunds | Confirm using own funds |
Recorded Data:
{
"termsAcceptedAt": "2024-01-15T10:30:00Z",
"riskDisclosureAcceptedAt": "2024-01-15T10:30:00Z",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0..."
}6. Step 3: Payment
Create Payment Intent: POST /participations/{id}/payment/intent
Response:
{
"paymentIntentId": "pi_xxx",
"clientSecret": "pi_xxx_secret_xxx",
"amount": 100000.00,
"currency": "RUB",
"paymentMethods": ["card", "bank_transfer"]
}Payment Processing:
- Frontend creates Stripe Elements form
- User enters payment details
- Frontend calls
stripe.confirmPayment() - Stripe sends webhook to backend
- Backend updates participation status
Payment Confirmation:
- Status changes to
PENDING_APPROVAL - Participation
submitted_atis set - User receives confirmation email
7. Confirmation and Activation
Approval Methods:
| Method | Criteria |
|---|---|
| Auto-approval | Amount < 100,000 RUB, user has previous investments |
| Manual approval | Amount >= 100,000 RUB or first-time investor |
Portfolio Record Created:
{
"id": "uuid",
"userId": "user-uuid",
"participationId": "participation-uuid",
"strategyId": "strategy-uuid",
"investedAmount": 100000.00,
"currentValue": 100000.00,
"totalReturns": 0.00,
"currency": "RUB",
"status": "ACTIVE",
"startDate": "2024-01-15",
"maturityDate": "2026-01-15"
}Commission Triggered:
- Commission job enqueued for MLM processing
- Referring partner receives commission
- See Commission Lifecycle
8. Portfolio Dashboard
Endpoint: GET /users/me/portfolio
Response:
{
"summary": {
"totalInvested": 350000.00,
"currentValue": 378500.00,
"totalReturns": 28500.00,
"overallReturnPercent": 8.14,
"currency": "RUB"
},
"investments": [
{
"id": "portfolio-uuid",
"strategyName": "Commercial Real Estate Fund",
"strategySlug": "commercial-real-estate-fund",
"investedAmount": 100000.00,
"currentValue": 108500.00,
"totalReturns": 8500.00,
"returnPercent": 8.5,
"status": "ACTIVE",
"startDate": "2024-01-15",
"maturityDate": "2026-01-15",
"daysToMaturity": 365,
"nextPayoutDate": "2024-04-15",
"nextPayoutEstimate": 3000.00
}
],
"recentActivity": [
{
"type": "RETURN_CREDITED",
"amount": 3000.00,
"date": "2024-01-01",
"portfolioId": "portfolio-uuid"
}
]
}9. Returns Tracking
Returns Calculation Schedule:
- Daily: Update current_value based on strategy NAV
- Quarterly: Credit returns to user balance (if payout schedule is QUARTERLY)
Returns History Endpoint: GET /portfolio/{id}/returns
Response:
{
"portfolioId": "uuid",
"investedAmount": 100000.00,
"currentValue": 108500.00,
"totalReturns": 8500.00,
"history": [
{
"period": "2024-Q1",
"startValue": 100000.00,
"endValue": 103000.00,
"returnAmount": 3000.00,
"returnPercent": 3.0,
"paidOut": true,
"paidDate": "2024-04-01"
}
],
"projectedAnnualReturn": 12.0
}10. Maturity Handling
Maturity Check: Scheduled job runs daily at 00:00 UTC
Maturity Options:
Option A: Withdraw
POST /portfolio/{id}/withdraw
{
"withdrawalMethod": "BANK_TRANSFER",
"bankDetails": {
"accountNumber": "40817810xxx",
"bankName": "Sberbank",
"bik": "044525225"
}
}Option B: Reinvest
POST /portfolio/{id}/reinvest
{
"strategyId": "same-or-different-uuid",
"amount": "FULL",
"additionalAmount": 0
}Reinvestment Options:
| Option | Description |
|---|---|
| Same strategy | Continue in current strategy |
| Different strategy | Move to another strategy |
| Partial reinvest | Withdraw some, reinvest rest |
11. Early Withdrawal
Endpoint: POST /portfolio/{id}/early-withdraw
Early Withdrawal Rules:
| Condition | Penalty |
|---|---|
| Strategy allows early withdrawal | strategy.early_withdrawal_penalty (e.g., 5%) |
| Before 6 months | Additional 2% penalty |
| Before 3 months | Additional 5% penalty |
Request:
{
"amount": "FULL",
"withdrawalMethod": "BANK_TRANSFER",
"acknowledgedPenalty": true
}Penalty Calculation Response:
{
"currentValue": 108500.00,
"penaltyPercent": 5.0,
"penaltyAmount": 5425.00,
"netWithdrawal": 103075.00,
"confirmationRequired": true,
"confirmationUrl": "/portfolio/{id}/early-withdraw/confirm"
}Error Scenarios
Participation Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| KYC not approved | 403 | KYC_REQUIRED | "Complete identity verification first" |
| KYC level insufficient | 403 | KYC_UPGRADE_REQUIRED | "Upgrade KYC for this investment amount" |
| Strategy closed | 422 | STRATEGY_CLOSED | "This strategy is no longer accepting investments" |
| Already participating | 409 | ALREADY_PARTICIPATING | "You have a pending participation" |
Payment Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| Payment declined | 422 | PAYMENT_DECLINED | "Payment was declined" |
| Payment timeout | 408 | PAYMENT_TIMEOUT | "Payment session expired" |
| Amount mismatch | 400 | AMOUNT_MISMATCH | "Payment amount does not match" |
Withdrawal Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| Early withdrawal not allowed | 403 | EARLY_WITHDRAWAL_DISABLED | "This strategy does not allow early withdrawal" |
| Already processing | 409 | WITHDRAWAL_PENDING | "A withdrawal is already in progress" |
| Insufficient balance | 422 | INSUFFICIENT_BALANCE | "Investment value is insufficient" |