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

# Record a manual payment

> Record a payment that was collected outside of Metrifox (cash, bank transfer, or check) against an invoice.

<Note>
  The currency of the payment is taken from the invoice — you don't pass it. The invoice must be in `open` or `overdue` status, and `amount_in_standard_unit` must not exceed the invoice's current outstanding amount. Partial payments are supported: call this endpoint multiple times until the invoice is fully paid.
</Note>


## OpenAPI

````yaml POST /api/v1/invoices/{invoice_id}/record-manual-payment
openapi: 3.0.1
info:
  title: Metrifox API Documentation
  version: v1
  description: >-
    Welcome to Metrifox Platform's API documentation. This comprehensive API
    suite enables seamless integration with our platform, providing secure and
    efficient access to our services.
servers:
  - url: https://{defaultHost}
    variables:
      defaultHost:
        default: api.metrifox.com
security:
  - api_key: []
paths:
  /api/v1/invoices/{invoice_id}/record-manual-payment:
    post:
      tags:
        - Invoices
      summary: Record a manual payment against an invoice
      description: >
        Records a payment that was collected **outside** of Metrifox (for
        example, cash, a bank transfer, or a check) against a specific invoice.


        Use this endpoint when a customer pays you out-of-band and you want
        Metrifox to reflect that payment so the invoice's outstanding balance is
        reduced and the invoice can transition to `paid` (or `partially_paid`)
        automatically.


        **How it works**


        1. Looks up the invoice by `invoice_id` (must belong to the tenant
        authenticated by the API key).

        2. Validates that the invoice is in a payable state (`open` or
        `overdue`).

        3. Validates that the supplied `amount_in_standard_unit` does not exceed
        the invoice's current outstanding amount.

        4. Creates a `ManualPayment` record and a corresponding payment
        transaction linked to the invoice.

        5. Recomputes the invoice's status — once outstanding reaches `0`, the
        invoice is marked `paid`.


        **Notes**


        - The currency of the payment is taken from the invoice — you do not
        pass it.

        - Partial payments are supported: send an `amount_in_standard_unit`
        smaller than the outstanding amount and call this endpoint again later
        for the remainder.

        - On sandbox tenants, this endpoint creates a fake gateway payment
        (instead of a real `ManualPayment`) so you can exercise the full
        payment-success workflow without a real gateway. The response shape is
        identical.
      operationId: recordManualPayment
      parameters:
        - name: invoice_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: ID of the invoice the payment should be applied to.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordManualPaymentRequest'
            examples:
              full_cash_payment:
                summary: Pay an invoice in full with cash
                value:
                  payment_method_type: cash
                  amount_in_standard_unit: 100
                  payment_date: '2026-05-29'
              partial_bank_transfer:
                summary: Record a partial bank transfer
                value:
                  payment_method_type: bank_transfer
                  amount_in_standard_unit: 50
                  payment_date: '2026-05-29'
              check_payment:
                summary: Record a check payment
                value:
                  payment_method_type: check
                  amount_in_standard_unit: 250
                  payment_date: '2026-05-25'
      responses:
        '200':
          description: Manual payment recorded successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordManualPaymentResponse'
              examples:
                payment_recorded:
                  summary: Manual payment recorded
                  value:
                    statusCode: 200
                    message: Manual payment recorded successfully
                    meta: {}
                    data:
                      id: 8d3f1b21-3a91-4e64-8e2a-1d4d7f2b9a01
                      payment_method_type: cash
                      amount_in_standard_unit: 100
                      amount_in_base_unit: 10000
                      currency: USD
                      created_at: '2026-05-29T18:42:11Z'
                      updated_at: '2026-05-29T18:42:11Z'
                    errors: {}
        '400':
          description: Bad request — validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invoice_not_payable:
                  summary: Invoice is not in a payable state
                  value:
                    message: 'Manual payment not allowed on invoice with status: paid'
                    errors: {}
                amount_exceeds_outstanding:
                  summary: Amount exceeds the invoice's outstanding balance
                  value:
                    message: Manual payment amount exceeds invoice total
                    errors: {}
        '401':
          description: Unauthorized — invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Invoice not found (or does not belong to the authenticated tenant)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >
            curl -X POST
            https://api.metrifox.com/api/v1/invoices/5e5d2f9a-4f4e-4f1d-8c9c-2f1c4e3b9a01/record-manual-payment
            \
              -H "x-api-key: $METRIFOX_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "payment_method_type": "cash",
                "amount_in_standard_unit": 100.0,
                "payment_date": "2026-05-29"
              }'
components:
  schemas:
    RecordManualPaymentRequest:
      type: object
      required:
        - payment_method_type
        - amount_in_standard_unit
        - payment_date
      properties:
        payment_method_type:
          type: string
          enum:
            - cash
            - bank_transfer
            - check
          description: |
            How the payment was collected outside of Metrifox. Must be one of:
            - `cash`
            - `bank_transfer`
            - `check`
        amount_in_standard_unit:
          type: number
          format: float
          minimum: 0.01
          description: >
            The amount paid, expressed in standard units of the invoice's
            currency

            (e.g. `100.00` means 100.00 USD on a USD invoice). Must be greater
            than `0`

            and must not exceed the invoice's current outstanding amount.
        payment_date:
          type: string
          format: date
          description: >-
            The date the payment was actually received (`YYYY-MM-DD`). Used as
            the effective date of the payment for accounting purposes.
    RecordManualPaymentResponse:
      type: object
      properties:
        statusCode:
          type: integer
          example: 200
        message:
          type: string
          example: Manual payment recorded successfully
        data:
          $ref: '#/components/schemas/ManualPaymentEntity'
        meta:
          type: object
          additionalProperties: true
        errors:
          type: object
          additionalProperties: true
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Error message
        errors:
          type: object
          additionalProperties: true
          description: Detailed error information
    ManualPaymentEntity:
      type: object
      description: A manual payment recorded against an invoice.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the manual payment record.
        payment_method_type:
          type: string
          enum:
            - cash
            - bank_transfer
            - check
          description: |
            How the payment was collected outside of Metrifox.
            - `cash` — paid in cash.
            - `bank_transfer` — wire/ACH or other bank transfer.
            - `check` — paid by physical or electronic check.
        amount_in_standard_unit:
          type: number
          format: float
          description: >-
            Payment amount in the invoice's currency, in standard units (e.g.
            dollars, not cents).
        amount_in_base_unit:
          type: number
          format: float
          description: >-
            Payment amount in the smallest currency subunit (e.g. cents).
            Computed automatically from `amount_in_standard_unit` and the
            invoice's currency.
        currency:
          type: string
          description: >-
            ISO 4217 currency code, copied from the invoice (e.g. `USD`, `EUR`,
            `NGN`).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
  securitySchemes:
    api_key:
      type: apiKey
      name: x-api-key
      in: header

````