Field 13: Scheduled Monthly Payment Amount
This field represents the regular payment amount due.
Calculation:
IF snapshot.loan_status IN ('ChargedOff', 'PaidOff'):
scheduled_payment = 0
ELIF lender_supplied_account_status = '97': # ChargedOff
scheduled_payment = 0
ELSE:
# Get current period obligation
obligation = find_obligation_in_period(month_start, month_end)
IF obligation:
scheduled_payment = obligation.obligation_amount
ELSE:
scheduled_payment = 0
RETURN round_to_whole_dollars(scheduled_payment)Field 22: Amount Past Due
This field reports the total amount that is past due on the account.
Calculation:
FUNCTION calculate_amount_past_due(loan, snapshot, lender_supplied_status):
# Priority 1: Paid-in-full statuses always report zero
IF lender_supplied_status IN ('61', '62', '63'): # Paid in full statuses
RETURN 0
# Priority 2: Voluntary Surrender when account is current
IF lender_supplied_status = '95' AND account_is_current:
RETURN 0
# Priority 3: Based on loan status
IF snapshot.loan_status IN ('Active', 'Frozen'):
amount_past_due = snapshot.overdue_over_30_days_balance_total_amount
ELIF snapshot.loan_status IN ('Accelerated', 'ChargedOff'):
amount_past_due = snapshot.outstanding_balance_total_amount
ELIF snapshot.loan_status IN ('Pending', 'Originated', 'Declined', 'PaidOff', 'Canceled'):
amount_past_due = 0
ELSE:
RAISE ERROR "Unknown loan status"
RETURN round_to_whole_dollars(max(amount_past_due, 0))Logic Explanation:
| Loan Status | Amount Past Due Source | Rationale |
|---|---|---|
| Active, Frozen | overdue_over_30_days_balance_total_amount | Only amounts 30+ days past due are reported |
| Accelerated, ChargedOff | outstanding_balance_total_amount | Entire balance is considered past due |
| PaidOff, Canceled, Pending, Originated, Declined | 0 | No amount past due |
Override Conditions:
| Condition | Result | CRRG Requirement |
|---|---|---|
| Status 61, 62, 63 (Paid in Full) | Always 0 | "Requires Current Balance and Amount Past Due = zero" |
| Status 95 (Voluntary Surrender) + Account Current | 0 | Account surrendered before becoming delinquent |
Field 21: Current Balance
Data Source: snapshot.outstanding_balance_total_amount
Components:
- Principal balance
- Accrued interest
- Outstanding fees
Special Rules:
- For status codes 13, 61, 62, 63: Always report $0
- Negative balances: Report as $0
- Round according to loan type configuration
The Actual Payment Amount field (Field 17) requires understanding which transactions count as "payments" for credit reporting purposes.
| Transaction Type | Description |
|---|---|
| Payment | Consumer payment (AutoPay, OneTimePayment, Settlement) |
| ServiceCredit | Lender-applied credit adjustment |
| Credit Type | Reports as Payment? | Description |
|---|---|---|
serviceAgent | [YES] | Agent-applied credit |
serviceSupervisor | [YES] | Supervisor-approved credit |
balanceTransfer | [YES] | Balance transferred from another account |
usuryCap | [YES] | Usury cap adjustment |
settlementOfDebt | [NO] | Settlement credit (considered a loss) |
fraud | [NO] | Fraud adjustment credit (considered a loss) |
badDebt | [NO] | Bad debt write-off credit (considered a loss) |
deceased | [NO] | Deceased borrower adjustment (considered a loss) |
bankruptcy | [NO] | Bankruptcy adjustment (special Account Status handling) |
refund | [NO] | Refund (always excluded) |
interestAdjustment | [NO] | Interest adjustment (always excluded) |
rewards | [YES] | Rewards credit (e.g., cashback applied to balance) |
rounding | [NO] | Rounding adjustment (always excluded) |
rewards | [YES] | Rewards credit (e.g., cashback applied to balance) |
Important: Service credits with types
settlementOfDebt,settlementOfDebtNoLoss,fraud,badDebt,deceased, andbankruptcyare NOT considered "real" payments for Actual Payment Amount or Date of Last Payment calculations.Of those, only
settlementOfDebt,fraud,badDebt, anddeceasedare also treated as "loss" transactions for Account Status determination — their presence prevents a charged-off loan from reporting as status 64 (Paid in Full).settlementOfDebtNoLossis explicitly excluded from the loss check — it is the variant for settlement scenarios where the lender does not want a loss recorded, allowing a 64 outcome.
bankruptcyis also excluded from the loss check because it is the mechanism for zeroing a balance after a bankruptcy discharge and does not by itself force a 97 status. See Account Status Codes for the full algorithm.The
bankruptcyservice credit type should only be used when a bankruptcy case has been discharged and the lender needs to zero the loan balance.
FUNCTION calculate_actual_payment_amount(loan, month_start, month_end):
total_payment = 0
# Query payments in the reporting period
transactions = query_transactions(
loan_id = loan.id,
is_virtual = False,
status IN ('Initiated', 'Pending', 'Succeeded'),
display_date BETWEEN month_start AND month_end
)
# Also include transactions that failed AFTER the report cutoff
# (they were valid at the time of reporting)
transactions += query_transactions(
loan_id = loan.id,
status = 'Failed',
failed_at > file_creation_max_datetime,
initiated_or_pending_at BETWEEN file_creation_min_datetime AND file_creation_max_datetime
)
FOR EACH tx IN transactions:
# Payment transactions
IF tx.transaction_type = 'Payment':
IF tx.payment_reason IN ('AutoPay', 'OneTimePayment', 'Settlement'):
total_payment += tx.effective_amount
# Service credits - ONLY these four types count as "real" payments
IF tx.transaction_type = 'ServiceCredit':
IF tx.credit_type IN ('serviceAgent', 'serviceSupervisor', 'balanceTransfer', 'usuryCap'):
total_payment += tx.effective_amount
RETURN round_to_whole_dollars(total_payment)Field 27: Date of Last Payment
Returns the date of the most recent qualifying transaction (same inclusion criteria as Actual Payment Amount):
FUNCTION get_date_of_last_payment(loan, date_of_account_info):
# Find most recent payment transaction
payment_tx = query_most_recent_transaction(
loan_id = loan.id,
transaction_type = 'Payment',
payment_reason IN ('AutoPay', 'OneTimePayment', 'Settlement'),
status IN ('Initiated', 'Pending', 'Succeeded'),
display_date <= date_of_account_info,
is_virtual = False
)
# Find most recent qualifying service credit
service_tx = query_most_recent_transaction(
loan_id = loan.id,
transaction_type = 'ServiceCredit',
credit_type IN ('serviceAgent', 'serviceSupervisor', 'balanceTransfer', 'usuryCap'),
status IN ('Initiated', 'Pending', 'Succeeded'),
display_date <= date_of_account_info,
is_virtual = False
)
# Return the most recent of the two
IF payment_tx AND service_tx:
RETURN max(payment_tx.display_date, service_tx.display_date)
ELIF payment_tx:
RETURN payment_tx.display_date
ELIF service_tx:
RETURN service_tx.display_date
ELSE:
RETURN NULL
> **Note:** The implementation combines these two lookups into a single query for efficiency, but the logic is equivalent.Note: The implementation combines these two lookups into a single query for efficiency, but the logic is equivalent.
Loan replay is the process of recalculating a loan's history when:
- Interest rates change retroactively
- Payments are backdated
- Errors are corrected
When a loan is replayed:
- Previous Metro 2 files remain unchanged (already submitted)
- Next Metro 2 file reflects corrected current state
- Payment History Profile may show different values for past months
BEFORE (Old Logic):
IF loan_status = 'ChargedOff' AND chargedOffReason = 'bankruptcy':
→ Report loan for the LAST time (stop immediately)AFTER (New Logic - Matches Spec):
IF loan_status = 'ChargedOff' AND outstanding_balance = 0:
→ Report loan for the LAST time (stop when balance reaches zero)Key Difference: Previously, bankruptcy charge-offs stopped reporting immediately regardless of balance. Now, all charge-offs (including bankruptcy) continue reporting until the balance reaches $0.
Credit reporting stops (terminal event) when:
| Condition | Final Status | Behavior |
|---|---|---|
| Loan paid off | 13 | Report once with status 13, then stop |
| Loan charged off with zero balance AND no service credit transaction types (settlementOfDebt, fraud, badDebt, deceased) | 64 | Report once with status 64, then stop |
| Loan charged off with zero balance BUT has service credit transaction types (settlementOfDebt, fraud, badDebt, deceased) | 97 | Report with status 97 (loss occurred) |
| Bankruptcy charge-off with balance | 97 | Continue reporting until balance reaches zero |
| Bankruptcy charge-off, balance reaches zero (no loss service credits) | 64 | Report once with status 64, then stop |
| Fraudulent charge-off | DF | Send deletion, then stop |
| Legal deletion | DA | Send deletion, then stop |
| Loan data corrupted | DA | Send deletion, then stop |
Service Credit Transaction Types Indicating Loss: Service credits of type
settlementOfDebt,fraud,badDebt, ordeceasedindicate the lender took a loss. If any of these were used to bring the balance to zero, the account reports status 97 instead of 64.
Special handling for bankruptcy charge-offs:
IF charged_off_reason = 'bankruptcy':
# Check for service credit transaction types that indicate a loss
# (excludes 'bankruptcy' serviceCreditType)
loss_service_credits = find_service_credits(
types = ['settlementOfDebt', 'fraud', 'badDebt', 'deceased'],
status = 'Succeeded'
)
IF outstanding_balance > 0:
# Continue reporting with status 97
reporting_continues = True
account_status = '97'
ELIF count(loss_service_credits) > 0:
# Balance is zero but loss occurred
reporting_continues = False
account_status = '97'
ELSE:
# Balance is zero, no loss - final report with 64
reporting_continues = False
account_status = '64'IF charged_off_reason = 'term':
loss_service_credits = find_service_credits(
types = ['settlementOfDebt', 'fraud', 'badDebt', 'deceased'],
status = 'Succeeded'
)
IF outstanding_balance > 0:
reporting_continues = True
account_status = '97'
ELIF count(loss_service_credits) > 0:
# Balance is zero but loss occurred
reporting_continues = False
account_status = '97'
ELSE:
# Balance is zero, no loss - final report with 64
reporting_continues = False
account_status = '64'When reporting should stop:
CreditReportingStatus.reporting_statusis set toStoppedreporting_end_dateis set to the final reporting date- Final file includes the loan with terminal status
- Subsequent files exclude the loan