We run subscription billing for a multi-tenant Rails SaaS: 2,000+ businesses, about $1M a year in subscription volume, plus Stripe Connect payouts on top. After we moved to a newer Stripe API version, the scariest kind of bug showed up: nothing broke loudly.
No exceptions. No failed jobs. Charges just stopped reconciling.
What changed
Newer Stripe API versions moved current_period_start and current_period_end off the Subscription object and onto each Subscription Item. Our webhook handlers, renewal logic and access checks all read the period from the subscription, like this:
period_end = Time . at ( subscription . current_period_end )
Enter fullscreen mode
Exit fullscreen mode
On the new API version that field is gone, so the code kept running with nil instead. Ruby didn't complain, Stripe didn't complain, and our reconciliation quietly skipped work.
Why we didn't notice
nil is a valid value in a lot of Ruby code.…