Twilio Integration Guide

This guide covers how to integrate Shuttle payments into your Twilio workflows using the <Pay> verb, handle responses, and leverage advanced features through our API.

Using the <Pay> Verb

The Twilio <Pay> verb enables DTMF payment collection during phone calls. Here's how to implement it with Shuttle.

Required Parameters

FieldDescription
paymentConnector(required) The unique name of your Twilio Pay Connector
action(required) URL for next TwiML instructions after payment
chargeAmount(required for payments) Amount to charge (decimal format)

Optional Parameters

FieldDescriptionDefault
statusCallbackURL for progress updates-
currencyISO currency code (lowercase)usd
paymentMethodPayment typecredit-card
postalCodeAVS postal code collectiontrue (US/CA only)
descriptionPayment description-

Shuttle-Specific Parameters

Pass these as <Parameter> elements within the <Pay> verb:

ParameterDescription
actionAUTH for pre-authorization, PAYMENT to capture funds
save_cardTokenize card during payment
alt_keyYour payment reference ID
account_crm_keyCustomer identifier
account_first_nameCustomer first name
account_last_nameCustomer last name
account_emailCustomer email
account_phoneCustomer phone
payment_method_codeUnique payment method ID
scheduled_dateSchedule payment for later (YYYY-MM-DDTHH:MI:SS)
frequencyMONTHLY, FORTNIGHTLY, or WEEKLY for recurring
occurrencesNumber of recurring payments
start_dateFirst installment date
metadata_{key}Custom metadata fields

Implementation Examples

Card Tokenization

To save a card for future use without charging:

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/next_step">
</Pay>

Standard Card Payment

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/next_step"
  chargeAmount="29.99"
  currency="usd"
  postalCode="false">
  <Parameter name="save_card" value="true"/>
  <Parameter name="alt_key" value="INV-12345"/>
  <Prompt for="payment-processing">
    <Say>Please wait while we process your payment</Say>
  </Prompt>
</Pay>

Pre-Authorization

For auth-only transactions (capture later):

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/next_step"
  chargeAmount="99.99">
  <Parameter name="action" value="AUTH"/>
</Pay>

ACH Payment

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/next_step"
  chargeAmount="49.99"
  paymentMethod="ach-debit"
  bankAccountType="consumer-checking">
  <Parameter name="AVSName" value="John Smith"/>
  <Prompt for="payment-processing">
    <Say>Processing your bank transfer</Say>
  </Prompt>
</Pay>

Recurring Payment

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/next_step"
  chargeAmount="19.99">
  <Parameter name="frequency" value="MONTHLY"/>
  <Parameter name="occurrences" value="12"/>
  <Parameter name="start_date" value="2024-01-01T00:00:00"/>
</Pay>

With Full Traceability

<Pay 
  paymentConnector="shuttle-pay-connector"
  action="https://yourapp.com/payment_complete"
  chargeAmount="149.99"
  description="Premium Plan - Monthly">
  <Parameter name="alt_key" value="SUB-2024-001"/>
  <Parameter name="account_crm_key" value="cus_123456"/>
  <Parameter name="account_first_name" value="Jane"/>
  <Parameter name="account_last_name" value="Doe"/>
  <Parameter name="account_email" value="[email protected]"/>
  <Parameter name="metadata_plan" value="premium"/>
  <Parameter name="metadata_billing_cycle" value="monthly"/>
</Pay>

Handling Payment Responses

The <Pay> verb sends a POST request to your action URL with payment results.

Response Fields

FieldDescription
ResultTwilio status (check PayConnector_payment_status instead)
PayErrorCodeTwilio error code if applicable
PaymentErrorError message or decline reason
PaymentConfirmationCodeShuttle payment ID
PaymentTokenShuttle payment method ID (for tokenization)
PayConnector_payment_statusPrimary status field - Always check this
PayConnector_gateway_statusGateway response (APPROVED, DECLINED, etc.)
PayConnector_gateway_messageDetailed gateway message
PayConnector_referenceYour reference (alt_key)
PayConnector_gateway_referenceGateway transaction ID
PayConnector_accountShuttle account ID
PayConnector_contractRecurring contract ID
PayConnector_payment_methodSaved payment method ID
PayConnector_transactionShuttle transaction ID
PayConnector_gatewayGateway identifier
PaymentCardNumberMasked card number
PaymentCardTypeCard brand (visa, mastercard, etc.)
ExpirationDateCard expiry (MMYY format)
SecurityCodeMasked CVV
PaymentCardPostalCodeAVS postal code
PaymentMethodPayment type (ach-debit for ACH)
BankAccountTypeAccount type (consumer-checking, etc.)
BankRoutingNumberBank routing number
BankAccountNumberMasked account number

Payment Status Values

StatusAction
SUCCESS, UNATTRIBUTEDPayment successful - provision service
PENDING, UNRESOLVEDPayment processing - await webhook
DECLINED, REQAUTHPayment failed - retry

Decline Types

The PayConnector_gateway_status field provides specific decline reasons:

TypeCustomer Action
DECLINEDCheck details and retry
DECLINED_CALL_BANKContact bank (e.g., insufficient funds)
DECLINED_BLOCKEDTry different card
DECLINED_ERRORTechnical issue - contact support
DECLINED_RETRYTemporary issue - retry

Example Response Handling

Success Response (Card Payment)

{
  "Result": "success",
  "PaymentError": "",
  "PaymentConfirmationCode": "pay_31660_10007",
  "PaymentToken": "",
  "PayConnector_account": "acc_20648_10002",
  "PayConnector_contract": "co_20648_10002",
  "PayConnector_gateway_reference": "pay_56242536421653621",
  "PayConnector_gateway_status": "APPROVED",
  "PayConnector_payment_method": "pm_20648_10002",
  "PayConnector_payment_status": "SUCCESS",
  "PayConnector_reference": "REF-00010002",
  "PayConnector_transaction": "tr_20648_10002",
  "PaymentCardNumber": "xxxxxxxxxxxx4242",
  "PaymentCardType": "visa",
  "ExpirationDate": "1223",
  "SecurityCode": "xxx",
  "PaymentCardPostalCode": ""
}

Success Response (ACH Payment)

{
  "Result": "success",
  "PaymentError": "",
  "PaymentConfirmationCode": "pay_31660_10007",
  "PaymentToken": "",
  "PayConnector_account": "acc_20648_10002",
  "PayConnector_contract": "co_20648_10002",
  "PayConnector_gateway_reference": "pay_56242536421653621",
  "PayConnector_gateway_status": "APPROVED",
  "PayConnector_payment_method": "pm_20648_10002",
  "PayConnector_payment_status": "SUCCESS",
  "PayConnector_reference": "REF-00010002",
  "PayConnector_transaction": "tr_20648_10002",
  "PaymentMethod": "ach-debit",
  "BankAccountType": "consumer-checking",
  "BankRoutingNumber": "110000000",
  "BankAccountNumber": "xxxxxxxxxx89"
}

Decline Response

{
  "Result": "payment-connector-error",
  "PayErrorCode": "64008",
  "PaymentError": "Payment Gateway rejected charge creation.",
  "PaymentConfirmationCode": "",
  "PaymentToken": "",
  "PayConnector_account": "acc_20648_10004",
  "PayConnector_contract": "co_20648_10004",
  "PayConnector_gateway": "gw_31660_10002",
  "PayConnector_gateway_status": "DECLINED",
  "PayConnector_gateway_message": "Invalid CVC",
  "PayConnector_payment_method": "pm_20648_10004",
  "PayConnector_payment_status": "DECLINED",
  "PayConnector_reference": "BOLT-00010004",
  "PayConnector_transaction": "tr_20648_10004",
  "PaymentCardNumber": "xxxxxxxxxxxx4242",
  "PaymentCardType": "visa",
  "ExpirationDate": "1223",
  "SecurityCode": "xxx",
  "PaymentCardPostalCode": ""
}

Error Response

{
  "Result": "too-many-failed-attempts",
  "PaymentError": "",
  "PaymentCardNumber": "",
  "PaymentCardPostalCode": "",
  "PaymentCardType": "",
  "PaymentConfirmationCode": "",
  "PaymentToken": ""
}

Error Response - Invalid Credentials

Warning: Twilio returns invalid credentials as "success" with no corresponding data. Always check PayConnector_payment_status:

{
  "Result": "success",
  "PaymentError": "",
  "PaymentConfirmationCode": "",
  "PaymentToken": "",
  "PaymentCardNumber": "xxxxxxxxxxxx4242",
  "PaymentCardType": "visa",
  "ExpirationDate": "1223",
  "SecurityCode": "xxx",
  "PaymentCardPostalCode": ""
}

Important: Always check PayConnector_payment_status as Twilio may return Result: "success" even for failed payments.

Webhooks

Configure webhooks to ensure reliable payment tracking, especially for:

  • Disconnected calls during payment
  • Gateway timeouts
  • Held transactions requiring review
  • Scheduled/recurring payment updates

Key Webhook Events

EventDescription
PAYMENT.SUCCESSPayment completed successfully
PAYMENT.DECLINEPayment declined (important for recurring)
CAPTURE.SUCCESSCapture completed (for async gateways)
CAPTURE.DECLINECapture failed
REFUND.SUCCESSRefund processed

Configure webhooks in your Shuttle instance settings. Each webhook contains reference IDs - use the API to retrieve full details.

API Integration

Access advanced features through the Shuttle API.

Authentication

URL: https://api.shuttleglobal.com/c/api/instances/{instance_key}
Header: Authorization: Basic {your_api_key}

Find your authentication details in the merchant portal under your application => Settings.

Find your Api KEY

Common Operations

Retrieve Payment Details

GET /payments/{payment_id}

Process Refund

POST /payments/{payment_id}/refund
{
  "amount": "19.99"
}

Capture Pre-Authorization

POST /payments/{payment_id}/capture
{
  "amount": "99.99"
}

Void Authorization

POST /payments/{payment_id}/void

Charge Saved Payment Method

POST /payments
{
  "payment_method_id": "pm_20648_10002",
  "amount": "49.99",
  "currency": "USD"
}

Manage Recurring Payments

# Update schedule
PUT /contracts/{contract_id}
{
  "amount": "29.99"
}

# Cancel recurring
POST /contracts/{contract_id}/cancel

Create Payment Link

POST /checkouts
{
  "amount": "99.99",
  "currency": "USD",
  "description": "Invoice #12345"
}

Best Practices

  1. Always use alt_key - Pass your internal reference for easy reconciliation
  2. Include customer data - Use account_* parameters for better tracking
  3. Handle all statuses - Don't assume success; check PayConnector_payment_status
  4. Configure webhooks - Essential for reliable payment tracking
  5. Test thoroughly - Use our demo app to verify your implementation
  6. Use metadata - Pass business context through metadata_* parameters

Troubleshooting

Common Issues

  1. "Invalid credentials" with Result: success

    • Always verify PayConnector_payment_status exists
    • Check your instance key and secret key
  2. Postal code errors

    • Set postalCode="false" for non-US/CA customers
    • Pass known postal codes directly: postalCode="12345"
  3. ACH requirements

    • Always include AVSName parameter for ACH payments
    • Ensure customer name matches bank account
  4. Slow gateways

    • Configure <Prompt for="payment-processing"> messages
    • Implement webhook handlers for async results

Additional Resources