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

# Collect payment details

> Collect payment details from the caller using DTMF and either charge or tokenize the payment method through a configured Pay connector. Pay pauses active call recordings while sensitive payment details are collected.

When `payment_token` is supplied, the DTMF collection steps are skipped and the existing token is sent to the connector.

**Expected Webhooks:**

- `call.payment.progress`
- `call.payment.completed`

**Test mode card numbers:** `4111111111111111` (Visa), `5555555555554444` (Mastercard), `378282246310005` (American Express), `6011111111111117` (Discover), `3065930009020004` (Diners Club), `3566002020360505` (JCB), `6200000000000005` (UnionPay), and `6771798021000008` (Maestro). Test-mode connectors reject other card numbers before contacting the configured processor. The UnionPay and Maestro numbers are accepted for processor testing, but Pay currently does not emit a card type for them.



## OpenAPI

````yaml /openapi/generated/call-control-commands/pay.yml post /calls/{call_control_id}/actions/pay
openapi: 3.1.0
info:
  contact:
    email: support@telnyx.com
  description: API for collecting payment details during a call.
  title: Telnyx Call Control - Pay
  version: 2.0.0
servers:
  - url: https://api.telnyx.com/v2
security:
  - bearerAuth: []
tags:
  - description: Call control command operations
    name: Command
  - description: Webhook callbacks for call events
    name: Callbacks
paths:
  /calls/{call_control_id}/actions/pay:
    post:
      tags:
        - Call Commands
      summary: Collect payment details
      description: >-
        Collect payment details from the caller using DTMF and either charge or
        tokenize the payment method through a configured Pay connector. Pay
        pauses active call recordings while sensitive payment details are
        collected.


        When `payment_token` is supplied, the DTMF collection steps are skipped
        and the existing token is sent to the connector.


        **Expected Webhooks:**


        - `call.payment.progress`

        - `call.payment.completed`


        **Test mode card numbers:** `4111111111111111` (Visa),
        `5555555555554444` (Mastercard), `378282246310005` (American Express),
        `6011111111111117` (Discover), `3065930009020004` (Diners Club),
        `3566002020360505` (JCB), `6200000000000005` (UnionPay), and
        `6771798021000008` (Maestro). Test-mode connectors reject other card
        numbers before contacting the configured processor. The UnionPay and
        Maestro numbers are accepted for processor testing, but Pay currently
        does not emit a card type for them.
      operationId: PayCall
      parameters:
        - $ref: '#/components/parameters/CallControlId'
      requestBody:
        description: Pay request
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PayRequest'
      responses:
        '200':
          description: Successful response upon making a call control command.
          content:
            application/json:
              schema:
                type: object
                title: Call Control Command Response
                properties:
                  data:
                    $ref: '#/components/schemas/CallControlCommandResult'
        '422':
          $ref: '#/components/responses/UnprocessableEntityResponse'
        default:
          $ref: '#/components/responses/call-control_GenericErrorResponse'
      x-codeSamples:
        - lang: JavaScript
          source: |-
            import Telnyx from 'telnyx';

            const client = new Telnyx({
              apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted
            });

            const response = await client.calls.actions.pay('call_control_id', {
              connector_name: 'Default',
            });

            console.log(response.data);
        - lang: Python
          source: |-
            import os
            from telnyx import Telnyx

            client = Telnyx(
                api_key=os.environ.get("TELNYX_API_KEY"),  # This is the default and can be omitted
            )
            response = client.calls.actions.pay(
                call_control_id="call_control_id",
                connector_name="Default",
            )
            print(response.data)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/team-telnyx/telnyx-go\"\n\t\"github.com/team-telnyx/telnyx-go/option\"\n)\n\nfunc main() {\n\tclient := telnyx.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.Calls.Actions.Pay(\n\t\tcontext.TODO(),\n\t\t\"call_control_id\",\n\t\ttelnyx.CallActionPayParams{\n\t\t\tConnectorName: telnyx.String(\"Default\"),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n"
        - lang: Java
          source: |-
            package com.telnyx.sdk.example;

            import com.telnyx.sdk.client.TelnyxClient;
            import com.telnyx.sdk.client.okhttp.TelnyxOkHttpClient;
            import com.telnyx.sdk.models.calls.actions.ActionPayParams;

            public final class Main {
                private Main() {}

                public static void main(String[] args) {
                    TelnyxClient client = TelnyxOkHttpClient.fromEnv();

                    ActionPayParams params = ActionPayParams.builder()
                        .connectorName("Default")
                        .build();
                    var response = client.calls().actions().pay("call_control_id", params);
                }
            }
        - lang: Ruby
          source: >-
            require "telnyx"


            telnyx = Telnyx::Client.new(api_key: "My API Key")


            response = telnyx.calls.actions.pay("call_control_id",
            connector_name: "Default")


            puts(response)
        - lang: PHP
          source: >-
            <?php


            require_once dirname(__DIR__) . '/vendor/autoload.php';


            use Telnyx\Client;

            use Telnyx\Core\Exceptions\APIException;


            $client = new Client(apiKey: getenv('TELNYX_API_KEY') ?: 'My API
            Key');


            try {
              $response = $client->calls->actions->pay(
                'call_control_id',
                connector_name: 'Default',
              );

              var_dump($response);
            } catch (APIException $e) {
              echo $e->getMessage();
            }
        - lang: CLI
          source: |-
            telnyx calls:actions pay \
              --api-key 'My API Key' \
              --call-control-id call_control_id \
              --connector-name Default
components:
  parameters:
    CallControlId:
      name: call_control_id
      description: Unique identifier and token for controlling the call
      in: path
      required: true
      schema:
        type: string
  schemas:
    PayRequest:
      type: object
      title: Pay Request
      properties:
        connector_name:
          type: string
          default: Default
          description: Name of the Pay connector used to process the transaction.
          example: Default
        amount:
          type: number
          minimum: 0
          description: Amount to charge. Required when `transaction_type` is `charge`.
          example: 10.5
        currency:
          type: string
          default: USD
          enum:
            - USD
            - usd
          description: Currency used for the transaction. Pay currently supports USD only.
          example: USD
        payment_token:
          type: string
          description: >-
            Existing payment token. When supplied, payment-detail collection is
            skipped.
          example: tok_abc123
        payment_method:
          type: string
          default: credit-card
          enum:
            - credit-card
            - ach-debit
          description: Payment method to collect.
        transaction_type:
          type: string
          enum:
            - charge
            - tokenize
          description: >-
            Transaction to perform. If omitted, Pay infers `tokenize` when
            `amount` is absent or zero and `charge` when `amount` is positive.
        description:
          type: string
          description: Optional description forwarded with the payment transaction.
          example: Order 12345
        client_state:
          type: string
          description: Base64-encoded state included in subsequent webhooks.
          example: aGF2ZSBhIG5pY2UgZGF5ID1d
        metadata:
          type: object
          description: Metadata forwarded to the Pay connector.
          additionalProperties: true
          example:
            order_id: ORD-12345
        parameters:
          type: object
          description: Additional parameters forwarded to the Pay connector.
          additionalProperties: true
          example:
            customer_id: CUST-67890
        prompts:
          $ref: '#/components/schemas/PayPrompts'
        max_attempts:
          type: integer
          format: int32
          minimum: 1
          maximum: 3
          default: 3
          description: Maximum number of attempts for each payment collection step.
        timeout_millis:
          type: integer
          format: int32
          minimum: 1
          maximum: 600000
          default: 5000
          description: >-
            Time in milliseconds to wait for DTMF input for each collection
            step.
        inter_digit_timeout_millis:
          type: integer
          format: int32
          minimum: 1
          maximum: 600000
          default: 5000
          description: Time in milliseconds to wait between consecutive DTMF digits.
        voice:
          type: string
          default: female
          description: >-
            Voice used for payment prompts. Accepts `male`, `female`, or a
            provider voice in `<Provider>.<Model>.<VoiceId>` format, for example
            `AWS.Polly.Joanna` or `Telnyx.KokoroTTS.af`.
          example: female
        language:
          type: string
          default: en-US
          description: Language used for payment prompts.
          example: en-US
        service_level:
          type: string
          default: premium
          description: >-
            Speech synthesis service level used for payment prompts. Pay
            defaults to `premium`.
        command_id:
          type: string
          description: >-
            Idempotency key for the command. Telnyx ignores a duplicate command
            with the same `command_id` for the same `call_control_id`.
          example: 891510ac-f3e4-11e8-af5b-de00688a4901
      example:
        connector_name: Default
        amount: 10.5
        currency: USD
        payment_method: credit-card
        transaction_type: charge
        max_attempts: 3
        timeout_millis: 5000
        inter_digit_timeout_millis: 5000
        voice: female
        language: en-US
        client_state: aGF2ZSBhIG5pY2UgZGF5ID1d
        command_id: 891510ac-f3e4-11e8-af5b-de00688a4901
    CallControlCommandResult:
      type: object
      title: Call Control Command Result
      example:
        result: ok
      properties:
        result:
          type: string
          example: ok
    PayPrompts:
      type: object
      title: Pay Prompts
      description: Custom text-to-speech prompts keyed by payment collection step.
      properties:
        payment-card-number:
          $ref: '#/components/schemas/PayPromptValue'
        expiration-date:
          $ref: '#/components/schemas/PayPromptValue'
        postal-code:
          $ref: '#/components/schemas/PayPromptValue'
        security-code:
          $ref: '#/components/schemas/PayPromptValue'
        bank-routing-number:
          $ref: '#/components/schemas/PayPromptValue'
        bank-account-number:
          $ref: '#/components/schemas/PayPromptValue'
      additionalProperties: false
      example:
        payment-card-number:
          - text: Please enter your card number.
          - text: That card number was not accepted. Please try again.
            attempt: 2 3
            error_type: invalid-card-number
    call-control_Errors:
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/call-control_Error'
    PayPromptValue:
      title: Pay Prompt Value
      description: A default prompt string or an ordered list of qualified prompts.
      oneOf:
        - type: string
          minLength: 1
        - type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/PayPrompt'
    call-control_Error:
      required:
        - code
        - title
      properties:
        code:
          type: string
          format: integer
        title:
          type: string
        detail:
          type: string
        source:
          type: object
          properties:
            pointer:
              description: JSON pointer (RFC6901) to the offending entity.
              type: string
              format: json-pointer
            parameter:
              description: Indicates which query parameter caused the error.
              type: string
        meta:
          type: object
    PayPrompt:
      type: object
      title: Pay Prompt
      description: A text-to-speech prompt with optional matching qualifiers.
      required:
        - text
      properties:
        text:
          type: string
          minLength: 1
          description: Text spoken for the payment collection step.
          example: Please enter your card number.
        attempt:
          type: string
          description: >-
            Space-separated 1-based attempt numbers for which this prompt
            applies.
          example: 2 3
        error_type:
          type: string
          description: Step error for which this prompt applies.
          enum:
            - timeout
            - invalid-card-number
            - invalid-date
            - invalid-security-code
            - invalid-postal-code
            - invalid-bank-routing-number
            - invalid-bank-account-number
            - input-matching-failed
          example: invalid-card-number
        card_type:
          type: string
          description: >-
            Lowercase, case-sensitive detected card type for which this prompt
            applies. Only the listed brands are currently detected; accepted
            UnionPay and Maestro test cards do not produce a card-type
            qualifier.
          enum:
            - visa
            - mastercard
            - amex
            - discover
            - diners-club
            - jcb
          example: amex
      additionalProperties: false
  responses:
    UnprocessableEntityResponse:
      description: >-
        Unprocessable entity. The request was well-formed but could not be
        processed due to semantic errors. This includes validation errors,
        invalid parameter values, call state errors, conference errors, queue
        errors, recording/transcription errors, and business logic violations.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/call-control_Errors'
          examples:
            missing_required_parameter:
              summary: Missing required parameter
              value:
                errors:
                  - code: '10004'
                    title: Missing required parameter
                    detail: The 'to' parameter is required and cannot be blank.
                    source:
                      pointer: /to
            invalid_call_control_id:
              summary: Invalid call control ID
              value:
                errors:
                  - code: '90015'
                    title: Invalid Call Control ID
                    detail: The call_control_id provided was not valid.
                    source:
                      pointer: /call_control_id
            call_already_ended:
              summary: Call has already ended
              value:
                errors:
                  - code: '90018'
                    title: Call has already ended
                    detail: This call is no longer active and can't receive commands.
            call_not_answered:
              summary: Call not answered yet
              value:
                errors:
                  - code: '90034'
                    title: Call not answered yet
                    detail: >-
                      This call can't receive this command because it has not
                      been answered yet.
            cannot_record_before_audio_started:
              summary: Cannot record before audio started
              value:
                errors:
                  - code: '90020'
                    title: Call recording triggered before audio started
                    detail: >-
                      Call recording cannot be started until audio has commenced
                      on the call.
            transcription_already_active:
              summary: Transcription already active
              value:
                errors:
                  - code: '90054'
                    title: Call transcription is already in progress
                    detail: Call transcription can not be started more than once.
            ai_assistant_already_active:
              summary: AI Assistant already active
              value:
                errors:
                  - code: '90061'
                    title: AI Assistant is already in progress
                    detail: AI Assistant cannot be started more than once.
            conference_already_ended:
              summary: Conference has already ended
              value:
                errors:
                  - code: '90019'
                    title: Conference has already ended
                    detail: >-
                      This conference is no longer active and can't receive
                      commands.
            conference_name_conflict:
              summary: Conference name conflict
              value:
                errors:
                  - code: '90033'
                    title: Unable to execute command
                    detail: Conference with given name already exists and it's active.
            max_participants_reached:
              summary: Maximum participants reached
              value:
                errors:
                  - code: '90032'
                    title: Maximum number of participants reached
                    detail: >-
                      The maximum allowed value of `max_participants` has been
                      reached at 100.
            queue_full:
              summary: Queue is full
              value:
                errors:
                  - code: '90036'
                    title: Queue full
                    detail: The 'support' queue is full and can't accept more calls.
            call_already_in_queue:
              summary: Call already in queue
              value:
                errors:
                  - code: '90038'
                    title: Call already in queue
                    detail: Call can't be added to a queue it's already in.
            invalid_connection_id:
              summary: Invalid connection ID
              value:
                errors:
                  - code: '10015'
                    title: Invalid value for connection_id (Call Control App ID)
                    detail: >-
                      The requested connection_id (Call Control App ID) is
                      either invalid or does not exist. Only Call Control Apps
                      with valid webhook URL are accepted.
                    source:
                      pointer: /connection_id
            invalid_phone_number_format:
              summary: Invalid phone number format
              value:
                errors:
                  - code: '10016'
                    title: Phone number must be in +E164 format
                    detail: The 'to' parameter must be in E164 format.
                    source:
                      pointer: /to
            srtp_not_supported_for_pstn:
              summary: SRTP not supported for PSTN calls
              value:
                errors:
                  - source:
                      pointer: /media_encryption
                    title: Media encryption not supported for PSTN calls
                    detail: SRTP media encryption is not supported for PSTN calls.
                    code: '10011'
            fork_not_found:
              summary: Call is not forked
              value:
                errors:
                  - code: '90031'
                    title: Call is not currently forked
                    detail: >-
                      Can't stop forking, because the call isn't currently
                      forked.
            media_streaming_used:
              summary: Media streaming in use
              value:
                errors:
                  - code: '90045'
                    title: Media Streaming is used
                    detail: This command can't be issued when media streaming is used.
            invalid_enumerated_value:
              summary: Invalid enumerated value
              value:
                errors:
                  - code: '10032'
                    title: Invalid enumerated value
                    detail: 'The value must be one of: dual, single.'
                    source:
                      pointer: /record_channels
            value_outside_range:
              summary: Value outside of range
              value:
                errors:
                  - code: '10033'
                    title: Value outside of range
                    detail: The value is outside of allowed range 1 to 5000
                    source:
                      pointer: /max_participants
    call-control_GenericErrorResponse:
      description: Unexpected error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/call-control_Errors'
  securitySchemes:
    bearerAuth:
      scheme: bearer
      type: http

````