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

# Capture Hold

> Captures a payment that is currently `HELD`, moving the held funds to the merchant. The request body is OPTIONAL: send no body to capture the full held amount, or send `{ "amount": 200 }` to capture only part of it. The bounds are `0 < amount <= heldAmount`; the 1 MXN minimum that applies to a charge does not apply to a capture. A successful capture leaves the payment `CONFIRMED` with `capturedAt` set, `amount` rewritten to the amount actually captured, and `heldAmount` still carrying the amount that was authorized. TWO RULES THAT SURPRISE INTEGRATORS: (1) there is exactly ONE capture per hold, so you cannot capture 200 now and the remaining 1000 later, and a second capture answers 409 `PAYMENT_NOT_HELD`; (2) Compago issues NO release for the difference on a partial capture, the cardholder's issuing bank frees it on its own schedule, usually within a few days. Capture is time-gated: it is refused from 23:00 America/Mexico_City on the last natural day of the hold window. The hold window is counted in NATURAL DAYS, not in elapsed hours. The day the hold is placed counts as day 1 and the time of day it was placed is irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29 both expire at the same instant, at the end of the following Sunday. The bank closes its day at 23:30 America/Mexico_City and Compago closes the hold at 23:00, 30 minutes earlier, so the last minute to capture is 22:59 on the last day.



## OpenAPI

````yaml POST /payment-method/{id}/payment/{paymentId}/capture
openapi: 3.1.0
info:
  title: Compago API
  version: 1.0.0
  description: >-
    Public and private API endpoints for Compago's payment infrastructure. This
    specification currently includes endpoints for one-time payments. More
    endpoints will be added as the platform evolves.
servers:
  - url: https://demo-api-harmony.compago.com/api
  - url: https://api-harmony.compago.com/api
security: []
tags:
  - name: OneTimePayment
    description: Endpoints for creating and processing one-time payment links
  - name: PaymentMethod
    description: >-
      Endpoints for saving cards, charging saved payment methods, holding and
      capturing funds, and processing refunds
  - name: PaymentIntent
    description: >-
      Endpoints for creating and managing card-present payment intents for POS
      terminal integrations
  - name: Payments
    description: Read the payments your organization has taken
  - name: Subscriptions
    description: Read and manage recurring billing agreements
  - name: PaymentLinks
    description: Create, edit and retire hosted checkout links
  - name: Products
    description: Manage the catalogue behind product-based payment links
  - name: Promotions
    description: Read the promotions your organization funds or benefits from
  - name: Salespeople
    description: Read the point-of-sale operators in your organization
  - name: Organization
    description: Read your organization profile and its members
  - name: SavedCards
    description: Read saved payment methods and their payments
paths:
  /payment-method/{id}/payment/{paymentId}/capture:
    post:
      tags:
        - PaymentMethod
      summary: Capture a held payment
      description: >-
        Captures a payment that is currently `HELD`, moving the held funds to
        the merchant. The request body is OPTIONAL: send no body to capture the
        full held amount, or send `{ "amount": 200 }` to capture only part of
        it. The bounds are `0 < amount <= heldAmount`; the 1 MXN minimum that
        applies to a charge does not apply to a capture. A successful capture
        leaves the payment `CONFIRMED` with `capturedAt` set, `amount` rewritten
        to the amount actually captured, and `heldAmount` still carrying the
        amount that was authorized. TWO RULES THAT SURPRISE INTEGRATORS: (1)
        there is exactly ONE capture per hold, so you cannot capture 200 now and
        the remaining 1000 later, and a second capture answers 409
        `PAYMENT_NOT_HELD`; (2) Compago issues NO release for the difference on
        a partial capture, the cardholder's issuing bank frees it on its own
        schedule, usually within a few days. Capture is time-gated: it is
        refused from 23:00 America/Mexico_City on the last natural day of the
        hold window. The hold window is counted in NATURAL DAYS, not in elapsed
        hours. The day the hold is placed counts as day 1 and the time of day it
        was placed is irrelevant: a hold placed Monday 10:00 and one placed
        Monday 23:29 both expire at the same instant, at the end of the
        following Sunday. The bank closes its day at 23:30 America/Mexico_City
        and Compago closes the hold at 23:00, 30 minutes earlier, so the last
        minute to capture is 22:59 on the last day.
      operationId: captureHoldPaymentMethodPayment
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The unique identifier of the payment method
        - name: paymentId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The unique identifier of the held payment to capture
      requestBody:
        required: false
        description: Optional. Omit the body entirely to capture the full held amount.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CaptureHoldRequest'
      responses:
        '200':
          description: >-
            Hold captured successfully. On a partial capture `amount` is what
            was captured and `heldAmount` is what had been authorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CaptureHoldPaymentResponse'
        '400':
          description: >-
            The payment does not belong to this payment method, or is not a
            payment method charge. | `INVALID_CAPTURE_AMOUNT`: the `amount` in
            the body was not a positive number (zero, negative or non-numeric).
            Nothing was sent to the bank. | `CAPTURE_AMOUNT_EXCEEDS_HOLD`: the
            `amount` is greater than the payment's `heldAmount`, which the
            message names. You can never capture more than you held. Nothing was
            sent to the bank.
        '401':
          description: Unauthorized – missing or invalid API key
        '402':
          description: >-
            `CAPTURE_DECLINED`: the bank declined the capture. The payment stays
            `HELD` at its full held amount and can be captured again or
            released.
        '404':
          description: Payment method or payment not found
        '409':
          description: >-
            `PAYMENT_NOT_HELD`: the payment is not in the `HELD` status. This
            covers a second capture of an already captured hold (there is only
            ever one capture per hold), a capture after the hold was released or
            expired, and a capture of an ordinary charge. |
            `HOLD_WINDOW_CLOSED`: the payment is still `HELD` but you called
            capture at or after 23:00 America/Mexico_City on the last natural
            day of its window. Compago refuses rather than race the bank's 23:30
            cutoff, and does so whether or not the automatic release sweep has
            physically run yet. The funds are on their way back to the
            cardholder. | `HOLD_CHANNEL_UNKNOWN`: the hold has no fee channel
            resolved, so it cannot be captured. The payment stays `HELD` and
            nothing was sent to the bank. Release it and contact Compago
            support.
      security:
        - ApiKeyAuth: []
components:
  schemas:
    CaptureHoldRequest:
      type: object
      description: >-
        Optional body for capturing a hold. Omit the body, or omit `amount`, to
        capture the full held amount. Sending `amount` equal to `heldAmount` is
        the same as sending no body.
      properties:
        amount:
          type: number
          format: decimal
          exclusiveMinimum: 0
          example: 200
          description: >-
            How much of the hold to capture, in MXN. Must be greater than 0 and
            no greater than the payment's `heldAmount`; 400
            `INVALID_CAPTURE_AMOUNT` and 400 `CAPTURE_AMOUNT_EXCEEDS_HOLD`
            respectively. The 1 MXN minimum that applies to a charge does NOT
            apply here, so small captures are accepted. Remember that there is
            only one capture per hold and that Compago issues no release for the
            difference.
    CaptureHoldPaymentResponse:
      type: object
      description: >-
        Response after capturing a held payment, in full or in part. `amount` is
        what was captured; `heldAmount` is what had been authorized.
      properties:
        id:
          type: string
          format: uuid
          example: 11111111-2222-3333-4444-555555555555
          description: Unique identifier of the payment
        status:
          type: string
          enum:
            - CONFIRMED
          example: CONFIRMED
          description: Payment status after a successful capture
        amount:
          type: number
          format: decimal
          description: >-
            The amount actually captured. It is the full held amount unless you
            sent a smaller `amount` in the request body, in which case it is
            that amount.
        heldAmount:
          type:
            - number
            - 'null'
          format: decimal
          example: 1200
          description: >-
            What the bank authorized when the hold was placed. It is never
            rewritten, so on a partial capture `amount` is what was captured and
            this is what had been held: capturing 200 of a 1200 hold reports
            amount 200 and heldAmount 1200. Compago issues no release for the
            1000 difference; the cardholder's issuing bank frees it on its own
            schedule.
        currency:
          type: string
          example: MXN
        externalId:
          type:
            - string
            - 'null'
          example: invoice-2025-01-8842
          description: >-
            The idempotency key supplied when the payment was created, echoed
            back so you can map this payment id to your own order reference.
            Null when none was supplied. Not to be confused with the payment
            method externalId, which identifies the saved card.
        heldAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-12T10:00:00.000Z'
          description: When the bank approved the hold
        capturedAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-14T09:30:00.000Z'
          description: >-
            When the hold was captured. This, and not createdAt, is the
            settlement date of a captured hold.
        holdReleasedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: 'Null on a captured hold: captured funds are never released.'
        holdExpiresAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-19T05:00:00.000Z'
          description: >-
            When the hold would have expired: 23:00 America/Mexico_City on the
            7th natural day, counting the day of heldAt as day 1. The hold
            window is counted in NATURAL DAYS, not in elapsed hours. The day the
            hold is placed counts as day 1 and the time of day it was placed is
            irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29
            both expire at the same instant, at the end of the following Sunday.
            The bank closes its day at 23:30 America/Mexico_City and Compago
            closes the hold at 23:00, 30 minutes earlier, so the last minute to
            capture is 22:59 on the last day. It keeps being reported after the
            capture, because it is a fact about the payment.
        holdExpired:
          type: boolean
          description: >-
            Whether the hold window has closed. It flips at 23:00
            America/Mexico_City on the last natural day, not 7 times 24 hours
            after heldAt.
        holdDaysRemaining:
          type:
            - integer
            - 'null'
          description: >-
            Null once the payment is captured: it is only reported while the
            payment is HELD.
      required:
        - id
        - status
        - amount
        - currency
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````