Skip to content

Investment Participation Flow

Complete user journey from strategy discovery to active investment management.

Overview

The investment flow includes:

  1. Strategy discovery and research
  2. Participation initiation
  3. Multi-step participation process (internal strategies)
  4. External provider redirect flow (external strategies)
  5. Payment and confirmation
  6. Portfolio management
  7. Returns tracking and maturity handling

Strategy Types

TypeKYCFlowManagement
InternalOn IWM Platform (Sumsub)Multi-step wizardFull control
ExternalOn Provider OR IWM (bi-directional sync)Redirect with deep SSOProvider handles

KYC Hub

The Invest platform is the KYC hub for the entire IWM ecosystem:

  • KYC verification is done on the Invest platform using Sumsub
  • KYC status is shared with Shop and Partner platforms within the region
  • Shop platform does NOT require KYC for purchases
  • External providers can receive IWM's KYC status OR sync their KYC back to IWM

Main Flow Diagram


Step Details

1. Strategy Discovery

Endpoint: GET /strategies

Query Parameters:

ParameterTypeDescription
categorystringCategory slug
riskLevelstringLOW, MEDIUM, HIGH, VERY_HIGH
minAmountnumberMinimum investment filter
maxReturnnumberMaximum expected return filter
durationstringSHORT (< 6mo), MEDIUM (6-12mo), LONG (> 12mo)
sortstringpopular, newest, return_desc, min_amount_asc
pagenumberPage number
limitnumberItems per page

Strategy List Item:

json
{
  "id": "uuid",
  "name": "Commercial Real Estate Fund",
  "slug": "commercial-real-estate-fund",
  "shortDescription": "Diversified portfolio of commercial properties",
  "riskLevel": "MEDIUM",
  "minAmount": 50000.0,
  "expectedReturnMin": 12.0,
  "expectedReturnMax": 18.0,
  "durationMonths": 24,
  "imageUrl": "https://cdn.../strategy.jpg",
  "participantsCount": 245,
  "totalInvested": 15000000.0,
  "status": "ACTIVE"
}

2. Strategy Details

Endpoint: GET /strategies/{slug}

Response:

json
{
  "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.0,
  "maxAmount": 5000000.0,
  "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.0,
    "averageInvestment": 61224.49
  },
  "status": "ACTIVE",
  "publishedAt": "2024-01-01T00:00:00Z"
}

3. Start Participation

Endpoint: POST /strategies/{id}/participate

Eligibility Requirements:

RequirementCheck
User authenticatedValid JWT token
Email verifieduser.email_verified_at IS NOT NULL
KYC approvedkyc_verification.status = 'APPROVED'
KYC level sufficientBased on investment amount
No pending participationFor same strategy

KYC Level Requirements:

KYC LevelMax Investment
BASICNot allowed
STANDARD$100,000
ENHANCEDUnlimited

Response:

json
{
  "participationId": "uuid",
  "strategyId": "uuid",
  "currentStep": 1,
  "totalSteps": 3,
  "status": "IN_PROGRESS",
  "nextStep": {
    "stepNumber": 1,
    "title": "Select Investment Amount",
    "stepType": "FORM",
    "config": {
      "minAmount": 1000,
      "maxAmount": 100000,
      "currency": "USD",
      "suggestedAmounts": [1000, 5000, 10000, 25000]
    }
  }
}

4. Step 1: Select Amount

Endpoint: POST /participations/{id}/steps/1

Request:

json
{
  "amount": 10000.0,
  "currency": "USD"
}

Validation Rules:

RuleConstraint
Amount>= strategy.min_amount
Amount<= strategy.max_amount (if set)
Amount<= user's KYC level limit
CurrencyMust match strategy currency

Error Scenarios:

ScenarioError CodeMessage
Below minimumBELOW_MINIMUM"Minimum investment is $X"
Above maximumABOVE_MAXIMUM"Maximum investment is $X"
KYC limit exceededKYC_LIMIT_EXCEEDED"Upgrade KYC for larger investments"

5. Step 2: Review Terms

Endpoint: POST /participations/{id}/steps/2

Request:

json
{
  "acceptTerms": true,
  "acceptRiskDisclosure": true,
  "acknowledgeNoGuarantee": true,
  "confirmOwnFunds": true
}

Required Acknowledgments:

FieldDescription
acceptTermsAccept investment terms
acceptRiskDisclosureAcknowledge risk disclosure
acknowledgeNoGuaranteeUnderstand returns not guaranteed
confirmOwnFundsConfirm using own funds

Recorded Data:

json
{
  "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:

json
{
  "paymentIntentId": "pi_xxx",
  "clientSecret": "pi_xxx_secret_xxx",
  "amount": 10000.0,
  "currency": "USD",
  "paymentMethods": ["card", "bank_transfer", "crypto"]
}

Payment Processing:

  1. Frontend creates Stripe Elements form
  2. User enters payment details
  3. Frontend calls stripe.confirmPayment()
  4. Stripe sends webhook to backend
  5. Backend updates participation status

Payment Confirmation:

  • Status changes to PENDING_APPROVAL
  • Participation submitted_at is set
  • User receives confirmation email

7. Confirmation and Activation

Approval Methods:

MethodCriteria
Auto-approvalAmount < $10,000, user has previous investments
Manual approvalAmount >= $10,000 or first-time investor

Portfolio Record Created:

json
{
  "id": "uuid",
  "userId": "user-uuid",
  "participationId": "participation-uuid",
  "strategyId": "strategy-uuid",
  "investedAmount": 10000.0,
  "currentValue": 10000.0,
  "totalReturns": 0.0,
  "currency": "USD",
  "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:

json
{
  "summary": {
    "totalInvested": 35000.0,
    "currentValue": 37850.0,
    "totalReturns": 2850.0,
    "overallReturnPercent": 8.14,
    "currency": "USD"
  },
  "investments": [
    {
      "id": "portfolio-uuid",
      "strategyName": "Commercial Real Estate Fund",
      "strategySlug": "commercial-real-estate-fund",
      "investedAmount": 10000.0,
      "currentValue": 10850.0,
      "totalReturns": 850.0,
      "returnPercent": 8.5,
      "status": "ACTIVE",
      "startDate": "2024-01-15",
      "maturityDate": "2026-01-15",
      "daysToMaturity": 365,
      "nextPayoutDate": "2024-04-15",
      "nextPayoutEstimate": 3000.0
    }
  ],
  "recentActivity": [
    {
      "type": "RETURN_CREDITED",
      "amount": 3000.0,
      "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:

json
{
  "portfolioId": "uuid",
  "investedAmount": 10000.0,
  "currentValue": 10850.0,
  "totalReturns": 850.0,
  "history": [
    {
      "period": "2024-Q1",
      "startValue": 10000.0,
      "endValue": 10300.0,
      "returnAmount": 300.0,
      "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

json
POST /portfolio/{id}/withdraw
{
  "withdrawalMethod": "BANK_TRANSFER",
  "bankDetails": {
    "accountNumber": "IBAN or account number",
    "bankName": "Bank Name",
    "swiftCode": "SWIFTXXX"
  }
}

Option B: Reinvest

json
POST /portfolio/{id}/reinvest
{
  "strategyId": "same-or-different-uuid",
  "amount": "FULL",
  "additionalAmount": 0
}

Reinvestment Options:

OptionDescription
Same strategyContinue in current strategy
Different strategyMove to another strategy
Partial reinvestWithdraw some, reinvest rest

11. Early Withdrawal

Endpoint: POST /portfolio/{id}/early-withdraw

Early Withdrawal Rules:

ConditionPenalty
Strategy allows early withdrawalstrategy.early_withdrawal_penalty (e.g., 5%)
Before 6 monthsAdditional 2% penalty
Before 3 monthsAdditional 5% penalty

Request:

json
{
  "amount": "FULL",
  "withdrawalMethod": "BANK_TRANSFER",
  "acknowledgedPenalty": true
}

Penalty Calculation Response:

json
{
  "currentValue": 108500.0,
  "penaltyPercent": 5.0,
  "penaltyAmount": 5425.0,
  "netWithdrawal": 103075.0,
  "confirmationRequired": true,
  "confirmationUrl": "/portfolio/{id}/early-withdraw/confirm"
}

Error Scenarios

Participation Errors

ScenarioHTTP CodeError CodeMessage
KYC not approved403KYC_REQUIRED"Complete identity verification first"
KYC level insufficient403KYC_UPGRADE_REQUIRED"Upgrade KYC for this investment amount"
Strategy closed422STRATEGY_CLOSED"This strategy is no longer accepting investments"
Already participating409ALREADY_PARTICIPATING"You have a pending participation"

Payment Errors

ScenarioHTTP CodeError CodeMessage
Payment declined422PAYMENT_DECLINED"Payment was declined"
Payment timeout408PAYMENT_TIMEOUT"Payment session expired"
Amount mismatch400AMOUNT_MISMATCH"Payment amount does not match"

Withdrawal Errors

ScenarioHTTP CodeError CodeMessage
Early withdrawal not allowed403EARLY_WITHDRAWAL_DISABLED"This strategy does not allow early withdrawal"
Already processing409WITHDRAWAL_PENDING"A withdrawal is already in progress"
Insufficient balance422INSUFFICIENT_BALANCE"Investment value is insufficient"