Satim Payment Gateway
STDIOMCP server for SATIM payment gateway integration in Algeria supporting CIB/Edhahabia card processing
MCP server for SATIM payment gateway integration in Algeria supporting CIB/Edhahabia card processing
A Model Context Protocol (MCP) server for integrating with the SATIM payment gateway system in Algeria. The server provides a structured interface for processing CIB/Edhahabia card payments through the SATIM-ePAY platform. This package enables AI assistants like Cursor, Claude, and Copilot to directly access your account data through a standardized interface.
More details : https://code2tutorial.com/tutorial/6b3a062c-3a34-4716-830e-8793a5378bcc/index.md
# Clone the repository git clone https://github.com/zakblacki/Satim-Payment-Gateway-Integration.git cd satim-payment-gateway-integration # Install dependencies npm install # Run the server npx tsx satim-mcp-server.ts or npm run dev # Demo Launch index.html
git clone https://github.com/zakblacki/Satim-Payment-Gateway-Integration.git cd satim-payment-gateway-integration
npm init -y
npm pkg set type=module
# Core dependencies npm install @modelcontextprotocol/sdk axios # Development dependencies npm install --save-dev typescript @types/node tsx
npx tsx satim-mcp-server.ts
# Compile TypeScript npm run build # Run compiled JavaScript npm start
npm run dev
To use this server with an MCP client (like Claude Desktop), add to your configuration:
{ "mcpServers": { "satim-payment": { "command": "npx", "args": ["@devqxi/satim-payment-gateway-mcp"], "env": { "SATIM_USERNAME": "your_test_username", "SATIM_PASSWORD": "your_test_password", "NODE_ENV": "development" } } } }
Before using any payment tools, configure your SATIM credentials:
// Configure credentials await mcp.callTool("configure_credentials", { userName: "your_merchant_username", password: "your_merchant_password" });
For production, consider using environment variables:
SATIM_USERNAME=your_merchant_username SATIM_PASSWORD=your_merchant_password SATIM_TERMINAL_ID=your_terminal_id SATIM_BASE_URL=https://test.satim.dz/payment/rest # or https://satim.dz/payment/rest for production
The complete payment process follows these steps:
const registrationResult = await mcp.callTool("register_order", { orderNumber: "ORDER_001_2024", amountInDA: 1500.50, // Amount in Algerian Dinars returnUrl: "https://yoursite.com/payment/success", failUrl: "https://yoursite.com/payment/failure", force_terminal_id: "E005005097", udf1: "merchant_ref_123", language: "FR" }); // Response includes orderId and formUrl // Redirect customer to formUrl for payment
const confirmResult = await mcp.callTool("confirm_order", { orderId: "received_order_id", language: "FR" }); // Validate the response const validation = await mcp.callTool("validate_payment_response", { response: confirmResult });
Based on validation results, display appropriate messages to customers.
Configure SATIM gateway credentials.
Parameters:
userName (string, required): Merchant loginpassword (string, required): Merchant passwordRegister a new payment order.
Parameters:
orderNumber (string, required): Unique order identifieramountInDA (number, required): Amount in Algerian Dinars (min: 50 DA)returnUrl (string, required): Success redirect URLfailUrl (string, optional): Failure redirect URLforce_terminal_id (string, required): Bank-assigned terminal IDudf1 (string, required): SATIM-specific parametercurrency (string, optional): Currency code (default: "012" for DZD)language (string, optional): Interface language ("AR", "FR", "EN")description (string, optional): Order descriptionudf2-udf5 (string, optional): Additional parametersResponse:
{ "orderId": "123456789AZERTYUIOPL", "formUrl": "https://test.satim.dz/payment/merchants/merchant1/payment_fr.html?mdOrder=123456789AZERTYUIOPL" }
Confirm order status after payment attempt.
Parameters:
orderId (string, required): Order ID from registrationlanguage (string, optional): Response languageResponse:
{ "orderNumber": "ORDER_001_2024", "actionCode": 0, "actionCodeDescription": "Votre paiement a été accepté", "amount": 150050, "errorCode": "0", "orderStatus": 2, "approvalCode": "303004", "params": { "respCode": "00", "respCode_desc": "Votre paiement a été accepté" } }
Process a refund for a completed order.
Parameters:
orderId (string, required): Order ID to refundamountInDA (number, required): Refund amount in DAcurrency (string, optional): Currency codelanguage (string, optional): Response languageResponse:
{ "errorCode": 0 }
Validate and interpret payment response.
Parameters:
response (object, required): Order confirmation responseResponse:
{ "status": "ACCEPTED", "displayMessage": "Votre paiement a été accepté", "shouldShowContactInfo": false, "contactNumber": "3020 3020" }
Create a simple test file test-simple.js:
import { spawn } from 'child_process'; // Start the MCP server const server = spawn('npx', ['tsx', 'satim-mcp-server.ts'], { stdio: ['pipe', 'pipe', 'inherit'] }); console.log('SATIM MCP Server started for testing'); // Let it run for a few seconds then exit setTimeout(() => { server.kill(); console.log('Test completed'); }, 5000);
Run with:
node test-simple.js
Create test-client.ts following the example in the documentation, then run:
npm run test
Use the HTTP wrapper example provided in the documentation to create REST API endpoints for easier testing with tools like Postman or curl.
"Cannot use import statement outside a module"
# Make sure package.json has "type": "module" npm pkg set type=module
"Module not found" errors
# Reinstall dependencies rm -rf node_modules package-lock.json npm install
TypeScript compilation errors
# Check tsconfig.json configuration # Make sure all dependencies are installed npm install --save-dev @types/node
Server connection issues
# Check if server is running ps aux | grep tsx # Check for port conflicts lsof -i :3000 # if using HTTP wrapper
Enable debug logging:
DEBUG=true npx tsx satim-mcp-server.ts
For accepted payments, show:
respCode_desc)orderId)orderNumber)approvalCode)Amounts must be multiplied by 100 when sent to SATIM:
The MCP server handles this conversion automatically.
| Error Code | Description | 
|---|---|
| 0 | Successfully confirmed | 
| 1 | Empty order ID | 
| 2 | Already confirmed | 
| 3 | Access denied | 
| 5 | Access denied | 
| 6 | Unknown order | 
| 7 | System error | 
| Error Code | Description | 
|---|---|
| 0 | No system error | 
| 5 | Password change required / Empty order ID | 
| 6 | Wrong order number | 
| 7 | Payment state error / Amount error / System error | 
// 1. Configure credentials await mcp.callTool("configure_credentials", { userName: "test_merchant", password: "test_password" }); // 2. Register order const order = await mcp.callTool("register_order", { orderNumber: `ORDER_${Date.now()}`, amountInDA: 250.75, returnUrl: "https://mystore.dz/payment/success", failUrl: "https://mystore.dz/payment/failure", force_terminal_id: "E005005097", udf1: "customer_ref_456", language: "FR", description: "Achat produit électronique" }); // 3. Redirect customer to order.formUrl // Customer completes payment and returns // 4. Confirm payment const confirmation = await mcp.callTool("confirm_order", { orderId: order.orderId, language: "FR" }); // 5. Validate response const validation = await mcp.callTool("validate_payment_response", { response: confirmation }); // 6. Handle result if (validation.status === "ACCEPTED") { // Process successful payment console.log("Payment successful:", validation.displayMessage); } else if (validation.status === "REJECTED") { // Handle rejection console.log("Payment rejected"); } else { // Handle error console.log("Payment error:", validation.displayMessage); }
// Full refund const refund = await mcp.callTool("refund_order", { orderId: "123456789AZERTYUIOPL", amountInDA: 250.75, // Full original amount language: "FR" }); // Partial refund const partialRefund = await mcp.callTool("refund_order", { orderId: "123456789AZERTYUIOPL", amountInDA: 100.00, // Partial amount language: "FR" });
# Production endpoints SATIM_BASE_URL=https://satim.dz/payment/rest # Development/Testing endpoints SATIM_BASE_URL=https://test.satim.dz/payment/rest
Implement health check endpoints to monitor gateway connectivity:
// Add to your server app.get('/health/satim', async (req, res) => { try { // Test connection to SATIM const response = await axios.get(`${SATIM_BASE_URL}/health`); res.json({ status: 'healthy', satim: 'connected' }); } catch (error) { res.status(503).json({ status: 'unhealthy', error: error.message }); } });
This MCP server implementation follows SATIM's official API specifications and includes all required integration points for Algerian e-commerce platforms.