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

# Print a refund receipt on a Terminal

> Prints a receipt for one succeeded card-present Refund on a Terminal
assigned to your account. Sales, PIN-debit returns, and voids that run on
the Terminal print there automatically. Other card-present Refunds and
Voids run without the card: when automatic refund receipts are on for
your account, one that included `terminal_id` prints automatically on that
Terminal, and any other prints when you call this route. A request for a
refund that already printed prints another copy.

The receipt can go to any ready Terminal in the same account and mode,
not only the one that took the sale. A Terminal runs one command at a
time: a busy Terminal returns `TERMINAL_BUSY` and prints nothing.

HTTP 200 reports the outcome in `status`: `printed` when the Terminal
confirmed the print, `failed` when it did not. Retry a failed print
with a new `Idempotency-Key`; reusing a key returns the first result.




## OpenAPI

````yaml /openapi/terminal-payments.yaml post /terminals/{id}/print
openapi: 3.0.3
info:
  title: Ionic Terminal Payments API
  version: '2026-09-02'
  description: >
    Process an existing Ionic PaymentIntent, with no payment method attached,

    on a Terminal owned by the same Merchant. The request and response are the

    same for physical hardware and Ionic's built-in simulated test Terminals.


    In test mode, list Terminals and choose one by `test_profile`. Its default

    outcome runs without a test-helper call. An exact PaymentIntent helper

    override, when armed, takes precedence over that default.


    The Terminal route selects card-present collection. Callers send neither a

    `payment_method_type` nor a credit/debit selector. When a payment cannot be

    routed automatically, Ionic asks the cardholder to select a supported tender

    on the Terminal before sending the Sale. The response reports the

    authoritative tender once it is confirmed.

    If a choice times out or its reply is lost, Ionic may show the prompt once

    more on the same payment. Tender selection can keep a payment `in_progress`

    for over a minute before a Sale starts when both prompts take their full
    time.


    HTTP 202 means Ionic has durably accepted the attempt for asynchronous

    terminal dispatch. It does not by itself mean that money was approved.

    A POS completes the sale only when `status` is `succeeded`. Reader

    availability is separate: a new payment may start when

    `terminal_interaction` is `completed`, even while an older payment remains

    financially `unknown`.


    Amounts are integer minor units. Timestamps are Unix epoch seconds. Test

    and live resources are isolated by the mode of the secret key.
servers:
  - url: '{baseUrl}/v1'
    variables:
      baseUrl:
        default: https://api.ionicfi.com
        description: API base URL for the selected environment.
security:
  - secretKey: []
tags:
  - name: Terminal Payments
    description: Run and retrieve card-present payment attempts.
paths:
  /terminals/{id}/print:
    post:
      tags:
        - Terminal Payments
      summary: Print a refund receipt on a Terminal
      description: >
        Prints a receipt for one succeeded card-present Refund on a Terminal

        assigned to your account. Sales, PIN-debit returns, and voids that run
        on

        the Terminal print there automatically. Other card-present Refunds and

        Voids run without the card: when automatic refund receipts are on for

        your account, one that included `terminal_id` prints automatically on
        that

        Terminal, and any other prints when you call this route. A request for a

        refund that already printed prints another copy.


        The receipt can go to any ready Terminal in the same account and mode,

        not only the one that took the sale. A Terminal runs one command at a

        time: a busy Terminal returns `TERMINAL_BUSY` and prints nothing.


        HTTP 200 reports the outcome in `status`: `printed` when the Terminal

        confirmed the print, `failed` when it did not. Retry a failed print

        with a new `Idempotency-Key`; reusing a key returns the first result.
      operationId: printTerminalReceipt
      parameters:
        - $ref: '#/components/parameters/PrintTerminalId'
        - $ref: '#/components/parameters/IonicAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrintTerminalReceiptRequest'
      responses:
        '200':
          description: The print ran; `status` reports whether the Terminal confirmed it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TerminalPrint'
              examples:
                printed:
                  value:
                    object: terminal_print
                    terminal_id: tmr_01JEXAMPLE8H2Q91P4T6K0M3N5
                    refund_id: rf_01JEXAMPLE4R7T2W9K3M8P5Q
                    livemode: false
                    status: printed
                failed:
                  value:
                    object: terminal_print
                    terminal_id: tmr_01JEXAMPLE8H2Q91P4T6K0M3N5
                    refund_id: rf_01JEXAMPLE4R7T2W9K3M8P5Q
                    livemode: false
                    status: failed
        '400':
          $ref: '#/components/responses/PrintBadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/RefundOrTerminalNotFound'
        '409':
          $ref: '#/components/responses/TerminalBusy'
        '422':
          $ref: '#/components/responses/TerminalCannotPrint'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - secretKey:
            - payments:write
components:
  parameters:
    PrintTerminalId:
      name: id
      in: path
      required: true
      description: Terminal to print on.
      schema:
        type: string
        pattern: ^tmr_
      example: tmr_01JEXAMPLE8H2Q91P4T6K0M3N5
    IonicAccount:
      name: Ionic-Account
      in: header
      required: false
      description: |
        Merchant ID when an authorized Platform acts for a connected Merchant.
        Omit when authenticating directly as that Merchant.
      schema:
        type: string
        pattern: ^mer_
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: |
        Unique checkout-attempt key. Reuse the same value only when retrying
        the same request body and route.
      schema:
        type: string
        minLength: 1
        maxLength: 255
      example: pos-order-1042-attempt-1
  schemas:
    PrintTerminalReceiptRequest:
      type: object
      additionalProperties: false
      required:
        - refund_id
      properties:
        refund_id:
          type: string
          pattern: ^rf_
          description: A succeeded Refund of a payment taken on a Terminal.
          example: rf_01JEXAMPLE4R7T2W9K3M8P5Q
    TerminalPrint:
      type: object
      required:
        - object
        - terminal_id
        - refund_id
        - livemode
        - status
      properties:
        object:
          type: string
          enum:
            - terminal_print
        terminal_id:
          type: string
          description: Terminal the receipt was sent to.
        refund_id:
          type: string
          description: Refund the receipt is for.
        livemode:
          type: boolean
        status:
          type: string
          enum:
            - printed
            - failed
          description: >-
            `printed` when the Terminal confirmed the print, `failed` when it
            did not.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          description: Details about the error.
          required:
            - code
            - message
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    PrintBadRequest:
      description: Malformed body, or a Refund that has no receipt to print.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            malformedBody:
              value:
                error:
                  code: INVALID_REQUEST
                  message: invalid request body
            notSucceeded:
              value:
                error:
                  code: INVALID_DATA
                  message: only a succeeded refund can be printed
            notCardPresent:
              value:
                error:
                  code: INVALID_DATA
                  message: only a refund of a terminal payment can be printed
    Unauthorized:
      description: Missing or invalid secret key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missingKey:
              value:
                error:
                  code: AUTHENTICATION_REQUIRED
                  message: API key is required
            invalidKey:
              value:
                error:
                  code: API_KEY_INVALID
                  message: invalid API key (key prefix sk_v1_test_abcdef12)
    Forbidden:
      description: >-
        Missing permission, invalid delegation, inactive Merchant, or
        unavailable live capability.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            permissions:
              value:
                error:
                  code: INSUFFICIENT_PERMISSIONS
                  message: insufficient permissions
            inactiveMerchant:
              value:
                error:
                  code: MERCHANT_INACTIVE
                  message: merchant is not active
            liveDisabled:
              value:
                error:
                  code: LIVE_PAYMENTS_NOT_ENABLED
                  message: merchant is not enabled for live payments
    RefundOrTerminalNotFound:
      description: Refund or Terminal was not found in this Merchant and mode.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            refund:
              value:
                error:
                  code: REFUND_NOT_FOUND
                  message: refund not found
            terminal:
              value:
                error:
                  code: TERMINAL_NOT_FOUND
                  message: terminal not found
    TerminalBusy:
      description: >-
        The Terminal is busy with another command, or this PaymentIntent already
        has an active attempt on a different Terminal or tender.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            terminalBusy:
              value:
                error:
                  code: TERMINAL_BUSY
                  message: terminal already has an active command
            paymentProcessing:
              value:
                error:
                  code: PAYMENT_PROCESSING
                  message: payment is currently being processed
    TerminalCannotPrint:
      description: The Terminal is not ready, or its connection cannot print.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            notReady:
              value:
                error:
                  code: TERMINAL_NOT_READY
                  message: terminal is not ready to print
            cannotPrint:
              value:
                error:
                  code: TERMINAL_NOT_READY
                  message: terminal cannot print receipts
    RateLimited:
      description: Request was throttled before a Terminal command was sent.
      headers:
        Retry-After:
          description: Seconds to wait before retrying the identical logical request.
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: RATE_LIMIT_EXCEEDED
              message: too many requests
    InternalError:
      description: >-
        Unexpected Ionic failure. Do not infer whether a financial command ran
        from this response alone.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: INTERNAL_ERROR
              message: internal error
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: Ionic secret key
      description: Merchant secret key, or a Platform secret key with delegation.

````

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