stripeprorationbilling modeinvoicing

Stripe's Classic Billing Mode Finally Knows Which Charge a Credit Belongs To

Stripe's Sept 30 release adds proration_details.credited_items to classic billing mode — closing a reconciliation gap flexible mode already had.

XY
5 October 2026 · 7 min read

A customer downgrades mid-cycle. Stripe generates a credit line item for the unused time on the old plan. Three weeks later, a support agent is staring at that line item — "Unused time on Pro plan," minus $41.20 — trying to answer a simple question: which charge is this actually crediting? On flexible billing mode, the Invoice Item object has an answer built in. On classic billing mode, until September 30, it didn't. The credit existed, the math was correct, and there was no structured way to point back at the debit it was offsetting.

Key stat
55%
Of SaaS finance leaders say gaps between billing and collections are actively hindering company growth
Source: Zuora, The Modern Finance Leader Report (2025)

That number isn't about credit prorations specifically — it's about order-to-cash friction broadly. But a credit with no traceable link to its charge is exactly the kind of gap that survey is measuring in aggregate: a billing system and a reconciliation process that don't agree on what happened, and a finance or support team stuck manually matching dates and dollar amounts to guess at the answer.

What shipped on September 30

Stripe's Endive release (API version 2026-09-30.endive) added proration_details to credit proration invoice items for subscriptions on classic billing mode. The field was already available on flexible mode. Inside it sits credited_items, which identifies the original debit a given credit is crediting against:

  • If the debit hasn't been invoiced yet, credited_items.type is invoice_item, and invoice_item holds that item's ID directly.
  • If the debit already landed on a finalized invoice, type is invoice_line_items, and invoice_line_item_details gives you the invoice ID plus an array of the specific line item IDs being credited.
  • A single credit can reference more than one debited line item — tiered unit pricing, for instance, can split one logical charge across several line items on the finalized invoice, and the array reflects all of them.

None of this changes what a customer is billed. It's a read-only addition to data Stripe already had internally — the kind of change that's easy to miss in a changelog and genuinely useful the first time a support ticket asks "why was I credited $41.20" and the answer used to require opening the Dashboard and eyeballing invoice dates.

CapabilityClassic mode, before Sept 30Classic mode, now
Credit line item exists on the invoiceYesYes
Credit amount is correctYesYes
API field linking credit to its original debitNoneproration_details.credited_items
Reconciling a credit against its chargeManual — match description text, dates, and amounts by handProgrammatic — follow the reference
Tiered pricing credits spanning multiple line itemsNo way to tell they were one logical chargecredited_items.invoice_line_item_details lists every one

Why classic mode's credits were harder to trust in the first place

This gap mattered more on classic billing mode than it would have on flexible, because the two modes don't even calculate a credit the same way. Stripe's own documentation walks through the difference with a worked example: a subscription starts at $10/month, upgrades to $20/month ten days later with proration_behavior: 'none' (so no invoice goes out for the upgrade itself), then downgrades back to $10/month eleven days after that with proration_behavior: 'always_invoice'.

Classic: credits a third of a month at $20 (never actually billed) → −$6.67, debits a third of a month at $10 → +$3.33. Net: −$3.34
Flexible: credits a third of a month at $10 (the price actually billed) → −$3.33, debits a third of a month at $10 → +$3.33. Net: $0.00

Same subscription, same sequence of changes, two different invoice totals — because classic mode credits against the current price on the item, even when the customer was never billed at that price, while flexible mode credits against the price that was last actually billed. Neither number is a bug; both modes are doing exactly what they're documented to do. But a support agent trying to explain a −$3.34 charge to a customer who only remembers paying $10 a month needs to know which calculation produced it, and until this release, classic mode gave them a dollar amount with no attached reasoning — just a line item that said "credit" and a number that didn't obviously map to anything the customer recalled doing.

What SaaS finance leaders say about order-to-cash friction
Say manual reconciliation work blocks strategic focus100%
Say they are bogged down by manual billing tasks97%
Say technology gaps are blocking order-to-cash effectiveness95%

Source: Zuora, The Modern Finance Leader Report (2025)

Those numbers are self-reported by finance leaders, not support teams, but the mechanism is identical. A credit without a traceable origin is one more thing somebody has to manually chase down before month-end close, before answering a customer, or before deciding whether a dispute is legitimate. We've covered the customer-facing half of this problem in proration confusion — why a mathematically correct invoice still reads as a mistake — and the collection-timing half in our piece on Stripe's credit-hold rules, which stops a credit from posting before the invoice it offsets is actually paid. This release is a third, narrower piece: once a credit exists and has posted, can anyone — your support team, your finance team, or an automated reconciliation script — actually trace it back to what it's crediting. Previously, on classic mode, the answer was only "manually, if you're lucky."

Where this shows up in practice

The places this matters are specific, not abstract:

  • Support deflection. A billing-question macro that currently tells agents to "check the Dashboard for the prior invoice and compare dates" can instead pull credited_items directly and surface the exact debit — turning a multi-minute manual lookup into a single API call.
  • Automated revenue reconciliation. Finance tooling that reconciles Stripe invoice items against a ledger no longer has to infer credit-to-debit relationships from description strings and timestamps, which is exactly the kind of fragile matching logic that breaks the moment a description format changes.
  • Downgrade and plan-change churn tracking. If you're segmenting cancellations that follow a confusing credit from cancellations that don't, having a structured link between the credit and the original charge makes that segmentation possible to automate instead of hand-tagging tickets.
  • Tiered and metered pricing. Because invoice_line_item_details.invoice_line_items is an array, a single credit spanning several tiers on a usage-based plan is now visibly one event instead of a set of line items with no obvious relationship to each other.

What it still doesn't fix

Stripe's own documentation is upfront about the limit: for subscriptions on classic billing mode, proration_details is absent in flows where Stripe can't confidently identify the original debit in the first place. This release closes a lot of those gaps, but it isn't a guarantee that every classic-mode credit will carry a reference — just that far more of them now will than did before September 30. It also doesn't change the underlying classic-versus-flexible calculation difference described above; a classic-mode credit can still net out to a different total than the same sequence of changes would on flexible mode. If that discrepancy itself is causing support load, migrating the subscription to flexible billing mode — not just upgrading your API version — is the actual fix, and it's a one-way move worth testing in a sandbox first.

What it does fix is cheap and specific: a field that was simply missing is now there for the cases Stripe can resolve, on a billing mode a large share of existing Stripe integrations are still running, since flexible only became the default for new subscriptions a year earlier. If your support or finance team has a standing workaround for "which charge does this credit belong to" — a spreadsheet, a date-matching script, a rule of thumb about checking the invoice right before the one in question — it's worth testing whether credited_items now makes that workaround unnecessary. And if credit-to-debit confusion has been quietly inflating the support load around plan changes, that's exactly the kind of friction a cancellation flow can't fix after the fact — the customer needs to trust the invoice before they ever reach a cancel page, not be talked out of leaving once a credit they don't understand has already eroded that trust.

Frequently asked questions

What is proration_details.credited_items on a Stripe Invoice Item?+

It's a field on a credit proration invoice item that identifies the specific debit the credit is offsetting. If the debit is still a pending invoice item, credited_items.type is invoice_item and the field points to that item's ID. If the debit already landed on a finalized invoice, type is invoice_line_items and invoice_line_item_details gives you the invoice ID plus an array of the specific line item IDs being credited — sometimes more than one, if tiered pricing split the original charge across several lines.

Do I need to migrate from classic to flexible billing mode to get this?+

No. This specific field — proration_details with credited_items — shipped for subscriptions on classic billing mode in the September 30, 2026 Endive API release. Flexible billing mode already had broader proration_details support. You do need to upgrade your API version to 2026-09-30.endive or later to see the field, but you don't have to change your subscriptions' billing_mode to get it.

Why couldn't classic billing mode do this before?+

Classic and flexible billing mode calculate credit prorations differently under the hood, and Stripe built the structured credit-to-debit link for flexible mode first. Classic mode credits are computed against a subscription item's current price rather than the price that was actually billed, which makes the original debit harder to pin down programmatically in some flows — part of why Stripe's own documentation still notes that proration_details can be absent on classic mode when it can't confidently identify the debit.

What's the actual difference between how classic and flexible mode calculate a credit?+

Classic mode bases a credit proration on the subscription item's current price, even if the customer was never actually billed at that price. Flexible mode bases it on the price that was last billed. The gap only shows up when a price changes more than once inside the same billing period without an invoice in between — in that case classic mode's credit can net out to a different total than flexible mode's would, for what looks like an identical sequence of plan changes.

Try CancelFlow

Stop losing subscribers today

One script tag. One function call. A live cancellation flow in under 10 minutes.

Start free trial →
← All postsHome