oussamamadjmaa / laravel-satim-payment
Laravel package for SATIM payment gateway integration
Package info
github.com/oussamamadjmaa/laravel-satim-payment
pkg:composer/oussamamadjmaa/laravel-satim-payment
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- mockery/mockery: ^1.5
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
README
A comprehensive Laravel package for integrating SATIM (Société d'Automatisation des Transactions Interbancaires et de Monétique) payment gateway for Algerian online payments.
Features
- ✅ Full SATIM payment gateway integration
- ✅ Order registration and payment processing
- ✅ Order confirmation and verification
- ✅ Refund processing
- ✅ Database models for payments and refunds tracking
- ✅ Comprehensive error handling
- ✅ Logging support
- ✅ Test card support for development
- ✅ Eloquent models with relationships
- ✅ Helper methods for amount conversion
- ✅ Sandbox and production environments
Requirements
- PHP 8.1 or higher
- Laravel 10.x or 11.x
- Guzzle HTTP client
Installation
Install the package via Composer:
composer require oussamamadjmaa/laravel-satim-payment
Publish Configuration
Publish the configuration file:
php artisan vendor:publish --tag=satim-config
Publish Migrations
Publish and run the migrations:
php artisan vendor:publish --tag=satim-migrations php artisan migrate
Configuration
Add the following environment variables to your .env file:
# SATIM Payment Gateway Configuration SATIM_USERNAME=your_merchant_username SATIM_PASSWORD=your_merchant_password SATIM_TERMINAL_ID=E0123456789 # Environment (sandbox or production) SATIM_ENVIRONMENT=sandbox # Currency (012 = DZD - Algerian Dinar) SATIM_CURRENCY=012 # Default Language (ar, fr, en) SATIM_LANGUAGE=en # Return URLs SATIM_RETURN_URL=https://yourdomain.com/payment/callback SATIM_FAIL_URL=https://yourdomain.com/payment/failed # Logging SATIM_LOGGING_ENABLED=true SATIM_LOGGING_CHANNEL=stack # HTTP Timeout (in seconds) SATIM_TIMEOUT=30
Usage
Basic Payment Flow
1. Register an Order
use OussamaMadjmaa\SatimPayment\Facades\SatimPayment; // Convert amount to centimes (multiply by 100) $amountInCentimes = SatimPayment::toCentimes(5000); // 5000 DZD $response = SatimPayment::registerOrder([ 'orderNumber' => 'ORDER-' . time(), 'amount' => $amountInCentimes, 'currency' => '012', // DZD 'returnUrl' => route('payment.callback'), 'failUrl' => route('payment.failed'), 'description' => 'Order payment', 'language' => 'en', 'udf1' => 'Invoice-12345', // Optional user-defined fields 'udf2' => 'Customer-001', ]); // Response contains: // - orderId: SATIM order ID // - formUrl: URL to redirect customer to payment page // - errorCode: 0 for success // Redirect customer to payment page return redirect()->away($response['formUrl']);
2. Handle Payment Callback
use OussamaMadjmaa\SatimPayment\Facades\SatimPayment; public function callback(Request $request) { $mdOrder = $request->query('mdOrder'); // Confirm the transaction $response = SatimPayment::confirmOrder($mdOrder); // Check payment status if ($response['OrderStatus'] == 2) { // Payment successful // Update your order status return view('payment.success', [ 'orderNumber' => $response['OrderNumber'], 'amount' => SatimPayment::fromCentimes($response['Amount']), 'pan' => $response['Pan'], // Masked card number ]); } else { // Payment failed return view('payment.failed', [ 'error' => $response['ErrorMessage'] ]); } }
3. Refund a Payment
use OussamaMadjmaa\SatimPayment\Facades\SatimPayment; $orderId = 'V721uPPfNNofVQAAABL3'; // SATIM order ID $amountToRefund = SatimPayment::toCentimes(1000); // 1000 DZD $response = SatimPayment::refundOrder($orderId, $amountToRefund); if ($response['errorCode'] === 0) { // Refund successful }
Using Models
The package provides Eloquent models for tracking payments and refunds:
use OussamaMadjmaa\SatimPayment\Models\Payment; use OussamaMadjmaa\SatimPayment\Models\Refund; // Create a payment record $payment = Payment::create([ 'order_number' => 'ORDER-123', 'order_id' => 'SATIM_ORDER_ID', 'amount' => 500000, // in centimes 'currency' => '012', 'status' => 0, ]); // Check payment status if ($payment->isSuccessful()) { // Payment is successful } if ($payment->isPending()) { // Payment is pending } // Get amount in DZD $amountInDzd = $payment->getAmountInDzd(); // 5000.00 // Query payments $successfulPayments = Payment::successful()->get(); $pendingPayments = Payment::pending()->get(); // Create a refund $refund = $payment->refunds()->create([ 'order_id' => $payment->order_id, 'amount' => 100000, 'status' => 'completed', ]);
Helper Methods
use OussamaMadjmaa\SatimPayment\Facades\SatimPayment; // Convert amounts $centimes = SatimPayment::toCentimes(5000); // 500000 $dzd = SatimPayment::fromCentimes(500000); // 5000.0 // Check status $isSuccess = SatimPayment::isSuccessfulStatus(2); // true $description = SatimPayment::getStatusDescription(2); // "Amount deposited successfully"
Order Status Codes
| Code | Description |
|---|---|
| 0 | Order registered, but not paid |
| -1 | Transaction declined or unsuitable status |
| 1 | Transaction approved (one-phase payment) |
| 2 | Amount deposited successfully (two-phase payment) |
| 3 | Authorization reversed |
| 4 | Transaction refunded |
| 6 | Authorization declined |
| 7 | Card added |
| 8 | Card updated |
| 9 | Card verified |
| 10 | Recurring template added |
| 11 | Debited |
Error Codes
| Code | Message |
|---|---|
| 0 | No system error |
| 1 | Order already processed or invalid childId |
| 3 | Unknown currency |
| 4 | Required parameter not specified |
| 5 | Incorrect parameter value or access denied |
| 7 | System error |
| 14 | Payment method invalid |
Testing
Test Cards (Sandbox Environment)
The package includes support for SATIM test cards:
| Card Number | Exp Date | CVV2 | PIN | Status |
|---|---|---|---|---|
| 6280581110007215 | 01/2027 | 373 | 123456 | Valid card |
| 6280581110006712 | 01/2027 | 897 | 123456 | Temporarily blocked |
| 6280581110006316 | 01/2027 | 657 | 123456 | Lost |
| 6280581110006415 | 01/2027 | 958 | 123456 | Stolen |
| 6280580610061219 | 01/2027 | 049 | 123456 | Card limit exceeded |
| 6280580610061110 | 01/2027 | 260 | 123456 | Insufficient balance |
Running Tests
# Run all tests composer test # Run specific test suite ./vendor/bin/phpunit tests/Unit ./vendor/bin/phpunit tests/Feature
Development Credentials
SATIM_USERNAME=your_test_username SATIM_PASSWORD=your_test_password SATIM_TERMINAL_ID=E0123456789 SATIM_ENVIRONMENT=sandbox
Example Implementation
See the examples directory for a complete implementation including:
- Controller with all payment methods
- Routes configuration
- View examples
- Complete payment flow
# Copy example controller cp vendor/oussamamadjmaa/laravel-satim-payment/examples/Controllers/PaymentController.php app/Http/Controllers/ # Copy example routes # Add routes from vendor/oussamamadjmaa/laravel-satim-payment/examples/routes.php to your routes/web.php
API Endpoints
The package interacts with these SATIM endpoints:
Sandbox (Test)
- Base URL:
https://test2.satim.dz/payment/rest
Production
- Base URL:
https://satim.dz/payment/rest
Available Endpoints
- Register Order:
/register.do - Confirm Order:
/public/acknowledgeTransaction.do - Refund Order:
/refund.do
Important Notes
Amount Handling
- All amounts must be in centimes (multiply by 100)
- Minimum amount is 50 DZD (5000 centimes)
- Example: 5000 DZD = 500000 centimes
// Correct $amount = 500000; // 5000 DZD // Wrong $amount = 5000; // This would be 50 DZD
Currency Code
Always use ISO 4217 currency codes:
012= DZD (Algerian Dinar)
Language
Supported languages:
en= Englishfr= Frenchar= Arabic
Terminal ID Format
Terminal ID must match the format: E followed by digits (e.g., E0123456789)
Security Considerations
- Never expose credentials: Keep your SATIM credentials secure and never commit them to version control
- Use HTTPS: Always use HTTPS in production for return URLs
- Validate callbacks: Always verify payment status by calling
confirmOrder()instead of trusting URL parameters - Log everything: Enable logging to track all transactions for debugging and audit purposes
Troubleshooting
Common Issues
Error: "Invalid amount"
- Ensure amount is at least 5000 centimes (50 DZD)
- Verify you're multiplying by 100 to convert to centimes
Error: "Access denied"
- Check your credentials in
.env - Verify your merchant account is active
- Ensure terminal ID is correct
Error: "Return URL cannot be empty"
- Set
SATIM_RETURN_URLin.envor pass it in parameters
Payment not confirmed
- Always call
confirmOrder()in your callback handler - Don't rely solely on URL parameters
Support
For issues, questions, or contributions:
- GitHub Issues: laravel-satim-payment
- Email: oussama@madjmaa.com
- SATIM Support: Contact SATIM for merchant account issues
License
This package is open-sourced software licensed under the MIT license.
Credits
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Testing
composer test
Security
If you discover any security-related issues, please email oussama@madjmaa.com instead of using the issue tracker.
Acknowledgments
- SATIM for the payment gateway
- Laravel community