Odoo integration
Connect Cashfree Payments to Odoo Orders
A payment gateway is only useful if the order behind it moves. This page is about the join: checkout on your storefront, payment at Cashfree, and an Odoo order that is confirmed exactly once.
- Checkout
- Webhooks
- Order confirmation
- Refunds
- Reconciliation
Reviewed by Bhavesh Selarka, COO & Co-Founder, Heliconia Solutions · Odoo 16 Functional Certification · Odoo Partner · Updated
Proof
Clients
Businesses that run on what we built
The short answer
What Does a Cashfree and Odoo Integration Cover?
Cashfree collects the money and tells you what happened. Odoo owns the customer, the order, the stock reservation and the accounting entry. The integration is the join between the two: a payment session created from an Odoo order, a signed webhook that confirms it, and an order state that only ever advances once.
If you sell from the Odoo website, Odoo's own payment provider support may be enough and you shouldn't pay for a project you don't need.
The work starts when checkout lives somewhere else. LittleQ sell through a Next.js storefront that talks to Odoo over GraphQL, with Cashfree in the checkout and Odoo running catalog, cart, orders, customers and stock behind it.
In that architecture the browser can never be trusted to confirm a payment, and the storefront can never be the system that decides an order is paid. Both jobs belong to a signed, idempotent server-side flow.
The first decision
Which System Owns What
Agree this before building. A headless storefront makes every ambiguity in this table visible within a week of launch.
| Object | System of record | Direction | Conflict rule |
|---|---|---|---|
| Payment instrument | Cashfree | Never leaves the gateway | Odoo stores a reference only, never card or UPI data |
| Cart | Storefront, briefly | Storefront to Odoo at checkout | A cart is not an order. Nothing is reserved until Odoo says so |
| Order | Odoo | Created before payment starts | The order exists first, in a draft or pending state, so the payment has something to confirm |
| Price and stock | Odoo | Odoo to storefront | Re-checked at order creation. A stale price in a cart is not a price |
| Payment outcome | Cashfree | Gateway to Odoo by webhook | The signed webhook is the truth. The return URL only moves the shopper along |
| Order confirmation | Odoo | Odoo only | Confirmed once, idempotently, whichever signal arrives first or twice |
| Refunds | Wherever issued | Both | Ends as a credit note in Odoo, and the stock decision is made deliberately |
| Shipment | Odoo, then the courier platform | Odoo to Shiprocket | Out of scope here. Picked up on the Shiprocket page |
The row that saves the most money is the third. Creating the Odoo order before the payment gives the webhook something to attach to. Without it you are matching payments to shoppers by email address and hoping.
The lifecycle
From Cart to Confirmed Order
The headless flow LittleQ run, written out so you can compare it with yours.
Step 01
Cart
The storefront holds the cart and reads prices, stock and promotions from Odoo over GraphQL, so what the shopper sees is what the ERP believes.
- Storefront
Step 02
Order created
At checkout, Odoo creates the order in a pending state with the customer, lines, totals and a reference the gateway will carry back.
- Odoo
Step 03
Payment session
Your server asks Cashfree for a payment session for that order and amount. The browser never states the amount, because the browser is not trusted with money.
- Server to gateway
Step 04
Payment
The shopper pays. Authentication happens at the gateway, which is why the redirect back cannot be treated as proof of anything.
- Cashfree
Step 05
Confirmation
Cashfree sends a signed webhook. Odoo verifies it, matches the reference, records the payment and confirms the order. A second delivery changes nothing.
- Webhook
Step 06
Status check
Meanwhile the shopper is looking at a thank-you page. It asks your server for the order state rather than deciding one, so a slow webhook doesn't become a wrong answer.
- Storefront
Step 07
Fulfilment hand-off
A confirmed, paid order becomes a delivery in Odoo and goes to the courier platform. That hand-off has its own page rather than being buried in this one.
- Shiprocket
Step 08
Reconciliation
Settlements arrive net of fees on the gateway schedule. Payments, fees and the bank line are matched in Odoo daily rather than at month end.
- Accounting
Which pattern
Native Provider, Community Module or Custom Integration?
Work down the list. We will tell you when you already have what you need.
| Your need | Approach | Why |
|---|---|---|
| Selling from the Odoo website or portal | A payment provider configured in Odoo | No development. Check that your gateway is supported on your version first |
| Selling from a custom storefront | Custom server-side integration | What LittleQ needed: payment sessions created server-side, orders confirmed by webhook |
| A mobile app that takes payments | The same server flow, different client | The client changes. The trust boundary does not |
| Marketplace or distributor ordering | Custom, with approval workflow | LittleQ also run distributor registration and approval inside Odoo |
| Subscriptions and recurring collection | Scope separately | Recurring billing is a lifecycle, not a checkout. We would look at your mandate flow specifically |
| Settlement and fee accounting | Custom, agreed with finance | Gross, fee and payout timing have to be modelled rather than assumed |
Failure handling
What Makes It Survive a Bad Day
- Signature verification on every webhook, with unsigned or replayed deliveries rejected before anything is read
- Idempotent order confirmation keyed on the gateway event and order reference, so a duplicate webhook can’t create a second confirmation, invoice or shipment
- A queue with retry and backoff between the webhook endpoint and Odoo, so a brief outage doesn’t lose a paid order
- An explicit status poll from the thank-you page, so the shopper gets a truthful answer while the webhook is still in flight
- A scheduled catch-up that pulls recent gateway transactions and closes any gap, because a webhook that never arrived can’t be retried by anyone
- A defined rule for abandoned pending orders: how long they hold stock, when they expire and what happens if payment lands afterwards
- Daily reconciliation of gateway transactions and settlements against Odoo orders and payments, with the differences reported
- Alerting on failed webhook processing, queue depth and pending orders older than the threshold
Security boundary
Credentials, Data and What We Do Not Touch
- 01
Card and UPI credentials never reach Odoo, the storefront or our code. The gateway holds the instrument and Odoo holds a reference.
- 02
Gateway keys and webhook secrets live in the server environment of your backend, never in the storefront bundle, never in the database and never in a repository.
- 03
Amounts are set server-side from the Odoo order. A client that can name its own price will eventually be asked to.
- 04
Webhook endpoints verify the signature, rate-limit, and do one thing only: enqueue a verified event.
- 05
Access to the Cashfree dashboard stays yours. We ask for the least access that lets us build and debug, and we don't need your login.
- 06
Every inbound event and outbound call is logged with its identifier, so a disputed order can be traced end to end.
- 07
We are not a payment institution and we do not advise on your compliance obligations. Where your setup raises them, they go to your adviser and we build to that answer.
How we run it
Implementation Sequence
Assessment
Odoo version and edition, where checkout lives, order volumes, payment methods, refund policy and what fulfilment does next.
Ownership and order model
The matrix above completed, plus the order states: pending, paid, confirmed, cancelled, refunded, and who moves each one.
Build in test mode
The full flow against test credentials, including the paths people skip: abandoned payment, late webhook, duplicate webhook, failed payment, partial refund.
Reconciliation first
The daily comparison job exists before go-live, not after the first settlement that nobody can match to orders.
Controlled go-live
Live keys, a small volume first, webhooks and pending orders watched, with a rollback path that never strands a paid shopper.
Support through the first peak
The first sale spike is the real test. We stay close through it, and through the first settlement reconciliation.
Evidence
Cashfree and Odoo in Production
A direct-to-consumer storefront where Cashfree sits inside a headless Odoo order flow, alongside shipping and a distributor portal.
| Project | Industry | Odoo | Key capabilities | Technology |
|---|---|---|---|---|
| LittleQ | eCommerce, baby care | Odoo | Headless Odoo API · Product Catalog Management · Product Discount Engine · Distributor Registration Portal | Odoo · Next.js · PayloadCMS · React · Node.js |
Integration assessment
Request an Integration Assessment
Send your Odoo version and edition, where checkout lives, your order volumes and payment methods, and whatever connector you run today. You get the ownership matrix filled in, the order state model, and an honest answer on whether a configured provider already covers you.
- Data ownership matrix completed for your setup
- Order state model: pending, paid, confirmed, cancelled, refunded
- Configured provider or custom server-side flow, with the reasoning
- Failure-handling plan: webhooks, retries, catch-up, pending-order expiry
- Reconciliation of gateway settlements and fees against the Odoo ledger
What clients say
In Their Words
Heliconia transformed our business with Odoo. They implemented a dynamic website with e-commerce capabilities, enhancing our online presence significantly.
Sandesh ThummarBusiness Owner, Ladder Logix
Heliconia provided a unique canteen solution, saving us valuable ordering time. Their innovative approach has been invaluable to our operations.
Pradeep LakhaniBusiness Owner, Avasar Agency
Questions
Cashfree and Odoo Questions, Answered Directly
Can Cashfree work with a storefront that is not the Odoo website?
Yes, and that is the case we have in production. LittleQ run a Next.js storefront on Odoo GraphQL with Cashfree in the checkout, while Odoo keeps catalog, cart, orders, customers and stock.
What confirms the order: the redirect or the webhook?
The webhook, always. The redirect brings the shopper back and nothing more. If the browser is what marks an order paid, then a closed tab, a flaky network or a curious shopper produces orders that disagree with the gateway.
What does the shopper see while the webhook is still in flight?
A thank-you page that asks your server what the order state is, and says "we are confirming your payment" until it changes. It never guesses, and it never tells someone their order is confirmed before Odoo agrees.
How do you stop an order being confirmed twice?
Idempotent handling. Confirmation is keyed on the gateway event and the order reference, so repeated deliveries, a retry and a catch-up job all reach the same state. Without it you get duplicate invoices and duplicate shipments for one payment.
What happens to stock while payment is pending?
It follows a rule you decide, and the rule matters more than the code. We agree how long a pending order holds stock, when it expires, and what happens if the payment lands after expiry. Leaving it undefined is how oversells happen.
Does this page cover shipping too?
No, on purpose. A confirmed, paid order becomes a delivery, and the courier platform takes it from there. LittleQ use Shiprocket, and that hand-off has its own page so neither topic gets half an explanation.
Next step
Confirm the Order Once, From the Right Signal
Tell us where your checkout lives and what a paid order has to trigger. We will map the states, the webhook flow and the reconciliation before anyone writes code.