***

title: pay
slug: /reference/python/relay/call/pay
description: Collect payment information on a call.
max-toc-depth: 3
---------------------

For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

[payaction]: /docs/server-sdks/reference/python/relay/actions

[calling-call-pay]: /docs/server-sdks/reference/python/relay/call#events

[call-events]: /docs/server-sdks/reference/python/relay/call#events

Start a payment collection session on the call. Collects credit card or other
payment information from the caller via DTMF. Returns a
[`PayAction`][payaction] that you can use to stop
the payment flow or wait for it to complete.

<Info>
  This method emits [`calling.call.pay`][calling-call-pay] events. See [Call Events][call-events] for payload details.
</Info>

## **Parameters**

<ParamField path="payment_connector_url" type="str" required={true} toc={true}>
  URL of the payment connector service that processes the payment.
</ParamField>

<ParamField path="control_id" type="Optional[str]" toc={true}>
  Custom control ID. Auto-generated if not provided.
</ParamField>

<ParamField path="input_method" type="Optional[str]" toc={true}>
  How the caller provides payment info.

  * `"dtmf"` -- caller enters digits on the keypad
  * `"speech"` -- caller speaks the payment information
</ParamField>

<ParamField path="status_url" type="Optional[str]" toc={true}>
  URL to receive payment status webhooks.
</ParamField>

<ParamField path="payment_method" type="Optional[str]" toc={true}>
  Payment method type. Valid values: `"credit-card"`.
</ParamField>

<ParamField path="timeout" type="Optional[str]" toc={true}>
  Timeout for the payment session.
</ParamField>

<ParamField path="max_attempts" type="Optional[str]" toc={true}>
  Maximum number of input attempts before failing.
</ParamField>

<ParamField path="security_code" type="Optional[str]" toc={true}>
  Whether to collect CVV.

  * `"true"` -- prompt the caller for the security code
  * `"false"` -- skip security code collection
</ParamField>

<ParamField path="postal_code" type="Optional[str]" toc={true}>
  Whether to collect postal code.

  * `"true"` -- prompt the caller for the postal code
  * `"false"` -- skip postal code collection
</ParamField>

<ParamField path="min_postal_code_length" type="Optional[str]" toc={true}>
  Minimum length for the postal code.
</ParamField>

<ParamField path="token_type" type="Optional[str]" toc={true}>
  Tokenization type for the payment data.
</ParamField>

<ParamField path="charge_amount" type="Optional[str]" toc={true}>
  Amount to charge (e.g., `"29.99"`).
</ParamField>

<ParamField path="currency" type="Optional[str]" toc={true}>
  Currency code (e.g., `"USD"`, `"EUR"`).
</ParamField>

<ParamField path="language" type="Optional[str]" toc={true}>
  Language for payment prompts (e.g., `"en"`).
</ParamField>

<ParamField path="voice" type="Optional[str]" toc={true}>
  Voice for TTS prompts during the payment flow.
</ParamField>

<ParamField path="description" type="Optional[str]" toc={true}>
  Description of the payment/charge.
</ParamField>

<ParamField path="valid_card_types" type="Optional[str]" toc={true}>
  Comma-separated list of accepted card types (e.g., `"visa,mastercard,amex"`).
</ParamField>

<ParamField path="parameters" type="Optional[list[dict]]" toc={true}>
  Additional parameters to pass to the payment connector.
</ParamField>

<ParamField path="prompts" type="Optional[list[dict]]" toc={true}>
  Custom prompts for the payment flow.
</ParamField>

<ParamField path="on_completed" type="Optional[Callable[[RelayEvent], Any]]" toc={true}>
  Callback invoked when the payment operation completes.
</ParamField>

## **Returns**

[`PayAction`][payaction] -- An action handle with
`stop()` and `wait()` methods.

## **Example**

```python {15}
from signalwire.relay import RelayClient

client = RelayClient(
    project="your-project-id",
    token="your-api-token",
    host="your-space.signalwire.com",
    contexts=["default"],
)

@client.on_call
async def handle_call(call):
    await call.answer()
    await call.play([{"type": "tts", "text": "We will now collect your payment."}])

    action = await call.pay(
        payment_connector_url="https://example.com/payment-connector",
        charge_amount="29.99",
        currency="USD",
        security_code="true",
        postal_code="true",
    )
    event = await action.wait()

    state = event.params.get("state", "")
    if state == "finished":
        await call.play([{"type": "tts", "text": "Payment processed successfully."}])
    else:
        await call.play([{"type": "tts", "text": "Payment failed. Please try again later."}])

    await call.hangup()

client.run()
```