Skip to content

Query the Simplex reporting API - #243

Open
j0ntz wants to merge 2 commits into
deployfrom
jon/simplex-reporting-api
Open

j0ntz wants to merge 2 commits into
deployfrom
jon/simplex-reporting-api

Conversation

@j0ntz

@j0ntz j0ntz commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Moves the Simplex plugin to GET /reporting/v1/payments with Authorization: ApiKey <key>. It walks forward in 30-day windows and follows the cursor inside each one.

This has never run against real Simplex data. That needs a server-side reporting key, which does not exist yet and which an agent must not source or set. The schema comes from the published API reference and the sample response Simplex sent us in Slack on 2024-10-14.

Tested

Check Result
Unit tests test/simplex.test.ts is new: mapping, host and auth, cursor paging, 30-day windows, progress, retries, quarantine, malformed pages, refunds. Full mocha suite passes.
verify-repo.sh, tsc Pass
Sandbox, dummy key, through the plugin 401 Invalid API key; error reported, progress held
Loopback HTTP server replaying the Slack sample over two cursor pages, real retryFetch 2 transactions, correct mapping, Authorization: ApiKey header sent
Production host, dummy key, from a dev Mac Cloudflare 403 before any route; error reported, progress held
QA case C2 retest: null, missing and blank order id plus one normal payment, two runs through runPlugin, loopback server, throwaway CouchDB Four documents after each run, unchanged revisions on the second, three keyed by payment_id, success status, progress moved
QA case C4 retest: HTML 200, connection cut mid-body, dropped before a response, never responds, then a good run, same setup The four bad runs each return an error status with no unhandled rejection (the two silent ones after 60 s), nothing stored, progress held; the good run stores two documents and moves progress

No live request has confirmed the production host. It comes from the Simplex message.

Behavior changes to check

  • A refunded payment is now recorded. A refund inside the 5-day lookback replaces the complete document for that order, which removes it from cacheEngine volume.
  • lastTimestamp only moves when a window completes, because pages run newest first inside a window. The old plugin could rewind to 0 on an empty run; replacing the query loop fixes that here rather than in a separate commit.
  • A row the plugin cannot process is quarantined and reported through PluginResult.error, as in ChangeNow and Houdini. A failed request or malformed page holds progress.
  • An unknown payment_method logs a warning and stores a null payment type.
  • A blank order_id falls back to payment_id. A payment with neither is quarantined, because a blank id would fail the whole CouchDB insert and stop every newer payment.
  • Each Simplex request has a 60 second timeout that covers the body as well as the response. Without it, a connection cut mid-body never settles, and the query loop waits until the 20 hour app timeout.
  • retryFetch now rethrows errors with no code. It used to read err.code unguarded, and a node-fetch timeout surfaced as a TypeError instead of its real message. Every plugin that calls retryFetch gets this.

Unverified assumption

orderId is references.order_id when present and not blank, else payment_id, on the assumption that order_id matches the id on older documents. The sample's value is the placeholder "string". If it does not match, reprocessed payments get new documents instead of updating the old ones. The first real run has to confirm this.

Deploy (human/ops only)

  1. Get a server-side reporting key from Simplex partner support and give them the reports-server egress IP for their allowlist.
  2. Set it as apiKeys.apiKey under partnerIds.simplex in the production reports_apps document, replacing the old value.
  3. Run npm run build.lib, then restart reportsQuery and reportsCache with pm2.
  4. Check the first run for skipping unprocessable payment errors.

With the old key the new plugin reports a 401 on each run and holds its progress. No data is lost.

Known issue, left as is

fetchWithBackoff puts the full response body in its error. A Cloudflare block therefore writes a long HTML page, including the egress IP, into logs and status text. The helper moved here unchanged from Banxa, and trimming it belongs in its own change.

An order id containing a colon would fail the insert, because queryEngine.ts takes the id from docId.split(':')[1]. Nothing suggests Simplex sends one, and the sample and reference show none. It predates this change.

docs/blocked-partner-reporting.md carries the evidence for the host, route and auth scheme.

Asana task

Test evidence

b5f1ee8
Query the Simplex reporting API
2026-11-01

1. C2 retest

2. C4 retest

j0ntz added 2 commits November 1, 2026 01:22
Banxa's retry helper is about to be shared with the Simplex plugin. Banxa
keeps injecting its snooze, so behavior is unchanged.
Simplex replaced its reporting API, so the plugin now reads
/reporting/v1/payments with Authorization: ApiKey, walking forward in
30-day windows with a cursor inside each one. The schema comes from the
published API reference and the sample response Simplex sent us. It has
not run against real data, because that needs a server-side key.

Progress only moves when a window completes, because results come newest
first inside a window. This also stops the old rewind to timestamp 0 on
a run with no transactions.

A payment that cannot be processed is quarantined and reported, matching
ChangeNow and Houdini. A failed request or malformed page holds progress.

Refunded payments are now recorded. A refund inside the lookback replaces
the complete document for that order.
@j0ntz
j0ntz force-pushed the jon/simplex-reporting-api branch from b7b434b to b5f1ee8 Compare November 1, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant