Design Installment-Loan Payment Processing
Company: Affirm
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Technical Screen
# Design Installment-Loan Payment Processing
Design a payment-processing system for an existing user's active installment loan. A payment may be initiated manually through an app or website, or automatically by a schedule. The system debits the user's bank through a synchronous API that is available during only one fixed one-hour window each day. After each attempt, notify the user of success or failure by SMS or email.
Cover APIs, state, scheduling, bank interaction, retries, accounting, and notifications.
### Constraints & Assumptions
- User and loan services already exist and may be represented by stubbed APIs.
- The bank debit API gives a synchronous result while its daily window is open and is unavailable outside it.
- Clients, schedulers, workers, and notification providers may retry requests.
- A payment must never be debited twice because of a retry.
- Payment state and the loan's applied repayment must remain reconcilable.
### Clarifying Questions to Ask
- Is a bank timeout known to mean failure, or can its outcome be unknown?
- Does the bank accept an idempotency key or expose a transaction-status lookup?
- Which timezone and holiday calendar define the one-hour window?
- May users cancel or edit a queued payment before the window opens?
- Are partial, early, late, or overpayments allowed?
- Which result should be communicated when an attempt is still pending reconciliation?
### What a Strong Answer Covers
- Payment intent, attempt, schedule, ledger/application, notification, and idempotency records.
- One ingestion path for manual and scheduled requests with authorization and amount validation.
- Durable queuing for the next bank window, bounded concurrency, and backpressure.
- Exactly-once business effect built from idempotent commands and state transitions, not exactly-once delivery claims.
- Unknown-result reconciliation and protection against retrying a possibly successful debit.
- Transactional loan application plus an outbox for reliable user notification.
### Follow-up Questions
- What happens when the bank times out one second before the daily window closes?
- How do you prevent the scheduler and a user retry from creating two payments?
- How would you catch up after workers are down for the whole bank window?
- Which metrics and reconciliation reports would operations need?
Quick Answer: Design installment-loan payment processing around a bank debit API available during one daily one-hour window. Unify manual and scheduled intents, prevent duplicate debits with durable idempotency and state transitions, reconcile unknown outcomes, apply accounting atomically, and notify through an outbox.