rahulpathak/stripe-subscription-manager-rsp

Laravel package for managing Stripe subscriptions using Laravel Cashier

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/rahulpathak/stripe-subscription-manager-rsp

dev-master 2025-09-26 11:47 UTC

This package is auto-updated.

Last update: 2025-12-26 12:17:51 UTC


README

A comprehensive Laravel package for managing Stripe subscriptions with seamless integration. Perfect for multi-project use with consistent subscription management.

Developer: Rahul Pathak (rahulp@webmobtech.com)
Package: rsp/stripe-subscription-manager-rsp

🚀 Key Features

  • Easy User-Stripe Integration - One trait adds all subscription functionality to User models
  • Magic Methods - Access Stripe data directly: $user->stripe_customer_id
  • Complete Subscription Flow - Subscribe, cancel, resume with simple method calls
  • Plan Management - Ready-to-use controller for managing subscription plans
  • Webhook Handling - Automatic sync with Stripe events
  • Trial Periods & Coupons - Full support for trials and discount codes
  • Payment History - Complete transaction tracking
  • Multi-project Ready - Easy to replicate across projects

📦 Installation & Setup

1. Install Package

composer require rsp/stripe-subscription-manager-rsp

2. Environment Variables

Add to your .env:

STRIPE_KEY=pk_test_your_stripe_publishable_key
STRIPE_SECRET=sk_test_your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
STRIPE_SUCCESS_URL=https://yoursite.com/subscription/success
STRIPE_CANCEL_URL=https://yoursite.com/subscription/cancel
STRIPE_CURRENCY=usd

3. Run Migrations

php artisan migrate

This creates: subscription_plans, stripe_users, user_subscriptions, payment_history, coupons

4. Add Trait to User Model

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Rsp\StripeSubscriptionManager\Traits\HasStripeUser;

class User extends Authenticatable
{
    use HasStripeUser;
    
    // Your existing code...
}

5. Publish Controllers (Optional)

php artisan vendor:publish --tag=stripe-controller

This adds PlanManagementController to your app/Http/Controllers/

🎯 Primary Usage (What Your Team Uses)

Core User Methods

$user = User::find(1);

// Create/Get Stripe Customer
$stripeUser = $user->getOrCreateStripeCustomer();

// Subscribe to Plan
try {
    $result = $user->subscribe(1, [
        'coupon_code' => 'SAVE20',              // optional
        'success_url' => 'https://example.com/success',
        'cancel_url' => 'https://example.com/cancel'
    ]);
    
    // Redirect user to: $result['session_url']
    
} catch (\Exception $e) {
    // Handle "User has active subscription" error
    echo $e->getMessage();
}

// Cancel Subscription
$result = $user->cancelSubscription(true); // true = cancel at period end

// Check Subscription Status
$user->hasActiveSubscription();      // boolean
$user->getSubscriptionStatus();      // string
$user->canPurchaseSubscription();    // boolean
$user->isOnTrial();                  // boolean
$user->getTrialDaysRemaining();      // integer

Magic Property Access

$user = User::find(1);

// Direct access to Stripe data
echo $user->stripe_customer_id;      // Stripe customer ID
echo $user->customer_email;          // Email in Stripe
echo $user->customer_name;           // Name in Stripe
echo $user->default_payment_method;  // Payment method ID

🛠️ Team Test Routes

Add these routes for testing in your projects:

// routes/web.php or routes/api.php

// Create user and Stripe customer
Route::get('/create-user-stripe', function () {
    $user = User::create([
        'name' => 'Test User',
        'email' => 'test@example.com',
        'password' => bcrypt('password')
    ]);

    $user->getOrCreateStripeCustomer();
    $user->load('stripeUserRsp');

    return $user;
});

// Test subscription flow
Route::get('/test-subscribe', function () {
    $user = User::firstOrCreate([
        'email' => 'test@example.com'
    ], [
        'name' => 'Test User',
        'password' => bcrypt('password')
    ]);

    try {
        $result = $user->subscribe(1, [
            'success_url' => 'https://example.com/success',
            'cancel_url' => 'https://example.com/cancel'
        ]);

        return response()->json([
            'message' => 'Checkout session created',
            'checkout_url' => $result['session_url'], // Redirect here
            'result' => $result
        ]);

    } catch (\Exception $e) {
        return response()->json([
            'error' => $e->getMessage(),
            'user_status' => [
                'has_active_subscription' => $user->hasActiveSubscription(),
                'subscription_status' => $user->getSubscriptionStatus(),
                'can_purchase' => $user->canPurchaseSubscription()
            ]
        ], 422);
    }
});

// Test cancellation
Route::get('/test-cancel', function () {
    $user = User::where('email', 'test@example.com')->first();
    
    if (!$user) {
        return ['error' => 'User not found'];
    }

    try {
        $result = $user->cancelSubscription(true); // Cancel at period end
        return [
            'message' => 'Subscription canceled',
            'result' => $result
        ];
    } catch (\Exception $e) {
        return ['error' => $e->getMessage()];
    }
});

📋 Plan Management

Create Plans via Controller

use App\Http\Controllers\PlanManagementController;

$controller = app(PlanManagementController::class);

// Quick create subscription plan
$plan = $controller->quickCreateSubscription(
    'Premium Monthly',  // name
    29.99,             // amount  
    'month',           // interval
    'usd',             // currency
    7                  // trial days
);

// Quick create one-time payment
$plan = $controller->quickCreatePayment('Setup Fee', 49.99);

Create Plans via API

# Create subscription plan
curl -X POST /api/plans \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Monthly",
    "amount": 29.99,
    "type": "subscription", 
    "interval": "month",
    "trial_days": 7,
    "currency": "usd"
  }'

# Get all plans
curl -X GET /api/plans

# Get active subscription plans only
curl -X GET /api/plans?type=subscription&is_active=true

🔄 Complete Subscription Flow

Frontend JavaScript Example

// 1. Create checkout session
async function subscribeUser(planId, couponCode = null) {
    try {
        const response = await fetch('/api/subscriptions/checkout', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + userToken
            },
            body: JSON.stringify({
                plan_id: planId,
                coupon_code: couponCode
            })
        });

        const data = await response.json();
        
        if (data.success) {
            // Redirect to Stripe Checkout
            window.location.href = data.session_url;
        } else {
            alert('Error: ' + data.error);
        }
    } catch (error) {
        console.error('Error:', error);
    }
}

// 2. Check subscription status
async function checkStatus() {
    const response = await fetch('/api/subscriptions/status', {
        headers: { 'Authorization': 'Bearer ' + userToken }
    });
    
    const data = await response.json();
    console.log('Subscription Status:', data);
}

// 3. Cancel subscription
async function cancelSubscription() {
    const response = await fetch('/api/subscriptions/cancel', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + userToken
        },
        body: JSON.stringify({
            cancel_at_period_end: true
        })
    });
    
    const data = await response.json();
    console.log('Cancellation:', data);
}

🎫 Working with Coupons

Create Coupons

use Rsp\StripeSubscriptionManager\Models\Coupon;

// 20% off coupon
Coupon::create([
    'code' => 'SAVE20',
    'name' => '20% Off First Month',
    'type' => 'percent',
    'value' => 20,
    'max_redemptions' => 100,
    'first_time_customers_only' => true,
    'valid_until' => now()->addDays(30),
    'is_active' => true,
]);

// Fixed amount coupon
Coupon::create([
    'code' => 'SAVE10',
    'name' => '$10 Off',
    'type' => 'fixed',
    'value' => 10.00,
    'currency' => 'usd',
    'is_active' => true,
]);

Validate Coupons

curl -X POST /api/subscriptions/validate-coupon \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "coupon_code": "SAVE20",
    "plan_id": 1
  }'

🔗 Webhook Setup

1. Setup Endpoint in Stripe Dashboard

https://yoursite.com/api/stripe/webhook

2. Select These Events

  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.payment_succeeded
  • invoice.payment_failed
  • payment_intent.succeeded

3. Copy Webhook Secret to .env

STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here

📊 Database Schema Overview

Key Tables

  • subscription_plans - Plans with pricing and trial periods
  • stripe_users - Links users to Stripe customers
  • user_subscriptions - Active/canceled subscriptions
  • payment_history - All transactions and payments
  • coupons - Discount codes and validation rules

Important Notes

  • UUID Support: Change user_id to string in migration if using UUIDs
  • Relationships: All models auto-link through proper foreign keys
  • Magic Methods: Access Stripe data directly on User model

🚨 Common Error Handling

// Check before subscribing
if (!$user->canPurchaseSubscription()) {
    throw new \Exception('User already has active subscription');
}

// Handle subscription errors
try {
    $result = $user->subscribe($planId);
} catch (\Exception $e) {
    if (str_contains($e->getMessage(), 'active subscription')) {
        // User already subscribed
        return redirect()->back()->with('error', 'You already have an active subscription');
    }
    
    // Other errors
    Log::error('Subscription failed: ' . $e->getMessage());
    return redirect()->back()->with('error', 'Subscription failed');
}

⚡ Quick Multi-Project Setup

1. Copy These Files to New Projects

  • .env settings (Stripe keys)
  • User model with HasStripeUser trait
  • Published PlanManagementController
  • Test routes for verification

2. Run Setup Commands

composer require rsp/stripe-subscription-manager-rsp
php artisan migrate

3. Verify Installation

# Test these routes exist:
GET /create-user-stripe
GET /test-subscribe  
GET /test-cancel
GET /api/plans

🎯 Team Best Practices

  1. Always check canPurchaseSubscription() before creating checkout sessions
  2. Use try/catch around subscribe/cancel methods
  3. Test with Stripe test cards: 4242424242424242 (success), 4000000000000002 (declined)
  4. Setup webhooks for production to keep data in sync
  5. Create plans programmatically using the controller methods
  6. Validate coupons before applying to checkout sessions

🔧 Available API Endpoints

GET    /api/plans                           - List plans
POST   /api/plans                           - Create plan
GET    /api/subscriptions/plans             - Get subscription plans
POST   /api/subscriptions/checkout          - Create checkout session
GET    /api/subscriptions/status            - Get user status
POST   /api/subscriptions/cancel            - Cancel subscription
POST   /api/subscriptions/resume            - Resume subscription
GET    /api/subscriptions/history           - Subscription history
GET    /api/subscriptions/payments          - Payment history
POST   /api/subscriptions/validate-coupon   - Validate coupon
POST   /api/stripe/webhook                  - Stripe webhooks

📞 Support & Questions

  • Review the comprehensive examples in this README
  • Check the test routes for working implementations
  • All methods return arrays with ['success' => true/false] structure
  • Use Laravel logs to debug Stripe integration issues

Ready to integrate subscriptions in minutes! 🚀

Copy this README to each project and follow the setup steps. The HasStripeUser trait and PlanManagementController provide everything your team needs for consistent subscription management across projects.

👨‍💻 Developer Information

Developed by: Rahul Pathak
Email: rahulp@webmobtech.com
Package: rsp/stripe-subscription-manager-rsp

For technical questions, implementation guidance, or package updates, contact the developer directly.