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

# Record a manual payment against an invoice

> Used when the customer pays off-platform (bank transfer, cash, cheque). Dispatches MarkInvoicePaid with Source=Manual — the saga handles the state transition (PartiallyPaid or Paid) via the same path as Stripe-originated payments.



## OpenAPI

````yaml post /invoices/{id}/payments
openapi: 3.1.1
info:
  title: Dolfin API
  description: >-
    Dolfin API for AR & AP. Authenticate using the `x-dolfin-api-key` header
    with the API key distributed to your organisation.
  version: v1
servers:
  - url: https://api.dolfinai.co
    description: Production
security:
  - {}
tags:
  - name: Webhooks
  - name: Users
  - name: TaxRates
  - name: Suppliers
  - name: Supplier Credit Notes
  - name: Bills
  - name: SpendCategories
  - name: Payables
  - name: RecurringInvoices
  - name: Receivables
  - name: Purchase Orders
  - name: Products
  - name: Payments
  - name: Invoices
  - name: Organisations
  - name: Members
  - name: MCP
  - name: Matching
  - name: Invoice Reminders
  - name: Industries
  - name: Gmail
  - name: Delivery Notes
  - name: Customers
  - name: Currencies
  - name: Credit Notes
  - name: Clients
  - name: ClientInvites
  - name: BankPayments
  - name: Bank details
  - name: Auth
  - name: ApprovalPolicies
  - name: ApiKeys
  - name: Agent
paths:
  /invoices/{id}/payments:
    post:
      tags:
        - Invoices
      summary: Record a manual payment against an invoice
      description: >-
        Used when the customer pays off-platform (bank transfer, cash, cheque).
        Dispatches MarkInvoicePaid with Source=Manual — the saga handles the
        state transition (PartiallyPaid or Paid) via the same path as
        Stripe-originated payments.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordInvoicePaymentRequest'
        required: true
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoicePaymentResponse'
        '400':
          description: >-
            Invoice.InvalidPaymentAmount — payment amount must be greater than
            zero
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Invoice.NotFound — no invoice with that id for this organisation
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '409':
          description: >-
            Invoice.NotInPayableState — invoice is not in Sent or PartiallyPaid
            status


            Invoice.OverPayment — payment amount exceeds the outstanding balance


            Invoice.CommandFailed — the invoice command was rejected by the saga
            (state conflict)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  schemas:
    RecordInvoicePaymentRequest:
      type: object
      properties:
        amount:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
            - number
            - string
          format: double
        paidAt:
          type:
            - 'null'
            - string
          format: date-time
        notes:
          type:
            - 'null'
            - string
    InvoicePaymentResponse:
      required:
        - currency
        - status
        - providerReference
      type: object
      properties:
        id:
          type: string
          format: uuid
        invoiceId:
          type: string
          format: uuid
        organisationId:
          type: string
          format: uuid
        amount:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
            - number
            - string
          format: double
        currency:
          type: string
        status:
          type: string
        provider:
          $ref: '#/components/schemas/PaymentProvider'
        providerReference:
          type: string
        chargeReference:
          type:
            - 'null'
            - string
        applicationFeeAmount:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
            - number
            - string
          format: double
        notes:
          type:
            - 'null'
            - string
        receiptUrl:
          type:
            - 'null'
            - string
        receiptEmail:
          type:
            - 'null'
            - string
        paymentMethod:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/PaymentMethodDetailsResponse'
        billing:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/PaymentBillingDetailsResponse'
        risk:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/PaymentRiskResponse'
        succeededAt:
          type:
            - 'null'
            - string
          format: date-time
        createdAt:
          type: string
          format: date-time
    ProblemDetails:
      type: object
      properties:
        type:
          type:
            - 'null'
            - string
        title:
          type:
            - 'null'
            - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int32
        detail:
          type:
            - 'null'
            - string
        instance:
          type:
            - 'null'
            - string
    PaymentProvider:
      enum:
        - Stripe
        - Manual
        - Yapily
        - null
    PaymentMethodDetailsResponse:
      required:
        - type
      type: object
      properties:
        id:
          type:
            - 'null'
            - string
        type:
          type: string
        brand:
          type:
            - 'null'
            - string
        last4:
          type:
            - 'null'
            - string
        expMonth:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int64
        expYear:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int64
        funding:
          type:
            - 'null'
            - string
        country:
          type:
            - 'null'
            - string
        wallet:
          type:
            - 'null'
            - string
    PaymentBillingDetailsResponse:
      type: object
      properties:
        name:
          type:
            - 'null'
            - string
        email:
          type:
            - 'null'
            - string
    PaymentRiskResponse:
      type: object
      properties:
        level:
          type:
            - 'null'
            - string
        score:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int64

````