Real-world systems I built and ran in production, rebuilt here so the approach can be
read. Same problems, same tools, same decisions — the business they served is the one
thing that could not come with them.
A dashboard and the test suite it dispatches are one system; the payment sandbox
stands alone. Both are drawn below.
SYSTEM ONE
Dashboard and test suite
Two repositories with no shared code, meeting at three points. One run, end to end.
Blue marks a crossing that has to prove who it is, and each proves it differently because
each is trusted differently. Nothing but the backend writes, and nothing reaches the
storage directly — a person asks through the page, a machine asks with a key, the workflow
reports back signed, and the finished report is served through the backend because the
storage is never public.
Standalone. Your backend talks to it exactly as it would to the real provider, the
callback comes back to your backend, and you drive what that callback says from the side.
The backend is unchanged, and the callback returns to the URL it registered on the way in —
a closed loop a test can assert on. What the sandbox adds is the second door, where a test
decides what comes back, including the cases a real staging environment will not produce on
demand.
One deliberate limit: 2C2P wraps production payloads in JWT/JWE and this sandbox speaks
plain JSON, so an integration points at it with encryption disabled. What it replaces is
the state machine, not the signing.
Self-service test running: pick a slice, press Run, and get a link to the report —
without waiting for someone else or digging through CI artifacts.
The interesting part is not the Run button, it is who may run what and who may then see
the result. Four roles get four different dashboards, and demo can never
trigger a real run, which is what makes its password safe to publish.
The same API suite built twice against one contract, so two ways of structuring a suite
can be read side by side and compared on evidence rather than preference. Both are
verified by breaking the thing under test and checking that both fail identically.
The finding worth taking away: removing the status-code check from the shared assertion
helper left every test passing in both packages. That is a property of centralising
assertions, not of either style.
This is the suite the dashboard dispatches. It covers the API today; UI tests are the
intended next layer and are not written yet. The dashboard asks for a slice by name
rather than knowing what is in it, so they arrive without a change on either side.
03Paygate SandboxLIVE
A sandbox that emulates the 2C2P and Omise payment APIs, so an integration can be tested
against responses a real staging environment will not produce on demand.
Settle a transaction, decline it with a specific issuer code, make an inquiry time out,
or deliver the same webhook twice out of order. A built-in callback inspector captures
what the webhook would have received. Unofficial, and not affiliated with either provider.
Each repository carries a provenance.md stating exactly what came across from the
production system and what did not, and how AI was used in the rebuild. Depth without
explanation invites the wrong question, so the explanation is written down.