A modern, simple, and powerful SaaS template built with PHP and SQLite.
π Just purchased? Start here: QUICKSTART.md (10 minutes)
π€ Using an AI assistant? This template is optimized for LLM-guided setup. Paste any
.mdfile into Claude, ChatGPT, or Cursor for step-by-step guidance!
We strongly recommend testing locally first:
-
QUICKSTART.md β Start here! (10 min)
- Install dependencies
- Set up Google OAuth
- Test locally at
http://localhost:9000 - Verify everything works
-
RAILWAY_DEPLOY.md β Deploy to production (10 min)
- After local setup works
- Push to GitHub
- Deploy to Railway
- Go live!
Why local first? You'll catch issues immediately, test with real credentials, and deploy with confidence knowing it works.
This is a commercial product with unlimited project use. By purchasing this template, you receive a license to use it for unlimited commercial projects. You may modify the code freely for your own use, but you may not resell, redistribute, or share the template source code with others. See LICENSE file for complete terms.
- Modern Design: Beautiful, responsive homepage with hero section
- Simple Stack: Pure PHP with SQLite - no complex dependencies
- Google OAuth Authentication: One-click sign-in with Google (no passwords!)
- User Dashboard: Personalized dashboard for authenticated users
- Items CRUD: Full create, read, update, delete functionality
- Stripe Integration: Complete subscription and payment processing
- Feature Gating: Plan-based limits (Free: 5 items, Pro: 50, Enterprise: unlimited)
- Usage Tracking: Real-time usage display with progress bars
- Subscription Management: Upgrade, downgrade, cancel subscriptions
- Database Ready: SQLite database with proper schema
- Secure Session Management: Database-backed session handling with token authentication
- Activity Logging: Track user actions and events
- Webhook Handling: Automated sync with Stripe events
- Responsive: Mobile-first design that works on all devices
- Fast & Lightweight: Minimal dependencies, maximum performance
Perfect for beginners! Railway provides automatic deployment with zero configuration.
-
Set up Google OAuth credentials (5 minutes)
- See
RAILWAY_DEPLOY.mdPart 1 for step-by-step instructions - You'll need a Google Cloud account (free)
- See
-
Deploy to Railway (3 minutes)
- See
RAILWAY_DEPLOY.mdPart 2 - Push to GitHub or use Railway CLI
- Railway automatically handles everything!
- See
-
Configure environment variables (2 minutes)
- Add your Google OAuth credentials in Railway dashboard
- See
RAILWAY_DEPLOY.mdPart 3
That's it! Your SaaS is live with HTTPS at your-app.up.railway.app
π Complete Railway Guide: See RAILWAY_DEPLOY.md
For advanced users who want to develop locally:
- PHP 7.4 or higher
- SQLite3 extension enabled
- Composer (for dependency management)
- A Google Cloud account (for OAuth)
- A web server (Apache, Nginx, or PHP built-in server)
-
Extract the template files
-
Install dependencies (already included in vendor/ folder)
# Optional - dependencies are pre-included composer install -
Create local configuration
# Copy the example file cp config.local.example.php config.local.phpEdit
config.local.phpand add your credentials:- Google Client ID and Secret
- (Optional) Stripe API keys
-
Initialize the database
php database/init.php php database/migrate_google_oauth.php php database/migrate_items.php php database/migrate_stripe.php
-
Set up Google OAuth (required)
Follow the detailed guide in
SETUP.mdto:- Create a Google Cloud project
- Configure OAuth consent screen
- Get your Client ID and Client Secret
- Add to your
config.local.php
-
Start the server
php -S localhost:9000
-
Open your browser
http://localhost:9000 -
Sign in with Google
Click "Sign in with Google" and authenticate. Your account will be created automatically!
π Complete Local Setup Guide: See SETUP.md
PHP SaaS Template/
βββ index.php # Homepage
βββ pricing.php # Pricing page with 3 tiers
βββ config.php # Configuration settings
βββ config.local.php # Local config (gitignored)
βββ composer.json # Dependency management
βββ README.md # Main documentation
βββ SETUP.md # Google OAuth setup guide
βββ STRIPE_SETUP.md # Stripe integration guide
βββ STRIPE_TESTING.md # Stripe testing guide
βββ .gitignore # Git ignore rules
βββ auth/
β βββ google-login.php # Initiate Google OAuth
β βββ google-callback.php # OAuth callback handler
β βββ logout.php # Logout handler
βββ checkout/
β βββ create-session.php # Create Stripe checkout session
β βββ success.php # Payment success page
β βββ cancel.php # Payment cancelled page
βββ webhooks/
β βββ stripe.php # Stripe webhook handler
βββ dashboard/
β βββ index.php # Items dashboard
β βββ item-new.php # Create new item
β βββ item-edit.php # Edit item
β βββ item-actions.php # Item CRUD actions
β βββ profile.php # User profile & subscription management
βββ includes/
β βββ Auth.php # Authentication class
β βββ GoogleOAuth.php # Google OAuth handler
β βββ Items.php # Items CRUD class
β βββ Subscription.php # Subscription management class
β βββ helpers.php # Helper functions
βββ assets/
β βββ css/
β β βββ style.css # Main stylesheet
β βββ js/
β β βββ main.js # JavaScript functionality
β βββ images/ # Your image assets
βββ database/
β βββ init.php # Database initialization
β βββ migrate_google_oauth.php # OAuth migration
β βββ migrate_items.php # Items table migration
β βββ migrate_stripe.php # Stripe tables migration
β βββ Database.php # Database class
β βββ saas.db # SQLite database
βββ uploads/
β βββ avatars/ # User avatar uploads
βββ vendor/ # Composer dependencies
- User authentication and profile information
- Fields: id, username, email, password_hash (nullable), full_name, avatar_url, google_id, oauth_provider, created_at, etc.
- Manage user sessions securely
- Fields: id, user_id, session_token, ip_address, user_agent, expires_at
- Store user items (your main SaaS feature)
- Fields: id, user_id, title, description, created_at, updated_at
- Handle user subscriptions and billing
- Fields: id, user_id, plan_name, status, amount, currency, billing_cycle, stripe_customer_id, stripe_subscription_id, stripe_price_id, current_period_start, current_period_end
- Track payment history
- Fields: id, user_id, stripe_invoice_id, amount, currency, status, invoice_pdf, hosted_invoice_url, period_start, period_end, paid_at
- Store customer payment methods
- Fields: id, user_id, stripe_payment_method_id, type, card_brand, card_last4, card_exp_month, card_exp_year
- Log all Stripe webhook events for debugging
- Fields: id, stripe_event_id, event_type, payload, processed, error_message, created_at, processed_at
- Track user actions and events
- Fields: id, user_id, action, description, ip_address, created_at
- Manage password reset tokens
- Fields: id, user_id, token, created_at, expires_at, used
Edit config.php to customize:
// Site settings
define('SITE_NAME', 'YourSaaS');
define('SITE_URL', 'http://localhost:9000');
define('SITE_EMAIL', '[email protected]');
// Google OAuth (REQUIRED - see SETUP.md)
define('GOOGLE_CLIENT_ID', 'YOUR_GOOGLE_CLIENT_ID');
define('GOOGLE_CLIENT_SECRET', 'YOUR_GOOGLE_CLIENT_SECRET');
// Security
define('SESSION_LIFETIME', 86400); // 24 hours
define('ENABLE_REGISTRATION', true);Important: You must set up Google OAuth credentials before the authentication will work. See SETUP.md for detailed instructions.
Good news: The template works WITHOUT Stripe! Feature gating and limits work immediately out of the box.
To enable actual payments (optional):
-
Sign up for Stripe (free)
- Go to: https://stripe.com
- Create account - takes 2 minutes
- Use test mode for development
-
Get Your API Keys
- Go to: https://dashboard.stripe.com/test/apikeys
- Copy your Publishable key (starts with
pk_test_) - Copy your Secret key (starts with
sk_test_)
-
Add Keys to
config.local.php// Replace the placeholders: define('STRIPE_PUBLISHABLE_KEY', 'pk_test_YOUR_ACTUAL_KEY'); define('STRIPE_SECRET_KEY', 'sk_test_YOUR_ACTUAL_KEY');
-
Create Products in Stripe Dashboard
- Go to: https://dashboard.stripe.com/test/products
- Create "Pro Plan": $29/month recurring
- Create "Enterprise Plan": $99/month recurring
- Copy each Price ID (starts with
price_)
-
Update Price IDs in
config.php// In the PRICING_PLANS array: 'stripe_price_id' => 'price_YOUR_ACTUAL_PRO_PRICE_ID', // Pro 'stripe_price_id' => 'price_YOUR_ACTUAL_ENTERPRISE_PRICE_ID', // Enterprise
-
Test with Test Cards
- Card:
4242 4242 4242 4242 - Expiry: Any future date
- CVC: Any 3 digits
- Card:
That's it! See STRIPE_SETUP.md for detailed instructions and webhook setup.
Without Stripe configured:
- β Pricing page displays
- β Feature limits enforced (5 items for free, etc.)
- β Upgrade prompts appear
- β Payment buttons show "not configured" message
With Stripe configured:
- β Everything above PLUS
- β Users can actually pay
- β Automatic subscription management
- β Webhook sync with Stripe
- β Invoice tracking
- Google OAuth Authentication: One-click sign-in with Google
- User Management: Automatic user creation and profile updates
- Session Management: Secure database-backed sessions with tokens
- Activity Logging: Track user login/logout events
- Basic Dashboard: Personalized dashboard for authenticated users
- Security: CSRF protection, XSS prevention, secure session handling
- Items Management: Full CRUD operations (Create, Read, Update, Delete)
- Modern Dashboard: Clean, responsive layout with item cards
- Profile Management: Edit profile, upload avatar
- Item Actions: Edit, duplicate, delete with confirmation
- Empty States: Beautiful empty state when no items exist
- Pricing Page: Beautiful 3-tier pricing display (Free, Pro, Enterprise)
- Stripe Checkout: Seamless payment flow with Stripe Checkout
- Subscription Management: View, cancel, and reactivate subscriptions
- Feature Gating: Item limits enforced by plan (5/50/unlimited)
- Usage Tracking: Real-time usage widget with progress bars
- Billing Page: View subscription details and payment history
- Webhook Handler: Automated sync with Stripe events
- Invoice History: View all payment records
- Plan Upgrades: Seamless plan switching with proration
- Email notifications for payment events
- Team collaboration features
- Advanced analytics dashboard
- API access for enterprise customers
- Custom branding options
Recommended for beginners - Zero configuration, auto HTTPS, production-ready instantly!
See RAILWAY_DEPLOY.md for the complete guide.
For advanced users who want to customize locally before deploying:
- Create Local Config: Copy
config.local.example.phptoconfig.local.php - Setup Database: Run all migration scripts (or Railway auto-initializes)
- Configure Google OAuth: See
SETUP.mdfor step-by-step guide - Optional: Add Stripe: Enable subscription payments
- Start Building: Customize for your specific use case
For complete local setup, see SETUP.md
1. Update Site Name & Branding
- Edit
config.php: ChangeSITE_NAME,SITE_URL,SITE_EMAIL - Replace
hero.jpgwith your own background image (2400Γ750px recommended)
2. Customize Homepage Content (index.php)
- Main headline and tagline
- Three benefit bullets
- Call-to-action button text
- Signup form text
3. Change Colors (assets/css/style.css)
/* Primary CTA Button */
.btn-cta {
background: linear-gradient(135deg, #ff6b6b 0%, #f06595 100%);
}
/* Popular alternatives: */
/* Blue: linear-gradient(135deg, #667eea 0%, #764ba2 100%); */
/* Green: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); */
/* Purple: linear-gradient(135deg, #a855f7 0%, #ec4899 100%); */4. Adjust Pricing & Limits (config.php)
define('PRICING_PLANS', [
'free' => ['price' => 0, 'item_limit' => 5],
'pro' => ['price' => 29, 'item_limit' => 50],
'enterprise' => ['price' => 99, 'item_limit' => null]
]);5. Replace "Items" with Your Feature
- Update database schema for your data model
- Modify
includes/Items.phpwith your business logic - Update UI terminology throughout the app
This template includes common security patterns:
- β SQL Injection Prevention: Prepared statements used throughout
- β
XSS Protection: Output sanitized with
htmlspecialchars() - β Secure Sessions: HTTP-only cookies, database-backed sessions
- β PCI Compliance: All payments handled by Stripe (no card data stored)
- β Webhook Verification: Signature validation on Stripe webhooks
This template implements common security best practices, but you are responsible for:
- Reviewing and testing code for your specific security requirements
- Conducting security audits before production deployment
- Keeping dependencies updated (run
composer updateregularly) - Monitoring for security vulnerabilities in your deployment
- Implementing additional security measures as needed for your use case
No software is 100% secure. This template is provided "AS-IS" per the LICENSE agreement. Always perform your own security review and testing before deploying to production with real users.
- Never commit
config.local.phpto version control (already in.gitignore) - Rotate credentials if ever accidentally exposed
- Use environment variables in production deployments
- Enable HTTPS before going live (set
session.cookie_secureto1inconfig.php)
- Disable error display:
error_reporting(0);andini_set('display_errors', '0'); - Enable HTTPS and secure cookies
- Use production Stripe keys (not test keys)
- Set up webhook signature verification
- Monitor error logs regularly
require_once 'config.php';
require_once 'includes/Auth.php';
$auth = new Auth();
// Check if user is logged in
if ($auth->isLoggedIn()) {
// Get current user data
$user = $auth->getCurrentUser();
echo "Welcome, " . $user['full_name'];
}
// Protect a page (requires authentication)
$auth->requireAuth();
// Get the Google OAuth URL
$googleOAuth = $auth->getGoogleOAuth();
$authUrl = $googleOAuth->getAuthUrl();
// Logout
$auth->logout();require_once 'config.php';
require_once 'database/Database.php';
$db = Database::getInstance();
// Fetch user data
$user = $db->fetchOne('SELECT * FROM users WHERE id = :id', [
'id' => 1
]);
// Insert data
$id = $db->insert('activity_log', [
'user_id' => 1,
'action' => 'page_view',
'description' => 'Viewed pricing page'
]);
// Update data
$db->update('users',
['full_name' => 'John Doe'],
'id = :id',
['id' => 1]
);- PHP 7.4+: Server-side logic
- Composer: Dependency management
- Google API Client: OAuth 2.0 authentication
- SQLite: Lightweight database
- Stripe PHP SDK: Payment processing (Milestone 3)
- CSS3: Modern styling with CSS Grid and Flexbox
- JavaScript: Interactive features
- SVG: Scalable icons
Commercial License - Unlimited Projects - This template is licensed for unlimited commercial projects. You may modify the code for your own use, but may not resell, redistribute, or share the template source code with others. See LICENSE file for complete terms.
For questions or issues, please create an issue in the repository.
Built with β€οΈ for the indie maker community
Happy building! π