WordPress Engineering

Connecting WordPress to the systems it has to talk to

An integration is not the request that works. It is what happens when the other system is down, slow, or answers with something you did not expect — and that is the part that is usually left unspecified.

The problem

The happy path is a day's work and the failure behaviour is the integration

Connecting two systems that are both working is straightforward: authenticate, send, receive, map the fields. What makes an integration trustworthy is everything else — the other end being unavailable, a request succeeding but the data being rejected, the same event arriving twice, a record changing on one side while it is being written on the other. Those cases are not edge cases; on a production integration they are the normal course of a month.

  • Data is being copied between WordPress and another system by hand
  • A form submission has to create a record somewhere else
  • The same customer or order exists in two systems and the two disagree
  • An integration was built and fails silently when the other system is unavailable
  • Somebody has to check each day whether the sync actually ran
  • Records are being duplicated by repeated events
  • A failure last month was found when a report did not add up
  • Credentials or API keys are stored in the database in plain text
Who this is for

The people who usually bring us this problem

Someone copying data by hand between systems

The volume is becoming a problem, or the errors are.

Someone whose integration fails quietly

It works most of the time and nobody knows when it does not.

Someone connecting a CRM, ERP or fulfilment system

The two systems need to agree about the same records and currently do not.

What it costs

What this costs while it goes unfixed

Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.

An integration that fails silently is worse than none

A manual process is visibly slow. An integration that stops working without reporting produces a gap in the data that is discovered later, usually from a report that does not reconcile, and by then the question is not how to fix it but how much is missing and since when.

Events arrive more than once

Webhooks are retried, a queued job runs twice, a network timeout is ambiguous — the request may have succeeded and the response been lost. Every write has to be safe to repeat, which is a design decision made before the integration is built rather than a bug fixed after a duplicate appears.

Two systems will disagree about the same record

They always do. Someone edits the name in the CRM, someone else edits it in WordPress, and whichever writes last wins. Deciding which system is authoritative per field is the actual design work of an integration, and it is what stops the disagreement being resolved arbitrarily.

Credentials are a security boundary

An integration holds a key that can read or write data in another system. Where it is stored, who can see it, what it is permitted to do and how it is rotated are all part of the design — and a key with more permission than the integration needs is the most common finding when one is reviewed.

What we do about it

Capabilities

Each of these is work we carry out, not an area we advise on.

Which system owns which field

The authoritative source per piece of data, decided and written down. Without it, two systems overwrite each other and the result depends on timing — which is the reason integrations develop data that nobody can explain.

Authentication and credential handling

The appropriate authentication for the other system, with credentials stored outside the codebase, scoped to what the integration actually needs, and rotatable without a deployment. A key that can do more than the integration does is a finding, not a convenience.

Data mapping and transformation

How each field on one side corresponds to a field on the other, including the ones that do not correspond and need a decision — a status that exists in one system and not the other, a date format, a required field the source does not always have.

Failure handling as a first-class behaviour

What happens when the other system is unavailable, returns an error, is slow, or answers with something unexpected. Specified per case with the resulting behaviour — retry, queue, alert, or stop and report — rather than left to whatever the code happens to do.

Idempotency and duplicate prevention

Making every write safe to repeat, so a retried event or a re-run job does not create a second record. This is the single most common defect in an integration and it is designed for rather than discovered.

Retry, queue and backoff

Failed operations queued rather than lost, retried with increasing intervals, and abandoned only after a bounded number of attempts with the failure recorded. The alternative is an integration that drops work whenever the other end has a bad minute.

Reconciliation

A way to establish that the two systems agree, and to correct them where they do not. An integration without reconciliation has no way to answer the question a business actually asks, which is whether the data is right.

Observability

What ran, when, what it did and what failed — visible without reading a log file on the server. The point of an integration is that nobody has to watch it, and that only holds if it reports its own failures.

Webhooks in both directions

Receiving events from the other system and emitting them from WordPress, with signature verification, replay protection and a defined behaviour when an event arrives for a record that does not exist yet.

How we work

Engineering methodology

The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.

  1. Establish the authoritative source before writing any code

    Per field, and written down. It is the decision everything else depends on, and an integration built without it produces data that changes depending on which system was edited most recently.

  2. Specify the failure behaviour as part of the design

    Unavailable, error, timeout, malformed response, rejected data, duplicate event. Each has a defined result, and the specification is reviewed before implementation rather than inferred from it afterwards.

  3. Make every write idempotent

    Assume each operation will be attempted more than once, because it will. The design carries an identity for each logical operation so a repeat is recognised and absorbed rather than creating a second record.

  4. Store credentials where they can be rotated

    Outside the codebase and outside the database, scoped to the minimum the integration needs. Rotation without a deployment is the property that makes a leaked credential an inconvenience rather than an incident.

  5. Build reconciliation alongside the integration

    A means of comparing the two systems and correcting differences. It is what makes the integration verifiable, and it is what answers the question asked after any incident: how much is wrong and since when.

  6. Test against the other system's bad days

    Unavailability, slow responses, rate limits, malformed payloads and duplicated events, exercised deliberately. An integration tested only against a working counterpart has been tested for the case that was never the problem.

Deliverables

What an engagement produces

Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.

Design

  • The authoritative source per field, written down
  • Authentication method and where credentials live
  • Field mapping, including the fields with no counterpart and their decision
  • Failure behaviour specified per case
  • Idempotency approach for every write
  • What reconciliation compares, and how differences are corrected

Implementation

  • The integration, with credentials outside the codebase
  • Retry, queue and backoff for failed operations
  • Duplicate prevention on every write path
  • Webhook handling with signature verification and replay protection
  • Observability: what ran, what failed, and where that is visible

Verification and handover

  • Failure cases exercised deliberately, not assumed
  • Reconciliation run and any differences resolved
  • What to do when the other system is unavailable, and for how long it is tolerable
  • Where credentials are stored and how they are rotated
  • What the integration does not do, stated plainly
Under the hood

Architecture and technology

The parts an integration needs

  • An authoritative source per field
  • Authentication scoped to what is needed
  • A field mapping, including the fields with no counterpart
  • Idempotency on every write, so a repeat is absorbed
  • Retry with backoff, and a queue so work is not lost
  • Defined behaviour for each failure case
  • Reconciliation, so the two systems can be compared
  • Observability, so a failure is reported rather than found

How integrations fail

  • Silently, so a gap is discovered from a report weeks later
  • By duplicating records when an event is delivered twice
  • By losing operations when the other system is briefly unavailable
  • By overwriting data because neither system was declared authoritative
  • By holding a credential with far more permission than it needs
  • By working until a field is added on one side and not the other
  • By succeeding against a test system and failing against production's rate limits
Adjacent problems

If this is not quite your problem

These overlap at the edges. Sending you to the right page is more useful than having you work it out.

The connection needs custom code in WordPress

Plugin development, including where the data should live.

Custom WordPress plugin development

The site needs building around the integration

Themes, templates and the application structure.

WordPress development

The integration is commerce-related

Products, orders, stock and fulfilment in WooCommerce.

WooCommerce development

The bespoke code is not a plugin

Application-level engineering outside WordPress's extension points.

Web engineering
Questions

Frequently asked

Do you have an integration you can show?

No. Our published engagements are forum platforms and a small number of other systems, and none of them is an API integration a reader could inspect. What this page describes is the design, which is the part that determines whether an integration is trustworthy: who owns which field, what happens when the other end is unavailable, and how a repeated event is absorbed rather than duplicated. That is evaluable without a reference, and it is more specific than a logo would be.

What happens when the other system goes down?

It is specified per case rather than left to whatever the code does. An operation that fails is queued rather than lost and retried with increasing intervals, and only abandoned after a bounded number of attempts with the failure recorded. What that means for the business is also stated: how long a gap is tolerable, what is visible during it, and what has to be reconciled once the other system returns. That specification is reviewed before implementation, because it is the part that decides whether the integration can be relied on.

How do you stop records being duplicated?

By assuming every operation will be attempted more than once and designing for it — which is the correct assumption, because webhooks are retried, jobs re-run and a timeout is ambiguous about whether the write succeeded. Each logical operation carries an identity, so a repeat is recognised and absorbed instead of creating a second record. Duplicate records are the most common defect in an integration, and they are a design decision rather than a bug to be fixed after the first one appears.

Which system should be the source of truth?

It is decided per field rather than per system, and that is the actual design work. A CRM usually owns the customer's contact details; WordPress may own their content or their account; an ERP may own stock and pricing. Whichever is authoritative for a field is the one that writes it, and the other receives it. Without that decision the two systems overwrite each other and the result depends on timing — which is how integrations produce data that nobody can explain.

Can you fix an integration someone else built?

Usually, and the first step is establishing what it does rather than what it was meant to do. The failure behaviour is where the problems usually are: operations dropped when the other end was unavailable, writes that are not safe to repeat, no reconciliation, and failures that are only visible in a log nobody reads. Where the existing code is sound but incomplete, it is extended; where the design is missing, that is what gets added first, because a fix applied to an unspecified design tends to produce the same class of problem again.

Bring us the problem you have not been able to fix

Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.