***

title: pay
slug: /reference/typescript/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/typescript/relay/actions

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

[call-events]: /docs/server-sdks/reference/typescript/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="paymentConnectorUrl" type="string" required={true} toc={true}>
  URL of the payment connector service that processes the payment.
</ParamField>

<ParamField path="controlId" type="string | undefined" toc={true}>
  Custom control ID. Auto-generated if not provided.
</ParamField>

<ParamField path="inputMethod" type="string | undefined" toc={true}>
  How the caller provides payment info.

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

<ParamField path="chargeAmount" type="string | undefined" toc={true}>
  Amount to charge (e.g., `"29.99"`).
</ParamField>

<ParamField path="currency" type="string | undefined" toc={true}>
  Currency code (e.g., `"USD"`, `"EUR"`).
</ParamField>

<ParamField path="securityCode" type="string | undefined" toc={true}>
  Whether to collect CVV (`"true"` or `"false"`).
</ParamField>

<ParamField path="postalCode" type="string | undefined" toc={true}>
  Whether to collect postal code (`"true"` or `"false"`).
</ParamField>

<ParamField path="statusUrl" type="string | undefined" toc={true}>
  URL to receive payment status webhooks.
</ParamField>

<ParamField path="paymentMethod" type="string | undefined" toc={true}>
  Payment method type (e.g., `"credit-card"`).
</ParamField>

<ParamField path="timeout" type="string | undefined" toc={true}>
  Timeout for the payment session.
</ParamField>

<ParamField path="maxAttempts" type="string | undefined" toc={true}>
  Maximum number of retry attempts for failed input.
</ParamField>

<ParamField path="minPostalCodeLength" type="string | undefined" toc={true}>
  Minimum length required for the postal code.
</ParamField>

<ParamField path="tokenType" type="string | undefined" toc={true}>
  Type of payment token to generate.
</ParamField>

<ParamField path="language" type="string | undefined" toc={true}>
  Language for payment prompts (e.g., `"en"`).
</ParamField>

<ParamField path="voice" type="string | undefined" toc={true}>
  Voice for payment prompts.
</ParamField>

<ParamField path="description" type="string | undefined" toc={true}>
  Description of the payment or charge.
</ParamField>

<ParamField path="validCardTypes" type="string | undefined" toc={true}>
  Comma-separated list of accepted card types (e.g., `"visa,mastercard"`).
</ParamField>

<ParamField path="parameters" type={"Record<string, unknown>[] | undefined"} toc={true}>
  Additional payment connector parameters.
</ParamField>

<ParamField path="prompts" type={"Record<string, unknown>[] | undefined"} toc={true}>
  Custom prompt overrides for the payment flow.
</ParamField>

<ParamField path="onCompleted" type="(event: RelayEvent) => void | Promise<void>" toc={true}>
  Callback invoked when the payment operation completes.
</ParamField>

## **Returns**

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

## **Example**

```typescript {13}
import { RelayClient } from '@signalwire/sdk';

const client = new RelayClient({
  project: process.env.SIGNALWIRE_PROJECT_ID!,
  token: process.env.SIGNALWIRE_TOKEN!,
  contexts: ['default']
});

client.onCall(async (call) => {
  await call.answer();
  await call.play([{ type: 'tts', text: 'We will now collect your payment.' }]);

  const action = await call.pay('https://example.com/payment-connector', {
    chargeAmount: '29.99',
    currency: 'USD',
    securityCode: 'true',
    postalCode: 'true',
  });
  const event = await action.wait();

  const state = (event.params.state ?? '') as string;
  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();
});

await client.run();
```