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

> ## Agent Instructions
> Notes on the Listo Partner Delivery API:
> - Every endpoint is under `https://api.listo.delivery/v1/` and authenticates with a bearer API key.
> - This documentation site is at https://docs.listo.delivery. The full machine-readable reference is the OpenAPI document at https://api.listo.delivery/docs/openapi.yaml (served by the API host, not by this site).
> - Any page of this site is also available as raw markdown by appending `.md` to its URL, for example https://docs.listo.delivery/en/guides/webhooks.md. The index of every page is https://docs.listo.delivery/llms.txt and all of them in one file is https://docs.listo.delivery/llms-full.txt.
> - Every page is published in English under https://docs.listo.delivery/en/ and in Spanish under https://docs.listo.delivery/es/, with the same path after the language. The API reference is under https://docs.listo.delivery/api-reference/ in English and https://docs.listo.delivery/es/api-reference/ in Spanish.
> - To debug an integration yourself: `GET /v1/request_logs` lists the calls your keys made with what you sent and what was answered, `GET /v1/events` lists the events Listo emitted, `GET /v1/webhook_deliveries` lists every attempt to deliver them, `POST /v1/events/{id}/resend` sends one event again and `POST /v1/test_webhooks` sends a sample event (`"test": true`). The page https://docs.listo.delivery/en/guides/debugging describes them. A resent event is a snapshot from when it happened; `GET /v1/deliveries` is still how you recover current state.
> - Every error response has `error.doc_url`, a page that explains that error code and what to do, and `error.request_id`, the same value as the `X-Request-Id` response header. All the pages are listed at https://docs.listo.delivery/en/errors. Filter `GET /v1/request_logs` with `request_id` to read the logged call.
> - A `409 account_exists` from `POST /v1/stores` means the restaurant already has its own Listo account: connect it instead of creating it, as the page https://docs.listo.delivery/en/guides/connect-existing-account describes.
> - Every live store carries one Plan Listo, charged to the partner. The exception is a connected restaurant that had already paid its current month: it keeps paying its own plan until its next renewal, shown as `paid_by: "store"` with the handover date in `pending_paid_by_on`. A `402 plan_required` from a quote, a delivery create or a retry means the store's plan is not paid or has ended; the page https://docs.listo.delivery/en/guides/plan-and-billing describes the plan, the `plan` block on a store and how to end or restart it.
> - An AI assistant (Claude Code, Cursor, Codex) can act through the same API key at `https://api.listo.delivery/mcp`, an MCP server over Streamable HTTP authenticated with `Authorization: Bearer <API key>`. Every tool runs the matching `/v1/` endpoint, and each one that moves money first previews and then needs a confirmation token; the page https://docs.listo.delivery/en/guides/connect-ai-client lists the tools and describes the two steps.

# Cash at the door

> Collecting cash from the customer on delivery, and what it settles to.

Send `payment_method: "cash"` and the courier collects from your customer at the
door. Most orders in Mexico are still paid this way, so this is a first-class
path rather than a fallback: it needs no card processing, no onboarding and no
checkout of your own.

## What the courier collects

```
cash_to_collect_cents = order_value_cents + customer_fee_cents
```

The value of the goods, plus whatever share of the delivery fee you decided the
customer pays. Nothing else, and never the share you pay.

Never a tip either: `tip_cents` is refused on a cash order, because a courier at
the door is tipped in the same hand that is already passing them money, and a
declared tip would change this total and count against the cash limit below. See
[quote and create](https://docs.listo.delivery/en/guides/quote-and-create.md).

It is on the quote and on the delivery, as `payment.cash_to_collect_cents`:

```json theme={null}
{
  "order_value_cents": 19600,
  "fee_cents": 8004,
  "business_fee_cents": 0,
  "customer_fee_cents": 8004,
  "payment": {
    "method": "cash",
    "status": "unpaid",
    "cash_to_collect_cents": 27604,
    "paid_at": null
  }
}
```

That number is fixed when the delivery is created. It does not move afterwards,
so it is safe to print on a receipt or read out over the phone.

`null` and `0` are different answers here. On a non-cash order the field is
`null`, because there is nothing to collect at all and a `0` would read as a
free order.

A cash order whose door total really is zero reports `0`. That happens when the
order value is `0` and you absorb the whole delivery fee: the order is still
cash, and what the courier takes is nothing. Its `fee_cents` also matches what
a prepaid order for the same trip would cost, because cash that is never
handled costs nothing extra to handle, and the courier is sent with no
collection to make.

## The limit

A courier can be asked to collect at most **MX\$1,000.00**, which is
`100000` cents, in `cash_to_collect_cents`. That is the total including the
customer's fee share, not just the order value.

Over it, both the quote and the create are refused with `422 cash_over_cap`.
There are two ways past it:

* Take the order by `card` instead, which has no such ceiling.
* Raise `business_fee_share` so more of the fee comes off your balance and less
  is collected at the door. This helps only when the fee is what pushed the
  total over.

> [!WARNING]
>
> **A ceiling moves money the other way**
>
> `business_fee_cap_cents` raises the door total instead of lowering it. Whatever
> the ceiling stops you absorbing goes to the customer's share, so capping what you
> pay increases `cash_to_collect_cents` by exactly the cents it refused.
>
> An order that clears the limit on a percentage alone can be refused with
> `cash_over_cap` once a ceiling is applied to the same split. If you set ceilings
> and take cash, check the quote's `cash_to_collect_cents` rather than reasoning
> from the percentage.

> [!WARNING]
>
> **Check the total, not the order**
>
> An order at MX$980 with a MX$80 fee the customer pays comes to MX\$1,060 at the
> door and is refused. If you validate against the cap yourself before quoting,
> validate the total.

## What the customer sees

Cash orders are always handed over in person. Whatever `handoff` you send, the
courier meets the customer at the door: nobody leaves an order that has to be
paid for.

## What happens to the money

The customer pays the courier, the cash makes its way back through Listo, and
your balance is credited with the **order value** when the delivery is marked
`delivered`.

The delivery fee never arrives on your balance, because it was never yours: the
customer's share was collected for Listo, and your share was already debited
when the delivery was created. So the net effect of a delivered cash order is:

```
order_value_cents - business_fee_cents
```

which is exactly what you would have kept if you had taken the payment yourself
and paid for delivery.

That credit is **held** at first. It counts in `balance_cents` immediately, so
you can spend it on the next delivery straight away, and it joins
`available_cents` once the cash has actually been settled to Listo, on a weekly
cycle. See [balance and withdrawals](https://docs.listo.delivery/en/guides/balance-and-withdrawals.md).

If a delivery ends `returned`, the credit is reversed: the courier brought the
order back and there is no cash to account for.

## `payment.status` stays `unpaid`

It is worth being clear about this, because it looks like a bug and is not.

On a cash order, `payment.status` stays `unpaid` and `paid_at` stays `null` for
the whole life of the delivery, including after it is delivered. That field
describes money moving through Listo, and cash never does: it goes from your
customer's hand to the courier's.

**`delivered_at` is the signal that the cash was collected.** A cash delivery
with a `delivered_at` is a cash delivery that was paid for. Do not wait for
`payment.status` to change, because it never will.

## When it is not the right choice

* The total is over MX\$1,000. Take card.
* You already took payment yourself. Use `prepaid`; there is nothing left to
  collect and no reason to make the courier handle money.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.