> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ndovu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Invest for a customer

> Creates a Payment for one plan. Whether it is an initial investment or a top-up is decided from the customer's holdings. For BANK_TRANSFER, the bank details to pay into are provided in the response, and the payment reference is required as the memo (narration) on the transfer; for MPESA, an STK push goes to phoneNumber. Resend a timed-out request with the same Idempotency-Key: you get the original Payment back, never a second one. After a FAILED Payment, use a new key.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v3/partners/{shortName}/customers/{externalUserId}/invest
openapi: 3.0.0
info:
  title: Ndovu Partner API
  description: API for partners distributing Ndovu investment products to their customers.
  version: '3'
  contact: {}
servers:
  - url: https://be-dev-1.dev.ndovu.co
    description: Development
security: []
tags: []
paths:
  /api/v3/partners/{shortName}/customers/{externalUserId}/invest:
    post:
      tags:
        - partners
      summary: Invest for a customer
      description: >-
        Creates a Payment for one plan. Whether it is an initial investment or a
        top-up is decided from the customer's holdings. For BANK_TRANSFER, the
        bank details to pay into are provided in the response, and the payment
        reference is required as the memo (narration) on the transfer; for
        MPESA, an STK push goes to phoneNumber. Resend a timed-out request with
        the same Idempotency-Key: you get the original Payment back, never a
        second one. After a FAILED Payment, use a new key.
      operationId: PartnerMoneyController_invest_v3
      parameters:
        - name: shortName
          required: true
          in: path
          description: Your partner short name
          schema:
            type: string
        - name: externalUserId
          required: true
          in: path
          description: Your own ID for the customer
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          description: >-
            Generate one per intended investment (a UUID is recommended) and
            resend it on retries. The same key with the same body returns the
            original Payment; with a different body, 409.
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerInvestDto'
            examples:
              BANK_TRANSFER:
                value:
                  planId: 12
                  amount: 5000
                  currency: KES
                  channel: BANK_TRANSFER
              MPESA:
                value:
                  planId: 12
                  amount: 5000
                  currency: KES
                  channel: MPESA
                  phoneNumber: '+254712345678'
      responses:
        '200':
          description: Payment already created with this Idempotency-Key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerInvestResponseDto'
        '201':
          description: Payment created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerInvestResponseDto'
        '400':
          description: >-
            IDEMPOTENCY_KEY_REQUIRED, or the amount is below the plan minimum
            for this currency
        '403':
          description: FUNDING_METHOD_NOT_ENABLED or PARTNER_DISABLED
        '404':
          description: CUSTOMER_NOT_FOUND or PLAN_NOT_FOUND
        '409':
          description: IDEMPOTENCY_KEY_REUSED
        '422':
          description: PLAN_NOT_INVESTABLE
      security:
        - bearer: []
components:
  schemas:
    PartnerInvestDto:
      type: object
      properties:
        planId:
          type: number
          example: 12
          description: A plan id from GET plans
        amount:
          type: number
          minimum: 1
          example: 5000
        currency:
          enum:
            - KES
            - USD
            - RWF
            - TZS
            - EUR
            - GBP
          type: string
          example: KES
        channel:
          enum:
            - MPESA
            - BANK_TRANSFER
          type: string
          example: BANK_TRANSFER
        phoneNumber:
          type: string
          example: '+254712345678'
          description: >-
            Required for MPESA: the number that receives the STK push. Any valid
            number; it need not be the customer's own
      required:
        - planId
        - amount
        - currency
        - channel
    PartnerInvestResponseDto:
      type: object
      properties:
        reference:
          type: string
          example: NDV7F3K9Q
          description: >-
            The PaymentReference. For a bank transfer, quote it as the transfer
            memo
        channel:
          type: string
          enum:
            - MPESA
            - BANK_TRANSFER
        amount:
          type: number
          example: 5000
        finalAmount:
          type: number
          example: 5000
          description: The amount to pay
        currency:
          type: string
          example: KES
        status:
          enum:
            - PENDING
            - COMPLETED
            - FAILED
          type: string
        mnoReference:
          type: string
          nullable: true
          description: The M-Pesa receipt
        bankReference:
          type: string
          nullable: true
          description: The bank's own transaction id, once reconciled
        phoneNumber:
          type: string
          nullable: true
          example: +2547...5678
          description: The paying number, redacted (M-Pesa)
        plan:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/PartnerPlanRefDto'
        transactionId:
          type: number
          nullable: true
          description: >-
            The Transaction this Payment funds. Null until the Payment is
            COMPLETED, when the Transaction is created
        createdAt:
          format: date-time
          type: string
        completedAt:
          format: date-time
          type: string
          nullable: true
        bankDetails:
          nullable: true
          description: >-
            Where to send a bank transfer. Only while a BANK_TRANSFER Payment is
            PENDING
          allOf:
            - $ref: '#/components/schemas/PartnerBankDetailsDto'
        fee:
          type: number
          example: 50
          description: The deposit fee this investment will be charged
      required:
        - reference
        - channel
        - amount
        - finalAmount
        - currency
        - status
        - createdAt
        - fee
    PartnerPlanRefDto:
      type: object
      properties:
        id:
          type: number
          example: 12
        name:
          type: string
          example: Ndovu Money Market Fund
      required:
        - id
        - name
    PartnerBankDetailsDto:
      type: object
      properties:
        bankName:
          type: string
        bankBranch:
          type: string
        accountName:
          type: string
        accountNumber:
          type: string
        swiftCode:
          type: string
          nullable: true
      required:
        - bankName
        - bankBranch
        - accountName
        - accountNumber
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.