Payment Gateway Module Structure - Complete Developer Guide
This guide provides a comprehensive overview of the directory structure and file organization for payment gateway modules in WhatsmarkSaaS. Understanding this structure is essential for creating, maintaining, and extending payment gateway modules.
Understanding this structure is absolutely critical - it's like having a map of the entire module ecosystem. I'm going to show you every directory, every file, and explain exactly why each piece exists and how it fits into the bigger picture.
Why Structure Matters
The modular structure ensures clean separation of concerns, making it easy to develop, test, deploy, and maintain payment gateway integrations independently of the core application. This isn't just organization for the sake of organization - it's the foundation that makes our system scalable and maintainable.
Module Creation Command
When you create a payment gateway module, this single command generates the entire structure:
php artisan module:make TapGateway --type=custom
[TapGateway] module created successfully.
Module type: Custom
To activate the module, run: php artisan module:activate TapGateway
Complete Directory Structure
Here's the complete structure that gets generated. I'll walk you through each section:
Complete Module Tree Structure
Modules/TapGateway/
├── 📄 composer.json # Module-specific Composer configuration
├── 📄 module.json # Module metadata and configuration
├── 📄 package.json # Frontend dependencies and build scripts
├── 📄 README.md # Module documentation
├── 📄 TapGateway.php # Main module class
├── 📄 vite.config.js # Vite configuration for asset compilation
├── 📁 Config/
│ └── 📄 config.php # Module configuration settings
├── 📁 Console/ # Console commands directory (empty initially)
├── 📁 Database/
│ ├── 📁 Factories/ # Model factories directory (empty initially)
│ ├── 📁 Migrations/ # Database migrations directory (empty initially)
│ └── 📁 Seeders/ # Database seeders directory (empty initially)
├── 📁 Http/
│ ├── 📁 Controllers/
│ │ └── 📄 TapGatewayController.php # Main module controller
│ └── 📁 Middleware/ # Custom middleware directory (empty initially)
├── 📁 Livewire/ # Livewire components directory (empty initially)
├── 📁 Models/ # Eloquent models directory (empty initially)
├── 📁 Providers/
│ ├── 📄 RouteServiceProvider.php # Routes service provider
│ └── 📄 TapGatewayServiceProvider.php # Main service provider
├── 📁 resources/
│ ├── 📁 assets/
│ │ ├── 📁 css/
│ │ │ └── 📄 app.css # Module-specific CSS
│ │ └── 📁 js/
│ │ └── 📄 app.js # Module-specific JavaScript
│ ├── 📁 lang/
│ │ ├── 📄 en.json # English translations
│ │ └── 📄 tenant_en.json # Tenant-specific English translations
│ └── 📁 views/
│ └── 📄 index.blade.php # Main module view
└── 📁 Routes/
├── 📄 api.php # API routes
└── 📄 web.php # Web routes
Root Level Files - The Module's DNA
The module.json
File - Your Module's Identity
Critical Configuration File
This file is the heart of your module. Without proper configuration here, your module won't load correctly.
{
"name": "TapGateway",
"alias": "tap-gateway",
"namespace": "Modules\\TapGateway\\",
"provider": "Modules\\TapGateway\\Providers\\TapGatewayServiceProvider",
"author": "Corbital Technologies",
"url": "https://codecanyon.net/user/corbitaltech",
"version": "1.0.0",
"description": "The TapGateway Payment Module",
"keywords": [],
"order": 0,
"providers": [
"Modules\\TapGateway\\Providers\\TapGatewayServiceProvider"
],
"aliases": [],
"require": [],
"conflicts": [],
"type": "custom"
}
// name: Module name for identification and commands
// alias: URL-friendly version for routing
// namespace: PHP namespace for all classes
// provider: Main service provider class path
// version: Semantic versioning (major.minor.patch)
// type: "custom" for payment gateways
// require: Dependencies on other modules
// conflicts: Incompatible modules
Composer Configuration
{
"name": "modules/tap-gateway",
"description": "Tap Gateway Payment Module",
"authors": [
{
"name": "Corbital Technologies",
"email": "[email protected]"
}
],
"autoload": {
"psr-4": {
"Modules\\TapGateway\\": ""
}
}
}
Core Directory Deep Dive
Config Directory - Module Settings
Configuration Best Practices
Keep all module-specific configurations here. This makes it easy to manage settings and provides a single source of truth.
<?php
return [
'name' => 'TapGateway',
// Payment gateway specific configuration
'api_version' => 'v1',
'timeout' => 30,
'retry_attempts' => 3,
// Default settings
'defaults' => [
'currency' => 'USD',
'sandbox_mode' => true,
],
];
Database Directory - Data Management
This directory manages all database-related functionality:
# Create migration
php artisan module:make-migration create_tap_gateway_transactions_table TapGateway
# Create model with migration
php artisan module:make-model TapGatewayTransaction TapGateway -m
# Create factory
php artisan module:make-factory TapGatewayTransactionFactory TapGateway
# Create seeder
php artisan module:make-seed TapGatewaySeeder TapGateway
<?php
// Database/Migrations/create_tap_gateway_transactions_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('tap_gateway_transactions', function (Blueprint $table) {
$table->id();
$table->string('gateway_transaction_id')->unique();
$table->decimal('amount', 10, 2);
$table->string('currency', 3);
$table->string('status');
$table->timestamps();
});
}
};
Http Directory - Request Handling
Controller Organization
Controllers are organized by functionality and user type (admin, tenant, API) for better maintainability.
The Http directory contains all request handling logic:
# Main controller (auto-generated)
# Already exists: TapGatewayController.php
# Admin controllers
php artisan module:make-controller Admin/TapGatewaySettingsController TapGateway
php artisan module:make-controller Admin/TapGatewayReportsController TapGateway
# API controllers
php artisan module:make-controller Api/TapGatewayApiController TapGateway
php artisan module:make-controller Api/WebhookController TapGateway
# Payment processing
php artisan module:make-controller PaymentGateways/TapGatewayPaymentController TapGateway
📁 Http/Controllers/
├── 📄 TapGatewayController.php # Main controller
├── 📁 Admin/ # Admin interface // [!code focus]
│ ├── 📄 TapGatewaySettingsController.php # Settings management // [!code focus]
│ └── 📄 TapGatewayReportsController.php # Reports & analytics // [!code focus]
├── 📁 Api/ # API endpoints // [!code focus]
│ ├── 📄 TapGatewayApiController.php # Main API controller // [!code focus]
│ └── 📄 WebhookController.php # Webhook handling // [!code focus]
└── 📁 PaymentGateways/ # Payment processing // [!code focus]
├── 📄 TapGatewayPaymentController.php # Payment logic // [!code focus]
└── 📄 TapGatewayCallbackController.php # Payment callbacks // [!code focus]
Livewire Directory - Interactive Components
When to Use Livewire
Use Livewire components for interactive elements like real-time payment status updates, dynamic forms, and admin dashboards.
# Admin components
php artisan module:make-livewire Admin/TapGatewaySettings TapGateway
php artisan module:make-livewire Admin/TapGatewayDashboard TapGateway
# Payment components
php artisan module:make-livewire Payment/TapGatewayCheckout TapGateway
php artisan module:make-livewire Payment/TapGatewayStatus TapGateway
📁 Livewire/
├── 📁 Admin/
│ ├── 📄 TapGatewaySettings.php # Settings component
│ └── 📄 TapGatewayDashboard.php # Dashboard component
└── 📁 Payment/
├── 📄 TapGatewayCheckout.php # Checkout component
└── 📄 TapGatewayStatus.php # Status component
Models Directory - Data Models
php artisan module:make-model TapGatewayTransaction TapGateway -m
php artisan module:make-model TapGatewayRefund TapGateway -m
php artisan module:make-model TapGatewayWebhookLog TapGateway -m
<?php
// Models/TapGatewayTransaction.php
namespace Modules\TapGateway\Models;
use Illuminate\Database\Eloquent\Model;
class TapGatewayTransaction extends Model
{
protected $fillable = [
'gateway_transaction_id',
'amount',
'currency',
'status'
];
protected $casts = [
'amount' => 'decimal:2',
];
public function isSuccessful(): bool
{
return $this->status === 'completed';
}
}
Service Providers - Module Bootstrap
Main Service Provider
Service Provider Importance
The service provider is what makes your module work. It registers views, translations, routes, and configurations with Laravel.
<?php
namespace Modules\TapGateway\Providers;
use Illuminate\Support\ServiceProvider;
class TapGatewayServiceProvider extends ServiceProvider
{
protected $moduleName = 'TapGateway';
public function boot()
{
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
$this->registerRoutes();
$this->registerEventListeners();
}
public function register()
{
$this->app->register(RouteServiceProvider::class);
}
}
Resources Directory - Frontend Assets
Assets Directory Structure
/* TapGateway Module Styles */
.tap-gateway-container {
padding: 2rem;
border-radius: 0.5rem;
}
.tap-gateway-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.tap-gateway-status {
border: 1px solid #e2e8f0;
}
// TapGateway Module JavaScript
import axios from 'axios';
window.TapGateway = {
init() {
console.log('TapGateway initialized');
},
processPayment(data) {
return axios.post('/api/tap-gateway/charge', data);
}
};
document.addEventListener('DOMContentLoaded', function() {
window.TapGateway.init();
});
Language Files - Internationalization
Translation Strategy
Always separate admin and tenant translations. This allows different language requirements and keeps interfaces clean.
{
"tap_gateway": "Tap Gateway",
"tap_gateway_settings": "Tap Gateway Settings",
"configure_tap_gateway": "Configure Tap Gateway",
"api_key": "API Key",
"secret_key": "Secret Key",
"sandbox_mode": "Sandbox Mode",
"enable_tap_gateway": "Enable Tap Gateway",
"test_connection": "Test Connection",
"connection_successful": "Connection successful!",
"connection_failed": "Connection failed. Please check your credentials.",
"save_settings": "Save Settings",
"settings_saved": "Settings saved successfully!"
}
{
"pay_with_tap": "Pay with Tap",
"tap_payment": "Tap Payment",
"processing_payment": "Processing Payment...",
"payment_successful": "Payment Successful",
"payment_failed": "Payment Failed",
"retry_payment": "Retry Payment",
"secure_payment_by_tap": "Secure payment powered by Tap",
"enter_card_details": "Enter your card details",
"card_number": "Card Number",
"expiry_date": "Expiry Date"
}
Views Directory - Blade Templates
@extends('layouts.app')
@section('content')
<div class="container tap-gateway-container"> // [!code focus]
<h1 class="text-3xl font-bold mb-6">{{ t('tap_gateway') }}</h1> // [!code focus]
<div class="bg-white rounded-lg shadow-md p-6"> // [!code focus]
<p class="text-gray-600 mb-4"> // [!code focus]
{{ t('tap_gateway_description') }}
</p>
@if(config('tap-gateway.enabled')) // [!code focus]
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800"> // [!code focus]
{{ t('enabled') }}
</span> // [!code focus]
@else
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
{{ t('disabled') }}
</span>
@endif
</div>
</div>
@endsection
Routes Directory - URL Mapping
Route Security
Always apply appropriate middleware to protect sensitive routes. Payment endpoints should never be accessible without proper authentication and authorization.
Web Routes Structure
<?php
use Illuminate\Support\Facades\Route;
use Modules\TapGateway\Http\Controllers\TapGatewayController;
use App\Http\Middleware\AdminMiddleware;
use App\Http\Middleware\SanitizeInputs;
use Modules\TapGateway\Http\Controllers\Admin\TapGatewaySettingsController;
// Admin routes
Route::middleware(['web', 'auth', AdminMiddleware::class, SanitizeInputs::class])->prefix('admin')->name('admin.')->group(function () {
Route::prefix('/settings/payment')->name('settings.payment')->group(function () {
Route::get('/tap-gateway', [TapGatewaySettingsController::class, 'index'])->name('tap-gateway');
Route::post('/tap-gateway', [TapGatewaySettingsController::class, 'store'])->name('tap-gateway.store');
Route::patch('/tap-gateway', [TapGatewaySettingsController::class, 'update'])->name('tap-gateway.update');
});
});
// Tenant routes
Route::middleware(['tenant'])->prefix('tenant/payment')->name('tenant.payment.')->group(function () {
Route::get('/tap-gateway/{invoice}', [TapGatewayController::class, 'checkout'])->name('tap-gateway.checkout');
Route::post('/tap-gateway/{invoice}', [TapGatewayController::class, 'process'])->name('tap-gateway.process');
Route::get('/tap-gateway/callback/{invoice}', [TapGatewayController::class, 'callback'])->name('tap-gateway.callback');
});
<?php
use Illuminate\Support\Facades\Route;
use Modules\TapGateway\Http\Controllers\Api\TapGatewayApiController;
use Modules\TapGateway\Http\Controllers\Api\WebhookController;
// Payment processing API
Route::middleware('api')->prefix('v1')->group(function () {
Route::prefix('tap-gateway')->name('tap-gateway.')->group(function () {
Route::post('/charge', [TapGatewayApiController::class, 'charge'])->name('charge');
Route::get('/status/{transactionId}', [TapGatewayApiController::class, 'status'])->name('status');
Route::post('/refund', [TapGatewayApiController::class, 'refund'])->name('refund');
});
});
// Webhook endpoints (no auth middleware - verified via signature)
Route::post('/tap-gateway/webhook', [WebhookController::class, 'handle'])
->name('tap-gateway.webhook');
Directory Usage Guidelines
Development Workflow
Understanding when and how to use each directory ensures consistent development patterns across your team.
Directory Usage Reference
Directory | When to Use | Command to Generate |
---|---|---|
Services/ | Business logic, API integration | php artisan module:make-class Services/ServiceName ModuleName |
Listeners/ | Event handling, system integration | php artisan module:make-listener ListenerName ModuleName |
Events/ | Custom event definitions | php artisan module:make-event EventName ModuleName |
Jobs/ | Background processing, queued tasks | php artisan module:make-job JobName ModuleName |
Requests/ | Form validation, input sanitization | php artisan module:make-request RequestName ModuleName |
Middleware/ | Request filtering, authentication | php artisan module:make-middleware MiddlewareName ModuleName |
Console/ | Custom Artisan commands | php artisan module:make-command CommandName ModuleName |
Asset Compilation Process
Asset Management
Your module's assets are compiled separately from the main application, allowing for modular deployment and updates.
Extended License Required
Commands like npm run dev
, npm run build
, and npm install
require Node.js and Vue.js dependencies that are only available with an extended license. Please note that these development tools and frameworks are NOT required for basic payment gateway development. They are only necessary if you want to add custom CSS/JS or make significant customizations to the application interface. Standard payment gateway integration can be accomplished without these tools.
# Compile module assets for development
npm run dev
# Compile and minify for production
npm run build
# Watch for changes during development
npm run dev -- --watch
// After compilation, assets are output to:
public/
└── build-tap-gateway/
├── assets/
│ ├── app-[hash].css
│ └── app-[hash].js
└── manifest.json
Module Development Lifecycle
Understanding the development lifecycle helps you work efficiently:
# 1. Create module
php artisan module:make TapGateway --type=custom
# 2. Generate core components
php artisan module:make-controller Admin/TapGatewaySettingsController TapGateway
php artisan module:make-class Services/TapPaymentGateway TapGateway
php artisan module:make-listener RegisterTapGateway TapGateway
# 3. Add functionality as needed
php artisan module:make-model TapGatewayTransaction TapGateway -m
php artisan module:make-job ProcessTapGatewayPayment TapGateway
php artisan module:make-request TapGatewaySettingsRequest TapGateway
# 4. Test and optimize
php artisan test
npm run build
php artisan module:publish TapGateway
Structure Summary
This standardized structure ensures consistency across all payment gateway modules, making them easier to develop, maintain, and distribute. Each directory serves a specific purpose in the module ecosystem.
Next Steps
Now that you understand the module structure, you're ready to dive into:
- Payment Gateway Implementation Guide - Build your first gateway
- Admin Configuration Guide - Create the admin interface
- Tenant Billing Integration - Connect to the billing system