Provider Management Guide
Overview
This guide covers how to add new shipping providers to the ProviderTrack system through the admin interface and management commands, without requiring Docker rebuilds.
Admin Interface: https://track.oklabs.my.id/admin/providers/provider/
Live System: Production deployment on VM
Table of Contents
- Adding Providers via Admin UI
- Adding Providers via Management Commands
- Provider Configuration Examples
- API Configuration Guide
- Status Mapping Guide
- Testing New Providers
- Troubleshooting
Adding Providers via Admin UI
Step 1: Access Admin Interface
Navigate to Admin:
https://track.oklabs.my.id/admin/providers/provider/Login Credentials:
- Use your Django admin credentials
- If you don't have access, contact the system administrator
Create New Provider:
- Click "Add Provider" button
- Fill in the required fields
Step 2: Basic Provider Information
Required Fields:
Name: JNE Express
Slug: jne
Base API URL: https://apiv2.jne.co.id/tracing/api/list/v1/cnote
Optional Fields:
Schedule Type: interval
Interval Minutes: 60
Schedule Enabled: ✓ (checked)
Step 3: API Configuration
For JNE Express Example:
{
"auth_method": "none",
"method": "POST",
"tracking_path": "",
"param_name": "cnote",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"body_encoding": "FORM",
"body": {
"cnote": "{tracking_number}"
},
"response_status_path": ["cnote", "pod_status"],
"timeout": 30
}
Step 4: Status Mapping
JNE Status Mapping Example:
{
"DELIVERED": "delivered",
"ON DELIVERY": "out_for_delivery",
"ON TRANSIT": "in_transit",
"PICKUP": "in_transit",
"SHIPMENT": "label_created",
"RETURN": "returned",
"HOLD": "exception",
"CANCEL": "cancelled"
}
Step 5: Save and Test
- Save Provider: Click "Save" button
- Test Connection: Use the "Test Connection" feature in admin
- Verify: Check that the provider appears in the providers list
Adding Providers via Management Commands
Method 1: SSH into VM and Create Provider
Step 1: Connect to VM
ssh root@core-stack
Step 2: Access Django Shell
docker exec -it track python manage.py shell
Step 3: Create Provider Programmatically
from providers.models import Provider
# Create JNE Provider
jne_provider = Provider.objects.create(
name='JNE Express',
slug='jne',
base_api_url='https://apiv2.jne.co.id/tracing/api/list/v1/cnote',
api_config={
'auth_method': 'none',
'method': 'POST',
'tracking_path': '',
'param_name': 'cnote',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'body_encoding': 'FORM',
'body': {
'cnote': '{tracking_number}'
},
'response_status_path': ['cnote', 'pod_status'],
'timeout': 30
},
status_mapping={
'DELIVERED': 'delivered',
'ON DELIVERY': 'out_for_delivery',
'ON TRANSIT': 'in_transit',
'PICKUP': 'in_transit',
'SHIPMENT': 'label_created',
'RETURN': 'returned',
'HOLD': 'exception',
'CANCEL': 'cancelled'
},
schedule_type='interval',
interval_minutes=60,
schedule_enabled=True
)
print(f"Created provider: {jne_provider.name} (ID: {jne_provider.id})")
Method 2: Create Management Command
Step 1: Copy Management Command to VM
# Create file locally first
cat > add_jne_provider.py << 'EOF'
from django.core.management.base import BaseCommand
from providers.models import Provider
class Command(BaseCommand):
help = 'Add JNE Express provider'
def handle(self, *args, **options):
provider, created = Provider.objects.get_or_create(
slug='jne',
defaults={
'name': 'JNE Express',
'base_api_url': 'https://apiv2.jne.co.id/tracing/api/list/v1/cnote',
'api_config': {
'auth_method': 'none',
'method': 'POST',
'tracking_path': '',
'param_name': 'cnote',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'body_encoding': 'FORM',
'body': {
'cnote': '{tracking_number}'
},
'response_status_path': ['cnote', 'pod_status'],
'timeout': 30
},
'status_mapping': {
'DELIVERED': 'delivered',
'ON DELIVERY': 'out_for_delivery',
'ON TRANSIT': 'in_transit',
'PICKUP': 'in_transit',
'SHIPMENT': 'label_created',
'RETURN': 'returned',
'HOLD': 'exception',
'CANCEL': 'cancelled'
},
'schedule_type': 'interval',
'interval_minutes': 60,
'schedule_enabled': True
}
)
if created:
self.stdout.write(f'Successfully created JNE provider (ID: {provider.id})')
else:
self.stdout.write(f'JNE provider already exists (ID: {provider.id})')
EOF
# Copy to VM
scp add_jne_provider.py root@core-stack:/tmp/
# Execute on VM
ssh root@core-stack "docker cp /tmp/add_jne_provider.py track:/app/providers/management/commands/ && docker exec track python manage.py add_jne_provider"
Provider Configuration Examples
1. JNE Express (Indonesian Domestic)
Basic Info:
- Name: JNE Express
- Slug: jne
- URL: https://apiv2.jne.co.id/tracing/api/list/v1/cnote
API Config:
{
"auth_method": "none",
"method": "POST",
"tracking_path": "",
"param_name": "cnote",
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "ProviderTrack/1.0"
},
"body_encoding": "FORM",
"body": {
"cnote": "{tracking_number}"
},
"response_status_path": ["cnote", "pod_status"],
"timeout": 30
}
Status Mapping:
{
"DELIVERED": "delivered",
"ON DELIVERY": "out_for_delivery",
"ON TRANSIT": "in_transit",
"PICKUP": "in_transit",
"SHIPMENT": "label_created",
"RETURN": "returned",
"HOLD": "exception",
"CANCEL": "cancelled",
"UNKNOWN": "unknown"
}
2. POS Indonesia (Government Postal)
Basic Info:
- Name: POS Indonesia
- Slug: pos-indonesia
- URL: https://mypos.pos.co.id/api/v1/trackandtrace
API Config:
{
"auth_method": "api_key",
"api_key": "YOUR_POS_API_KEY",
"api_key_header": "X-API-Key",
"method": "GET",
"tracking_path": "/tracking",
"param_name": "barcode",
"headers": {
"Accept": "application/json"
},
"response_status_path": ["data", "status"],
"timeout": 45
}
Status Mapping:
{
"10": "label_created",
"20": "in_transit",
"30": "in_transit",
"40": "out_for_delivery",
"50": "delivered",
"60": "exception",
"70": "returned"
}
3. SiCepat (Indonesian Express)
Basic Info:
- Name: SiCepat Express
- Slug: sicepat
- URL: https://api.sicepat.com/customer/waybill
API Config:
{
"auth_method": "api_key",
"api_key": "YOUR_SICEPAT_API_KEY",
"api_key_header": "api-key",
"method": "GET",
"tracking_path": "",
"param_name": "waybill",
"headers": {
"Accept": "application/json"
},
"response_status_path": ["sicepat", "result", "last_status", "status"],
"timeout": 30
}
4. UPS (International)
Basic Info:
- Name: UPS
- Slug: ups
- URL: https://onlinetools.ups.com/api/track/v1/details
API Config:
{
"auth_method": "oauth",
"client_id": "YOUR_UPS_CLIENT_ID",
"client_secret": "YOUR_UPS_CLIENT_SECRET",
"oauth_token_url": "https://onlinetools.ups.com/security/v1/oauth/token",
"oauth_scope": "tracking",
"method": "GET",
"tracking_path": "/{tracking_number}",
"headers": {
"Accept": "application/json"
},
"response_status_path": ["trackResponse", "shipment", 0, "package", 0, "currentStatus", "type"],
"timeout": 45
}
5. TNT (FedEx Network)
Basic Info:
- Name: TNT Express
- Slug: tnt
- URL: https://api.tnt.com/tracking/v3/shipments
API Config:
{
"auth_method": "api_key",
"api_key": "YOUR_TNT_API_KEY",
"api_key_header": "TNT-API-KEY",
"method": "GET",
"tracking_path": "",
"param_name": "con",
"headers": {
"Accept": "application/json"
},
"response_status_path": ["tracker", "consignmentLevelDetails", "statusData", "status"],
"timeout": 30
}
API Configuration Guide
Authentication Methods
1. No Authentication (none)
{
"auth_method": "none"
}
2. API Key Authentication (api_key)
{
"auth_method": "api_key",
"api_key": "your_api_key_here",
"api_key_header": "X-API-Key"
}
3. Bearer Token (bearer)
{
"auth_method": "bearer",
"bearer_token": "your_bearer_token_here"
}
4. Basic Authentication (basic)
{
"auth_method": "basic",
"username": "your_username",
"password": "your_password"
}
5. OAuth 2.0 (oauth)
{
"auth_method": "oauth",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"oauth_token_url": "https://api.provider.com/oauth/token",
"oauth_scope": "tracking"
}
HTTP Methods and Body Encoding
GET Request (Query Parameters)
{
"method": "GET",
"param_name": "tracking_number",
"tracking_path": "/track/{tracking_number}"
}
POST Request (JSON Body)
{
"method": "POST",
"body_encoding": "JSON",
"body": {
"trackingNumber": "{tracking_number}",
"includeDetails": true
}
}
POST Request (Form Data)
{
"method": "POST",
"body_encoding": "FORM",
"body": {
"awb": "{tracking_number}",
"format": "json"
}
}
Response Path Configuration
Simple Path (Single Level)
{
"response_status_path": ["status"]
}
Nested Path (Multiple Levels)
{
"response_status_path": ["data", "shipment", "status", "code"]
}
Array Access
{
"response_status_path": ["shipments", 0, "currentStatus"]
}
Status Mapping Guide
Internal Status Codes
The system uses these standardized internal status codes:
| Internal Code | Description |
|---|---|
pending |
Initial/unknown status |
label_created |
Shipping label created |
in_transit |
Package in transit |
out_for_delivery |
Out for delivery |
delivered |
Successfully delivered |
exception |
Exception/problem occurred |
returned |
Package returned to sender |
cancelled |
Shipment cancelled |
unknown |
Status unknown/unmapped |
Provider-Specific Mapping Examples
DHL Status Mapping
{
"delivered": "delivered",
"transit": "in_transit",
"failure": "exception",
"unknown": "unknown",
"pre-transit": "label_created",
"pickup": "in_transit",
"exception": "exception",
"on-hold": "exception",
"out-for-delivery": "out_for_delivery"
}
FedEx Status Mapping
{
"DL": "delivered",
"IT": "in_transit",
"OD": "out_for_delivery",
"PU": "in_transit",
"SH": "label_created",
"DE": "exception",
"CA": "cancelled",
"RS": "returned"
}
JNE Status Mapping
{
"DELIVERED": "delivered",
"ON DELIVERY": "out_for_delivery",
"ON TRANSIT": "in_transit",
"PICKUP": "in_transit",
"SHIPMENT": "label_created",
"RETURN": "returned",
"HOLD": "exception",
"CANCEL": "cancelled"
}
Testing New Providers
1. Admin Interface Testing
Navigate to Provider in Admin:
https://track.oklabs.my.id/admin/providers/provider/[provider_id]/change/Use Test Connection Feature:
- Enter a real tracking number in the test field
- Click "Test Connection" button
- Review the response and status mapping
Example Test Cases:
JNE: 8820326200001 POS Indonesia: EA123456789ID SiCepat: 000123456789
2. Django Shell Testing
# SSH into VM and run
ssh root@core-stack "docker exec -it track python manage.py shell"
# Test provider tracking
from providers.models import Provider
from awbs.models import AWB
from django.contrib.auth.models import User
# Get provider
provider = Provider.objects.get(slug='jne')
# Create test AWB
user = User.objects.first() # Get any user
awb = AWB.objects.create(
user=user,
provider=provider,
awb_number='8820326200001',
current_status_internal='pending'
)
# Test tracking (if tracking service is implemented)
from providers.services import ProviderService
service = ProviderService(provider)
result = service.track_awb('8820326200001')
print(f"Tracking result: {result}")
3. API Testing with Real AWBs
Create a test script to verify provider integration:
#!/usr/bin/env python3
"""
Test new provider integration
"""
import requests
import json
def test_jne_provider():
"""Test JNE provider directly"""
api_url = "https://apiv2.jne.co.id/tracing/api/list/v1/cnote"
data = {
'cnote': '8820326200001' # Test tracking number
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'ProviderTrack/1.0'
}
try:
response = requests.post(api_url, data=data, headers=headers, timeout=30)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
if response.status_code == 200:
json_data = response.json()
status = json_data.get('cnote', {}).get('pod_status')
print(f"Extracted status: {status}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
test_jne_provider()
Troubleshooting
Common Issues and Solutions
1. Authentication Errors
Problem: 401 Unauthorized or 403 Forbidden
Solution:
- Verify API key/credentials are correct
- Check if API key header name is correct
- Ensure OAuth token is not expired
- Verify rate limits are not exceeded
2. Response Parsing Errors
Problem: Cannot extract status from response
Solution:
- Use admin "Test Connection" to see raw response
- Verify response_status_path matches actual JSON structure
- Check if response is array vs object
- Add debug logging to track response format
3. SSL/Certificate Errors
Problem: SSL verification failed
Solution:
- Ensure base_api_url uses HTTPS
- Verify SSL certificate is valid
- Check if provider uses custom certificates
4. Timeout Issues
Problem: Requests timing out
Solution:
- Increase timeout value in api_config
- Check provider's rate limiting
- Verify network connectivity from VM
5. Status Mapping Issues
Problem: Statuses not mapping correctly
Solution:
- Review provider's actual status codes
- Test with multiple tracking numbers
- Add fallback mapping for unknown statuses
- Use "unknown" as default for unmapped statuses
Debug Commands
Check Provider Configuration
# SSH to VM
ssh root@core-stack
# Check provider details
docker exec track python manage.py shell -c "
from providers.models import Provider
p = Provider.objects.get(slug='jne')
print('Name:', p.name)
print('URL:', p.base_api_url)
print('Config:', p.api_config)
print('Mapping:', p.status_mapping)
"
Test Provider API Directly
# Test JNE API
curl -X POST "https://apiv2.jne.co.id/tracing/api/list/v1/cnote" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "User-Agent: ProviderTrack/1.0" \
-d "cnote=8820326200001"
Check Provider Logs
# Check Django logs for provider errors
ssh root@core-stack "docker logs track | grep -i 'provider\|tracking\|error'"
Quick Reference
Adding Provider Checklist
- [ ] Determine provider's API documentation
- [ ] Identify authentication method
- [ ] Find tracking endpoint URL
- [ ] Test API manually with curl/Postman
- [ ] Map response structure to status path
- [ ] Create status code mapping
- [ ] Add provider via admin or management command
- [ ] Test with real tracking numbers
- [ ] Verify status updates work correctly
- [ ] Enable scheduling if needed
Provider URLs for Testing
| Provider | Test Tracking Numbers | Status Check URL |
|---|---|---|
| JNE | 8820326200001 | Manual API call |
| POS Indonesia | EA123456789ID | https://mypos.pos.co.id |
| SiCepat | 000123456789 | https://sicepat.com |
| DHL | 5451596323 | Built-in system |
| FedEx | 883134258320 | Built-in system |
Important Notes
- No Docker Rebuild Required: All provider additions can be done through admin interface or management commands
- Live System Testing: Always test on the live system after adding providers
- API Rate Limits: Be mindful of provider API rate limits when scheduling
- Security: Never commit API keys to version control
- Monitoring: Monitor provider performance and adjust timeouts as needed
For additional support or specific provider integrations, contact the development team or check the provider's official API documentation.