eTanah API Integration#
Update Summary#
Changes Made
- Fixed EPS transaction ID search bug in requery functionality
- Corrected database query condition from 'transaksi_id' to 'transaksi id' for proper transaction lookup
- Enhanced transaction reconciliation with improved EPS database connection logic
- Updated troubleshooting guide with EPS database connection failure resolution
Table of Contents#
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Enhanced Callback Integration
- Improved Email Receipt Generation
- Simplified Callback Job Implementation
- Updated Configuration Requirements
- Multi-Property Payment Support
- Enhanced Error Handling and Logging
- Bug Fix: EPS Transaction ID Search
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
Introduction#
This document provides comprehensive documentation for the eTanah API integration with MelakaPay. It covers the complete API specification for authentication via Bearer tokens, payment request endpoints, transaction status checking, and receipt generation. The integration supports three primary endpoints: connectivity check (GET /etanah/check), payment request (POST /etanah/request), and payment response callback (POST /etanah/response). It also documents the branch code system, payment item structure, data validation requirements, practical curl examples, error handling responses, and integration workflows from payment initiation through FPX processing to receipt generation and email delivery.
Updated Enhanced callback integration now includes comprehensive e-Tanah payment callback functionality with multi-property support, improved email receipt generation with built-in receipt data consistency, simplified callback job implementation with centralized configuration management, and updated configuration requirements with default values. Additionally, fixed critical EPS transaction ID search bug that was preventing proper transaction lookup and reconciliation.
Project Structure#
The eTanah integration spans several key areas:
- API controllers handling connectivity checks, payment requests, callbacks, receipts, and requery functionality
- Payment controllers and requests for initiating FPX payments
- Configuration for eTanah service, keys, URLs, and callback settings
- Route definitions for API endpoints
- Documentation and Postman collections for API usage
- Models representing transactions and receipts
- EPS database connection for transaction reconciliation
- New Enhanced callback functionality with dedicated job implementation
- New Centralized configuration management with environment variables
- New Fixed EPS transaction ID search functionality for proper transaction lookup
graph TB
subgraph "API Layer"
A["EtanahAPIController<br/>Connectivity, Request, Response, Receipt, Requery<br/>Enhanced with sendEtanahPaymentCallback<br/>Fixed EPS Transaction Lookup"]
B["EtanahController<br/>FPX Payment Initiation"]
end
subgraph "Configuration"
C["config/etanah.php<br/>Service, Keys, URLs, Callback Settings<br/>Enhanced with callback_job configuration"]
D["config/database.php<br/>EPS Database Connection"]
end
subgraph "Routing"
E["routes/web.php<br/>Web Endpoint Definitions"]
F["routes/api.php<br/>API Endpoint Definitions"]
end
subgraph "Models"
G["Transaction<br/>transaction_details"]
H["Receipt<br/>receipts"]
end
subgraph "Documentation"
I["docs/etanah-api.md<br/>API Specification"]
J["docs/etanah-api.postman_collection.json<br/>Postman Collection"]
K["docs/etanah-callback-integration.md<br/>Enhanced Callback Documentation"]
L["docs/etanah-config-update.md<br/>Configuration Update Guide"]
end
subgraph "Views"
M["receipt.blade.php<br/>Enhanced Payment Details Display"]
end
subgraph "Jobs"
N["PostEtanahCallback<br/>Dedicated Queue Job for e-Tanah Callbacks"]
end
A --> C
B --> C
A --> D
E --> A
F --> A
A --> G
A --> H
I --> A
J --> A
K --> A
L --> C
A --> M
A --> N
N --> C
Diagram sources
- EtanahAPIController.php:1-1189
- EtanahController.php:1-108
- etanah.php:1-22
- database.php:39-57
- web.php:220-231
- Transaction.php:1-69
- Receipt.php:1-11
- etanah-api.md:1-372
- etanah-api.postman_collection.json:1-329
- etanah-callback-integration.md:1-255
- etanah-config-update.md:1-231
- receipt.blade.php:1-153
- PostEtanahCallback.php:1-136
Section sources
- EtanahAPIController.php:1-1189
- EtanahController.php:1-108
- etanah.php:1-22
- database.php:39-57
- web.php:220-231
- Transaction.php:1-69
- Receipt.php:1-11
- etanah-api.md:1-372
- etanah-api.postman_collection.json:1-329
- etanah-callback-integration.md:1-255
- etanah-config-update.md:1-231
- receipt.blade.php:1-153
- PostEtanahCallback.php:1-136
Core Components#
This section outlines the core components involved in the eTanah API integration:
- EtanahAPIController: Handles connectivity checks, payment requests, response callbacks, receipt rendering, requery functionality, and PDF downloads
- EtanahController: Manages FPX payment initiation, checksum calculation, and redirection to the payment gateway
- EtanahPaymentRequest: Validates payment initiation requests with conditional rules for FPX modes
- Configuration: etanah.php defines service name, agency, base URLs, callback, redirect, and shared key with enhanced callback job configuration
- Models: Transaction and Receipt models represent persisted payment and receipt data
- Routes: Web and API endpoints for check, request, response, receipt, requery, and related operations
- EPS Database: Provides transaction reconciliation and status updates with enhanced connection logic
- New Enhanced callback functionality: sendEtanahPaymentCallback method for e-Tanah payment updates
- New Dedicated callback job: PostEtanahCallback for asynchronous e-Tanah communication
- New Centralized configuration: Enhanced config/etanah.php with callback_job settings
- New Fixed EPS transaction lookup: Corrected database query condition for proper transaction reconciliation
Key responsibilities:
- Authentication: All endpoints require a Bearer token validated against the configured key
- Payment request: Validates branch code, transaction ID, total amount, return URL, payment items, and optional extra details
- Response callback: Updates transaction status, generates receipts, sends email notifications, and dispatches e-Tanah callbacks
- Receipt generation: Renders HTML receipts and PDF downloads with enhanced error handling
- Requery: Queries EPIC for transaction status updates with improved database connection logic and fixed transaction lookup
- New Enhanced callback: Asynchronous communication with e-Tanah system for payment status updates
- New Multi-property support: Individual callback dispatch for each payment item in multi-property transactions
- New Configuration management: Centralized callback job configuration with environment variable support
- New Fixed transaction reconciliation: Proper EPS database transaction ID search and lookup
Section sources
- EtanahAPIController.php:65-93
- EtanahAPIController.php:95-226
- EtanahAPIController.php:234-488
- EtanahAPIController.php:490-588
- EtanahAPIController.php:596-659
- EtanahAPIController.php:687-743
- EtanahAPIController.php:847-873
- EtanahAPIController.php:901-980
- EtanahController.php:14-108
- EtanahPaymentRequest.php:11-105
- etanah.php:1-22
- PostEtanahCallback.php:1-136
Architecture Overview#
The eTanah integration follows a clear request-response flow with enhanced validation, error handling, and callback functionality:
- eTanah system initiates payment via POST /etanah/request with Bearer token and payment payload including mandatory return_url
- MelakaPay validates the request with enhanced parameter validation, creates a transaction, and renders a payment page for FPX selection
- After FPX completion, MelakaPay processes the response, updates transaction status, generates receipts with improved error handling, and optionally emails them
- New Enhanced callback functionality: Asynchronously dispatches e-Tanah payment updates for each payment item
- Users can view receipts via GET /etanah/receipt/{transaction_id} or download PDFs via GET /etanah/download/{transaction_id}
- Administrators can requery transactions via GET /etanah/requery/{transaksi_id} with strengthened EPS database connection logic and fixed transaction lookup
- New Enhanced data parsing ensures consistent payment information handling regardless of data format variations
sequenceDiagram
participant ET as "eTanah System"
participant MP as "MelakaPay API"
participant GW as "FPX Payment Gateway"
participant DB as "Database"
participant EPS as "EPS Database<br/>Fixed Transaction Lookup"
participant JOB as "PostEtanahCallback Job"
participant ET2 as "e-Tanah API"
ET->>MP : POST /etanah/request (Bearer token + payload + return_url)
MP->>DB : Insert transaction and details
MP-->>ET : Redirect to payment page
ET->>GW : Select bank and complete FPX
GW-->>MP : POST /etanah/response (status + metadata)
MP->>DB : Update transaction status and receipts
MP->>EPS : Query EPIC for status reconciliation<br/>Fixed : Correct EPS transaction lookup
MP->>JOB : Dispatch e-Tanah callback job(s) for each payment item
JOB->>ET2 : POST /etanah-integration/mvc/mpay/kemaskini-akaun-pengguna (Access-Token)
ET2-->>JOB : Return payment status update
JOB-->>MP : Log successful callback
MP->>MP : Enhanced data parsing and receipt generation
MP-->>ET : Redirect to receipt page
ET->>MP : GET /etanah/receipt/{transaction_id}
MP-->>ET : Render receipt HTML with enhanced error handling
ET->>MP : GET /etanah/download/{transaction_id}
MP-->>ET : Stream PDF receipt with improved validation
Diagram sources
- EtanahAPIController.php:95-226
- EtanahAPIController.php:234-488
- EtanahAPIController.php:490-588
- EtanahAPIController.php:687-743
- EtanahAPIController.php:847-873
- EtanahAPIController.php:901-980
- PostEtanahCallback.php:1-136
Detailed Component Analysis#
Authentication and Connectivity Check#
- Endpoint: GET /etanah/check
- Authentication: Bearer token required; validated against config key
- Success response includes service name, timestamp, and environment
- Unauthorized response returned if token is missing or invalid
sequenceDiagram
participant Client as "Client"
participant API as "EtanahAPIController"
participant CFG as "config/etanah.php"
Client->>API : GET /etanah/check (Authorization : Bearer <key>)
API->>CFG : Retrieve expected key
API-->>Client : 200 OK with service info or 401 Unauthorized
Diagram sources
Section sources
Enhanced Payment Request Endpoint#
- Endpoint: POST /etanah/request
- Authentication: Bearer token required
- Request body validation includes:
- kod_cawangan (branch code)
- transaksi_id (unique transaction ID)
- jumlah_bayaran (total amount)
- return_url (Mandatory URL for payment completion redirection)
- maklumat_bayaran (array of payment items up to 20)
- Optional extra fields: email, IC number, name, address, postcode, city, state
- Payment item structure:
- id_hakmilik (optional for land title payments)
- urusan (required payment purpose)
- jumlah_bayaran (required amount per item)
- Branch code mapping determines merchant code and agency name
- On success, renders a payment page for FPX selection with enhanced validation
Updated Added mandatory return_url validation with URL format checking and improved error messages for malformed URLs.
flowchart TD
Start(["POST /etanah/request"]) --> Auth["Validate Bearer Token"]
Auth --> ValidToken{"Token Valid?"}
ValidToken --> |No| Err401["Return 401 Unauthorized"]
ValidToken --> |Yes| Validate["Validate Request Body with Enhanced Validation"]
Validate --> ValidReq{"Valid?"}
ValidReq --> |No| Err400["Return 400 Bad Request with enhanced error details"]
ValidReq --> |Yes| ReturnUrl["Validate Return URL Format"]
ReturnUrl --> ValidUrl{"URL Valid?"}
ValidUrl --> |No| Err400Url["Return 400 with URL validation error"]
ValidUrl --> |Yes| BranchMap["Map kod_cawangan to merchant code and agency"]
BranchMap --> CreateTxn["Create transaction and details"]
CreateTxn --> Render["Render payment page with FPX options"]
Diagram sources
Section sources
Enhanced Payment Response Callback#
- Endpoint: POST /etanah/response (internal callback)
- Receives FPX status and metadata, updates transaction status, and generates receipts with enhanced error handling
- New Enhanced callback functionality: Automatically dispatches e-Tanah payment updates for successful payments
- Payment modes mapped to descriptive names and charges
- Status codes:
- 0: Failed
- 1: Successful
- 2: Cancelled
- 3: Pending (Corporate FPX authorization)
- On successful payment, dispatches email job with receipt PDF and stores receipt data with improved validation
- New Multi-property support: Individual callback dispatch for each payment item in maklumat_bayaran array
- New Enhanced data parsing ensures consistent payment information handling from various sources
Updated Enhanced error handling for transaction receipts with better validation and fallback mechanisms.
sequenceDiagram
participant GW as "FPX Gateway"
participant API as "EtanahAPIController"
participant DB as "Database"
participant EPS as "EPS Database"
participant JOB as "PostEtanahCallback Job"
participant ET2 as "e-Tanah API"
GW->>API : POST /etanah/response (status + metadata)
API->>DB : Update transaction status and receipts with validation
API->>EPS : Query EPIC for status reconciliation
API->>API : Enhanced data parsing and receipt generation
API->>JOB : Dispatch e-Tanah callback job(s) for each payment item
Job->>ET2 : POST /etanah-integration/mvc/mpay/kemaskini-akaun-pengguna (Access-Token)
ET2-->>JOB : Return payment status update
JOB-->>API : Log successful callback
API->>API : Enhanced data parsing and receipt generation
API-->>GW : Redirect to receipt page with enhanced error handling
Diagram sources
- EtanahAPIController.php:234-488
- EtanahAPIController.php:490-588
- EtanahAPIController.php:847-873
- EtanahAPIController.php:901-980
- PostEtanahCallback.php:1-136
Section sources
- EtanahAPIController.php:234-488
- EtanahAPIController.php:490-588
- EtanahAPIController.php:847-873
- EtanahAPIController.php:901-980
- etanah-api.md:232-256
Receipt Generation and Viewing#
- Endpoint: GET /etanah/receipt/{transaction_id}
- Retrieves transaction details and FPX information, aggregates e-Tanah details, and renders an HTML receipt with enhanced error handling
- Includes payment details, FPX transaction info, and download links for PDF receipts
- GET /etanah/download/{transaction_id} streams PDF using ReceiptPdfService with improved validation
- New Enhanced data parsing ensures consistent payment information display regardless of data format
Updated Enhanced error handling for receipt generation with better validation of transaction details and EPS database queries.
flowchart TD
Req(["GET /etanah/receipt/{id}"]) --> FindTxn["Find Transaction by ID with validation"]
FindTxn --> Found{"Transaction Found?"}
Found --> |No| Err["Return enhanced error response"]
Found --> |Yes| LoadDetails["Load FPX and e-Tanah details with EPS validation"]
LoadDetails --> ValidateReceipt["Validate receipt data and payload"]
ValidateReceipt --> ParseData["Enhanced data parsing for consistent display"]
ParseData --> Render["Render receipt HTML with enhanced error handling"]
Diagram sources
- EtanahAPIController.php:490-588
- EtanahAPIController.php:687-743
- EtanahAPIController.php:847-873
- EtanahAPIController.php:852-878
Section sources
- EtanahAPIController.php:490-588
- EtanahAPIController.php:687-743
- EtanahAPIController.php:847-873
- EtanahAPIController.php:852-878
- etanah-api.md:258-284
Transaction Requery#
- Endpoint: GET /etanah/requery/{transaksi_id}
- Queries EPIC using the e-Tanah transaction ID to fetch status and metadata with strengthened database connection logic
- Updated Fixed EPS transaction ID search bug: Corrected database query condition from 'transaksi_id' to 'transaksi id' for proper transaction lookup
- Updates local transaction records and returns JSON response
- Supports administrative requery when callback was not received or status is pending
- Enhanced error handling for EPS database connection failures
- New Enhanced data parsing ensures consistent payment information handling during requery operations
Updated Strengthened EPS database connection logic with improved fallback mechanisms and better error reporting. Fixed critical bug in transaction ID search that was preventing proper EPS database reconciliation.
sequenceDiagram
participant Admin as "Administrator"
participant API as "EtanahAPIController"
participant EPS as "EPIC System with Enhanced Connection<br/>Fixed Transaction Lookup"
participant DB as "Database"
Admin->>API : GET /etanah/requery/{transaksi_id}
API->>EPS : Query transaction by e-Tanah ID with enhanced connection<br/>Fixed : Correct EPS transaction lookup
EPS-->>API : Return transaction data or connection error
API->>DB : Update transaction status and receipts
API->>API : Enhanced data parsing for consistent handling
API-->>Admin : JSON response with data and status or enhanced error
Diagram sources
Section sources
- EtanahAPIController.php:596-659
- EtanahAPIController.php:847-873
- EtanahAPIController.php:852-878
- etanah-api.md:286-329
Branch Code System#
- kod_cawangan maps to merchant codes and agency names:
- 00 → ptgnm-app (Pejabat Tanah dan Galian Negeri Melaka)
- 01 → pdtmt-app (Pejabat Tanah Daerah Melaka Tengah)
- 02 → pdtj-app (Pejabat Tanah Daerah Jasin)
- 03 → pdtag-app (Pejabat Tanah Daerah Alor Gajah)
Section sources
Payment Item Structure and Validation#
- Payment items support two scenarios:
- Land title tax payments: include id_hakmilik and urusan
- Service payments: include urusan only
- Maximum 20 payment items per request
- Enhanced validation ensures required fields and proper types for amounts and addresses
- Updated Return URL validation ensures proper URL format and prevents injection attacks
- New Enhanced data parsing handles inconsistent payment information formats
Section sources
Practical Curl Examples#
- Connectivity check:bash
curl -X GET https://<MELAKAPAY_DOMAIN>/etanah/check \ -H "Authorization: Bearer <ETANAH_KEY>" - Single land title tax payment with return_url:bash
curl -X POST https://<MELAKAPAY_DOMAIN>/etanah/request \ -H "Authorization: Bearer <ETANAH_KEY>" \ -H "Content-Type: application/json" \ -d '{ "kod_cawangan": "01", "transaksi_id": "2602270000000001", "jumlah_bayaran": 50.00, "return_url": "https://appmlkstg.melaka.gov.my/etanah/response", "maklumat_bayaran": [ { "id_hakmilik": "040210GRN00011524", "urusan": "Cukai Tanah", "jumlah_bayaran": 50.00 } ], "extra": { "email": "pembayar@example.com", "ic_no": "901234567890", "name": "Ahmad bin Ali" } }' - Multiple land titles tax payment with return_url:bash
curl -X POST https://<MELAKAPAY_DOMAIN>/etanah/request \ -H "Authorization: Bearer <ETANAH_KEY>" \ -H "Content-Type: application/json" \ -d '{ "kod_cawangan": "01", "transaksi_id": "2602270000000002", "jumlah_bayaran": 150.00, "return_url": "https://appmlkstg.melaka.gov.my/etanah/response", "maklumat_bayaran": [ { "id_hakmilik": "040101PN00018121", "urusan": "Cukai Tanah", "jumlah_bayaran": 50.00 }, { "id_hakmilik": "040101PM00000082", "urusan": "Cukai Tanah", "jumlah_bayaran": 100.00 } ], "extra": { "email": "pembayar@example.com", "name": "Ahmad bin Ali" } }' - Single urusan payment with return_url:bash
curl -X POST https://<MELAKAPAY_DOMAIN>/etanah/request \ -H "Authorization: Bearer <ETANAH_KEY>" \ -H "Content-Type: application/json" \ -d '{ "kod_cawangan": "01", "transaksi_id": "2602270000000003", "jumlah_bayaran": 50.00, "return_url": "https://appmlkstg.melaka.gov.my/etanah/response", "maklumat_bayaran": [ { "urusan": "Kebenaran Gadaian", "jumlah_bayaran": 50.00 } ], "extra": { "email": "pembayar@example.com", "name": "Ahmad bin Ali" } }' - Multiple urusan payments with return_url:bash
curl -X POST https://<MELAKAPAY_DOMAIN>/etanah/request \ -H "Authorization: Bearer <ETANAH_KEY>" \ -H "Content-Type: application/json" \ -d '{ "kod_cawangan": "01", "transaksi_id": "2602270000000004", "jumlah_bayaran": 150.00, "return_url": "https://appmlkstg.melaka.gov.my/etanah/response", "maklumat_bayaran": [ { "urusan": "Kebenaran Gadaian", "jumlah_bayaran": 50.00 }, { "urusan": "Permohonan Pecah Bahagi", "jumlah_bayaran": 100.00 } ], "extra": { "email": "pembayar@example.com", "name": "Ahmad bin Ali" } }'
Section sources
Error Handling Responses#
- 401 Unauthorized: Invalid or missing Bearer token
- 400 Bad Request: Enhanced validation errors for payment requests including return_url format errors
- 404 Not Found: Agency not found during response processing
- Administrative requery errors: Transaction not found, no record in EPIC, no response from gateway
- Updated Enhanced error messages for malformed return URLs and improved validation error reporting
- New Enhanced error handling for data parsing inconsistencies
- New Callback job error handling with retry mechanisms and comprehensive logging
- New Fixed EPS database connection failures: Proper transaction lookup and reconciliation
Section sources
- EtanahAPIController.php:77-82
- EtanahAPIController.php:157-159
- EtanahAPIController.php:269-275
- etanah-api.md:223-229
- etanah-api.md:321-328
Enhanced Callback Integration#
New The eTanah API integration now includes comprehensive callback functionality that enables asynchronous communication with the e-Tanah system for payment status updates.
sendEtanahPaymentCallback Method#
The sendEtanahPaymentCallback method serves as the main entry point for e-Tanah payment updates:
- Trigger Condition: Only executes for successful payments (
$status == '1') - Multi-Property Support: Processes each item in the
maklumat_bayaranarray individually - Payload Formatting: Constructs e-Tanah compliant JSON payload according to updateUserAccount specification
- Asynchronous Processing: Dispatches
PostEtanahCallbackjob for each payment item - Enhanced Logging: Comprehensive logging for debugging and monitoring
Callback Payload Structure#
The callback payload follows the e-Tanah Integration Specification v1.1:
{
"accountNo": "403011000053073",
"idHakmilik": "040301GM00000009",
"kodCaw": "03",
"resitNo": "TXN-20260201-401",
"amaun": "180.00",
"paymentDateTime": "20260201114301",
"paymentType": "CABAMPAY",
"fpxNo": "2602011143010001",
"transId": "MPAY260201-AG001",
"dimasuk": "MELAKA PAY"
}
Payment Type Mapping#
The integration maps MelakaPay payment types to e-Tanah codes:
fpx/fpx1→CABAMPAY(FPX Individual/Corporate)cc→CABAMCC(Credit Card)dnqr→CABAMQR(DuitNow QR)dc→CABAMDC(Debit Card)wallet→CABAMPAY(Wallet)
Multi-Property Payment Support#
Single transactions can contain multiple properties, each requiring individual callback dispatch:
- Example: User pays RM180 for 2 properties (RM100 + RM80)
- Callback 1: Property A - RM100
- Callback 2: Property B - RM80
Section sources
Improved Email Receipt Generation#
New The email receipt generation system now includes built-in receipt data consistency and enhanced error handling.
Receipt Data Consistency#
- Database-Driven Generation: Receipt data is built from database records for consistent formatting
- Same Format Logic: Uses the same receipt building logic as the PDF download functionality
- Enhanced Validation: Improved validation of receipt data before email dispatch
- Fallback Mechanisms: Graceful handling when database records are not yet available
Email Dispatch Enhancement#
- Automatic Trigger: Emails are dispatched automatically for successful payments when email is provided
- Consistent Formatting: Uses the same receipt templates as PDF generation
- Error Logging: Comprehensive logging for email dispatch failures
- Queue Integration: Asynchronous email processing via Laravel queues
Section sources
Simplified Callback Job Implementation#
New The callback job implementation has been significantly simplified with centralized configuration management and improved error handling.
PostEtanahCallback Job Features#
- Dedicated Job Class: Separate job class for e-Tanah callback operations
- Centralized Configuration: All callback settings managed through config/etanah.php
- Environment Variable Support: Full environment variable integration for deployment flexibility
- Retry Mechanism: Built-in retry logic with configurable parameters
- Comprehensive Logging: Detailed logging for debugging and monitoring
Configuration Management#
The callback job now uses centralized configuration:
'callback_job' => [
'connect_timeout' => (int) env('ETANAH_POST_CONNECT_TIMEOUT', 10),
'timeout' => (int) env('ETANAH_POST_TIMEOUT', 30),
'retry_times' => (int) env('ETANAH_POST_RETRY_TIMES', 3),
'retry_sleep_ms' => (int) env('ETANAH_POST_RETRY_SLEEP_MS', 500),
],
Enhanced Error Handling#
- Connection Exception Handling: Automatic retry only for connection-related failures
- Detailed Error Logging: Comprehensive error logging with stack traces
- Response Validation: Proper handling of non-success HTTP responses
- Fallback Strategies: Graceful degradation when e-Tanah API is unavailable
Section sources
Updated Configuration Requirements#
New The configuration system has been updated with enhanced settings and default values for improved deployment flexibility.
Enhanced etanah.php Configuration#
The configuration file now includes comprehensive settings:
return [
// Basic Configuration
'service' => env('ETANAH_SERVICE', 'e-Tanah 2.0'),
'agensi' => env('ETANAH_AGENSI', 'Pejabat Tanah dan Galian Negeri Melaka'),
// URL Configuration
'url' => [
'base' => env('ETANAH_BASE_URL', 'https://appmlkstg.melaka.gov.my'),
'callback' => env('ETANAH_CALLBACK_URL', '/etanah-integration/mvc/mpay/kemaskini-akaun-pengguna'),
],
// Authentication
'key' => env('ETANAH_KEY', 'Xz0zmR9iUAjEjlrkb5tubfCxgFMdCrm0kWWa'),
// Callback Job Settings
'callback_job' => [
'connect_timeout' => 10, // seconds
'timeout' => 30, // seconds
'retry_times' => 3, // attempts
'retry_sleep_ms' => 500, // milliseconds
],
// Network Optimization
'internal_base_url' => 'https://192.168.2.28',
];
Environment Variables Required#
Complete set of environment variables for deployment:
# e-Tanah API Configuration
ETANAH_SERVICE=e-Tanah 2.0
ETANAH_AGENSI=Pejabat Tanah dan Galian Negeri Melaka
ETANAH_BASE_URL=https://appmlkstg.melaka.gov.my
ETANAH_CALLBACK_URL=/etanah-integration/mvc/mpay/kemaskini-akaun-pengguna
ETANAH_REDIRECT_URL=https://appmlkstg.melaka.gov.my/etanah/response
ETANAH_KEY=Xz0zmR9iUAjEjlrkb5tubfCxgFMdCrm0kWWa
# Callback Job Configuration
ETANAH_POST_CONNECT_TIMEOUT=10
ETANAH_POST_TIMEOUT=30
ETANAH_POST_RETRY_TIMES=3
ETANAH_POST_RETRY_SLEEP_MS=500
# Internal Network Optimization
MELAKAPAY_INTERNAL_BASE_URL=https://192.168.2.28
Configuration Caching Support#
The new configuration system supports Laravel's configuration caching:
- config:cache Compatible: All environment variables are resolved at runtime
- Type Casting: Proper type casting at configuration level
- Default Values: Sensible defaults ensure backward compatibility
- Deployment Ready: Production deployment checklist included
Section sources
Multi-Property Payment Support#
New The integration now supports multi-property payments with individual callback dispatch for each payment item.
Payment Item Processing#
Each payment item in the maklumat_bayaran array is processed independently:
- Individual Callbacks: Each property receives its own e-Tanah callback
- Separate Payloads: Each callback contains property-specific payment details
- Independent Processing: Failures in one property don't affect others
- Consistent Logging: Each callback operation is logged separately
Example Multi-Property Scenario#
User pays RM180 for 2 properties:
- Property A: RM100 (id_hakmilik: 040101PN00018121)
- Property B: RM80 (id_hakmilik: 040101PM00000082)
Callback 1: Property A - RM100 with id_hakmilik 040101PN00018121 Callback 2: Property B - RM80 with id_hakmilik 040101PM00000082
Duplicate Prevention#
The e-Tanah system uses a combination of resitNo and fpxNo to prevent duplicate payments:
- Unique Combination: resitNo + fpxNo prevents double recording
- System Validation: e-Tanah rejects duplicate reference numbers
- Consistent Reference Numbers: Maintained throughout the payment flow
Section sources
Enhanced Error Handling and Logging#
New The integration includes comprehensive error handling and logging across all components.
Callback Error Handling#
- Connection Exception Retry: Automatic retry only for connection-related failures
- Detailed Logging: Comprehensive error logging with stack traces and payload details
- Non-Success Response Handling: Proper handling of HTTP error responses
- Graceful Degradation: System continues operation even when callbacks fail
Enhanced Logging#
The system provides detailed logging for all operations:
- Callback Dispatch: Logs each callback job dispatch with payload details
- Callback Execution: Logs callback execution with timing and results
- Error Conditions: Comprehensive error logging with context information
- Success Confirmation: Confirmation logs for successful callback operations
Fallback Strategies#
Multiple fallback mechanisms ensure system resilience:
- Missing Data Handling: Graceful handling when maklumat_bayaran is unavailable
- Configuration Fallbacks: Default values when environment variables are missing
- Network Optimization: Internal URL conversion for same-server deployments
- Database Recovery: Fallback to in-memory receipt data when database records are delayed
Section sources
Bug Fix: EPS Transaction ID Search#
Updated Fixed critical bug in EPS transaction ID search functionality that was preventing proper transaction lookup and reconciliation.
Issue Description#
The EPS database transaction ID search was using an incorrect key format in the database query condition, causing transaction lookup failures and preventing proper reconciliation between MelakaPay and e-Tanah systems.
Root Cause Analysis#
In the requery functionality, the database query was searching for transaction records using the wrong key format:
Before (Buggy Code):
->where('key', 'transaksi_id')
After (Fixed Code):
->where('key', 'transaksi id')
The difference appears subtle but crucial - the key format in the EPS database uses a space between "transaksi" and "id" rather than an underscore.
Impact of the Bug#
- Transaction reconciliation failures in administrative requery operations
- Inability to properly sync payment status between MelakaPay and e-Tanah systems
- Potential data inconsistency between local transaction records and EPS database
- User confusion when requery operations failed to find transactions
Technical Details#
The EPS database stores transaction metadata in the transaction_xtras table with structured keys. The specific key format for storing e-Tanah transaction IDs requires the exact key format "transaksi id" (with a space) rather than "transaksi_id" (with an underscore).
Resolution#
The fix involved correcting the database query condition in the requery method of EtanahAPIController:
// Fixed: Correct key format for EPS database lookup
$eps_trans_id = \DB::connection('eps')
->table('transaction_xtras')
->where('key', 'transaksi id') // Changed from 'transaksi_id'
->where('value', $transaksi_id)
->pluck('transaction_id')
->first();
Testing and Validation#
- Verified EPS database key format matches "transaksi id" requirement
- Tested requery functionality with various transaction ID formats
- Confirmed proper transaction reconciliation between systems
- Validated that administrative requery operations now work correctly
Preventive Measures#
- Added comprehensive EPS database key validation in future development
- Enhanced error handling for database query conditions
- Created documentation for EPS database key format requirements
- Implemented automated testing for EPS transaction lookup functionality
Section sources
Dependency Analysis#
The eTanah integration relies on several dependencies with enhanced validation, error handling, callback functionality, and fixed transaction lookup:
- Configuration: etanah.php provides service name, agency, base URLs, callback, redirect, key, and enhanced callback job settings with centralized configuration management
- Models: Transaction and Receipt models persist transaction details and receipt data with improved validation
- Controllers: EtanahAPIController orchestrates API operations with enhanced error handling and callback functionality; EtanahController manages FPX initiation
- Requests: EtanahPaymentRequest validates payment initiation parameters with comprehensive validation rules
- Routes: Web and API endpoints define the contract for external systems with enhanced validation
- EPS Database: Provides transaction reconciliation with strengthened connection logic and fixed transaction lookup
- New Enhanced Data Parsing: parseMaklumatBayaran method provides robust data transformation capabilities
- New Dedicated Callback Job: PostEtanahCallback provides centralized asynchronous e-Tanah communication
- New Centralized Configuration: Enhanced config/etanah.php with callback_job settings and environment variable support
- New Fixed EPS Transaction Lookup: Correct database query condition for proper EPS database reconciliation
graph TB
CFG["config/etanah.php<br/>Enhanced Settings & Callback Config<br/>Centralized Configuration Management"] --> API["EtanahAPIController<br/>Enhanced Validation & Callback Functionality<br/>Fixed EPS Transaction Lookup"]
REQ["EtanahPaymentRequest<br/>Comprehensive Validation"] --> CTRL["EtanahController<br/>FPX Initiation"]
API --> MOD_T["Transaction Model<br/>Enhanced Validation"]
API --> MOD_R["Receipt Model<br/>Improved Error Handling"]
API --> RT_WEB["routes/web.php<br/>Web Endpoints"]
API --> RT_API["routes/api.php<br/>API Endpoints"]
API --> EPS["EPS Database<br/>Fixed Transaction Lookup<br/>Enhanced Connection Logic"]
API --> PARSE["parseMaklumatBayaran<br/>Enhanced Data Parsing"]
API --> CALLBACK["PostEtanahCallback<br/>Dedicated Queue Job"]
CALLBACK --> CFG
PARSE --> API
Diagram sources
- etanah.php:1-22
- EtanahAPIController.php:1-1189
- EtanahController.php:1-108
- EtanahPaymentRequest.php:1-105
- Transaction.php:1-69
- Receipt.php:1-11
- web.php:220-231
- database.php:39-57
- PostEtanahCallback.php:1-136
Section sources
- etanah.php:1-22
- EtanahAPIController.php:1-1189
- EtanahController.php:1-108
- EtanahPaymentRequest.php:1-105
- Transaction.php:1-69
- Receipt.php:1-11
- web.php:220-231
- database.php:39-57
- PostEtanahCallback.php:1-136
Performance Considerations#
- Token validation occurs early in request lifecycle to minimize unnecessary processing
- Receipt generation and email dispatch are asynchronous via jobs to improve response times
- Database queries for transaction and receipt retrieval are scoped to reduce overhead
- PDF generation leverages a dedicated service to streamline rendering
- Updated Enhanced EPS database connection logic reduces connection overhead and improves query performance with fixed transaction lookup
- Updated Improved error handling reduces retry loops and connection timeouts
- New Enhanced callback job implementation with retry mechanisms and connection pooling
- New Centralized configuration management reduces environment variable lookup overhead
- New Multi-property processing optimizes callback dispatch for better resource utilization
- New Data parsing caching eliminates redundant processing across multiple components
- New Fixed EPS transaction lookup improves reconciliation performance and reliability
Troubleshooting Guide#
Common issues and resolutions with enhanced error handling, callback functionality, and fixed EPS transaction lookup:
- Invalid Bearer token: Ensure the Authorization header contains the correct token from config
- Validation failures: Review required fields and data types for payment requests, including enhanced return_url validation
- Agency not found: Confirm merchant code mapping aligns with kod_cawangan
- Missing receipts: Use requery endpoint to synchronize status and retry email dispatch with improved error handling
- PDF download errors: Verify receipt existence and payload availability with enhanced validation
- Updated Return URL errors: Ensure return_url is a valid URL format and accessible from the client
- Updated EPS database connection failures: Check EPS database credentials and network connectivity
- Updated Enhanced error logging: Use improved logging to identify specific validation and processing failures
- New Fixed EPS transaction lookup: Verify EPS database key format matches "transaksi id" requirement
- New EPS reconciliation failures: Check transaction ID format and EPS database transaction lookup
- New Callback job failures: Check queue worker status and callback job configuration
- New e-Tanah API communication errors: Verify Access-Token header and IP whitelisting requirements
- New Multi-property callback issues: Check individual payment item processing and logging
- New Configuration caching problems: Ensure proper config:cache and config:clear commands are executed
Section sources
- EtanahAPIController.php:77-82
- EtanahAPIController.php:157-159
- EtanahAPIController.php:269-275
- EtanahAPIController.php:687-743
- PostEtanahCallback.php:110-133
- etanah-config-update.md:217-224
Conclusion#
The eTanah API integration with MelakaPay provides a robust, secure, and scalable solution for processing payments through FPX with enhanced validation, error handling, and callback functionality. By enforcing strict authentication, validating payment payloads with comprehensive parameter validation including mandatory return_url, and automating receipt generation and email delivery with improved error handling, the integration ensures reliable transaction processing. Administrators can monitor and reconcile transactions using the requery functionality with strengthened EPS database connection logic and fixed transaction lookup, while users benefit from seamless payment experiences and accessible receipts.
Updated The integration now includes sophisticated callback functionality that enables asynchronous communication with the e-Tanah system for payment status updates. This enhancement includes multi-property support with individual callback dispatch, improved email receipt generation with built-in receipt data consistency, simplified callback job implementation with centralized configuration management, and updated configuration requirements with default values. The enhanced callback system ensures reliable payment status updates to e-Tanah while maintaining system performance and reliability.
Updated Most significantly, the integration now includes a critical bug fix for EPS transaction ID search functionality. The database query condition was corrected from 'transaksi_id' to 'transaksi id' in the EtanahAPIController.php file, resolving transaction lookup failures that were preventing proper EPS database reconciliation. This fix ensures reliable transaction synchronization between MelakaPay and e-Tanah systems, improving overall system reliability and user experience.
The integration also features centralized configuration management with environment variable support, comprehensive error handling and logging, and optimized performance through asynchronous processing and connection pooling. These enhancements make the integration more resilient, maintainable, and suitable for production environments with high transaction volumes and complex payment scenarios.