Skip to content

Instantly share code, notes, and snippets.

@tuhuynh27
Last active June 1, 2026 17:59
Show Gist options
  • Select an option

  • Save tuhuynh27/9f66b4560567be90bcf0ac698c7ea81b to your computer and use it in GitHub Desktop.

Select an option

Save tuhuynh27/9f66b4560567be90bcf0ac698c7ea81b to your computer and use it in GitHub Desktop.
REPORT.md

Subscription Issue


What happened

Some people who cancelled their subscription or stopped paying were still getting premium access for free. Normally, when someone's paid period ends, our system should drop them back to the Free plan automatically. That automatic step was broken, so 69 accounts kept their paid features without paying. We've now reset all of them, double-checked everything against Stripe (our payment provider), and fixed the underlying bugs.


The numbers

Accounts getting premium for free 69
→ on the Max plan 29
→ on the Pro plan 3
→ on the Plus plan 37
Oldest case (free since) late January 2026

All 69 are now back on the Free plan. The audit afterward came back 100% clean.


Why it happened

  1. The "cancel cleanup" robot was unplugged. We have an automated daily job that's supposed to revoke access once someone's paid time runs out. Due to a configuration mistake, it had never actually run since launch - so nobody was ever automatically downgraded.

  2. Some cancellations never reached us. When a member cancels, the payment provider (Stripe) is supposed to notify us when their time finally expires. For a group of accounts those notifications were lost, so our records still showed them as "active paying members" when they weren't.


Who exactly was affected (the categories)

We grouped the affected accounts by how they ended up wrong. This matters because each group required a slightly different fix.

Group A - "Cancelled, but never downgraded" - 26 accounts

These people clearly cancelled, and our system even knew they had cancelled. But because the cleanup robot was unplugged (problem #1), nobody ever flipped them back to Free. They simply kept their paid features after their time ran out. Fix: reset to Free.

Email Plan Access ended
phuongmy1923@gmail.com Max 2026-02-20
ngophucthuan2406.hanu@gmail.com Max 2026-03-26
trungptit89@gmail.com Max 2026-03-27
lenguyenminhphat1511@gmail.com Max 2026-04-03
dpd0807@gmail.com Max 2026-04-04
luanpham2003@gmail.com Max 2026-04-30
nhannhan19578@gmail.com Max 2026-05-10 (has since resubscribed - now paying)
freelancer0197@gmail.com Max 2026-05-11
phungcuong2003@gmail.com Max 2026-05-13
stevetranbg97@gmail.com Max 2026-05-13
ducminhluu1612@gmail.com Pro 2026-02-24
leson.tpc@gmail.com Pro 2026-03-06
nhinx1909@gmail.com Plus 2026-03-16
vantrung56@gmail.com Plus 2026-03-18
tuandinh1340@gmail.com Plus 2026-04-02
doannam.nh@gmail.com Plus 2026-04-10
phamtungvu1997@gmail.com Plus 2026-04-24
pedona.hoangvq@gmail.com Plus 2026-04-25
taylienhon87@gmail.com Plus 2026-04-26
fx.minh12@gmail.com Plus 2026-05-01
justintuan1405@gmail.com Plus 2026-05-05
hang.mt@melvgroup.vn Plus 2026-05-09
josh.tuan.huynh@gmail.com Plus 2026-05-19
ngocthanhle650@gmail.com Plus 2026-05-19
pauljohnson0845@gmail.com Plus 2026-05-21
thaoneu137@gmail.com Plus 2026-05-21

Group F - "Looked active, but were actually cancelled" - 33 accounts (the biggest group)

These people cancelled too, but our system still showed them as active paying members - because the "your membership has now ended" notification from Stripe never arrived (problem #2). On paper they looked fine; in reality they'd stopped paying. We confirmed each one directly with Stripe before correcting it. Fix: matched our records to Stripe's truth, then reset to Free.

Email Plan Access ended
lampt002@gmail.com Max 2026-02-05
jimmyluong03@gmail.com Max 2026-02-13
thach.bui@gmail.com Max 2026-02-18
minhtuham90@gmail.com Max 2026-02-26
vuduy9795@gmail.com Max 2026-03-06
thainam.tran@outlook.com Max 2026-03-20
hahong260891@gmail.com Max 2026-04-03
dvotran@yahoo.com Max 2026-04-08
duongphucthuc@gmail.com Max 2026-04-11
sonnyle78@yahoo.com Max 2026-04-14
hmcuongit@gmail.com Max 2026-04-18
karlsson.pham@gmail.com Max 2026-04-22
bendaminpranklin@gmail.com Max 2026-04-24
joannachen1819@gmail.com Max 2026-05-01
henryvan0611@gmail.com Max 2026-05-19
ducduy9293@gmail.com Max 2026-05-21
hades199143@gmail.com Pro 2026-03-12
sangnhle@gmail.com Plus 2026-01-28
caophucthinh24@gmail.com Plus 2026-03-04
accclonethong@gmail.com Plus 2026-03-08
supermario365vn@gmail.com Plus 2026-03-29
william.kieu.80@gmail.com Plus 2026-03-30
ducp171@gmail.com Plus 2026-04-03
kanazawahere@gmail.com Plus 2026-04-04
h.d.dang@gmail.com Plus 2026-04-04
tienthai.hus@gmail.com Plus 2026-04-07
tranbau.fbg@gmail.com Plus 2026-04-22
ngokieuphu@gmail.com Plus 2026-04-26
khanhle91@gmail.com Plus 2026-05-04
vinhhieu40@gmail.com Plus 2026-05-06
myd7310@gmail.com Plus 2026-05-08
truongduynguyen16@gmail.com Plus 2026-05-11
duc.trinh0103@gmail.com Plus 2026-05-19

Group G - "Payment failed, then quietly cancelled" - 10 accounts

Their renewal payment failed. Stripe kept retrying for a while (so they were marked "payment overdue"), then eventually cancelled them - but again, that final cancellation never reached us, so they stayed on premium. We only spotted these when we widened our check to include "payment overdue" accounts. Fix: confirmed with Stripe, then reset to Free.

Email Plan Access ended
longdoan20@gmail.com Max 2026-03-02
khanhanh1999btbt@gmail.com Max 2026-03-26
vuhoangdung086@gmail.com Max 2026-05-27
nhattvdx@gmail.com Plus 2026-03-15
nguyenhieu120225@gmail.com Plus 2026-03-27
plmoknijb1408@gmail.com Plus 2026-04-18
lordsauron5598@gmail.com Plus 2026-05-02
kien178178@gmail.com Plus 2026-05-19
trunghieu229buh@gmail.com Plus 2026-05-25
admin@chuyentin.info Plus 2026-05-30

What we did to fix it permanently

We added four layers of protection so that even if one part fails again, the others catch it:

  1. Reconnected and upgraded the daily cleanup job. It now also double-checks our records against Stripe every day and self-corrects any mismatch - so a missed notification can no longer cause a silent leak.
  2. Fixed the notification handling so end-of-membership events are no longer dropped.
  3. Added the "don't touch paying customers" safety rule (protects resubscribers and edge cases like Group H).
  4. Fixed a database rule that was causing some payment events to fail.

We also built reusable check-up scripts so we (or anyone) can re-run this audit anytime in minutes.


Bottom line

This was a revenue leak, not a data-loss or security breach - no customer data was lost or exposed, and no paying customer lost access. We've recovered the affected accounts, protected the genuine customers, and put safeguards in place so it won't quietly happen again.

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