Services

Backends, APIs and integrations

The part of a system nobody sees and everybody depends on: the API a client talks to, the webhook a payment provider calls, the integration with the tool your business already runs on. Designed on the assumption that the network is hostile and the client is wrong.

Ty Johnston
Ty Johnston Scopes it, builds it, runs it. Fopull LLC, Knoxville, TN.
Stack
REST, OAuth 2.0, PKCE, Stripe, Webhooks, Sanctum, JWT/JWKS, PostgreSQL
Terms
Scope call, paid discovery, written plan, fixed-bid milestones

How Fopull approaches it

An API that works in a demo and an API that works at 3am are different things. The difference is idempotency, so a retried request does not double-charge; ordering, so an event that arrives late does not undo a newer one; and failure modes that fail in the safe direction, which is not always closed.

Integrations are where the assumptions of two systems meet, and every one of them has to be checked against what the other side actually sends rather than what its documentation says. Payment providers move fields between API versions. Identity providers omit fields on some payloads. A field that is absent and a field that is false are different facts, and treating them the same way is how a real payment quietly stops being credited.

Fopull builds the API, the webhook handlers, the client SDK if there is one, and the tests that replay real payloads against them. Existing brittle APIs get a written assessment first: what is dangerous, what is fine, what to rewrite and what to leave alone.

Worked example: the Stripe webhook that shares a URL with real money

fopull.com takes payments for two different products through one Stripe webhook endpoint: one-off purchases of an in-game currency, and monthly subscriptions for Floptle Cloud. Both are live, and the subscription side had to be testable in Stripe's sandbox on the same server without touching the purchases. The webhook accepts 2 signing secrets for that reason, one per Stripe mode, and a test-mode event can never modify a row a live subscription wrote.

Three decisions came out of that. Every event id is claimed in a unique-indexed table before anything is applied, so a replayed event is a no-op rather than a second credit. An update generated before a deletion cannot resurrect a dead subscription, because Stripe promises no ordering and the two are compared on the item's period start rather than on arrival. And a payload whose live-mode flag is absent is not judged at all: on the first version, absent read as test and a live server silently refused to credit real money.

The subscription code also reads two spellings of the same field, newest first, because which one arrives depends on the API version pinned on the endpoint in a dashboard nobody on the code side controls. That is the kind of fact an integration has to carry.

More of this, dated and with the numbers, in the engineering log.

Questions people ask

Can you integrate with a system you have not seen before?
Yes. Every integration starts by reading what the other side actually sends, with real payloads, and building the tests from those rather than from the documentation.
Do you build mobile or game client authentication?
Yes. OAuth 2.0 with PKCE is the default for any client that cannot keep a secret, which is every mobile and desktop client. See the game backends page for the worked example.
What happens when a third party changes their API?
The tests that replay their payloads fail, which is the point. Under a retainer, Fopull fixes it; otherwise the runbook says where to look.

How an engagement goes

  1. A scope call

    Thirty minutes on the problem and the constraints.

  2. A written plan

    Short paid discovery, then a document you can take anywhere.

  3. Built in milestones

    Fixed-bid where the scope is clear, hourly where it cannot be.

  4. Handed over with a runbook

    Or run for you under a retainer.