![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/public_html/ |
# Credits/Subscription Tracks Reset Issue - Analysis
## Problem Description
Stephane Bergeron (Taz) has:
- Essential subscription plan (5 tracks/month)
- Purchased 500 credits
- After using 5 subscription tracks (which are used first), the subscription tracks reset to 5 available again
## How the System Should Work
1. **Subscription Tracks (5/month)**: Used first when creating tracks
2. **Credits (500)**: Used after subscription tracks are exhausted
3. **Subscription tracks reset**: Only on billing date (subscription period renewal)
## Potential Causes
### 1. Subscription Period Detection Bug ⚠️ **MOST LIKELY**
**Location**: `webhooks/stripe.php` → `handleSubscriptionUpdated()` (line 1727)
**Issue**: The period comparison might be incorrectly detecting a period change:
```php
$period_changed = ($db_period_start && $stripe_period_start !== $db_period_start);
```
**Potential Problems**:
- Timezone mismatch between database and Stripe timestamps
- Format differences (with/without microseconds)
- If `$old_period_start` is NULL or empty, comparison might fail
- Webhook might be triggered when it shouldn't be (e.g., when credits are added)
**Fix Needed**: Add better logging and validation of period comparison
### 2. Duplicate Usage Records
**Issue**: Multiple `monthly_track_usage` records for the same period could cause confusion
**Check**: Run diagnostic script to see if there are duplicate records
### 3. Webhook Triggered Incorrectly
**Issue**: When credits are added, a subscription webhook might be triggered that resets usage
**Check**: Review webhook logs around the time credits were added
### 4. Cron Job Issue
**Issue**: The `reset_monthly_limits.php` cron might be creating/resetting usage incorrectly
**Check**: Review cron logs
## Diagnostic Steps
1. **Run the diagnostic script**: `investigate_stephane_credits.php`
- Check current credits balance
- Check subscription status
- Check monthly track usage records
- Check for duplicate usage records
- Review credit transactions
2. **Check webhook logs**:
- Look for `customer.subscription.updated` events around the time credits were added
- Check if period was incorrectly detected as changed
3. **Check subscription period**:
- Verify `current_period_start` in database matches Stripe
- Check if period format is consistent
## Recommended Fixes
### Fix 1: Improve Period Comparison (CRITICAL)
Add better logging and validation in `handleSubscriptionUpdated()`:
```php
// Convert both to timestamps for accurate comparison
$stripe_timestamp = $subscription->current_period_start;
$db_timestamp = is_numeric($old_period_start) ? $old_period_start : strtotime($old_period_start);
// Log the comparison for debugging
error_log("Period comparison: DB={$db_timestamp} (" . date('Y-m-d H:i:s', $db_timestamp) . "), Stripe={$stripe_timestamp} (" . date('Y-m-d H:i:s', $stripe_timestamp) . ")");
// Only reset if timestamps differ by more than 1 hour (to account for minor differences)
$period_changed = ($db_timestamp && abs($stripe_timestamp - $db_timestamp) > 3600);
```
### Fix 2: Add Safeguard Against Accidental Resets
Before resetting, check if tracks_created > 0 and log a warning:
```php
if ($period_changed) {
// Check if we're about to reset non-zero usage
$current_usage = getMonthlyTrackUsage($user_id, $plan_name_to_use);
if ($current_usage && $current_usage['tracks_created'] > 0) {
error_log("WARNING: Resetting usage with {$current_usage['tracks_created']} tracks created. Old period: {$db_period_start}, New period: {$stripe_period_start}");
}
// ... rest of reset code
}
```
### Fix 3: Prevent Webhook on Credit Addition
Ensure that adding credits doesn't trigger subscription webhooks that could reset usage.
## Next Steps
1. Run `investigate_stephane_credits.php` to gather current state
2. Review webhook logs for the time period when issue occurred
3. Check if there are duplicate usage records
4. Implement Fix 1 (improved period comparison)
5. Add additional logging to track when/why resets occur
## Files to Review
- `webhooks/stripe.php` → `handleSubscriptionUpdated()` (lines 1620-1800)
- `utils/subscription_helpers.php` → `getMonthlyTrackUsage()` (lines 69-181)
- `cron/reset_monthly_limits.php`
- Webhook logs: `logs/stripe_actions.log`
- Credit logs: `logs/user_credits.log`