Appearance
Handoff: SVC-019-sepay-legacy-response-parity payment-service SePay legacy response parity
Scope
- Service/area:
payment-service - Task pack:
docs/agents/service-tasks/payment-service.md - Goal: accept the bounded
SVC-019slice that normalizes legacy SePay webhook payloads and preserves legacy response envelopes before any gateway route-table rehearsal. - Non-goals: public/default route promotion, browser proof, gateway route changes, billing subscription activation, wallet balance/ledger crediting, provider secret management, live SePay calls, Postgres data migration, or changes to legacy source under
/Users/velikho/Desktop/WORKING/HOCTAPAZ/.
Docs Read
go-platform/docs/agents/service-agent-execution-queue.jsongo-platform/docs/agents/service-agent-closeout-ledger.jsongo-platform/docs/agents/service-tasks/payment-service.mdgo-platform/docs/agents/service-tasks/billing-service.mdgo-platform/docs/agents/service-tasks/wallet-service.mdgo-platform/docs/agents/service-tasks/monetization-broker-transport.mdgo-platform/docs/agents/agent-handoff-format.mdgo-platform/docs/api/payment-service.mdgo-platform/services/payment-service/README.mdgo-platform/services/payment-service/api/openapi.yamlgo-platform/contracts/openapi/services/payment-service.yaml
Legacy Evidence Read
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet.controller.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet.utils.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet.service.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/az-credit.service.ts- Legacy source was read-only evidence only; no legacy files were changed.
Files Changed
go-platform/services/payment-service/internal/http/server.gogo-platform/services/payment-service/internal/http/legacy_sepay.gogo-platform/services/payment-service/internal/http/server_test.gogo-platform/services/payment-service/api/openapi.yamlgo-platform/contracts/openapi/services/payment-service.yamlgo-platform/services/payment-service/README.mdgo-platform/docs/api/payment-service.mdgo-platform/docs/agents/service-tasks/payment-service.mdgo-platform/docs/agents/handoffs/SVC-019-sepay-legacy-response-parity.mdgo-platform/docs/agents/service-agent-closeout-ledger.jsongo-platform/docs/agents/service-agent-closeout-ledger.md
Behavior Implemented
- Added service-local rehearsal routes
POST /v1/legacy/hooks/sepay-paymentandPOST /v1/legacy/wallet/webhooks/sepay. - Reused the existing SePay provider-auth verifier before accepting legacy payloads.
- Added a legacy SePay adapter that accepts flat bank-transfer payloads and nested payment-gateway payloads from the old wallet controller flow.
- Extracted HocTapAZ payment codes from legacy content while preserving provider reference codes separately, so bank references do not replace native payment-order references.
- Routed normalized payloads through the existing native
RecordProviderWebhookusecase for idempotency, replay, unmatched evidence, paid events, and amount-mismatch review. - Preserved the legacy success envelope split: wallet, unmatched, review, and replay outcomes return
{ success: true }without native internals; subscription payment-order matches return{ success: true, data: ... }. - Documented that billing-service still owns subscription activation and wallet-service still owns wallet credits/ledger mutation.
Tests And Verification
- Command:
GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/internal/http -run 'TestLegacySePay|TestPaymentWebhookReplayDoesNotDuplicateTransaction|TestPaymentWebhookAmountMismatchRequiresReview|TestPaymentWebhookUnknownReferenceIsRecordedUnmatched' -count=1 -v - Result: passed.
- Evidence: focused HTTP tests covered flat wallet payload parsing, nested gateway subscription payload parsing, legacy envelopes, replay idempotency, unmatched acknowledgment, amount-mismatch review, and provider-auth enforcement.
- Command:
GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/... -count=1 - Result: passed.
- Evidence: payment-service command, auditsink, eventfanout, HTTP, repository, and usecase packages passed.
- Command:
make test-monetization-event-chain test-monetization-routes test-monetization-broker-transport - Result: passed.
- Evidence: payment/billing/wallet/usage event-chain tests, monetization route guards, wallet admin-review self-test, broker transport coverage, broker live-smoke self-test, eventfanout package tests, and monetization outbox tool tests passed.
- Command:
ruby -e 'require "yaml"; ARGV.each { |path| YAML.load_file(path); puts "ok #{path}" }' services/payment-service/api/openapi.yaml contracts/openapi/services/payment-service.yaml - Result: passed.
- Evidence: both payment OpenAPI files parsed successfully.
- Command:
cmp -s services/payment-service/api/openapi.yaml contracts/openapi/services/payment-service.yaml - Result: passed.
- Evidence: service OpenAPI and contract mirror are byte-identical.
- Command:
PAYMENT_SERVICE_POSTGRES_TEST_DATABASE_URL=postgres://... GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/internal/repository -run TestPostgresPaymentWebhookReplayIntegration -count=1 -v - Result: not run.
- Evidence: optional Postgres integration requires an external DSN that was not provided in this local handoff run.
Route State
- Legacy route: public
/api/hooks/sepay-paymentand/api/wallet/webhooks/sepayremain legacy-proxied by default. - Native route:
/v1/provider-webhooks/sepayremains the native webhook endpoint;/v1/legacy/hooks/sepay-paymentand/v1/legacy/wallet/webhooks/sepayare service-local rehearsal endpoints. - Gateway state: no default gateway route table was changed and no public hook route was promoted.
- Rollback: keep
deploy/gateway/routes.jsonon the legacy public hook routes. If the rehearsal adapter regresses, revert the service-local/v1/legacy/*handlers/tests/docs without changing public route state.
Data Notes
- Tables touched: none in this handoff run; tests used in-memory stores and package-level repository tests without a live Postgres URL.
- Migration run: none.
- Validation report: not applicable because no live data was migrated or backfilled.
Risks / Blockers
SVC-016now has accepted bounded renewal/subscription evidence, but billing remainsnot-complete; this handoff only returns a compatibility subscription data object and emits payment events.- Wallet balance and AZ Credit ledger mutation remain wallet-service ownership and are not implemented here.
- Public hook promotion still needs gateway route-table rehearsal, live/runtime provider proof, browser or caller proof, rollback evidence, and downstream billing/wallet replay proof.
- The adapter keeps existing payment-service SePay auth behavior; legacy-only direct secret-header variants remain outside this bounded response-parity slice.
- Optional Postgres replay integration was not run without a DSN.
Next Step
- Add a non-default gateway route-table rehearsal for the two SePay hook routes after billing/wallet downstream subscriber proof exists, then attach live request/response and rollback artifacts before considering public route promotion.