Add audit trail tracking fields (created_by, last_modified_by) to customers and payment_methods tables
Description
Add audit-trail fields to track who creates and modifies customer and payment method records. This is required for compliance, platform-model correctness, and security investigations, especially in scenarios involving platform merchants and connected merchants.
Problem
In the current platform setup:
- A platform merchant owns the overall payment setup.
- Connected merchants process payments under the platform.
- A payment may be triggered by:
- The platform’s API key acting on behalf of a connected merchant,
- A connected merchant’s API key,
- A dashboard user authenticated via JWT.
However:
- Customers are created automatically during a payment when they do not already exist.
- All customers always belong to the platform merchant, not the connected merchant.
- Customers are shared across connected merchants under the same platform.
- Payment methods belong to customers, and therefore also belong to the platform merchant.
This introduces a visibility gap:
Even though the platform merchant is always the owner of these records, the system does not currently track:
- Which merchant or user triggered customer creation,
- Who triggered payment method creation,
- Who performed updates to these entities.
This gap makes it difficult to:
- Meet compliance and audit requirements,
- Investigate unauthorized or unexpected changes,
- Distinguish platform-initiated operations from connected-merchant-initiated operations,
- Track user vs API-key usage patterns.
created_by and last_modified_by fields already exist for payment intents and payment attempts. Customers and payment methods need the same auditability.
Proposed Solution
Add two audit fields to both customers and payment_methods tables:
created_by(VARCHAR(255)): indicates who initiated creationlast_modified_by(VARCHAR(255)): indicates who last modified the record
Implementation Details
- Storage format: String serialization of the
CreatedByenum
Example values:Api:merchant_xxxJwt:user_xxx
- Domain representation:
Option<CreatedBy>with variants:Api { merchant_id: String }Jwt { user_id: String }
- On creation,
last_modified_byis conceptually equal tocreated_by. - Conversion logic between storage and domain representations will be added.
Affected Components
- Database migrations for both tables
- Diesel schema (v1 and v2)
- Domain model updates
- Router core code paths for:
- Customer creation (implicit during payments)
- Payment method creation
- Customer updates
- Payment method updates
- Test helpers where applicable
Follow-up Work Required
These fields will be added but not populated in this PR.
All values will initially be stored as None.
Follow-up tasks:
- Integrate authentication context extraction to populate
created_by - Populate
last_modified_byon all update flows - Add
last_modified_byto:- Specific
CustomerUpdateflows (connector customer updates, default payment method updates) - Specific
PaymentMethodUpdateflows
- Specific
- Add integration tests validating correct audit trail behavior across platform and connected merchant flows
Related
Part of the broader effort to improve audit capabilities and align customer and payment method behavior with existing tracking in payment intents and attempts, especially within platform merchant environments where customers and payment methods are shared across multiple connected merchants.