This document satisfies the Checkout.com offline assessment request to capture key design considerations and assumptions.

API surface

  • POST /api/payments — merchants submit card data to process a payment.
  • GET /api/payments/:id — merchants retrieve a previously stored payment by UUID.

Paths follow the public payment-gateway-challenge-go template convention (/api/payments).

Status model

Status When
Rejected Validation failed before calling the bank (HTTP 400). No database row is created.
Authorized Bank returned HTTP 200 with "authorized": true. Row persisted (HTTP 201).
Declined Bank returned HTTP 200 with "authorized": false. Row persisted (HTTP 201).

If the simulator returns 503 (PAN ending in 0), the gateway returns 503 to the merchant and does not persist a payment (no definitive auth outcome).

PCI / data minimisation

  • Full PAN and CVV exist only in memory for the lifetime of a single request.
  • PostgreSQL stores last four digits and original PAN length so we can render a mask like ************8877 without storing the full number.
  • We never log raw card numbers or CVVs.

Card expiry validation

The brief requires the expiry month/year combination to remain valid. We treat a card as valid through the end of the printed expiry month (common card-network interpretation), implemented with time.Date(y, m+1, 0, …) in UTC.

Currencies

The assessment allows at most three ISO 4217 codes. Default: USD, GBP, EUR, overridable via ALLOWED_CURRENCIES (comma-separated).

Bank simulator contract

Mountebank expects:

  • card_number, expiry_date as MM/YYYY, currency, amount, cvv
  • Odd last digit → authorised; even → declined; 0 → HTTP 503

The gateway maps merchant JSON (expiry_month + expiry_year) into expiry_date.

Swagger / OpenAPI

  • Uses swag (github.com/swaggo/swag) annotations on cmd/server/main.go and handlers, same pattern as Checkout’s official payment-gateway-challenge-go template.
  • echo-swagger serves UI at /swagger/*.
  • Regenerate after annotation changes: make swagger (requires swag CLI).

Technology choices

  • Echo — lightweight HTTP router as requested.
  • PostgreSQL + GORM — durable storage (the original brief allows an in-memory test double; we use Postgres as requested).
  • Automated tests — validation unit tests + handler test with httptest bank stub (no Docker required for go test).

Out of scope (deliberately)

  • Merchant authentication / API keys
  • Idempotency keys & double-submit protection
  • Rate limiting, circuit breaking beyond basic HTTP client timeout
  • 3DS / SCA flows