Skip to main content
Every amount on this API is an integer count of Mexican peso cents, and every money-bearing response says so with a currency of "MXN". There are no decimals, no other currency, and no formatted strings: 19600 is MX$196.00.

One fee, split two ways

A delivery costs one number, fee_cents. It is the whole cost of moving the order, computed for that distance, that moment and that payment method. A trip by car carries its surcharge inside this same number (see sending it by car). That single number is then split between two payers:
always, on the quote and on the delivery alike. You choose the split with business_fee_share, a percentage from 0 to 100 saying how much of the fee you absorb:
  • business_fee_share: 100 means you pay the whole delivery fee and the customer pays nothing towards it. Free delivery, from the customer’s side.
  • business_fee_share: 0 means the customer pays all of it.
  • Anything between splits it.
Each store carries a default_business_fee_share so you can set the policy once, and any single order can override it. The value of the order itself, order_value_cents, is separate from all of this. Listo never adds the fee into it or takes the fee out of it.

Capping what you absorb

When your rule is an amount rather than a ratio, send business_fee_cap_cents: an absolute ceiling, in cents, on what you pay.
The customer still pays the exact remainder, so the two figures sum to fee_cents exactly as before. Every cent the ceiling stops you absorbing is a cent your customer pays instead. The common arrangement is business_fee_share: 100 with a ceiling, which reads “I cover delivery up to MX$30 and the customer pays anything above that". A ceiling with a lower share puts a roof on a percentage: `50` with `3000` is "half the fee, but never more than MX$30”. Send the amount rather than converting it into a percentage yourself. A percentage is only a ceiling against the fee it was worked out from, so a converted one breaks as soon as the real fee differs from the one you converted against. MX$30 of a MX$100 quote is 30%, and 30% of the MX$120 the trip actually costs is MX$36: over the ceiling you meant to set. Send 3000 and it is applied to the fee actually being split, whatever that fee turns out to be. Two things to know:
  • There is no store-level default ceiling. A ceiling usually depends on the basket, so it is a per-order field rather than a setting you leave standing.
  • A ceiling higher than the fee is not an error. It does not bind on that order, and the percentage decides the split on its own.
On a cash order a ceiling works against you at the door. See cash at the door.

Your share comes off the balance

Your account holds a prepaid balance per mode, and business_fee_cents is debited from it when the delivery is created, before any courier is called. Everything on that balance can be spent on deliveries the moment it arrives, but not all of it can be withdrawn straight away: cash your couriers collected and money you added by card are each held for a period first. See balance and withdrawals. If the balance does not cover it, the create is refused with 402 insufficient_balance and nothing is dispatched. That is the whole balance gate on a create: no credit, no overdraft, and no partial dispatch. Each live store also carries one Plan Listo, a monthly charge per store. A store you create is yours to pay from the day you create it in live mode, from this balance or from a card saved on your account. A restaurant that connects to you with its current month already paid keeps paying its own plan until its next renewal: its store reads paid_by: "store", and pending_paid_by and pending_paid_by_on name the day the plan passes to you, which is the day of your first charge. If its current month is unpaid when it connects, the plan passes to you that day: the month it had not paid is voided, so nobody is charged for it, and one full month is charged to you that day. If the restaurant cancels its own plan before the handover, the plan never passes to you. The plan is a gate of its own: a live store whose plan is left unpaid by whoever pays it, or has ended, has its quotes and creates refused with 402 plan_required whatever the balance holds. A debt the restaurant still owes on its own plan never stops a store whose plan you pay. A month paid from the balance appears on GET /v1/ledger as a plan_charge row naming the store. See plan and billing. The customer’s share never touches the balance. It is collected from the customer directly, folded into what the courier collects on a cash order or added to the charge on a card order. A courier tip comes off the balance the same way. tip_cents on a prepaid create is debited together with your fee share, as one movement for one order, and the balance has to cover both or the create is refused. The tip is not part of fee_cents and is never split with your customer, so it changes what you pay and nothing else. Listo keeps no part of it: the whole amount reaches the courier. See quote and create for the rules on the field itself.
Prepaid orders are always fully yoursOn payment_method: prepaid, the share is always 100 and business_fee_cap_cents is ignored. Listo never charges the customer on a prepaid order, so there is nobody to collect a customer share from, and a ceiling is a way of handing part of the fee to exactly that nobody. What happens to a share you send depends on where you send it:
  • On a quote, a business_fee_share other than 100 is refused with 422 validation_failed naming business_fee_share, so a price you show your customer is never one that cannot be booked. A prepaid quote that sends no share is priced at 100, whatever your store’s default is. So is a quote with no payment_method, because the only delivery that can bind it is a prepaid one: it is priced like a prepaid quote and refuses a share other than 100 the same way.
  • On a create with no quote, a share you send is forced to 100 and the order is created.
  • A create that binds a quote needs a quote that was itself requested with payment_method: prepaid or with no payment_method.
Charge your customer for delivery in your own checkout if you want them to bear it.

Whose balance a store spends

By default every store you create spends from the one balance above: you fund it once and ship from all of your locations. That is the arrangement most integrations want, and it is unchanged. A store can instead own its money. Each store carries an access_tier: Where a store’s money lives and who may sign in are one setting rather than two, because neither half stands on its own: a store cannot be shown a balance it does not own, and a store that owns one needs somewhere to see it. Every store object also carries a read-only billing, either "partner" or "store", saying which arrangement that store is on. Read that rather than mapping tiers to payers yourself. A full store can also dispatch orders of its own from the console, and those deliveries reach you like any other. See where a delivery came from. A restaurant that already runs on Listo with an account of its own reaches full a different way: it is connected, never created. Its owner approves the connection on a Listo page, and the store you get back already has access_tier: "full" and billing: "store", with the console, the balance and the history it had before. See connect a restaurant that already uses Listo. On a store that owns its money, both sides of an order land on its balance: your share of the fee is debited there when the delivery is created, and the cash a courier collects is credited there when it arrives. Its earnings fund its own deliveries, and its owner withdraws to its own bank. Changing the tier takes effect on the next delivery. Orders already on the road keep billing the account they started on, so nothing in flight can end up with its debit on one balance and its credit on another. A test store cannot own its money. Play money and real money never share an account, so access_tier on a test store is always api_only, and setting anything else is refused with 422 validation_failed. Reading one store’s balance and its movements, and giving its owner a login, are both in balance and withdrawals.

Charging your own markup

markup_cents on a store adds a fixed amount to every delivery fee for that store, and credits that amount to your balance when the delivery arrives. It is how you price your own service into the orders you dispatch, without running a second billing system. It is part of fee_cents like every other component, so business_fee_share splits it exactly like the rest of the fee, and quotes include it: a quote you bind charges the markup it was priced with, even if you changed the setting in between. Two consequences worth planning for:
  • On a cash order the markup rides into what the courier collects, so it counts toward the MX$1,000 cash limit.
  • The credit posts when the delivery is delivered, not when it is created. A canceled or returned order collects nothing, refunds your fee share in full, and pays no markup, so there is no reversal to handle.
On a store that spends your balance, a markup is a visible wash: the same balance pays the fee that includes it and is credited it back. Both movements appear on the ledger rather than being quietly netted, because they are two different facts about the order.

What each payment method settles to

Cash is the only method that pays into the balance. See cash at the door.

When a delivery does not happen

If a delivery ends canceled, returned, or no_courier, your share of the fee is refunded to the balance, and so is any tip you sent with it. You are not charged for a trip that did not deliver. One thing can be deducted from that refund. A cancellation late enough that a courier is already working on the order, or a return trip after a failed dropoff, means a trip was driven anyway, and that trip is billed to you as a separate debit: the delivery fee for each leg that was driven, less your own store markup. A late cancellation is one leg. A return is two, the trip out and the trip back. Cancel before a courier is engaged, or end at no_courier, and nothing was driven: the refund is whole. This changed on 29 August 2026. These charges used to be what the trip cost Listo, so on the same orders they are larger now than they were. The two are separate movements rather than one quietly reduced refund, so what came back and what was charged are always told apart. Both are readable, in two places: the charge is on the delivery itself, in charges, and both the refund and the charge are rows on GET /v1/ledger. A charge can also come back later. Some of these trips are costs Listo takes up on your behalf after the fact, and when that succeeds the money returns as a third movement, a provider_charge_reversal row on the ledger: the same amount, credited in full, against the same order, weeks after the charge in some cases. It is a new row rather than a rewrite of the old one, so the charge you already billed to your own merchant stays exactly where it was and the credit is something you can pass on in turn. Bill the charge when it lands. Do not hold an order open in the hope of a reversal: not every charge is eligible for one, and an eligible one can still be refused.
charges is an array on every delivery and it is empty on almost all of them. type is cancellation_fee or return_fee, naming what the charge was for, and amount_cents is positive here: it is what you were charged. The same money on the ledger is a row whose own type is provider_charge, carrying the negative sign that says which way it moved on the account. The two type fields are separate vocabularies, so do not go looking for return_fee on the ledger. What the charge comes to depends on the trip and on how many legs were driven, so read the number rather than assuming one, and charged_at is when it posted, which is not when the delivery ended. Iterate the array rather than reaching for charges[0]: a charge object has no id of its own, the delivery it hangs off is the handle for it, and that delivery id is also how you line it up with the ledger.
The charge can arrive after the delivery is overThe charge is settled once the cancellation or the return has been. When that happens with the status change itself, the delivery’s final event already carries the charge. When it happens afterwards, charges fills in later and a delivery.updated fires for a delivery that already sent its final delivery.status_changed.So if you bill your own merchant the moment a delivery reaches its terminal status, the orders whose charge landed later are billed short. Handle that late delivery.updated too, or read the delivery back before you invoice. See webhooks.
A refund you issue to your own customer on a delivery that did arrive does not give you the delivery fee back. The trip ran and it was paid for.

Reading the numbers back

Every delivery carries all of these figures, so nothing has to be recomputed:
fee_cents is the total and nothing breaks it down further. How Listo divides that total internally is not part of what you are billed, and it is not published. tip_cents sits beside those figures rather than inside them. It is on every delivery and it is 0 rather than absent when there is no tip, so you read one integer instead of testing for the field. What your balance was charged for an order is business_fee_cents + tip_cents. Two endpoints answer for the account behind those numbers. GET /v1/balance is what it holds right now; GET /v1/ledger is how it got there, one row per movement, the same rows the partner dashboard draws its ledger page from. When you rebuild your books, rebuild them from the ledger rather than from the events you received: the ledger is the record, and an event was only ever a notification about one. See balance and withdrawals.

Prices are never invented

If a delivery cannot be priced, it is refused. There is no fallback fee anywhere in the system, so you will never be quoted a number that was made up because the real one was unavailable. Depending on why, that refusal is 503 provider_unavailable (temporary, retry), 409 no_couriers_available (nobody near the trip is free right now, retry in a few minutes), 422 out_of_service_area (too far from that store), or 422 address_undeliverable (the address itself).