> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ringup.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Retell AI

> Add card-on-file payments to a Retell agent by call transfer: create a Checkout Session, transfer, and reconcile on the webhook.

Add card-on-file payments to a Retell agent by call transfer. This works like a hosted web
checkout, over the phone: when the order is confirmed, your agent creates a **Checkout Session**
and transfers the live call to it, the caller pays on the Ringup line, and the call optionally
returns to your agent. Ringup recognizes the caller, charges their saved card, settles it
against the order, and texts a receipt. Your server reconciles from a webhook. If the model is
new to you, read [Call transfer](/concepts/call-transfer) first.

This page is end to end: first-time setup, the call, the return, and what happens after payment.

## How the pieces map to Retell

| Ringup piece        | On Retell                                                                                     |
| ------------------- | --------------------------------------------------------------------------------------------- |
| `create_checkout`   | A custom function on your agent that creates a Checkout Session and returns where to transfer |
| The transfer target | The `transfer_to` SIP URI the Checkout Session returns                                        |
| The transfer        | Retell's `transfer_call` tool (or Transfer Call node) with `custom_sip_headers`               |
| The result          | A `checkout.completed` webhook to your server                                                 |

## Prerequisites

* A Retell agent you already run, with a phone number.
* Your Retell API key.
* A Ringup account and API key (from your Ringup dashboard). Test mode works out of the box on
  a shared sandbox, so there is nothing to connect. See [Testing](/concepts/testing).

## Step 1: Add the Ringup checkout function to your agent

This is the one-time setup. Register a custom function on your Retell agent that creates a
Ringup Checkout Session, authenticated with your Ringup API key. Add it in the Retell dashboard
(Agent, then Functions, then Add custom function) or through the Retell API:

```jsonc theme={null}
{
  "type": "custom",
  "name": "create_checkout",
  "description": "Create a Ringup Checkout Session for the order and return where to transfer the call.",
  "url": "https://api.ringup.dev/v1/checkouts",
  "headers": { "Authorization": "Bearer <YOUR_RINGUP_KEY>" },
  "parameters": {
    "amount_cents": { "type": "number", "description": "Order total in cents" },
    "order_id":     { "type": "string", "description": "Your processor order id, if you have one" }
  }
}
```

Then add one line to your agent's prompt so it knows when to call it:

> When the caller has confirmed their order, call `create_checkout` with the order total.

That is the whole setup. Nothing else is provisioned in Retell, and your agent is otherwise
unchanged.

<Note>
  A CLI to register this for you is on the way. Until then, the function above is the only setup
  step, and it is a copy and paste.
</Note>

## Step 2: Create a Checkout Session when the order is confirmed

Your agent calls the function from Step 1. It takes the same inputs a hosted checkout session
takes (amount, line items, order), plus how you want the call to end, and returns where to send
the call:

```jsonc theme={null}
create_checkout({
  "amount_cents": 2500,
  "line_items": [{ "name": "Large pepperoni", "quantity": 1, "amount_cents": 2500 }], // optional
  "order_id": "sq_abc",                              // optional: settle against an existing order
  "return_to": "sip:agent@your-retell-number",       // optional: transfer the caller back after payment
  "success_message": "You are all set, your order will be ready shortly.",  // optional (if no return_to)
  "failure_message": "That card was declined. Please call back with another card."  // optional
})

// response (the Checkout Session)
{
  "id": "cs_x9f2",                                   // Checkout Session id; the correlation token
  "payment_required": "required",                    // "required" | "optional" | "none"
  "transfer_to": "sip:cs_x9f2@transfer.ringup.dev"   // where to transfer; embeds the id
}
```

* `payment_required: "none"`: the merchant does not take payment for this order. There is no
  `transfer_to`; carry on and end the call normally.
* `required` or `optional`: transfer the call to `transfer_to`.

The `id` and `transfer_to` are what Step 3 uses. `order_id` and `line_items` mirror a checkout
session. `return_to`, `success_message`, and `failure_message` control how the call ends (Step 5).

## Step 3: Transfer to the returned target

Transfer to the `transfer_to` from Step 2, and attach the Checkout Session `id` as a custom SIP
header so Ringup can match the call to the session. Inject both through Retell dynamic
variables, never as values the model types:

```jsonc theme={null}
{
  "type": "transfer_call",
  "transfer_destination": "{{transfer_to}}",          // from Step 2
  "custom_sip_headers": { "X-Session-Id": "{{id}}" }  // the Checkout Session id, from Step 2
}
```

Ringup matches the call by the `X-Session-Id` header, with the id also embedded in the SIP URI
as a backstop, so correlation holds even if a middlebox strips the header.

<Warning>
  Transfer to the SIP URI, not to a PSTN number. Custom SIP headers survive to a SIP endpoint but
  may be stripped on the way to a PSTN number, which would drop the header match.
</Warning>

## Step 4: Keep the caller comfortable during the handoff

A cold transfer drops your agent as the payment line connects. Two easy, configurable moves
remove the rough edge:

* Have your agent speak one short bridge line just before the transfer fires ("One moment,
  connecting you to secure payment"), so the caller is never on silence.
* On the warm transfer path, set on-hold music instead of the default ringtone for the brief
  connect gap.

The payment line's voice and model are set in your Ringup dashboard, so you can match them to
your agent.

## Step 5: The return, and the result (the webhook)

Ringup answers the transferred call, recognizes the Caller, charges the saved Card on the
merchant's own payment processor, and texts the caller a receipt. A first-time caller with no
saved card is texted a secure pay link instead. Then the call ends one of three ways, depending
on what you passed in Step 2:

* **`return_to` set**: Ringup transfers the caller back to your agent and attaches the outcome as
  SIP headers (`X-Payment-Status: completed`, `X-Confirmation`), so your agent resumes already
  knowing payment succeeded and can confirm the order, upsell, or say goodbye in its own voice.
* **`success_message` / `failure_message` set (no `return_to`)**: Ringup reads your line for the
  outcome and ends the call on its line. Use this when you want the closing words in your own
  wording but do not need the caller back on your agent.
* **Neither**: Ringup reads a short default confirmation and ends. The receipt is the proof.

A `return_to` that cannot connect falls back to reading your `success_message` (or the default)
and ending, so a failed return never strands the caller. Either way, your server learns the
outcome from a webhook. This is how you mark the order paid:

```jsonc theme={null}
{
  "id": "evt_9f2",
  "type": "checkout.completed",         // or "checkout.failed"
  "created": "2026-07-07T18:05:12Z",
  "data": {
    "checkout_id": "cs_x9f2",
    "payment_id": "pay_abc",            // the Payment
    "amount_cents": 2500,
    "order_id": "sq_abc",               // the id you passed in Step 2, echoed back
    "confirmation": "2PJJZY",
    "caller": "+14155551234",
    "card": { "brand": "VISA", "last_4": "5858" }
  }
}
```

Match on the `order_id` you passed, store the `payment_id`, and flip your order to paid. See
[Webhooks](/concepts/webhooks) for the full event catalog, the statuses, signature
verification, and idempotency.

## Validation status

Retell's `transfer_call` and its `custom_sip_headers` support are documented by Retell. Ringup
confirms each new platform by capturing the first real transfer and checking the Checkout
Session id arrives as expected; until that check runs for your account, treat the transfer
wiring as documented, not yet validated on your specific Retell and telephony setup. The
recognition, charge, receipt, and webhook behavior is the same payment path Ringup runs
everywhere.
