Design Installment-Loan Payment Processing

Read the full interview experience this question came from →

Quick Overview

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.

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?

Overview: 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.

Read the full Affirm Software Engineer interview experience this question came from

|Home/System Design/Affirm
Affirm logo
Affirm
Apr 19, 2026
mediumSoftware EngineerTechnical ScreenSystem Design
19
0

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 Guidance

  • 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 Guidance

  • 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 Guidance

  • 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?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...