Skip to content

feat(payments): add the inbound webhook http endpoint - #230

Merged
tiana-code merged 1 commit into
mainfrom
feat/E-02-payments-webhook-endpoint
Jun 18, 2026
Merged

feat(payments): add the inbound webhook http endpoint#230
tiana-code merged 1 commit into
mainfrom
feat/E-02-payments-webhook-endpoint

Conversation

@tiana-code

Copy link
Copy Markdown
Owner

What

Completes the #214/#216 split: the HTTP endpoint for the inbound payment webhook over the existing PaymentWebhookHandler.

  • PaymentWebhookController (POST /v1/payments/webhooks, thin): @RequestBody String rawBody (the exact bytes, so HMAC verifies against what the provider signed) + @RequestHeader X-Webhook-Signature -> parse to WebhookRequest (manual ObjectMapper, wrapped so a parse failure becomes a scoped MalformedWebhookException) -> handler.handle(rawBody, signature, notification) -> 200 for any WebhookResult.
  • Error mapping: WebhookSignatureException -> 401 (INVALID_SIGNATURE), MalformedWebhookException -> 400, missing signature header -> 400. The handler is scoped (controller-level try/catch), so the global advice does not register a broad JsonProcessingException handler that could mask server-side 500s (critic fix).
  • No SecurityConfig change: /v1/payments/webhooks is already permitAll (F-02.9 Payments REST API + OpenAPI #216); HMAC is the gate, and the handler verifies the signature before any side effect.
  • @WebMvcTest: valid (no token) -> 200 with the parsed notification asserted, bad signature -> 401, malformed body -> 400 (handler not called), missing header -> 400.

Gates

Local (-x integrationTest): :services:payments:{test,detekt,detektTest,spotlessCheck,assemble,compileIntegrationTestKotlin} green. critic GO (scoped exception applied), security-auditor PASS (HMAC-gated fail-closed before side effect, raw-body exact, §5.3 clean, 5/5 ACs), evaluator 0.91. No security-config change -> no csrf alert expected.

Closes #228

Expose the inbound payment webhook over HTTP: a thin controller reads the raw
request body (so the HMAC is verified over the exact bytes), parses it, and
delegates to the existing webhook handler, returning 200 for any handled
outcome. An invalid signature maps to 401 and a malformed body to 400 through a
scoped exception, leaving the global advice free of a broad json handler. The
path is already permitted in the security config; the signature is the gate.

Closes #228
@tiana-code tiana-code added this to the v0.2.0 milestone Jun 18, 2026
@tiana-code
tiana-code merged commit 51cb03e into main Jun 18, 2026
8 checks passed
@tiana-code
tiana-code deleted the feat/E-02-payments-webhook-endpoint branch June 18, 2026 16:49
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.

F-02.9b Payments webhook HTTP endpoint

1 participant