Skip to main content
KRA eTIMSKenyaTax ComplianceERPNext

Integrating KRA eTIMS with ERPNext, end to end

eTIMS is not a checkbox you tick at go-live. It is a transmission pipeline bolted onto every Sales Invoice you submit. Here is how the integration actually behaves, and where it bites.

CoaleTech Engineering11 min read

Every VAT-registered business in Kenya now has to transmit invoices to the Kenya Revenue Authority in real time through eTIMS. For a company running ERPNext, the question is not whether to comply but where the compliance logic lives. Bolting a separate eTIMS portal onto the side of your ERP means two sources of truth, manual re-keying, and reconciliation work at month end. Pushing it directly into the invoice lifecycle means compliance happens automatically the moment a cashier hits submit.

We have deployed the second model across retail, manufacturing, and distribution clients. This is what the integration looks like in practice, what breaks, and how to keep it from blocking your sales floor.

What eTIMS actually requires

eTIMS is a real-time invoice transmission system. For each taxable sale, KRA expects a signed invoice payload that includes item-level tax classification, a control unit signature, and a generated QR code that ends up on the printed receipt. The same applies in reverse: purchase invoices from your suppliers should be validated against KRA records before you treat them as input VAT.

That breaks down into a handful of moving parts the integration has to own:

  • Device onboarding: registering the eTIMS control unit and storing its credentials so invoices can be signed.
  • Item classification: every sellable item needs a KRA item code and tax category before it can appear on a transmitted invoice.
  • Invoice signing and transmission: turning a submitted Sales Invoice into a signed payload KRA accepts.
  • QR code generation: the signed response carries data that must render as a QR code on the receipt.
  • Credit notes: returns and corrections transmit as their own document type, not as edits to the original.
  • Error reconciliation: when transmission fails, you need a queue, a retry path, and a log you can audit.

Where it hooks into ERPNext

The natural attachment point is the Sales Invoice submit event. In Frappe terms, the eTIMS app registers a doc_event on Sales Invoice that runs on submit: build the payload, sign it, transmit, and store the response against the invoice.

This is the central design decision in the integration, and it is a trade-off. If transmission runs synchronously on submit and fails, you have two options: let the failure block the submission, or let the invoice through and queue the transmission for retry.

Blocking on transmission failure guarantees you never have an unreported sale, but a flaky KRA endpoint or a dropped connection will freeze your tills. Queue-and-retry keeps the sales floor moving but means an invoice can exist as submitted in ERPNext while still unreported to KRA for a few minutes. We almost always choose queue-and-retry for retail, paired with a tight 15-minute retry scheduler and alerting on anything stuck in the queue.

The DocTypes you end up with

A complete eTIMS layer on ERPNext is not one DocType. The integrations we run typically settle on a set like this, each with a clear job:

  • eTIMS Device: the registered control unit and its credentials.
  • eTIMS Invoice Log: one record per transmission attempt, holding the signed payload, KRA response, and QR data.
  • eTIMS Transmission Queue: pending and failed transmissions awaiting retry.
  • KRA Item Code and KRA Tax Category: the classification masters items map onto.
  • Invoice Signature: the signature returned by the control unit, linked back to the invoice.
  • Error Log: structured failure records you can actually search during an audit.

Item classification deserves special attention because it is where most go-lives stall. KRA will reject an invoice that contains an unclassified item, so before you can transmit a single sale you have to register your entire catalogue. On one distribution client we mapped over 2,500 items to eTIMS classification codes through a dedicated registered-items master before the first invoice went out. Treat that as a data project in its own right, run it during configuration, and do not leave it to the week of go-live.

Purchase-side validation

The sell side gets all the attention, but the purchase side is where you protect your input VAT. eTIMS lets you validate supplier invoices against KRA records. The pattern we deploy validates a Purchase Invoice on submission and, where the client wants it strict, blocks Payment Entries against any supplier invoice that has not been verified.

This is a strong control. It means a supplier who has not actually declared the sale to KRA cannot quietly become an input VAT claim on your books. It also creates friction, so it is worth turning on deliberately rather than by default, and worth pairing with a clear message to finance staff explaining why a payment is held.

Failure handling is the real work

In a demo, eTIMS looks like a single API call. In production, the API call is the easy 20 percent. The other 80 percent is everything that happens when it does not return cleanly:

  • Network timeouts between your server and KRA leave invoices stuck in an unknown state.
  • KRA rejects a payload because an item code is missing, a tax category is wrong, or the signature is invalid.
  • A duplicate submission attempt risks creating two records if you do not key on the invoice number.
  • A callback you expected never arrives, so the invoice sits in a pending state until the scheduler polls for it.

One more gotcha worth flagging: KRA constrains invoice numbering with its own sequence rules. If you let ERPNext naming series and KRA sequencing drift apart, you will get rejections that look like data problems but are really ordering problems. Decide your numbering strategy up front and keep the two in lockstep.

What good looks like at go-live

When the integration is right, the compliance step fades from the operator's view. A cashier scans, takes payment, and prints a receipt that already carries a valid QR code. Finance sees a clean queue, an empty error log, and a month-end VAT return that reconciles to the penny because every invoice was reported as it happened. On the Toysam Distributors deployment, moving eTIMS off a third-party portal and into the invoice lifecycle cut monthly tax reporting from five days of manual work to two.

The lesson we keep relearning is that eTIMS is not a feature you add at the end. It is a pipeline that touches item setup, invoice submission, purchasing, payments, and scheduled jobs. Design it into the implementation from day one and it becomes invisible. Bolt it on at the end and it becomes the thing that breaks on go-live morning.

Running ERPNext in Kenya and weighing how to handle eTIMS? We have done this across retail, manufacturing, and distribution. Book a discovery call and we will walk through your catalogue, your transmission strategy, and your failure handling before you commit to an approach.

Working on something like this?

We ship ERPNext and custom Frappe apps across Kenya, Uganda, Tanzania, Rwanda, Ethiopia, and Somalia. Let's talk through your build.

Working on something like this?

We ship ERPNext and custom Frappe apps across Kenya, Uganda, Tanzania, Rwanda, Ethiopia, and Somalia. Let's talk through your build.