> ## 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.

# Request cancellation of an active Terminal Payment

> Records the cancellation request, then sends at most one abort
command to the Terminal. `cancellation_requested: true` is not a
financial outcome, and an HTTP 200 does not mean the payment was
canceled. Read the returned `status`, retrieve the same Terminal
Payment, or consume terminal-payment webhooks. The payment can still
be approved after the request; refund an unwanted late approval
separately. Cancellation checks are read-only: Ionic checks the
status of the original attempt and never resubmits it.




## OpenAPI

````yaml /openapi/terminal-payments.yaml post /terminal_payments/{id}/cancel
openapi: 3.0.3
info:
  title: Ionic Terminal Payments API
  version: '2026-08-18'
  description: |
    Process an existing Ionic PaymentIntent, with no payment method attached,
    on a physical Terminal owned by the same Merchant.

    The Terminal route selects card-present collection. Callers do not send a
    `payment_method_type`. The `payment_type` field selects the tender behavior
    requested from the Terminal. Supported values are `credit` and `debit`;
    Debit additionally requires a ready `debit_pin` Terminal capability.

    HTTP 200 means Ionic has recorded the attempt and returned its current
    status. It does not by itself mean that money was approved.
    A POS completes the sale only when `status` is `succeeded`.

    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:
  /terminal_payments/{id}/cancel:
    post:
      tags:
        - Terminal Payments
      summary: Request cancellation of an active Terminal Payment
      description: |
        Records the cancellation request, then sends at most one abort
        command to the Terminal. `cancellation_requested: true` is not a
        financial outcome, and an HTTP 200 does not mean the payment was
        canceled. Read the returned `status`, retrieve the same Terminal
        Payment, or consume terminal-payment webhooks. The payment can still
        be approved after the request; refund an unwanted late approval
        separately. Cancellation checks are read-only: Ionic checks the
        status of the original attempt and never resubmits it.
      operationId: cancelTerminalPayment
      parameters:
        - $ref: '#/components/parameters/TerminalPaymentId'
        - $ref: '#/components/parameters/IonicAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: The Terminal Payment; inspect `status`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TerminalPayment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/TerminalPaymentNotFound'
        '422':
          $ref: '#/components/responses/TerminalPaymentNotReady'
      security:
        - secretKey:
            - payments:write
components:
  parameters:
    TerminalPaymentId:
      name: id
      in: path
      required: true
      description: Terminal Payment identifier.
      schema:
        type: string
        pattern: ^tpr_
      example: tpr_01JEXAMPLE2K8V4N9C6M1Q7R
    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:
    TerminalPayment:
      type: object
      additionalProperties: false
      required:
        - id
        - object
        - merchant_id
        - terminal_id
        - payment_intent_id
        - charge_id
        - livemode
        - amount_requested
        - amount_approved
        - amount_remaining
        - currency
        - payment_type
        - status
        - cancellation_requested
        - cancellation_requested_at
        - failure_code
        - failure_message
        - created_at
        - updated_at
      properties:
        id:
          type: string
          pattern: ^tpr_
        object:
          type: string
          enum:
            - terminal_payment
        merchant_id:
          type: string
          pattern: ^mer_
        terminal_id:
          type: string
          pattern: ^tmr_
        payment_intent_id:
          type: string
          pattern: ^pi_
        charge_id:
          type: string
          nullable: true
          pattern: ^ch_
          description: Present only after an approved attempt creates a Charge.
        livemode:
          type: boolean
        amount_requested:
          type: integer
          format: int64
          minimum: 1
          description: PaymentIntent amount in minor currency units.
        amount_approved:
          type: integer
          format: int64
          minimum: 0
        amount_remaining:
          type: integer
          format: int64
          minimum: 0
        currency:
          type: string
          enum:
            - usd
        payment_type:
          type: string
          enum:
            - credit
            - debit
            - ebt_food
            - ebt_cash
          description: Tender type used for this attempt.
        status:
          $ref: '#/components/schemas/TerminalPaymentStatus'
        cancellation_requested:
          type: boolean
          description: >-
            Whether cancellation was requested. This alone does not mean the
            payment was canceled.
        cancellation_requested_at:
          type: integer
          format: int64
          nullable: true
        failure_code:
          $ref: '#/components/schemas/TerminalPaymentFailureCode'
        failure_message:
          type: string
          nullable: true
          description: Safe Ionic explanation suitable for a POS.
        created_at:
          type: integer
          format: int64
        updated_at:
          type: integer
          format: int64
    TerminalPaymentStatus:
      type: string
      enum:
        - pending
        - in_progress
        - unknown
        - succeeded
        - voided
        - declined
        - failed
        - canceled
      description: >
        `succeeded`: approved; complete the sale.

        `voided`: authorized and then voided; do not complete the sale.

        `declined`: explicitly declined; request another tender.

        `canceled`: interaction canceled or timed out. When

        `cancellation_requested` is true, the PaymentIntent is also canceled;

        create a new PaymentIntent if payment is still needed. Otherwise,

        retry this PaymentIntent only after it returns to

        `requires_payment_method`, using a new Idempotency-Key.

        `failed`: known processing failure; show the failure before a new
        attempt.

        `unknown`: both the command response and the immediate read-only status

        check were inconclusive; do not process the order again.

        `pending` or `in_progress`: retrieve this Terminal Payment until final.
    TerminalPaymentFailureCode:
      type: string
      nullable: true
      description: >
        Stable Ionic detail for a known non-approval. This is intentionally an

        open string: branch on `status`, use recognized values for richer POS

        guidance, and fall back to `failure_message` for an unfamiliar value.

        Raw device responses are not returned.


        Currently emitted values:


        - `dispatch_not_started`: Ionic rejected the command before payment
        processing began.

        - `processor_error`: Ionic confirmed a final processing failure.

        - `invalid_routing`: the Merchant's payment setup is invalid.

        - `pin_processing_error`: PIN processing failed.

        - `do_not_honor`: the payment received a generic decline.

        - `insufficient_funds`: the payment was declined for insufficient funds.

        - `incorrect_pin`: the payment was declined for an incorrect PIN.

        - `pin_attempts_exceeded`: the PIN retry limit was reached.

        - `transaction_not_permitted`: the transaction is not permitted for the
        selected payment setup.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    BadRequest:
      description: Malformed body, identifier, amount, currency, or unsupported tender.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            malformedBody:
              value:
                error:
                  code: INVALID_REQUEST
                  message: invalid request body
            invalidData:
              value:
                error:
                  code: INVALID_DATA
                  message: terminal payment type is not supported
    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
    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
    TerminalPaymentNotFound:
      description: Terminal Payment was not found in this Merchant and mode.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: TERMINAL_PAYMENT_NOT_FOUND
              message: terminal payment not found
    TerminalPaymentNotReady:
      description: PaymentIntent state or Terminal configuration cannot run this payment.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidPaymentState:
              value:
                error:
                  code: INVALID_PAYMENT_STATE
                  message: >-
                    payment intent must require a payment method and use
                    automatic capture
            terminalNotReady:
              value:
                error:
                  code: TERMINAL_NOT_READY
                  message: terminal is not ready for this payment type
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: Ionic secret key
      description: Merchant secret key, or a Platform secret key with delegation.

````