Skip to content

Add TransactionValidator and shared SubunitConverter (R2.1) - #76

Merged
jules-paystack merged 2 commits into
masterfrom
feat/r2-1-transaction-validator
Sep 28, 2026
Merged

jules-paystack merged 2 commits into
masterfrom
feat/r2-1-transaction-validator

Conversation

@jules-paystack

Copy link
Copy Markdown
Collaborator

Summary

  • Adds Gateway/Validator/TransactionValidator.php: pure checks of a Paystack verify-transaction response against status, currency, a bounded amount window, and live/test domain — not wired into any of the three payment consumers yet.
  • Adds Gateway/SubunitConverter.php, a shared static helper repointing Controller/Payment/Setup.php's previously-inline subunit computation so the send side and this validator can never independently drift.
  • Adds PaystackApiClient::isTestMode() as the single source of truth for test_mode, so a future caller doesn't introduce a second independent config read.
  • Went through a full plan → 3-critic panel → implement → 2-critic diff review → fix loop → dedicated test pass cycle (docs/plans/2026-09-28-r2-1-transaction-validator.md, untracked per this repo's convention for unfixed money-path defect maps).
  • Before implementing the amount check, measured on dev-repro/ that the browser's popup amount and the server's post-placement order total agree exactly, on both a same-currency and a display≠base-currency guest checkout — the parent plan's explicit blocking prerequisite for this item.

Test plan

  • Test/Unit/vendor/bin/phpunit -c phpunit.xml --no-coverage — 162 tests, 225 assertions, all green
  • Independent Gate 3 test-runner pass found and closed 2 real coverage gaps beyond the implementer's own tests
  • Adversarial security-critic + architecture-critic review of both the plan and the final diff, with a documented fix loop (3 high-severity findings actioned: an in-flight-vs-failed status regression against the shipped D5 fix, a "did money move" ambiguity on the domain-mismatch code now resolved via chargeIsReal(), and a duplicated test_mode config read)
  • Runtime measurement on dev-repro/ (2.4.9, PHP 8.5, CSP on) confirming the amount comparand is correct before it was implemented

🤖 Generated with Claude Code

jules-paystack and others added 2 commits September 28, 2026 11:11
Introduces the accept-side verification gate's first building block: a
pure TransactionValidator checking a Paystack verify response against
status, currency, bounded amount window, and live/test domain, plus a
SubunitConverter shared between the send side (Setup.php) and this
validator so the two can never independently drift. Not wired into any
consumer yet.

Verified on dev-repro that the browser's popup amount and the server's
post-placement order total agree exactly, on both a same-currency and a
display-currency-!=-base-currency guest checkout, before implementing
the amount comparand.
Model/Payment/Paystack.php extends DataObject implementing
MethodInterface directly, not AbstractMethod — caught during the
R2.2/R2.3 review panel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jules-paystack
jules-paystack merged commit 094ea83 into master Sep 28, 2026
5 checks passed
@jules-paystack
jules-paystack deleted the feat/r2-1-transaction-validator branch September 28, 2026 11:01
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