Process a payment
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.progresscall.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.
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);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)
package main
import (
"context"
"fmt"
"github.com/team-telnyx/telnyx-go"
"github.com/team-telnyx/telnyx-go/option"
)
func main() {
client := telnyx.NewClient(
option.WithAPIKey("My API Key"),
)
response, err := client.Calls.Actions.Pay(
context.TODO(),
"call_control_id",
telnyx.CallActionPayParams{
ConnectorName: telnyx.String("Default"),
},
)
if err != nil {
panic(err.Error())
}
fmt.Printf("%+v\n", response.Data)
}
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);
}
}require "telnyx"
telnyx = Telnyx::Client.new(api_key: "My API Key")
response = telnyx.calls.actions.pay("call_control_id", connector_name: "Default")
puts(response)<?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();
}telnyx calls:actions pay \
--api-key 'My API Key' \
--call-control-id call_control_id \
--connector-name Defaultcurl --request POST \
--url https://api.telnyx.com/v2/calls/{call_control_id}/actions/pay \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"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"
}
'{
"data": {
"result": "ok"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Unique identifier and token for controlling the call
Body
Pay request
Name of the Pay connector used to process the transaction.
"Default"
Amount to charge. Required when transaction_type is charge.
x >= 010.5
Currency used for the transaction. Pay currently supports USD only.
USD, usd "USD"
Existing payment token. When supplied, payment-detail collection is skipped.
"tok_abc123"
Payment method to collect.
credit-card, ach-debit Restricts accepted card numbers to the listed card types. When the caller enters a card number that does not match one of the listed types, Pay treats the input as invalid and re-prompts for the card number. Cannot be used together with payment_token.
1visa, mastercard, amex, maestro, discover, optima, jcb, diners-club, enroute ["visa", "mastercard"]
Controls billing postal code collection for credit-card payments when no payment_token is supplied. Set to true or the string "true" (the default) to prompt the caller for a postal code. Set to false or the string "false" to skip the postal code prompt without supplying a postal code to the payment connector. Supply any other non-empty string, such as "90210", to use that postal code without prompting. Empty or whitespace-only strings are rejected. This option does not affect ACH debit payments or payments using an existing token.
1\Sfalse
Minimum number of digits the caller must enter when collecting a credit-card billing postal code. Applies only when postal_code is true or "true" and no payment_token is supplied. The default is 1. The maximum number of digits collected is the greater of 10 and this value. This does not validate the length of a postal code supplied directly in postal_code.
1 <= x <= 1285
Transaction to perform. If omitted, Pay infers tokenize when amount is absent or zero and charge when amount is positive.
charge, tokenize Optional description forwarded with the payment transaction.
"Order 12345"
Base64-encoded state included in subsequent webhooks.
"aGF2ZSBhIG5pY2UgZGF5ID1d"
Metadata forwarded to the Pay connector.
{ "order_id": "ORD-12345" }
Additional parameters forwarded to the Pay connector.
{ "customer_id": "CUST-67890" }
Custom text-to-speech prompts keyed by payment collection step.
Show child attributes
Show child attributes
{
"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"
}
]
}
Maximum number of attempts for each payment collection step.
1 <= x <= 3Time in milliseconds to wait for DTMF input for each collection step.
1 <= x <= 600000Time in milliseconds to wait between consecutive DTMF digits.
1 <= x <= 600000Voice 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.
"female"
Language used for payment prompts.
"en-US"
Speech synthesis service level used for payment prompts. Pay defaults to premium.
Idempotency key for the command. Telnyx ignores a duplicate command with the same command_id for the same call_control_id.
"891510ac-f3e4-11e8-af5b-de00688a4901"
Response
Successful response upon making a call control command.
Show child attributes
Show child attributes
{ "result": "ok" }
Was this page helpful?
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);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)
package main
import (
"context"
"fmt"
"github.com/team-telnyx/telnyx-go"
"github.com/team-telnyx/telnyx-go/option"
)
func main() {
client := telnyx.NewClient(
option.WithAPIKey("My API Key"),
)
response, err := client.Calls.Actions.Pay(
context.TODO(),
"call_control_id",
telnyx.CallActionPayParams{
ConnectorName: telnyx.String("Default"),
},
)
if err != nil {
panic(err.Error())
}
fmt.Printf("%+v\n", response.Data)
}
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);
}
}require "telnyx"
telnyx = Telnyx::Client.new(api_key: "My API Key")
response = telnyx.calls.actions.pay("call_control_id", connector_name: "Default")
puts(response)<?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();
}telnyx calls:actions pay \
--api-key 'My API Key' \
--call-control-id call_control_id \
--connector-name Defaultcurl --request POST \
--url https://api.telnyx.com/v2/calls/{call_control_id}/actions/pay \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"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"
}
'{
"data": {
"result": "ok"
}
}