Skip to content

macnux/API-Gateway

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Order and Payment Management API

A comprehensive RESTful API for managing orders and payments with JWT authentication, built with Laravel 10.x following clean code principles and design patterns.

Features

  • JWT Authentication: Secure API endpoints with JWT tokens
  • Order Management: Full CRUD operations for orders and order items
  • Payment Processing: Multiple payment gateway support with Strategy pattern
  • Extensible Architecture: Easy to add new payment gateways
  • Database Transactions: Atomic operations for order creation
  • Soft Deletes: Safe deletion with recovery capability
  • API Resources: Standardized response transformation
  • Comprehensive Testing: Unit and feature tests
  • Validation: Form request validation with custom error messages

Technology Stack

  • Laravel: 10.x
  • PHP: 8.1+
  • MySQL: Database
  • JWT: tymon/jwt-auth for authentication
  • PHPUnit: Testing framework
  • PSR-12: Coding standards

Project Structure

app/
├── Contracts/                  # Interfaces and abstract classes
│   ├── PaymentGatewayInterface.php
│   └── PaymentResult.php
├── Exceptions/                 # Custom exception classes
│   ├── OrderException.php
│   └── PaymentProcessingException.php
├── Http/
│   ├── Controllers/Api/        # API controllers
│   │   ├── AuthController.php
│   │   ├── OrderController.php
│   │   └── PaymentController.php
│   ├── Requests/               # Form request validation
│   │   ├── RegisterRequest.php
│   │   ├── LoginRequest.php
│   │   ├── CreateOrderRequest.php
│   │   ├── UpdateOrderRequest.php
│   │   └── ProcessPaymentRequest.php
│   └── Resources/              # API resource classes
│       ├── UserResource.php
│       ├── OrderResource.php
│       ├── OrderItemResource.php
│       └── PaymentResource.php
├── Models/                     # Eloquent models
│   ├── User.php
│   ├── Order.php
│   ├── OrderItem.php
│   ├── Payment.php
│   └── PaymentGateway.php
└── Services/
    ├── OrderService.php        # Order business logic
    ├── PaymentService.php      # Payment orchestration
    └── PaymentGateways/        # Concrete gateway implementations
        ├── CreditCardGateway.php
        ├── PayPalGateway.php
        └── StripeGateway.php
database/
├── migrations/                 # Database migrations
└── seeders/                    # Database seeders
tests/
├── Feature/                    # Feature tests
│   ├── AuthenticationTest.php
│   ├── OrderTest.php
│   └── PaymentTest.php
└── Unit/                       # Unit tests
    ├── PaymentGatewayTest.php
    └── OrderServiceTest.php

Installation

Prerequisites

  • PHP 8.1 or higher
  • Composer
  • MySQL 5.7 or higher
  • Git

Setup Instructions

  1. Clone the repository

    git clone <repository-url>
    cd API-Gateway
  2. Install dependencies

    composer install
  3. Configure environment

    cp .env.example .env
  4. Generate application key

    php artisan key:generate
  5. Generate JWT secret

    php artisan jwt:secret
  6. Configure database (edit .env)

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=api_gateway
    DB_USERNAME=root
    DB_PASSWORD=
  7. Run migrations

    php artisan migrate
  8. Seed the database (optional)

    php artisan db:seed
  9. Start the development server

    php artisan serve

    The API will be available at http://localhost:8000

API Endpoints

Base URL

http://localhost:8000/api

Response Format

All responses follow a standardized format:

Success Response:

{
  "success": true,
  "message": "Operation successful",
  "data": {...}
}

Error Response:

{
  "success": false,
  "message": "Error description",
  "error": "detailed error information"
}

Paginated Response:

{
  "data": [...],
  "links": {...},
  "meta": {
    "current_page": 1,
    "per_page": 15,
    "total": 100
  }
}

Authentication Endpoints

Register User

POST /api/register
Content-Type: application/json

{
  "name": "John Doe",
  "email": "[email protected]",
  "password": "password123",
  "password_confirmation": "password123"
}

Response: 201 Created

{
  "success": true,
  "message": "User registered successfully",
  "data": {
    "user": {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]",
      "created_at": "2024-01-26T10:00:00Z"
    },
    "token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
  }
}

Login

POST /api/login
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "password123"
}

Response: 200 OK

{
  "success": true,
  "message": "Login successful",
  "data": {
    "user": {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]"
    },
    "token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
  }
}

Get Current User

GET /api/me
Authorization: Bearer {token}

Response: 200 OK

{
  "success": true,
  "message": "User retrieved successfully",
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "[email protected]",
    "created_at": "2024-01-26T10:00:00Z"
  }
}

Logout

POST /api/logout
Authorization: Bearer {token}

Response: 200 OK

{
  "success": true,
  "message": "Logout successful"
}

Order Endpoints

Create Order

POST /api/orders
Authorization: Bearer {token}
Content-Type: application/json

{
  "items": [
    {
      "product_name": "Laptop",
      "quantity": 1,
      "price": 999.99
    },
    {
      "product_name": "Mouse",
      "quantity": 2,
      "price": 29.99
    }
  ]
}

Response: 201 Created

{
  "success": true,
  "message": "Order created successfully",
  "data": {
    "id": 1,
    "user_id": 1,
    "total_amount": 1059.97,
    "status": "pending",
    "items": [
      {
        "id": 1,
        "product_name": "Laptop",
        "quantity": 1,
        "price": 999.99,
        "total": 999.99
      },
      {
        "id": 2,
        "product_name": "Mouse",
        "quantity": 2,
        "price": 29.99,
        "total": 59.98
      }
    ],
    "payments": []
  }
}

List Orders

GET /api/orders?status=pending&per_page=15
Authorization: Bearer {token}

Query Parameters:

  • status: Filter by order status (pending, confirmed, cancelled)
  • per_page: Number of results per page (default: 15)
  • page: Page number (default: 1)

Response: 200 OK

{
  "data": [
    {
      "id": 1,
      "user_id": 1,
      "total_amount": 1059.97,
      "status": "pending",
      "created_at": "2024-01-26T10:00:00Z"
    }
  ],
  "links": {
    "first": "http://localhost:8000/api/orders?page=1",
    "last": "http://localhost:8000/api/orders?page=1",
    "prev": null,
    "next": null
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "per_page": 15,
    "to": 1,
    "total": 1
  }
}

Get Specific Order

GET /api/orders/{id}
Authorization: Bearer {token}

Response: 200 OK

Update Order Status

PUT /api/orders/{id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "status": "confirmed"
}

Valid Statuses: pending, confirmed, cancelled

Response: 200 OK

Delete Order

DELETE /api/orders/{id}
Authorization: Bearer {token}

Response: 200 OK

{
  "success": true,
  "message": "Order deleted successfully"
}

Payment Endpoints

Process Payment - Credit Card

POST /api/orders/{id}/payments
Authorization: Bearer {token}
Content-Type: application/json

{
  "payment_method": "credit_card",
  "card_number": "4111111111111111",
  "card_holder": "John Doe",
  "expiry_month": 12,
  "expiry_year": 2025,
  "cvv": "123"
}

Process Payment - PayPal

POST /api/orders/{id}/payments
Authorization: Bearer {token}
Content-Type: application/json

{
  "payment_method": "paypal",
  "paypal_email": "[email protected]"
}

Process Payment - Stripe

POST /api/orders/{id}/payments
Authorization: Bearer {token}
Content-Type: application/json

{
  "payment_method": "stripe",
  "stripe_token": "tok_visa"
}

Response: 201 Created

{
  "success": true,
  "message": "Payment processed successfully",
  "data": {
    "id": 1,
    "order_id": 1,
    "payment_gateway": "credit_card",
    "amount": 1059.97,
    "status": "successful",
    "transaction_id": "CC_1_abc123def",
    "payment_data": {
      "card_last_four": "1111",
      "amount": 1059.97,
      "request_timestamp": "2024-01-26T10:05:00Z"
    }
  }
}

Get Payments for Order

GET /api/orders/{id}/payments?per_page=15
Authorization: Bearer {token}

Response: 200 OK (Paginated collection)

List All Payments

GET /api/payments?status=successful&gateway=stripe&per_page=15
Authorization: Bearer {token}

Query Parameters:

  • status: Filter by status (pending, successful, failed)
  • gateway: Filter by gateway (credit_card, paypal, stripe)
  • per_page: Results per page (default: 15)

Response: 200 OK (Paginated collection)

Get Specific Payment

GET /api/payments/{id}
Authorization: Bearer {token}

Response: 200 OK

Adding a New Payment Gateway

The API uses the Strategy Pattern for payment gateways, making it easy to add new ones.

Step 1: Create Gateway Class

Create a new file in app/Services/PaymentGateways/YourGateway.php:

<?php

namespace App\Services\PaymentGateways;

use App\Contracts\PaymentGatewayInterface;
use App\Contracts\PaymentResult;
use App\Models\Order;
use App\Models\Payment;

class YourGateway implements PaymentGatewayInterface
{
    /**
     * Process a payment using your gateway.
     */
    public function processPayment(Order $order, array $paymentData): PaymentResult
    {
        // Validate payment data
        if (!$this->validateData($paymentData)) {
            return PaymentResult::failure('Invalid payment data');
        }

        // Process payment through your gateway
        $transactionId = 'YOUR_' . $order->id . '_' . uniqid();
        $success = true; // Simulate or make actual API call

        if ($success) {
            return PaymentResult::success(
                $transactionId,
                'Payment successful',
                ['gateway_response' => 'data']
            );
        }

        return PaymentResult::failure('Payment failed');
    }

    /**
     * Refund a payment.
     */
    public function refund(Payment $payment): bool
    {
        // Implement refund logic
        return true;
    }

    /**
     * Get the gateway name.
     */
    public function getGatewayName(): string
    {
        return 'your_gateway';
    }

    /**
     * Validate payment data.
     */
    private function validateData(array $data): bool
    {
        // Add your validation logic
        return true;
    }
}

Step 2: Register Gateway

Register your gateway in app/Services/PaymentService.php:

private array $gateways = [
    'credit_card' => CreditCardGateway::class,
    'paypal' => PayPalGateway::class,
    'stripe' => StripeGateway::class,
    'your_gateway' => YourGateway::class,  // Add this line
];

Or dynamically register it:

$paymentService->registerGateway('your_gateway', YourGateway::class);

Step 3: Update Validation (Optional)

Update app/Http/Requests/ProcessPaymentRequest.php to include validation for your gateway:

case 'your_gateway':
    $rules['your_gateway_field'] = ['required', 'string'];
    break;

Step 4: Test Your Gateway

Create tests for your gateway in tests/Unit/PaymentGatewayTest.php:

public function test_your_gateway_processes_payment(): void
{
    $gateway = new YourGateway();

    $result = $gateway->processPayment($this->order, [
        'your_gateway_field' => 'value',
    ]);

    $this->assertInstanceOf(PaymentResult::class, $result);
    $this->assertTrue($result->success || !$result->success);
}

Business Rules

  1. Payments can only be processed for confirmed orders - Orders must have status 'confirmed' before payment processing
  2. Orders cannot be deleted if they have payments - Safety mechanism to prevent data loss
  3. Order total is calculated automatically - Total is computed from items (quantity × price)
  4. All inputs are validated - Server-side validation on all API endpoints
  5. Meaningful error messages - Clear, actionable error responses
  6. Proper HTTP status codes - Industry-standard status codes used throughout

Running Tests

Run All Tests

php artisan test

Run Specific Test File

php artisan test tests/Feature/AuthenticationTest.php

Run with Coverage

php artisan test --coverage

Run Unit Tests Only

php artisan test tests/Unit

Run Feature Tests Only

php artisan test tests/Feature

Error Handling

The API provides comprehensive error handling with meaningful messages:

Validation Errors (422)

{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "email": ["Email is already registered"],
    "password": ["Password must be at least 8 characters"]
  }
}

Unauthorized (401)

{
  "success": false,
  "message": "Invalid credentials"
}

Forbidden (403)

{
  "success": false,
  "message": "Unauthorized"
}

Not Found (404)

{
  "success": false,
  "message": "Resource not found"
}

Server Error (500)

{
  "success": false,
  "message": "An error occurred",
  "error": "Error details"
}

Database Schema

Users Table

  • id - Primary key
  • name - User name
  • email - Unique email
  • password - Hashed password
  • timestamps - created_at, updated_at

Orders Table

  • id - Primary key
  • user_id - Foreign key to users
  • total_amount - Decimal(10,2)
  • status - Enum: pending, confirmed, cancelled
  • deleted_at - Soft delete
  • timestamps - created_at, updated_at

Order_Items Table

  • id - Primary key
  • order_id - Foreign key to orders
  • product_name - String
  • quantity - Integer
  • price - Decimal(10,2)
  • deleted_at - Soft delete
  • timestamps - created_at, updated_at

Payments Table

  • id - Primary key
  • order_id - Foreign key to orders
  • payment_gateway - String
  • amount - Decimal(10,2)
  • status - Enum: pending, successful, failed
  • transaction_id - Unique identifier
  • payment_data - JSON
  • deleted_at - Soft delete
  • timestamps - created_at, updated_at

Payment_Gateways Table

  • id - Primary key
  • name - Unique name
  • is_active - Boolean
  • config - JSON
  • deleted_at - Soft delete
  • timestamps - created_at, updated_at

Performance Optimization

  • Eager loading: Related data is loaded efficiently using load() and with()
  • Pagination: Large datasets are paginated (default 15 per page)
  • Database transactions: Multi-step operations use transactions for consistency
  • Indexes: Foreign keys and unique fields are indexed

Security Features

  • JWT Authentication: Secure token-based authentication
  • Password Hashing: Passwords hashed with bcrypt
  • Authorization: All protected routes check user ownership
  • Input Validation: All inputs validated before processing
  • SQL Injection Prevention: Using Eloquent ORM
  • CORS: Can be configured as needed

Environment Configuration

Key environment variables in .env:

APP_NAME="Order Payment API"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=api_gateway
DB_USERNAME=root
DB_PASSWORD=

JWT_SECRET=your-secret-key-here
JWT_ALGORITHM=HS256

STRIPE_API_KEY=sk_test_your_key
PAYPAL_CLIENT_ID=your_client_id
PAYPAL_CLIENT_SECRET=your_secret

Troubleshooting

"Token has expired"

  • Refresh your token using /api/refresh endpoint

"Unauthorized"

  • Ensure token is included in Authorization header as Bearer {token}

"Payment can only be processed for confirmed orders"

  • Update order status to 'confirmed' using PUT /api/orders/{id}

"Orders cannot be deleted if they have associated payments"

  • Only orders without payments can be deleted

Database Connection Error

  • Verify MySQL is running
  • Check database credentials in .env
  • Ensure database exists: CREATE DATABASE api_gateway;

Development Workflow

  1. Create a feature branch: git checkout -b feature/your-feature
  2. Make changes and commit: git commit -am 'Add new feature'
  3. Write tests for new features
  4. Run tests to ensure everything passes: php artisan test
  5. Push to repository: git push origin feature/your-feature
  6. Create a pull request

Contributing

  1. Follow PSR-12 coding standards
  2. Write tests for all new features
  3. Ensure all tests pass
  4. Update documentation as needed

License

This project is open source and available under the MIT license.

Support

For issues, questions, or suggestions, please open an issue in the repository.


Last Updated: January 26, 2024

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages