Skip to content

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:

bash
php artisan module:make TapGateway --type=custom
text
[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.

json
{
    "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"
}
php
// 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

json
{
    "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
<?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:

bash
# 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
<?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:

bash
# 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
plaintext
📁 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.

bash
# 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
plaintext
📁 Livewire/
├── 📁 Admin/
│   ├── 📄 TapGatewaySettings.php           # Settings component
│   └── 📄 TapGatewayDashboard.php          # Dashboard component
└── 📁 Payment/
    ├── 📄 TapGatewayCheckout.php           # Checkout component
    └── 📄 TapGatewayStatus.php             # Status component

Models Directory - Data Models

bash
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
<?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
<?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

css
/* 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;
}
javascript
// 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.

json
{
    "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!"
}
json
{
    "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

blade
@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
<?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
<?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

DirectoryWhen to UseCommand to Generate
Services/Business logic, API integrationphp artisan module:make-class Services/ServiceName ModuleName
Listeners/Event handling, system integrationphp artisan module:make-listener ListenerName ModuleName
Events/Custom event definitionsphp artisan module:make-event EventName ModuleName
Jobs/Background processing, queued tasksphp artisan module:make-job JobName ModuleName
Requests/Form validation, input sanitizationphp artisan module:make-request RequestName ModuleName
Middleware/Request filtering, authenticationphp artisan module:make-middleware MiddlewareName ModuleName
Console/Custom Artisan commandsphp 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.

bash
# 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
javascript
// 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:

bash
# 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
bash
# 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
bash
# 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:

© 2024 - Corbital Technologies. All rights reserved.