Background
Merchants need to generate API keys to authenticate server-to-server integrations. Keys must be shown only once at generation time and stored only as a hash.
Proposed Steps
- Create
POST /merchants/api-keys (protected) — generate a key in format sk_live_<32-char-random>, store prefix and sha256(key) hash, return the raw key once only
- Create
GET /merchants/api-keys (protected) — list all non-revoked keys with prefix, label, lastUsedAt, createdAt
- Create
DELETE /merchants/api-keys/:id (protected) — revoke a key by setting revokedAt = now
- Create an
apiKeyAuth middleware that hashes the incoming bearer token, looks it up in ApiKey, updates lastUsedAt, and attaches the merchant to req.merchant
- Support both JWT and API key authentication transparently in
auth.middleware.ts
Acceptance Criteria
POST /merchants/api-keys returns { key, prefix, id, label, createdAt } — raw key only in this response
- Raw key is not stored in DB; only the SHA-256 hash is persisted
GET /merchants/api-keys returns list without exposing hashes or raw keys
DELETE /merchants/api-keys/:id marks key as revoked; subsequent auth attempts return 401
- A merchant can only see and revoke their own keys
- API key auth middleware works alongside JWT middleware
lastUsedAt is updated on each successful API key authentication
- Maximum of 10 active API keys per merchant (return
400 if limit exceeded)
Background
Merchants need to generate API keys to authenticate server-to-server integrations. Keys must be shown only once at generation time and stored only as a hash.
Proposed Steps
POST /merchants/api-keys(protected) — generate a key in formatsk_live_<32-char-random>, storeprefixandsha256(key)hash, return the raw key once onlyGET /merchants/api-keys(protected) — list all non-revoked keys withprefix,label,lastUsedAt,createdAtDELETE /merchants/api-keys/:id(protected) — revoke a key by settingrevokedAt = nowapiKeyAuthmiddleware that hashes the incoming bearer token, looks it up inApiKey, updateslastUsedAt, and attaches the merchant toreq.merchantauth.middleware.tsAcceptance Criteria
POST /merchants/api-keysreturns{ key, prefix, id, label, createdAt }— raw key only in this responseGET /merchants/api-keysreturns list without exposing hashes or raw keysDELETE /merchants/api-keys/:idmarks key as revoked; subsequent auth attempts return401lastUsedAtis updated on each successful API key authentication400if limit exceeded)