Skip to content

When inserting a new subscription cycle, read the actual subscription start/end period, not invoice period#3899

Merged
jurgenwerk merged 4 commits intomainfrom
fix-subscription-cycle-dates
Feb 4, 2026
Merged

When inserting a new subscription cycle, read the actual subscription start/end period, not invoice period#3899
jurgenwerk merged 4 commits intomainfrom
fix-subscription-cycle-dates

Conversation

@jurgenwerk
Copy link
Contributor

@jurgenwerk jurgenwerk commented Jan 26, 2026

This PR fixes a bug where we process a webhook coming from Stripe when a new subscription is made, or when it renews.

At that time we create a new subscription_cycles record, which has fields period_start, period_end, which we read from the event's payload. The issue is that the source of where we are reading these values is wrong - we are reading the invoice period while we should be reading the subscription period which is included in the invoice's line item.

So the result of this error is that the subscription cycle periods are lagging 1 month behind. This PR fixes this with a data fix migration and adjusted logic to read the periods from the correct attributes in stripe event's payload.

@github-actions
Copy link

github-actions bot commented Jan 26, 2026

Host Test Results

    1 files  ±0      1 suites  ±0   1h 43m 40s ⏱️ - 1m 52s
1 941 tests ±0  1 924 ✅ ±0  17 💤 ±0  0 ❌ ±0 
1 956 runs  ±0  1 939 ✅ ±0  17 💤 ±0  0 ❌ ±0 

Results for commit 8c5c7e0. ± Comparison against base commit bcc525f.

♻️ This comment has been updated with latest results.

@jurgenwerk jurgenwerk force-pushed the fix-subscription-cycle-dates branch from 514c7db to c1dff08 Compare January 27, 2026 12:48
@github-actions
Copy link

Preview deployments

@jurgenwerk jurgenwerk marked this pull request as ready for review January 28, 2026 12:51
@jurgenwerk jurgenwerk requested a review from a team January 28, 2026 12:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes subscription cycle period_start/period_end being derived from the invoice period (lagging behind) by instead using the subscription line-item period from Stripe invoice webhooks, and backfills existing incorrect rows.

Changes:

  • Update invoice.payment_succeeded handling to read subscription cycle periods from the invoice line item’s period.start/end.
  • Update webhook/billing tests to include Stripe line-item fields (type, proration, period) and assert corrected cycle periods.
  • Add a Postgres data-fix migration to update existing subscription_cycles periods using stored Stripe event payloads.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/billing/stripe-webhook-handlers/payment-succeeded.ts Reads subscription cycle period from invoice subscription line item and passes it into subscription/subscription-cycle creation.
packages/billing/stripe-webhook-handlers/index.ts Extends invoice line typing to include type and proration.
packages/postgres/migrations/1769517089459_fix-subscription-cycle-dates.js Data migration to rewrite incorrect subscription_cycles.period_start/end based on stored Stripe event line-item periods.
packages/realm-server/tests/server-endpoints/stripe-webhook-test.ts Updates mocked Stripe webhook payloads to include required line-item fields for period extraction.
packages/realm-server/tests/billing-test.ts Updates billing tests to assert that cycle periods come from line-item period, not invoice period_start/end.
packages/host/config/schema/1769517089459_schema.sql Adds the latest generated SQLite schema snapshot corresponding to the newest migration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +39 to +40
line.period?.start &&
line.period?.end,
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The predicate line.period?.start && line.period?.end treats 0 as “missing” because it relies on truthiness. Use an explicit null/undefined check (e.g., != null) so valid numeric timestamps aren’t accidentally rejected.

Suggested change
line.period?.start &&
line.period?.end,
line.period?.start != null &&
line.period?.end != null,

Copilot uses AI. Check for mistakes.
@jurgenwerk jurgenwerk force-pushed the fix-subscription-cycle-dates branch from 52171b3 to 8c5c7e0 Compare February 4, 2026 12:15
@jurgenwerk jurgenwerk merged commit 4a90bd7 into main Feb 4, 2026
95 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants