Skip to main content
The Checkout Session is the object every payment turns on. You create one the moment an order is ready to pay, and it carries everything the payment step needs: the resolved amount, the policy decision for this purchase, the caller’s cards chargeable at this merchant, and, when payment runs by transfer, where to send the live call. Both integration modes start here. Whether your agent charges a card itself or hands the call to Ringup’s payment line, the session is the same object.
Response

What you send

The order is the amount authority

When you pass order_id, Ringup reads the total from the merchant’s own order and returns it as amount_cents with amount_source: "order". You do not have to compute the total, and a total nobody derived from a real order cannot reach the caller. amount_cents is required only when there is no order_id, and it is never trusted over an order. If you send both, the order wins: the amount you sent is ignored and the total comes from the merchant’s order. The response says where the number came from:
  • amount_source: "order": resolved from the merchant’s order.
  • amount_source: "request": the amount you sent, because there was no order to read.

The cards are the ones chargeable here

cards holds the caller’s saved cards chargeable at this merchant, newest first. Each entry is the same shape everywhere a card appears:
Offer them by brand and last four, then pass the chosen instrument_id to charge. This filter is handle-aware, not merely processor-aware. On a processor that scopes card-on-file per merchant, a card enrolled at one merchant has no charge handle at another, and cannot get one without the card again. Listing it would fail at the charge, after the caller had already said yes to it. So a card that cannot be charged here is not offered here. An empty cards array means there is nothing to offer: text a link instead. default_card_id is the newest card, a suggestion for what to offer first. It is never charged implicitly: charge always requires an explicit instrument_id.

Two ways it is used

A Checkout Session works two ways, and the difference is invisible to your order logic.
  • In your agent (API). Your agent reads the session, offers a card from cards, and calls charge itself. Nothing transfers. The flexible path.
  • Call transfer. A hosted web checkout, over the phone: transfer_to is the checkout URL, transferring the call is the redirect, and return_to is the return URL. The caller pays on the Ringup line and the call comes back to your agent.
transfer_to (in the response) is where you send the call. return_to (in the request) is where Ringup sends the caller back. Both destinations are null whenever payment is not required, because there is nothing to transfer to. The response carries the destination in two forms; pick the one your platform can dial:
  • transfer_to, a SIP URI. The default: it carries a signed session credential, so the payment line reads the session directly from the leg. Use it whenever your platform can transfer a call to a SIP address.
  • transfer_to_number, a plain phone number, for platforms that can only transfer calls to a number. The call arrives without the credential, and the payment line resolves the session by the caller’s number, which Ringup stored when you created the checkout.
Treat transfer_to as opaque. The user part is a signed credential naming exactly one session. It is not the session id and cannot be assembled from one: build the URI yourself and the transfer will be rejected. Pass the string through exactly as returned, and do not append parameters to it. On some platforms only the URI survives the transfer leg, so anything you add to the end is dropped without an error.

Three ways a transfer ends

However the transfer ends, the payment is identical: Ringup charges the caller, texts them an SMS receipt, and posts a webhook to your server. The three options below change only what the caller hears and where the call goes next. return_to and the spoken messages are complementary; use whichever fits.
  1. Transfer back (return_to). Ringup returns the caller to your agent with the outcome attached as SIP headers, so your agent resumes knowing payment succeeded and closes in its own voice. Best when you want to keep talking (upsell, fulfillment, goodbye).
  2. Ringup speaks the result (success_message). No transfer back: Ringup reads your line and ends the call. Best when payment is the last thing on the call but you want the closing words in your words.
  3. Neither. Ringup reads a short default confirmation and ends.
A return_to that cannot connect falls back to speaking success_message (or the default) and ending, so a failed return never strands the caller.

Read a session back

To check on a session later, fetch it by id:
Response
session_status is open, complete, or expired. The charge has its own status inside charge, null until something is attempted. This is a read, so a declined charge comes back 200 with a failed charge rather than an error.

Reconcile from the webhook

However the call ends, your server learns the outcome from a checkout.succeeded webhook. That is your source of truth, independent of what the caller heard, and it is what you flip your own order on.

Next steps

Payment Policy

How Ringup decides payment_required for the session.

Charge

Run the card the caller picked out of the session.