DEV Community

Miran
Miran

Posted on

Billing Reports, Processor Payouts, and Bank Statements Should Not Share One Upload Type

Three files can describe the same bookkeeping period while representing different stages of the money flow, so the request model needs source identity before it needs automation.

Three separate source lanes for billing activity, processor settlements, and bank activity connected to one May bookkeeping request while retaining their expected source, review status, and next-action owner instead of merging into one generic revenue report
A May document request contains three files:

  • billing-activity-may.csv
  • processor-payouts-may.csv
  • bank-statement-may.pdf

All three are related to the subscription business’s activity for the same month.

If the application stores each one as:

type = revenue_report
period = May 2026
Enter fullscreen mode Exit fullscreen mode

the upload technically succeeded, but the request record has already lost information the reviewer needs.

The billing export describes what customers were billed.

The processor report describes how payments were settled, including fees, refunds, disputes, timing differences, or withheld funds.

The bank statement describes what actually reached or left the bank account.

Those sources may be related. They are not interchangeable.

One generic report type loses the source boundary

A generic upload field is attractive because it keeps the interface simple.

The client selects a file, the application saves it, and the team sees a filename and upload timestamp.

That may be enough for an occasional supporting document.

It becomes fragile when a subscription business provides several reports that cover the same period but answer different questions.

Consider a requested item labeled:

May revenue report

Which source should the client use?

  • The billing platform’s invoice export?
  • A subscription plan activity summary?
  • The payment processor’s payout report?
  • A bank statement?
  • A client-prepared billing schedule?

Each file may look relevant. None necessarily satisfies the same request.

A reviewer should not have to infer the expected source from the filename after the upload arrives.

The requested item needs to identify the source before the client submits anything.

Source identity belongs on the requested item

For this kind of request, I would keep several pieces of context together:

  • client
  • bookkeeping period
  • source category
  • expected report
  • named platform, processor, or account
  • required or optional
  • current review status
  • next action owner

A simplified requested item might look like this:

{
  "requested_item": "Processor payout report",
  "source_category": "payment_processor",
  "expected_source": "Client payment processor",
  "bookkeeping_period": "2026-05",
  "required": true,
  "status": "pending_review",
  "next_action_owner": "staff"
}
Enter fullscreen mode Exit fullscreen mode

The model does not need to understand the entire accounting treatment.

It only needs enough information to preserve why this file was requested and what should happen after it arrives.

A billing platform item could use:

source_category = billing_platform
expected_report = billing activity report
Enter fullscreen mode Exit fullscreen mode

A bank statement item could use:

source_category = bank_account
expected_report = May operating account statement
Enter fullscreen mode Exit fullscreen mode

The labels prevent the application from presenting three different sources as interchangeable copies of the same “revenue” file.

They also make the client-facing request more specific.

“Upload your May reports” becomes several observable tasks:

  • Upload the May billing platform activity report.
  • Upload the May processor payout or settlement report.
  • Upload the May operating account statement.

The upload control can stay simple because the requested item carries the meaning.

Preserve provenance for client-prepared schedules

The source distinction becomes even more important for schedules prepared by the client.

A client may already maintain an annual billing schedule or a deferred revenue schedule and provide it when the firm requests it.

The application should preserve that provenance.

It should record something like:

expected_report = client-prepared annual billing schedule
Enter fullscreen mode Exit fullscreen mode

It should not quietly turn the upload into:

system-generated deferred revenue calculation
Enter fullscreen mode Exit fullscreen mode

Those are very different claims.

The first says that the client supplied an existing supporting record.

The second implies that the application calculated, validated, or approved an accounting result.

A document request layer does not gain that authority merely because the file is stored in its database.

I would avoid attaching fields such as these to the collection event:

{
  "reconciled": true,
  "mrr_verified": true,
  "deferred_revenue_calculated": true,
  "revenue_recognized": true
}
Enter fullscreen mode Exit fullscreen mode

The request workflow has not established any of those conclusions.

Its evidence is narrower:

  • the named source is identifiable
  • the requested period is identifiable
  • the report arrived
  • staff can now review it

Preserving the source is useful.

Inventing a stronger accounting conclusion is not.

Review status should describe the requested report

Once a file arrives, the status should continue describing the collection and review work.

For example:

Waiting on client
→ no report uploaded

Pending review
→ report uploaded, staff decision not recorded

Received
→ staff accepted the report for this requested item

Needs reupload
→ staff identified the wrong report, wrong period, or unusable file
Enter fullscreen mode Exit fullscreen mode

These statuses are tied to one requested item.

A processor settlement report can be Received while the corresponding bank statement is still Waiting on client.

A billing activity report can be Pending review while a refund report is already accepted.

The request should not collapse those results into one universal statement about the business’s subscription accounting.

Received does not mean:

  • processor payouts match customer billing
  • deposits match the bank statement
  • refunds have been classified
  • revenue has been recognized
  • monthly recurring revenue is correct

It means the team accepted one requested report under its collection criteria.

That narrow meaning keeps the status useful without asking it to impersonate reconciliation or accounting software.

The next owner depends on the report’s current condition

Source identity also helps keep reminders pointed at the correct person.

If the May processor report has not been uploaded:

status = waiting_on_client
next_action_owner = client
Enter fullscreen mode Exit fullscreen mode

If the report arrived and has not been reviewed:

status = pending_review
next_action_owner = staff
Enter fullscreen mode Exit fullscreen mode

If staff determines that it covers April rather than May:

status = needs_reupload
next_action_owner = client
Enter fullscreen mode Exit fullscreen mode

The same document category can move between client and staff ownership as the request progresses.

A reminder system that checks only whether the whole request is open may send the client another upload message while the report is already waiting for internal review.

The request record needs the current owner, not just the existence of a file.

I captured these distinctions in the subscription business bookkeeping document checklist.

The checklist separates billing activity, processor settlements, refunds, disputes, banking, payroll, expenses, and supporting records while keeping the exact requirements dependent on the client, period, and firm’s service scope.

It is a source request structure, not a subscription accounting engine.

Keep the sources separate until someone is authorized to connect them

It may be tempting to make the interface look cleaner by merging related reports.

A single “subscription revenue documents” item sounds easier than separate billing, processor, and banking items.

The simplification happens in the wrong place.

The client may upload three files successfully, but the reviewer still needs to know what each file represents. The accounting team may later compare, reconcile, or interpret them, but that is a separate stage with different evidence and professional judgment.

At the request layer, the safer rule is:

Preserve the source before interpreting the relationship.

That means keeping customer billing activity distinct from processor settlement activity, and keeping both distinct from bank activity.

The same month does not make them the same record.

The same filename does not make them the same source.

The upload component can remain generic.

The data surrounding the upload cannot.

Top comments (0)