Capability 30 · Integrations

Integrations

Make everything talk — your systems, third parties, old tools and new platforms.

Before you read: Written from live engineering practice — the money-moving, million-user work our team runs on our own products, set down so anyone building something can learn from it.

01 · What it is

Software never lives alone. We build integrations that make your systems talk: third-party APIs connected with correct contracts, webhooks and event-driven sync so changes propagate immediately instead of in end-of-day batches, and legacy connectors that let the old tool keep running while modern logic happens elsewhere. Data mapping and transformation are explicit — fields land where the receiving system actually expects them — and retries, failure handling and reconciliation are built in so a flaky partner doesn't silently corrupt your records. Every integration is monitored like the production path it is.

What a integrations build covers:

  • Third-party API integrations done to contract
  • Webhooks & event-driven sync instead of nightly batches
  • Legacy system connectors that keep old tools working
  • Explicit data mapping & transformation
  • Retry, failure & reconciliation handling for flaky partners
  • Integration monitoring treated as production
What we do · How we do it — as TGJOF Enterprise

This is how we do Integrations

Software never lives alone, and every integration is a promise about data moving between two systems built by different people under different assumptions. The seam is the answer: a deliberate adapter layer that keeps the partner's dialect out of the product, webhooks that push events the moment they happen, OAuth delegation that keeps credentials out of the database, and idempotent replay that makes at-least-once delivery harmless. Payment rails are the hardest classroom, and every one of them is treated as a first-class citizen — M-Pesa/Daraja lived as a home-market reality beside PayPal, Stripe, PayStack, cards, bank transfers and client-specific gateways, each boarded with the same verification, idempotency and reconciliation discipline. When a partner fails, retries or misbehaves, the money stays correct anyway.

What we do

  • Webhooks that push, not batch — events arrive the moment they happen, are verified before they are trusted, and are answered with their recorded outcome when redelivered instead of re-executed.
  • OAuth delegation over stored passwords — user connections go through their identity provider with narrow scopes and rehearsed refresh flows, and whatever must be stored lives in a vault rather than a config file.
  • Every payment gateway a first-class adapter — M-Pesa/Daraja as lived home-market reality, plus PayPal, Stripe, PayStack, cards, bank transfers and client-specific gateways, all boarded behind one interface with their own signing, status queries and settlement reconciliation.
  • Idempotent replay as a law of the boundary — every mutating call and inbound event carries a reference, so a replay, a double-tap or a redelivered webhook returns the settled answer instead of producing a second effect.
  • Reconciliation as the daily referee — the partner's statement and the product's records are matched line by line on schedule, and a mismatch becomes an investigation with a drill-down rather than a quiet rounding.

How we do it

  • Read the contract before the code — endpoints, schemas, rate limits, auth and failure shapes are proven with real calls in a real environment, so the integration honours the API's hard parts, not its brochure.
  • The adapter seam is built first — the domain speaks one vocabulary behind a thin, versioned boundary that owns timeouts, retries, backoff, logging and dead-lettering once, so a gateway swap is a contract job instead of a rewrite.
  • Callbacks are claims until proven — an inbound event is verified by signature, and where money is involved the rail's own status API is queried before any credit, with transport errors staying pending and definitive failures acknowledged without booking a cent.
  • Failures are classified, never merged — transient, permanent, auth-revoked and invalid-payload errors each get their own treatment, with backoff for the transient, a visible dead letter for the hopeless and honest 'pending' copy for the user.
  • Tested by replay and race — the suite re-delivers every callback, re-sends every request and simulates duplicate-purchase races and cross-rail refunds, asserting the ledger changed exactly once every time.

02 · The full discipline

Software never lives alone. We make the system you run talk to the systems the world runs.

Every system that does not talk to the others is a silo you pay to duplicate — data re-entered, orders re-keyed, balances re-typed, errors re-explained. Integration is how software stops being a collection of islands: third-party APIs connected to contract, webhooks pushing events the moment they happen, and legacy systems kept working while modern logic runs beside them.

We build the integration seam the way a live platform has to — because our own work integrates with the hardest partners of all. KodiiPay lives on Safaricom's Daraja rails — STK Push, PayBill, C2B, B2B, B2C, Till — plus banks, email, SMS, WhatsApp, push notifications and the device ecosystem, all connected by adapters, verified callbacks, retries and reconciliation. That is not a diagram; it is production code that has carried real money through a partner who occasionally fails, retries and misbehaves — and the money has stayed correct every time.

Below is how integrations are really engineered when a broken partner would be a financial incident, not a ticket. Contracts, webhooks, OAuth delegation, data mapping, the adapter seam, the M-Pesa and messaging rails, error handling, idempotency, reconciliation and the honest truth that bolted-on integration is a special kind of debt.

03

Software never lives alone

The moment a product is useful, it needs the world: a payment rail to take money, an email service to say thank you, a CRM to remember the customer, a warehouse system to know what is in stock, a bank to settle. Every one of those is an integration, and every integration is a promise about how data moves between two systems that were built by different people, for different purposes, under different assumptions.

  • Every bound is a contract — the request shape, the response shape, the error shape and the retry behaviour are defined and documented before code is written on either side.
  • Events beat end-of-day batches — a webhook telling you 'the deposit arrived' the moment it arrives beats a nightly file telling you about it tomorrow.
  • The mapping is explicit — field by field, the sender's 'client_code' becomes the receiver's 'customerId' by a documented rule, never by an engineer's midnight guess.
  • Both sides know the failure shape — the partner will fail; the question is whether your system knows what a failure looks like and behaves correctly when it happens.
  • Legacy keeps running while modern logic grows beside it — the old system stays live behind a connector while the new world builds on clean ground.
  • Every integration has an owner — a human or a team is named responsible for a bound's health, its changes and its eventual retirement.

A product is only ever as useful as the systems it can reach. We build the reach deliberately, to contract, with the failure behaviour designed before the celebration of success.

04

API integration done to contract

An API is a contract wearing a URL. The competent integration reads the contract first — endpoints, schemas, pagination, rate limits, idempotency keys, auth — and then proves the reading with real calls against a real environment. The amateur integration writes code against a guess and blames the partner when the guess was wrong.

  • The contract is read before the code — the API's actual behaviour (not its aspirational docs) is the specification, verified with real calls.
  • Authentication is set up properly — keys, tokens, scopes and expiry handled through secure storage, never a credential committed to a repository.
  • Pagination is honoured, not assumed — the integration reads every page the API returns, including the pages the demo never reached.
  • Rate limits are respected and designed around — the integration knows its quota, backs off when asked, and queues what cannot be sent now.
  • The error responses are mapped — 400s, 401s, 429s and 5xxs each mean something different, and the system behaves differently for each instead of one catch-all.
  • Versioning is deliberate — the integration pins the API version it was written against and has a path forward when the partner moves on.

The credible line between a sandbox and production is whether the code honours the contract's hard parts. We read the contract, prove it in the environment, and ship an integration that behaves correctly when the partner is neither happy nor fast.

05

Webhooks: events, not end-of-day batches

A webhook is the partner calling you instead of you polling the partner. It is how money tells you it arrived, how an order tells you it shipped, how a form tells you it submitted. The win is immediacy and honesty; the cost is that inbound events are untrusted, unordered and sometimes delivered twice — which is exactly what the design accommodates.

  • Events move money instantly — a C2B confirmation from Safaricom triggers the credit the moment it lands, not at the next sweep.
  • Delivery is at-least-once, so idempotency is a requirement — a webhook that arrives twice is answered with the settled state, never processed a second time.
  • Every inbound event is verified, not trusted — signatures and shared secrets authenticate the sender, and for money the gateway's own status API is queried to prove the claim before credit. On M-Pesa a callback is a claim; the STK Query is the proof.
  • The dead letter tells the truth — events that fail processing rest visibly with their payload, ready for a human, not lost to a silent log line.
  • Secrets rotate — webhook signing keys have a lifecycle, and the change is rehearsed before the partner is forced to re-key.
  • Replays are answered, not re-run — an event that has already been processed returns the recorded outcome; history is never rewritten by a redelivery.

The webhook is the difference between 'the money is here' and 'we will check at midnight'. We build the instant, honest event path — and the discipline that keeps redeliveries harmless.

06

OAuth delegation and credential handling

Credential handling is the least glamorous and most important part of integration. A leaked key is an incident that usually outlives the fix; a shared password is a bomb with a delayed fuse. We delegate where the partner supports it, store what must be stored in a vault, rotate what can rotate, and treat secrets as a security control, not an operational detail.

  • OAuth delegation where the partner offers it — the user's own accounts (Google, Microsoft, a bank's developer portal) are connected through their identity provider, not through their passwords sitting in our database.
  • Scopes are granted narrowly — the integration asks for the minimum access the task needs and no more; 'read email to make the invoice' does not get 'send email as you'.
  • Refresh flows are engineered — tokens refresh on schedule, failures surface visibly, and the user is invited back to re-authorize before the integration breaks silently.
  • Secret vaults, not config files — keys and credentials live in a managed secret store, injected at runtime, never in the repository, never in logs.
  • Rotation is rehearsed — the integration handles a credential change gracefully and on schedule, because keys expire whether or not anyone remembered.
  • Least privilege per connection — each partner gets its own credential, so a compromised connection is contained to that connection and revoked alone.

Credentials are the keys to the integration, and keys get lost. We store them like the crown jewels, delegate instead of copying where the partner allows, and rehearse rotation so a change is a routine, not an outage.

07

The integration seam: adapters

The most important architectural decision in integrations is the seam: a thin, deliberate layer where the outside world's shape is translated into the product's own language. The rest of the codebase never needs to know whether 'the partner' is Safaricom, a bank, a postal API or a CSV importer — it talks to an adapter, and the adapter talks to the world.

  • The domain never learns the partner's dialect — the product calls a deposit, an order, a shipment in its own vocabulary; the adapter translates, so a partner swap never ripples through the codebase.
  • The seam is where testing concentrates — the adapter is mocked in every test and exercised against the real partner in integration tests, so both halves are provable.
  • A partner change is a seam change — migrating from one gateway, one email vendor or one SMS provider is an adapter swap with a contract, not a rewrite of the business.
  • Legacy systems sit behind the same seam — an old inventory or accounting system gets an adapter, giving modern code a clean interface over ancient behaviour.
  • The seam owns the non-functional details — timeouts, retries, backoff, logging and dead-lettering live at the boundary once, and every future integration inherits them.
  • The seam is versioned — the domain's contract with the adapter is stable, so internals can evolve without breaking every screen that calls them.

The adapter is the reason 'we are switching payment rails' can be a two-week contract job instead of a system rebuild. We build the seam first, so the world can change behind it without the product noticing.

08

Data mapping and transformation

Integration is mostly translation: the partner's field names, formats, timezones and enums almost never match yours. The same customer is 'user_id' in one system, 'client_no' in another and 'CUSTOMER_REF' in a third. Getting the mapping right is where integrations succeed or quietly corrupt.

  • The field map is documented, not improvised — every transformed field has a written rule: source, destination, transformation, example.
  • Formats are normalised at the seam — dates, phone numbers and currencies arrive in the product's own canonical shape, so no screen ever re-learns the partner's luck.
  • Phone numbers are the Kenyan classic — +254, 07, 254 and '0' forms are normalised to one truth, because a payment addressed to an un-normalised number is a payment aimed at a guess.
  • Enums map both directions — the partner's 'P', 'X' and 'FAILED' become the product's one vocabulary, and the reverse mapping carries back out.
  • Unmapped fields are visible — a field the partner sends that the product does not yet understand lands in a logged surplus, discoverable, not discarded silently.
  • Mapping is tested with real samples — the transformation suite runs against captured payloads, the kind the partner actually sends, including the odd ones.

A mapping bug is a silent corruption bug: the integration succeeds, the data lands, and it lands wrong. We translate explicitly, normalise at the seam and test against real partner output, so 'landed wrong' is a test failure, not a month-end discovery.

09

Sync, ETL and data movement

Some integrations are request/response, but many are data movement: a nightly sync, a bulk load, a warehouse feed, a customer migration, a statement export. The discipline of moving data correctly is not glamorous, and its failures are the kind that surface weeks later as a quiet 'why is this number off?'

  • Sync is designed, not scheduled and hoped — the state machine of a sync — pending, running, partial, complete, failed — is explicit, and a rerun is a safe, recorded operation.
  • Batch processing is idempotent — re-running yesterday's load does not duplicate the rows; the batch carries a run identity the recipients deduplicate against.
  • Incremental beats full where it is true — delta syncs move only what changed when a change log reliably exists; full syncs are the fallback with a cost the user knows.
  • ETL is honest about transformations — the extract, transform and load steps are separated and logged, so 'which step corrupted this' has an answer.
  • Encryption in transit and at rest — personal and financial data moving between systems is protected on the wire and where it rests.
  • Counts reconcile — a load that moved 1,000 rows must be able to prove it moved 1,000, by comparing counts and checksums, not by hoping.

Data movement is where integrations earn their keep at scale — and where they leak if nobody checks the counts. We make every bulk move provable: idempotent reruns, logged transforms and a count it can defend.

10

M-Pesa and payment integrations — the lived detail

There is no more instructive integration than the payment gateway, and no sterner partner in the Kenyan market than Safaricom's Daraja. Our own platform is the classroom. Every integration we build for clients inherits what we learned sending real money through it: the callbacks are claims, the network drops, the retries redeliver, and reconciliation with the statement is the only truth that settles the day.

  • STK Push — the customer pays with a PIN from their own phone; the app requests the charge, Safaricom pushes it, and nobody's card or PIN ever touches our side.
  • PayBill and Till (Lipa na M-Pesa) — money lands on a business number or merchant till; the C2B confirmation says it arrived, and the balance is credited only after verification.
  • C2B / B2B / B2C — confirmations in, business-to-business disbursements, and outbound payouts to a phone — each with its own callback shape and correlation rules.
  • The callback is a claim, not a proof — for STK, before crediting, the backend calls the STK Query status API and only a genuinely verified ResultCode 0 settles the transaction.
  • Transport errors stay pending — a network failure in verification returns the retry signal to the gateway, and the money remains pending with nothing half-credited.
  • Every payment interaction is logged — raw callbacks and verification results land in a queryable gateway log, so 'where is my money' has an inspectable answer and reconciliation can prove the day.

Payment integration is the most exacting seam there is, and our classroom is a live platform. Whatever we integrate for you — payments or anything else — inherits the discipline that kept real money correct through a partner that fails, retries and misbehaves.

11

Every gateway, one adapter

A product that can take money one way turns away everyone who prefers another, and a platform that knows only a single gateway is a feature away from re-platforming. The payment layer is built rail-agnostic: one adapter interface behind which every gateway boards as a first-class citizen — M-Pesa/Daraja lived as a home-market reality, beside PayPal, Stripe, PayStack, card processors, direct bank transfers and client-specific gateways. Each rail arrives with its own shape, and each is reduced to the same contract the domain already speaks.

  • Every rail boards behind the same seam — a gateway arrives as an adapter carrying its own protocol, auth and callback shape, while the product keeps calling 'charge', 'verify' and 'refund' in one vocabulary.
  • M-Pesa/Daraja as the lived example — STK Push, PayBill, C2B, B2B, B2C and Till are adapted as home-market reality, so the layer is proven on the hardest rail before a second one ever boards.
  • Cards, PayPal, Stripe and PayStack as citizens — Visa and Mastercard, PayPal, Stripe, PayStack, direct bank transfers and client-specific gateways slot beside mobile money without adding surface area to the business logic.
  • Verification is the same on every rail — a callback from any gateway is a claim until the rail itself confirms: a signature check here, a status query there, and the credit lands only on the rail's own proof.
  • Idempotency runs once, protects every rail — the reference, the replay absorption and the settled-answer contract live in the shared seam, so boarding a new gateway inherits the money-safety by construction.
  • Reconciliation is per rail, one discipline — each gateway's statement is matched line by line on the same cadence, and the drill-down that isolates an M-Pesa discrepancy is the same one that isolates a card discrepancy.

A rail is a business decision rather than a technology invention, and the adapter layer is what makes switching, adding or dropping a gateway a conversation about money instead of a rewrite. Every gateway that boards inherits the verification, idempotency and reconciliation discipline — none of it unique to one rail, all of it mandatory for every rail.

12

Email, SMS, WhatsApp and push

Communication integrations are many and subtle: email with its deliverability physics, SMS with its concatenation and sender-ID rules, WhatsApp with its templates and business constraints, push with its token lifecycles. Each is a partner with quirks, and each is a promise about whether the right person hears the right thing at the right moment.

  • Email is deliverability engineering — branded, structured, correctly signed and sent with honest sender identity, because a payment receipt that lands in spam is a receipt that did not arrive.
  • SMS is premium and precise — short, transactional, sender-ID-respecting, and counted, because every message is paid for and every message must be worth it.
  • WhatsApp follows the platform's rules — templates approved in advance, conversations within the window, and business flows that respect the channel's etiquette.
  • Push is a token lifecycle — device tokens register, expire and change; the integration cleans dead tokens and knows that a push is a suggestion, not a guarantee.
  • The send path is asynchronous and observable — messages queue, retry and log their outcome, so 'did the receipt go?' is answerable without waking a database.
  • One preference model, many channels — the user's notification choices govern every channel through one configuration, so honouring a choice is a rule, not a hope.

A notification that misses its person is a promise broken silently. We engineer each channel to its own quirks and connect them to one honest preference model, so the right message reaches the right person at the right moment — and we can prove it did.

13

Device and hardware integrations

Sometimes the integration is not a service but a device: a printer, a barcode scanner, a point-of-sale terminal, a camera, an IoT sensor. Device integrations live at the edge of the network where things break physically — cables, drivers, firmware, Bluetooth pairing — and the discipline is the same as for any partner, plus a layer of reality: the hardware is a partner with a body.

  • The device speaks through a driver boundary — the product talks to an adapter over the device's protocol; a printer swap is an adapter change, not a rewrite.
  • Offline devices behave honestly — a printer that is unplugged or a scanner that is out of range produces a visible, retryable state, never a silent queue that is 'somewhere'.
  • Pairing and discovery are engineered — Bluetooth and network discovery follow a guided, recoverable flow instead of a settings-screenshot treasure hunt.
  • Firmware and driver drift is tracked — the integration logs the device's version and flags the model that behaves differently, because hardware compatibility is a spectrum.
  • The physical failure is recoverable — reprints, reset paths and operator recovery for the physical world are designed, not improvised on a support call.
  • Comms are encrypted and monotonic — receipts and point-of-sale messages carry sequence numbers and signing, so nothing is duplicated or forged on the wire.

A device is a partner with a body and a temper. We engineer the edge so the physical world fails visibly, retries cleanly and reports honestly — and the money side, where a register and a payment meet, carries the same safety as any financial integration.

14

Error handling: retries, dead letters and timeouts

Every partner fails; the difference between a robust integration and a fragile one is what happens next. Timeouts are set, retries are scheduled with backoff, failures are classified, and work that can never succeed goes somewhere visible. The partner's failure is a design input, and the design answers it.

  • Timeouts with a consequence — every outbound call has a deadline and a defined behaviour when it passes; a customer request never waits forever on a partner's silence.
  • Retries with backoff and jitter — transient failures retry on a schedule that does not stampede the partner or the log, and gives up at a defined ceiling.
  • Failures are classified, not merged — 'transient', 'permanent', 'auth revoked' and 'invalid payload' are different diseases with different treatments; the catch-all 'it broke' cures none.
  • Dead letters are a visible queue, not a log line — work that fails past its ceiling rests with its full payload, assigned to a human, re-playable when the partner recovers.
  • Downstream idempotency absorbs the retries — because the recipient deduplicates on a reference, the retry-and-backoff loop is safe by construction.
  • The retry honestly tells the user — a payment or an order that is retrying is reported as pending or retrying, never as a silent success.

The reliable integration is not the one that never fails; it is the one whose failure is visible, bounded and recoverable. We design the failure behaviour the way the success is designed — because in production they share the same stage.

15

Idempotency across system boundaries

When two systems meet over a network, 'at least once' is a law, not a policy — a redelivered webhook, a retried request, a double-tapped confirm. The defence is idempotency: the receiving system remembers the reference and answers repeats with the recorded outcome instead of re-executing. This is the difference between a dropped notification and a double-charged customer.

  • Every mutating integration carries a reference — the request that creates, credits or dispatches something names its intent with a unique key, born at initiation.
  • Duplicate arrivals are answered, not re-run — a retried webhook or a redelivered event is matched to its earlier outcome and returned it; history is never written twice.
  • The money paths are the strictest — a repeated STK callback, a replayed C2B confirmation or a retried disbursement can never double-credit or double-send.
  • Batches are rerun-safe — a sync or a load carries a run identity, and a re-run deduplicates instead of accumulating.
  • The reference is the audit trail — when support asks 'did this happen twice?', the idempotency key is the proof, recorded with every outcome.
  • Idempotency is tested, not assumed — the suite re-delivers every callback and re-sends every request, asserting the ledger changed exactly once.

The network will make your integration lie about whether something already happened; idempotency is how the system tells the truth anyway. We build remembering into the boundary so the retry is a friend and the duplicate is a no-op.

16

Reconciliation and verification

Integration sources of truth disagree, and somewhere a human has to know which one to trust. For money, the gateway's statement is the truth; for data, the source system is. Reconciliation is the standing practice of proving your records and the partner's agree — line by line where it matters, total by total where it scales.

  • Match by reference, not guesswork — transactions are matched to the partner's echoes by their shared reference, never by amount-and-date coincidence.
  • Totals are compared daily — your side versus the partner's side is reconciled at a cadence, and a mismatch is an incident with an investigation, not a quiet rounding.
  • The drill-down isolates the rows — when totals disagree, the system separates the specific discrepancies, so 'which transaction' has an answer before anyone guesses.
  • Expected mismatches are classified — pending-at-cut and in-flight-at-cut items are parked deliberately, so only genuine anomalies reach a human.
  • Bulk loads verify their own counts — row counts, checksums and totals prove a transfer moved what it claims to have moved.
  • Reconciliation runs unattended — a scheduled job performs the close, flags exceptions and pages the right person instead of waiting to be remembered.

The partner's records and yours will disagree one day; the question is whether you find it at reconcile time with an investigation, or at audit time with a surprise. We build the daily proof so the answer is already known when anyone asks.

17

Integration health monitoring

An integration is a production path with a heartbeat of its own: the partner can be healthy while every call to it fails, and the servers can all be green while the data silently stops moving. Monitoring integrations means watching the boundary itself — call volume, latency, error rate, dead-letter depth and staleness — not just the boxes on either side.

  • Every partner call is counted and timed — the success rate and p95 latency of each partner call are numbers with alert thresholds, so a degrading partner is found by data.
  • The dead-letter depth is a red light — work that is stuck in a retry or dead-letter state accumulates visibly and alerts whoever owns the bound.
  • Staleness is monitored, not just errors — a sync that quietly stopped running or an event that stopped arriving is as loud as an explicit failure, caught by a staleness check.
  • Webhook failures get their own dashboard — inbound delivery failures and signature problems are visible per partner, so 'they changed their payload' is a searchable fact.
  • Reconciliation outcomes are trended — the daily reconcile result is a series, so a pattern of near-limit discrepancies is caught before it is a real mismatch.
  • The alert means a human with a runbook — a paged integration incident points at a documented response, so the team accelerates instead of improvising.

Integration health is the least visible and most business-critical monitoring there is. We watch the boundary the way we watch the servers — with numbers, thresholds and a runbook — so the partner's silence is never mistaken for obedience.

18

Integrations are production paths

An integration that moves money, orders or customer data is production infrastructure, not a utility script to be tried in isolation and forgotten. It deserves the same discipline as the core product: security, logging, error visibility, testing and a named owner. We refuse the framing that calls external calls 'someone else's problem'.

  • Credentials are managed like crown jewels — partner keys and tokens live in a vault, scoped minimally, rotated on schedule and revoked alone when compromised.
  • Every call is logged end-to-end — request, response, latency, status and correlation ID, so a support question about any partner event has a searchable answer.
  • Integration tests run in CI — the adapter is exercised against mock and contract, and the real-partner suite runs on the release cadence that matches the risk.
  • The failure mode has an owner — when a partner degrades, someone is woken with a runbook and the decision rights to queue, fail or fall back.
  • It is versioned like the product — a partner's API change, a payload evolution, a deprecation — the integration has a lifecycle with a migration plan, not a 'works in staging' memory.
  • Ownership persists beyond launch — the integration is maintained, monitored and improved as long as it carries value, not abandoned the week it shipped.

There is no integration that is 'just a call out' once it carries real business meaning. We treat every boundary as a production path with a heartbeat, a runbook and an owner — the same discipline the core product gets.

19

Honest limits: integration debt when it is bolted on

Integration is a special kind of debt when it is bolted on — a direct call to a partner's SDK from ten different screens, credentials living in three config files, a 'quick CSV' written in a week and authoritative ever since. We say plainly what bolted-on integration costs, because the fix is cheaper the earlier it is named.

  • Bolted-on integration spreads the partner through the codebase — ten screens calling the SDK directly means a partner change is a ten-screen rewrite; the seam was the cheap conversation that skipped it.
  • It hides its own failure modes — without a boundary, timeout and retry behaviour is improvised per call site, so the same partner is handled three different ways and all three are wrong somewhere.
  • It becomes sacred by age — the 'quick CSV' that has run unexamined for years is now the load-bearing beam nobody dares touch; naming it is the beginning of fixing it.
  • It fails without a trail — a direct call with no logging leaves 'what happened to that order?' as a mystery; the seam is where the trail would have lived.
  • It multiplies with every new partner — each bolt-on re-invents timeouts, retries and secret handling from scratch; a seam centralises once and every future integration inherits it.
  • The retrofit has a cost, so we price it honestly — moving a bolted-on integration behind a seam is real work with real value; we give the client the true number and the payoff case for doing it.

We will tell you honestly where your existing integrations are carrying bolt-on debt and what it will cost to put a seam under them. And when we build integration from the start, we build the seam first — so the debt is never yours to accrue.

The toolchain

The integration toolchain

The contract readers, adapters, event machinery, credential vaults, messaging rails and reconciliation tools that make our integrations correct — the same machinery that keeps a live M-Pesa platform talking to the world.

stack.toolchain

01

API & contract layer

Talk to the partner, to contract

  • Typed API clientsThe contract in code — request and response shapes checked at compile time, not discovered at runtime.
  • Contract testsThe integration is exercised against the documented shape; a partner drift is caught as a failing suite.
  • Pagination & cursor helpersEvery page of every partner response is read, with the loop proven not assumed.
  • Rate-limit middlewareQuota-aware calls with backoff, queued when the partner says slow down.
  • Error taxonomyTransient, permanent, auth and invalid-payload failures each treated as the disease they are.
  • Mock-first test suitesThe adapter is tested against faithful mocks and the real partner in the integration harness.

02

Webhooks & events

The partner calls you

  • Signature verificationEvery inbound event authenticated by shared-secret signature before it is trusted even to be read.
  • Idempotency keysRe-delivered events matched to their recorded outcome and answered, never re-executed.
  • Dead-letter queuesFailed events rest visibly with full payload, replayable when the cause clears.
  • Event replay toolingA webhook retried on demand against a captured payload — the recovery path, rehearsed.
  • Webhook payload versioningThe receiver records the shape it understood, so a partner's next payload is a diff, not a mystery.
  • Verified-event fan-outOne verified event fanned to every legitimate consumer without re-processing the source.

03

Auth & secrets

Keys like crown jewels

  • OAuth delegationUser accounts connected through their identity provider, with narrow scopes and working refresh flows.
  • Managed secret vaultPartner credentials injected at runtime from a store — never in the repo, never in the logs.
  • Key rotation routinesCredential changes rehearsed and executed on schedule, because keys expire whether remembered or not.
  • Scoped credentialsEach partner connection its own least-privileged identity, contained and revocable alone.
  • Service tokens with TTLsShort-lived service tokens that reduce damage when a single key leaks.
  • Access auditsWho can read, rotate or deploy a credential is recorded, reviewed and revocable.

04

Data mapping & movement

Translation, tested with real output

  • Transform mapping definitionsEvery field's source, destination, transformation and example written down, not improvised.
  • Canonical format normalisersPhone numbers (+254 / 07 / 254), dates and currencies reduced to one truth at the seam.
  • Incremental-sync toolingDelta moves when a reliable change log exists; full loads as the priced fallback.
  • Batch-run identityEach load carries a run key so re-runs deduplicate instead of accumulating.
  • Encrypted transportPersonal and financial data protected on the wire and at rest in every hop.
  • Count-and-checksum verificationA transfer proves it moved what it says it moved.

05

Payment rails

The hardest classroom of all

  • Daraja (M-Pesa) adaptersSTK Push, PayBill, C2B, B2B, B2C and Till on the real Safaricom rails.
  • STK Query / verification loopA callback is a claim; the gateway's own status API is the proof before any credit.
  • Callback correlationOutbound sends carry a reference the gateway echoes, so matching is never guesswork.
  • Gateway failure taxonomyTransport retries, definitive failures, amount mismatches — each acknowledged correctly and never mis-credited.
  • Payment gateway logsRaw callbacks and verification results queryable, because 'where is my money' deserves an inspectable answer.
  • Reconciliation engineDaily match against the gateway statement by reference, with drill-down to the discrepancy.

06

Messaging & channels

The right person, the right moment

  • Email delivery stackSigned, branded, deliverability-engineered transactional mail — receipts that will not vanish into spam.
  • SMS provider adaptersShort, transactional, sender-ID-respecting messages counted and logged.
  • WhatsApp Business APITemplate-approved, conversation-window-respecting business messaging.
  • Push notification serviceToken lifecycle managed — dead tokens cleaned, delivery a suggestion that is tracked as such.
  • Unified preference modelThe user's channel choices honoured as a rule across email, SMS, WhatsApp and push.
  • Async send queuesMessages queue, retry and log outcomes asynchronously, never blocking the user's request.

07

Reliability & observability

The boundary has a heartbeat

  • Call telemetryCount, latency and error rate per partner, with thresholds that page a human.
  • Dead-letter dashboardsStuck work visible by depth and age, not discoverable by rumour.
  • Staleness monitorsA sync or event stream that stopped moving is as loud as an explicit failure.
  • Reconcile-outcome trendingDaily results as a series, so near-limit drift is caught while small.
  • Partner-change detectionPayload drift and signature failures surface with the recorded 'before' for a fast diff.
  • Incident runbooksA paged integration incident points at documented response steps, not improvisation.

Lifecycle

The integration lifecycle — from discovery to a seam that endures

Every integration we build travels the same path, from the first reading of the partner's contract to the maintained production path it becomes. This is the lifecycle for every API, webhook, data flow and payment rail we connect.

01

Discover the seam

Find where the product meets the outside world, and what the boundary needs to own.

02

Read the contract

Endpoints, schemas, rate limits, auth and failure shapes proven with real calls, not docs on faith.

03

Design the adapter

A thin boundary translating the partner's dialect into the product's language, once.

04

Map the data

Every field's source, destination, transformation and example written and reviewed.

05

Secure the credential

OAuth where possible, vault-held secrets otherwise, narrow scopes and rotation rehearsed.

06

Engineer failure

Timeouts, classified errors, backoff retries and dead letters — the partner's failure as a design input.

07

Build idempotency

References on every mutating call and event, so replays and redeliveries are answered, never re-run.

08

Fire the webhook

Events delivered confirmed, verified and logged; the consumer idempotent by construction.

09

Reconcile

Daily match against the partner's truth, by reference, with drill-down to the discrepancy.

10

Monitor the boundary

Call counts, latency, error rates, dead-letter depth and staleness watched with alert thresholds.

11

Document the surface

The contract, the mapping, the failure behaviour and the runbook written for whoever owns it next.

12

Own it

Version it, evolve it as the partner changes, and refactor it out of bolt-on debt over time.

Closing

More than development

Integrations are where your product meets the systems the world runs on — and where silos either close or quietly keep you paying to duplicate. When we design and build integrations, that includes:

Third-party APIs integrated to contract, proven with real calls.Webhooks pushing events the moment they happen, not at end-of-day.OAuth delegation and vault-held secrets with rotation rehearsed.The adapter seam, so a partner swap is a contract job, not a rewrite.Explicit data mapping, with formats normalised at the boundary.M-Pesa on Daraja: STK Push, PayBill, C2B, B2B, B2C and Till.Callback verification where a claim is proven against the gateway before credit.Email, SMS, WhatsApp and push engineered to each channel's quirks.Device and hardware integrations that fail visibly and retry cleanly.Timeouts, classified errors and backoff retries on every partner call.Dead letters as a visible queue, not a silent log line.Idempotency across every boundary, tested not assumed.Reconciliation daily, matched by reference, with drill-down.Integration health monitored as a production path with a heartbeat.Every call logged end-to-end with correlation.Credentials scoped, separated and never in the repository.The legacy system kept running behind a modern connector.The 'quick CSV' named and priced before it becomes load-bearing.The discipline run live on a platform integrated with Safaricom's hardest rails.An owner, a version, a runbook and a migration path for every bound.You own the seams, the adapters, the keys and the documentation.Integration debt called out honestly instead of deferred forever.

The partner will change, fail, retry and misbehave. The seam, the idempotency and the reconciliation are how your side stays correct anyway — and the reason a bolted-on integration is a debt we name before it accrues.

We build the seam first and own the boundary forever — so every system you run talks to every system your world runs, correctly, all the time.

Previous capability

Accessibility

Next capability

Legacy System Modernization

Building something like this?

The discipline above is what we run on our own products every day. If it would help on yours, our door is open.