A Laravel-based RESTful API for managing orders and payments with a focus on clean architecture, extensibility, and maintainability.
- Authentication System - JWT-based authentication
- Order Management - Full CRUD operations for orders with items
- Payment Processing - Multiple payment gateways with Strategy Pattern
- Modular Architecture - Self-contained modules for scalability
- Comprehensive Testing - Feature tests
- API Documentation - Complete API documentation with examples
- Requirements
- Installation
- Configuration
- Architecture
- Testing
- API Documentation
- Adding New Payment Gateway
- PHP 8.4+
- Composer
- MySQL 8.0+ / PostgreSQL / SQLite
- Laravel 12.x
git clone https://github.com/Shemaees/order-payment-api.git
cd order-payment-apicomposer installcp .env.example .env
php artisan key:generate
php artisan jwt:secretEdit .env file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=order_payment_api
DB_USERNAME=root
DB_PASSWORD=your_passwordphp artisan migrate --seedphp artisan serveAPI will be available at: http://localhost:8000
JWT_SECRET=your_generated_secret
JWT_TTL=60
JWT_REFRESH_TTL=20160Configure payment gateway credentials:
CREDIT_CARD_API_KEY=your_api_key
CREDIT_CARD_SECRET=your_secret
PAYPAL_CLIENT_ID=your_client_id
PAYPAL_SECRET=your_secretapp/Modules/
├── Auth/
│ ├── DTOs/
│ ├── Services/
│ ├── Http/
│ └── Routes/
├── Order/
│ ├── Database/
│ │ ├── Migrations/
│ │ ├── Factories/
│ │ └── Seeders/
│ ├── DTOs/
│ ├── Models/
│ ├── Repositories/
│ ├── Services/
│ ├── Http/
│ │ ├── Controllers/
│ │ ├── Requests/
│ │ └── Resources/
│ ├── Routes/
│ └── Providers/
└── Payment/
├── Database/
├── DTOs/
├── Models/
├── Repositories/
├── Services/
│ └── Gateways/
├── Http/
└── Routes/
- Repository Pattern - Data access abstraction
- Service Layer Pattern - Business logic separation
- Strategy Pattern - Payment gateway implementation
- DTO Pattern - Data transfer objects
- Factory Pattern - Payment gateway factory
All modules extend from base classes:
BaseDTO- Data Transfer Object baseBaseRepository- Repository base with common operationsBaseService- Service base with exception handling
php artisan test# Auth tests
php artisan test --filter=Auth
# Order tests
php artisan test --filter=Order
# Payment tests
php artisan test --filter=Paymentphp artisan test --coverageTests use MySQL database by default. Configure in phpunit.xml:
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_DATABASE" value="order_management_api"/>See API_DOCUMENTATION.md for complete API reference.
- Register User
POST /api/auth/register
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}- Login
POST /api/auth/login
{
"email": "john@example.com",
"password": "password123"
}- Create Order
POST /api/order
Authorization: Bearer {token}
{
"items": [
{
"product_id": 1,
"quantity": 2,
"price": 50.00
}
],
"billing_address": "123 Street",
"shipping_address": "456 Avenue"
}- Process Payment
POST /api/orders/{order_id}/payment
Authorization: Bearer {token}
{
"payment_method": "credit_card",
"amount": 100.00
}Create app/Modules/Payment/Services/Gateways/YourGateway.php:
<?php
namespace App\Modules\Payment\Services\Gateways;
use App\Modules\Payment\DTOs\ProcessPaymentDTO;
class YourGateway extends AbstractPaymentGateway
{
protected function getGatewayPrefix(): string
{
return 'YOUR';
}
public function process(ProcessPaymentDTO $dto): array
{
// Your payment processing logic
return [
'success' => true,
'payment_id' => $this->generatePaymentId(),
'payment_status' => PaymentStatusEnum::COMPLETED,
'transaction_details' => [
'gateway' => 'your_gateway',
'message' => 'Payment processed',
],
];
}
public function refund(string $transactionId, float $amount): array
{
// Your refund logic
}
public function getStatus(string $transactionId): string
{
// Your status check logic
}
}Edit app/Modules/Payment/Services/Gateways/PaymentGatewayFactory.php:
private const GATEWAYS = [
'credit_card' => CreditCardGateway::class,
'paypal' => PayPalGateway::class,
'stripe' => StripeGateway::class,
'your_gateway' => YourGateway::class, // Add this line
];Add to .env:
YOUR_GATEWAY_API_KEY=your_api_key
YOUR_GATEWAY_SECRET=your_secret$dto = new ProcessPaymentDTO(
order_id: 1,
payment_method: 'your_gateway',
amount: 100.00
);
$payment = $paymentService->processPayment($dto);That's it! No changes needed in controllers, services, or routes.
- JWT token authentication
- Password hashing with bcrypt
- Input validation on all requests
- SQL injection prevention via Eloquent ORM
- CSRF protection
- Rate limiting on API endpoints
- Order must have at least one item
- Order can only be deleted if no payments exist
- Order status transitions:
pending→completed✅pending→cancelled✅completed→cancelled✅completed→pending❌cancelled→ any ❌
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/orders/{order_id}/payment |
Process payment for order | Yes |
| GET | /api/payments/{id} |
Get payment details | Yes |
| GET | /api/payments/order/{order_id} |
Get order payments | Yes |
- Payments can only be processed for
completedorders - Supported payment methods:
credit_card,paypal,stripe - Payment amount must be greater than 0
- Each payment generates unique payment ID
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is open-sourced software licensed under the MIT license.
- Mahmoud Shemaees - Initial work - Shemaees