Skip to main content

<Pay>

Overview

The <Pay> verb enables secure payment processing during voice calls. When implemented in your voice application, it handles the complete payment flow including data collection, validation, and processing through your configured payment gateway.

The <Pay> verb also has two nouns that are embedded within it:

  • <Parameter>: Pass custom parameters to your payment processor.
  • <Prompt>: Customize the prompts used during payment collection.

Core Functionality

  • Secure payment information collection
  • Real-time payment processing
  • Payment method tokenization
  • Multi-currency support
  • Automated retry handling
  • Status tracking via webhooks

Transaction Types

The <Pay> verb supports two primary transaction types: immediate charges and tokenization.

Immediate Charges

When you need to process a payment right away, use an immediate charge transaction. This collects the payment details and processes the transaction in one step.

To execute an immediate charge:

<Pay chargeAmount="25.00"/>

Setting any positive value for chargeAmount initiates an immediate charge transaction.

Tokenization

Tokenization allows you to securely store payment information for future use. Instead of processing a payment, it generates a secure token that represents the payment method. This is particularly useful for:

  • Subscription services
  • Recurring billing
  • One-click checkout experiences

To tokenize payment information:

<Pay chargeAmount="0"/>

You can also omit the chargeAmount attribute entirely:

note

The actual token is provided & stored by your payment processor, which can be used for future transactions without requiring customers to re-enter their payment details. This may differ depending on the payment processor you are using.


Attributes

AttributeAllowed ValuesDefaultDescription
inputoptionaldtmfdtmfThe only supported input method for payment data collection. All captured digits are automatically redacted in logs.
actionoptionalAn absolute URLCurrent cXML document URLHTTPS endpoint that receives POST requests after payment completion. Must be HTTPS. Response determines next cXML instructions. For tokenization, receives PaymentToken and ProfileId. For charges, receives PaymentConfirmationCode.
statusCallbackoptionalAn absolute URL-HTTPS endpoint that receives real-time payment status updates via POST requests. Includes details about current payment stage, errors, and attempt counts.
See Status Callback Parameters for more details.
paymentMethodoptionalcredit-cardcredit-cardDetermines payment collection flow. Credit card flow captures card number, expiration, security code, and postal code. ACH flow captures routing and account numbers.
paymentConnectorUrlrequiredAn absolute URL-The URL to which to POST the encrypted payment data.
timeoutoptionalA positive integer greater than 3 seconds.5Number of seconds to wait for the next digit input before timing out. Applies to all input collection stages.
maxAttemptsoptional1, 2, 31Maximum number of retry attempts when timeout occurs or invalid data is received. Payment flow terminates after maxAttempts is reached.
securityCoderequiredtrue, falsetrueControls whether CVV/security code collection is required. When false, skips security code collection.
postalCodeoptionaltrue, false, or a String valuetrueControls postal code collection.
  • When false: Skips collection for postal code.
  • When true: Prompts the user for collection.
  • When a String value: Uses provided value without needing to collect the postal code from the user.
minPostalCodeLengthrequiredpositive integer-Minimum required length for postal code input. Used for input validation.
tokenTypeoptionalone-time, reusablereusableDetermines token persistence. One-time for single use, reusable for recurring use. Payment-method specific to certain processors (e.g., Stripe).
chargeAmountoptionaldecimal (0-1,000,000)-Amount to charge. Set to 0 or omit for tokenization only. Must be between 0 and 1,000,000.
currencyoptionalA String value of a three-letter currency code. usd is the only value accepted right now.usdThree-letter currency code (e.g., usd, eur, gbp). Must be supported by selected payment connector.
languageoptionalSee language listen-usControls prompt language. Supports en-AU, en-CA, en-GB, en-IN, en-US for all payments. Additional es-ES, es-MX, fr-CA, fr-FR, de-DE, it-IT for credit card only.
descriptionoptionalA String value.-Transaction description passed to payment processor. Appears in transaction records.
validCardTypesoptionalvisa, mastercard, amex, maestro, discover, optima, jcb, diners-club, enroutevisa mastercard amexSpace-separated list of accepted card types. Validates card number against specified types.

Webhook Request Parameters

paymentConnectorUrl Request Parameters

When a transaction is completed, SignalWire will POST to your paymentConnectorUrl URL. Based on the transaction type, the body of the request will contain the below parameters:

Response from paymentConnectorUrl

A valid response from your paymentConnectorUrl must be provided to indicate the success or failure of the transaction. More information can be found in the Webhook Response section.

ParameterTypeDescription
transaction_idStringUnique identifier for the transaction
methodStringPayment method (credit-card)
cardnumberStringCustomer's credit card number
cvvStringCard security code
postal_codeStringBilling postal code
descriptionStringTransaction description
chargeAmountDecimalAmount to charge
expiry_monthStringCard expiration month (2 digits)
expiry_yearStringCard expiration year (2 digits)
currency_codeStringThree-letter currency code
parametersObjectCustom key-value parameters

Example

{
"transaction_id":"id",
"method":"credit-card",
"cardnumber":"1234123412341234",
"cvv":"123",
"postal_code":"12345",
"description":"renew plan",
"chargeAmount":123.45,
"expiry_month":"01",
"expiry_year":"38",
"currency_code":"USD",
"parameters":{
"custom1":"value1"
}
}

action Request Parameters

When a transaction is completed, SignalWire will POST to your action URL. The body of the request will contain the standard request parameters as well as the following parameters:

Response from action URL

A valid cXML response must be provided if the action URL is provided. More information can be found in the Webhook Response section.

ParameterDescription
ResultFinal outcome of the payment attempt. The possible values can be seen in the Result Values table.
ProfileIdCustomer profile identifier from payment processor
PaymentTokenTokenized payment method reference
PaymentConfirmationCodeTransaction confirmation code
PaymentMethodType of payment method used
PaymentCardNumberMasked card number (last 4 digits visible)
PaymentCardTypeCard brand (visa, mastercard, etc.)
ExpirationDateCard expiration in MMYY format
SecurityCodeMasked security code
PaymentCardPostalCodePostal code provided
BankAccountNumberMasked bank account number
BankRoutingNumberBank routing number
PaymentErrorDetailed error information
PayErrorCodeNumeric error reference
ConnectorErrorRaw processor error details

Result Values

ValueDescription
successPayment processed successfully
too-many-failed-attemptsMaximum retry attempts reached
payment-connector-errorGateway communication failure
caller-interrupted-with-starUser canceled with * key
caller-hung-upCall terminated by user
validation-errorInvalid parameter provided
internal-errorSystem processing error

statusCallback Request Parameters

When a status change occurs, the following parameters are sent to your statusCallback URL:

ParameterDescription
ForIndicates the present phase of the <Pay> request. The table below outlines the potential values. Possible values can be seen in the For Values table.
ErrorTypeSpecifies the nature of the error encountered (if any). Refer to the table below for detailed error type descriptions. The possible values can be seen in the Error Types table.
AttemptCurrent attempt number
PaymentMethodType of payment being processed
PaymentCardNumberMasked card number
PaymentCardTypeType of card provided
SecurityCodeMasked security code
ExpirationDateCard expiration date
PaymentCardPostalCodePostal code provided

Status Callback Events

EventDescription
payment-card-numberCollecting card number
expiration-dateCollecting expiration date
security-codeCollecting CVV/security code
postal-codeCollecting postal code
bank-routing-numberCollecting routing number
bank-account-numberCollecting account number
payment-processingProcessing transaction

For Values

ValueDescription
payment-card-numberRequesting the customer's credit or debit card details
expiration-dateRequesting the expiration date of the customer's payment card
security-codeRequesting the security code (CVV) of the customer's payment card
postal-codeRequesting the postal code linked to the customer's payment card
payment-processingExecuting the payment transaction

Error Types

ErrorDescription
input-timeoutUser input timeout
invalid-card-numberFailed card validation
invalid-card-typeUnsupported card type
invalid-dateInvalid expiration date
invalid-security-codeInvalid CVV format
invalid-postal-codeInvalid postal code format
invalid-bank-routing-numberInvalid routing number
invalid-bank-account-numberInvalid account number
session-in-progressConcurrent session attempt

Webhook Response

paymentConnectorUrl Response

The response from your paymentConnectorUrl is used to inform if the transaction was successful or not.

Successful Transaction

When a transaction is successful, the webhook should respond with one of the following formats (depending on the transaction type):

{
"charge_id":"charge_id",
"error_code":null,
"error_message":null
}

Unsuccessful Transaction

When a transaction is unsuccessful (declined by the payment processor), the webhook should respond with the following format:

{
"charge_id": null,
"error_code": "some error code",
"error_message": "some error message"
}

action Response

When a transaction is completed, SignalWire will POST to your action URL. The response should return valid cXML for the next step in your application.

Example

<Response>
<Say>Thank you for your payment. Your transaction has been completed.</Say>
<Hangup/>
</Response>

Language Support

The language attribute controls the language of automated prompts during payment collection.

note

You can customize prompt messages in any language using the <Prompt> noun, regardless of the selected language attribute.

Credit Card Payments

All credit card payments support the following languages:

English Variants

  • en-AU (Australian English)
  • en-CA (Canadian English)
  • en-GB (British English)
  • en-IN (Indian English)
  • en-US (American English)

Additional Languages

  • es-ES (European Spanish)
  • es-MX (Mexican Spanish)
  • fr-CA (Canadian French)
  • fr-FR (European French)
  • de-DE (German)
  • it-IT (Italian)

Examples

Simple payment collection:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please enter your payment information</Say>
<Pay chargeAmount="20.45"/>
</Response>

Payment with status tracking:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please enter your payment information</Say>
<Pay
chargeAmount="20.45"
action="https://your-callback-url.example.com/pay"
statusCallback="https://your-callback-url.example.com/status"
/>
</Response>

Basic tokenization:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please enter your card information to save for future use</Say>
<Pay
tokenType="reusable"
chargeAmount="0"
/>
</Response>

Tokenization with validation:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please enter your card information</Say>
<Pay
tokenType="reusable"
chargeAmount="0"
validCardTypes="visa mastercard"
securityCode="true"
postalCode="true"
/>
</Response>

Custom retry logic:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please enter your payment information</Say>
<Pay
chargeAmount="75.00"
maxAttempts="3"
timeout="10"
/>
</Response>

International payment:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Por favor, ingrese su información de pago</Say>
<Pay
chargeAmount="100.00"
currency="mxn"
language="es-MX"
description="Mexican peso transaction"
/>
</Response>

Example with custom parameters and prompts

<Response>
<Pay chargeAmount="123.45" paymentConnectorUrl="https://example.com/accept-payment" description="renew plan">
<Parameter name="custom1" value="value1"/>
<Prompt name="payment-card-number" attempt="1"><Say>Let's collect your payment information. Please enter your credit card number</Say></Prompt>
<Prompt name="payment-card-number" attempt="2 3"><Say>Please enter your credit card number</Say></Prompt>
<Prompt for="security-code" cardType="amex"><Say>Please enter your credit card’s security code. It's the 4 digits located on the front of your card. </Say></Prompt>
</Pay>
</Pay>
</Response>

Security Best Practices

  1. Always use HTTPS for callback URLs
  2. Implement webhook validation
  3. Monitor payment status callbacks
  4. Handle errors gracefully
  5. Store tokens securely
  6. Use appropriate timeout values
  7. Implement proper error handling
  8. Validate all inputs
  9. Monitor transaction patterns
  10. Keep payment connector configurations secure