Skip to content

Navigation Menu

Sign in
Sign up

fix(subscription): resolve same-timestamp webhook ties by refetching latest state - #279

Open
SumitKumar-17 wants to merge 1 commit into
stripe:main from
SumitKumar-17:fix/268-subscription-timestamp-tiebreak
Open

fix(subscription): resolve same-timestamp webhook ties by refetching latest state #279
SumitKumar-17 wants to merge 1 commit into
stripe:main from
SumitKumar-17:fix/268-subscription-timestamp-tiebreak

Conversation

@SumitKumar-17

@SumitKumar-17 SumitKumar-17 commented Feb 23, 2026

Copy link
Copy Markdown

...latest state (#268)

What kind of change does this PR introduce?

Bug fix, feature, docs update, ...

What is the current behavior?

Please link any relevant issues here.

What is the new behavior?

Feel free to include screenshots if it includes visual changes.

Additional context

Add any other context or screenshots.

coderabbitai Bot commented Feb 23, 2026
edited
Loading

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉


i️ Recent review info

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6b9c0b2 and 45da4a3.

📒 Files selected for processing (2)
  • packages/fastify-app/src/test/subscriptionTimestampTieBreak.test.ts
  • packages/sync-engine/src/stripeSync.ts

📝 Walkthrough

Summary by CodeRabbit

  • Tests

    • Added comprehensive validation for subscription event handling when multiple updates occur within the same second.
  • Bug Fixes

    • Enhanced subscription state synchronization to correctly handle rapid consecutive updates that occur within the same second. The system now ensures all changes are properly applied and the latest subscription status, billing cycle information, and related details remain accurate.

Walkthrough

A new test file validates tie-breaking behavior for Stripe subscription events occurring within the same second. The sync engine has been enhanced with a conflict-resolution mechanism that detects when two subscription updates share identical timestamps. When this condition is detected, the system refetches the latest subscription state from Stripe and applies it with a fresh timestamp, ensuring deterministic state handling during concurrent webhook processing.

Sequence Diagram(s)

sequenceDiagram
 participant Webhook as Webhook Event
 participant StripeSync as StripeSync
 participant DB as Database
 participant Stripe as Stripe API
 
 Webhook->>StripeSync: processEvent (same timestamp)
 StripeSync->>DB: upsert subscription
 StripeSync->>DB: query subscriptions with same last_synced_at
 DB-->>StripeSync: existing row found
 StripeSync->>Stripe: subscriptions.retrieve()
 Stripe-->>StripeSync: latest subscription state
 StripeSync->>DB: upsert with fresh timestamp
 DB-->>StripeSync: complete
 StripeSync-->>Webhook: success
Loading

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Shouldn't this be solved for all objects not just subscriptions? It just so happens that we found this issue with subscriptions, but it may apply to other models as well.

SumitKumar-17 commented Feb 24, 2026
edited
Loading

Copy link
Copy Markdown
Author

@andrejpavlovic Yeah i think you are correct. last_synced_at conflict protection is generic, so same-second tie behavior can affect any object. I suppose the repo maintainer of Supabase can continue here as this issue would require a lot of changes

Copy link
Copy Markdown

The if (refetched || upsertedSubscriptions.length > 0) return short-circuit on upsertedSubscriptions.length > 0 looks intended but won't work as written — upsertManyWithTimestampProtection builds an INSERT ... ON CONFLICT DO UPDATE ... WHERE ... with no RETURNING clause, so its returned rows array is always empty regardless of whether the update applied. So that branch never short-circuits in practice; the post-upsert SELECT runs on every webhook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /