Your customer paid the driver, the driver paid the courier company, and Odoo still shows the order as unpaid. Here is why that happens with cash on delivery in Odoo 19, and a settlement routine your accountant can audit.
Cash on delivery is still one of the most common ways people pay for online orders in Oman. On a recent project, an online retailer delivering across the country had a long list of web orders paid by cash on delivery whose payment status was still pending and whose invoices were still open. The goods had been delivered. The customers had paid the driver. The courier company had even transferred part of the money. On paper, almost nobody had paid.
Nothing in Odoo was broken. Cash on delivery simply works differently from a card payment, and if nobody owns the step between "delivered" and "paid", the open items pile up quickly.
This note describes standard Odoo 19 behaviour, checked against the Odoo 19 documentation and source code. Custom modules, courier connectors or Studio changes in your database can change it.
How cash on delivery works in standard Odoo 19
- You switch it on per delivery method. Cash on delivery is a setting on the delivery method form (in the Sales, Inventory or Website configuration menu, Delivery Methods, the Cash on Delivery checkbox). The Cash on Delivery payment provider is enabled and published automatically. If the delivery method the customer picks does not allow it, the option is hidden at checkout.
- The order is confirmed straight away. When the customer chooses cash on delivery, Odoo confirms the sales order, so your warehouse gets the delivery order without waiting for money.
- The payment transaction stays "Pending". Cash on delivery is an offline provider. It records that the customer chose to pay on delivery, and the transaction is set to Pending. Nothing in standard Odoo 19 moves it to Done when the driver collects the cash, and the transaction form has no button for that.
- No payment is registered and no invoice is created automatically. The Automatic Invoice setting only creates and pays invoices when the payment provider confirms the transaction. A pending cash on delivery transaction never reaches that point, so you invoice the order yourself and you register the money yourself.
So "Pending" on a cash on delivery order is not an error. It means: we promised to collect cash, and the accounting has not been told yet that we did.
Why the open invoices pile up
In our project the gap came from three things:
- No one owned the step. The warehouse delivered, the courier collected, and the accounts team only saw a bank transfer from the courier with one total for many orders.
- The courier pays in batches, not per order. One transfer can cover a few days of deliveries, minus the courier's fee, and sometimes minus an order that was refused at the door. Matching one bank line to dozens of invoices by hand is where teams give up.
- Delivered is not the same as collected. Some orders were refused or returned, so treating every delivered order as paid would have been wrong too.
The result: receivables that looked far too high, customers who appeared to owe money they had already paid, and a courier balance that nobody could prove.
The fix: settle each courier remittance as one batch
What we did on the project was to put a clearing account between the customer and the bank, and settle every courier remittance in one go:
- Create a clearing account for cash held by the courier (for example "Courier COD clearing", a current asset). Keep one per courier if you use more than one.
- Invoice the delivered orders. If you invoice on delivered quantities, invoice after the delivery is validated. Do not invoice refused or returned orders as if they were collected.
- When the courier sends its remittance statement, post one journal entry for that batch: debit the courier clearing account with the total collected, and credit the customer receivable with one line per customer, using the invoice number as the label.
- Reconcile the receivable lines with the invoices. Each credit line appears as an outstanding credit on the matching invoice; add it, and the invoice moves to Paid.
- When the courier's bank transfer arrives, reconcile the bank line against the clearing account. The courier's fee goes to an expense account at this point, so your invoices keep the full sales amount. Anything still left on the clearing account after the transfer is a shortfall you can chase.
Some teams prefer to use Register Payment on the invoices with a dedicated courier journal instead of a manual entry. That can work as well. Agree one method with your accountant and use it every time, so the courier balance always lives in one place.
What this gives you
- Invoices that are Paid when the customer has actually paid, not when the goods left the warehouse.
- A courier balance you can prove. The clearing account shows how much cash the courier is holding for you at any time.
- Fees and shortfalls you can see. The courier's fee is a visible expense, and a missing order shows up as a difference on the clearing account instead of disappearing into an old open invoice.
- Clean receivables for credit control. If your aged receivable is full of cash on delivery orders, your follow-up on real overdue customers gets lost. See our guide on credit control in Odoo.
Before you go live with cash on delivery
- Decide which delivery methods allow cash on delivery, and tick the setting only on those.
- Decide who confirms collection and when: the warehouse, the delivery team or accounts. Write it down.
- Create the courier clearing account (one per courier) before the first order, not after the first remittance.
- Agree the remittance statement format with your courier: order or invoice number, amount collected, refused orders and fee. A statement with only a total cannot be reconciled line by line.
- Decide how refused and returned orders are handled: return receipt in stock, credit note or cancelled invoice.
- Keep proof of delivery for each order. Our post on proof of delivery and delivery notes explains why.
- Review the clearing account and the list of pending cash on delivery transactions every week, and match the courier's transfers in bank reconciliation.
- If you also take card payments online, set those up as well. See our comparison of online payment providers in Oman.
Want a second pair of eyes?
If your cash on delivery orders are stuck as unpaid, or you are about to switch it on for your online shop, I can review your delivery methods, invoicing policy and courier settlement routine with you. See how I work on Odoo implementation in Oman, or book a free 30-minute review.
Related guides
- Odoo implementation services in Oman
- Odoo online payments in Oman: Thawani vs OmanNet vs Tap
- How to launch an e-commerce store in Oman with Odoo 19
- Bank reconciliation in Odoo 19 for Oman
- Odoo proof of delivery: delivery notes that stop invoice disputes
- Odoo credit control for Oman businesses
- Contact Ata Khadivi
Book a Free 30-Minute Odoo Review
Bring a list of cash on delivery orders that still show as unpaid, or your courier remittance statement, and we will check the settlement routine together.