Files
mercadodevida/work/artifacts/F-023/implementer.md
2026-08-17 22:23:10 +02:00

1.7 KiB

Implementer — F-023 Payments: provider interface + Stripe + webhooks

Summary

Implemented payments module with PaymentProvider interface, Stripe-style webhook signature verification, idempotent event recording via (provider, provider_event_id) unique constraint, and order state transitions on PaymentSucceeded/PaymentFailed. Domain code never imports the Stripe SDK; the adapter handles all signing.

Files changed

  • project/migrations/017_payments.js
  • project/src/modules/payments/**
  • project/src/app/build-app.ts

Acceptance evidence

  • AC1 zero Stripe imports: payments/tests/boundary.test.ts scans domain/application/api files for stripe references in code; only the adapter mentions Stripe.
  • AC2 bad signature -> 400: stripe-payment-provider.test.ts covers invalid signature, missing signature, expired timestamp and unsupported event type; the API maps InvalidWebhookSignatureError to 400.
  • AC3 webhook processed exactly once: payments-service.test.ts proves first event returns processed and replayed event returns duplicate with a single recorded transaction.
  • AC4 PaymentSucceeded -> order PAID: PaymentsService.handleWebhook calls ordersAdapter.transition to PAID.
  • AC5 frontend not trusted: webhook endpoint is unauthenticated and signature-validated; no client status fields are accepted.

Commands run

  • cd project && npm run lint/typecheck/build/test passed
  • cd project && TEST_DATABASE_URL='postgres://mdv:mdv_dev_only@localhost:5432/mdv_test' npm run test:integration -- migrations.itest passed; 14 files, 53 tests
  • ./scripts/verify.sh passed

Notes

  • No new runtime dependency: webhook signature is HMAC-SHA256 implemented in pure Node crypto.
  • Provider is a stub for createIntent; F-022 already uses the stub.