Introduction
- Overview
- Getting Started
- Core Features
- Directory Structure
- Database Architecture
- Authentication and security
- API Endpoints
- Courier Partner Integrations
- External API Integrations
- Environment Variables
Overview
OnDelivery API (OSAS - OnDelivery Smart Agent System) is a comprehensive multi-courier shipping logistics platform built with Node.js. The system enables:
- Multi-courier aggregation - Integrate and manage multiple shipping partners (JNE, Lion Parcel, JT Cargo, AnteRaja, etc.)
- Real-time package tracking - Track shipments from pickup to delivery
- Dynamic pricing - Calculate shipping fees based on origin, destination, weight, and service type
- Warehouse operations - Manage scanning, manifesting, handovers, and quality control
- Financial management - Handle billing, commissions, and VIP customer pricing
- Driver mobile app - Support delivery drivers with marketplace integration
- Marketplace integration - Connect with multiple e-commerce platforms
Project Name: ondelivery-api
Version: 1.0.0
Main Entry Point: ondeliv-backend.js
Default Port: 4220
License: ISC
Architecture & Technology Stack
Core Technologies
| Technology | Version | Purpose |
|---|---|---|
| Node.js | - | Runtime environment |
| Express.js | 5.2.1 | Web application framework |
| PostgreSQL | - | Primary database (dual setup: OSAS + ONMART) |
| Sequelize | 6.37.7 | ORM for database operations |
Key Dependencies
Authentication & Security:
-
jsonwebtoken(9.0.2) - JWT token generation and verification -
passport(0.7.0) - Authentication middleware -
passport-http(0.3.0) - HTTP Basic authentication -
bcryptjs(3.0.3) - Password hashing -
helmet(8.1.0) - Security headers -
express-rate-limit(8.2.1) - Rate limiting protection
Data Validation & Processing:
-
ajv(8.17.1) - JSON schema validation -
ajv-formats(3.0.1) - Additional format validators -
ajv-keywords(5.1.0) - Extended validation keywords
HTTP & External APIs:
-
axios(1.13.2) - HTTP client for external API calls -
cors(2.8.5) - Cross-origin resource sharing
File Processing:
-
multer(2.0.2) - File upload handling -
sharp(0.34.5) - Image processing and optimization -
exceljs(4.4.0) - Excel file generation -
pdfmake(0.2.20) - PDF document generation -
xlsx(0.20.3) - Excel file parsing
Utilities:
-
moment(2.30.1) /dayjs(1.11.19) - Date/time manipulation -
lodash(4.17.21) - Utility functions -
node-cron(4.2.1) - Scheduled tasks -
nodemailer(7.0.11) - Email sending -
nanoid(5.1.6) - Unique ID generation -
morgan(1.10.1) - HTTP request logging -
cli-color(2.0.4) - Colorized console output
Getting Started
Prerequisites
- Node.js (v14+ recommended)
- PostgreSQL (v15+ recommended)
- npm or yarn package manager
Installation
# Clone the repository
git clone <repository-url>
cd ondelivery-api
# Install dependencies
npm install
# Setup environment variables
# Copy .env.example to .env and configure
cp .env.example .env
Configuration
-
Database Setup:
- Create two PostgreSQL databases (OSAS and ONMART)
- Update database credentials in
.env
-
Environment Variables:
- Configure all required environment variables (see Environment Variables)
-
Initialize Database:
# Run migrations if available # The application uses Sequelize ORM
Running the Application
# Development mode with auto-reload
npm start
# Production mode
node ondeliv-backend.js
The server will start on port 4220 (or as configured in PORT environment variable).
Verify Installation
Visit http://localhost:4220/ - you should see:
{
"message": "This backend osas works well for now"
}
Core Features
1. Waybill Management
- Create Waybills - Generate shipping labels with unique AWB (Air Waybill) numbers
- Edit Waybills - Modify shipment details before dispatch
- Track Waybills - Real-time tracking with status updates
- Multi-AWB Operations - Batch operations on multiple waybills
2. Scanning Operations
Outgoing Scans:
- Packing - Package preparation and verification
- Handover - Transfer between logistics hubs
Incoming Scans:
- Receiving - Package arrival at distribution center
- Delivery - Final delivery to customer
- Problem Scan - Exception handling (damaged, lost, etc.)
3. Courier Partner Integration
- Support for 10+ courier partners
- Webhook-based status synchronization
- API-based shipment creation
- Automatic status mapping to internal codes
4. Fee Calculation
- Dynamic pricing based on:
- Origin and destination locations
- Package weight and dimensions
- Service type (regular, express, cargo)
- Customer-specific pricing (VIP)
- Special location surcharges
5. Reports & Analytics
Operational Reports:
- Monitoring pickup/delivery status
- Manifest reports
- Arrival/departure reports
- SLA performance tracking
Financial Reports:
- Billing reports (standard & VIP)
- Agent commission calculations
- Distribution center (DC) commissions
- Finance reconciliation
Quality Reports:
- Courier performance
- Problem scan analysis
- Weight discrepancy tracking
6. Quality Management
- Weight Verification - Alter weight for discrepancies
- POD (Proof of Delivery) - Capture delivery signatures/photos
- POP (Proof of Pickup) - Document package pickup with photos
7. Driver App Support
- Mobile-friendly endpoints for delivery drivers
- Marketplace order management
- Route optimization support
- Real-time status updates
8. Marketplace Integration
- Pickup Management - Handle marketplace order pickups
- Receiving - Process incoming marketplace orders
- Support for multiple platforms
9. Administration
- Account Management - User and agent administration
- Customer Management - Customer profiles and preferences
- Feed Information - System notifications and updates
10. Financial Operations
- VIP Billing - Custom pricing for premium customers
- Payment Gateway - Xendit integration for payments
- Commission Tracking - Calculate agent and DC commissions
Directory Structure
ondelivery-api/
├── ondeliv-backend.js # Main application entry point
├── package.json # Dependencies and scripts
├── README.md # Basic project information
├── BACKEND_DOCUMENTATION.md # This file
│
├── app/ # Application code
│ ├── config/ # Configuration files
│ │ ├── api.js # External API endpoints
│ │ ├── auth.config.js # JWT secret configuration
│ │ └── db.config.js # Database connection config
│ │
│ ├── controllers/ # Business logic controllers
│ │ ├── 3p/ # 3rd-party courier integrations
│ │ │ ├── jne.controller.js
│ │ │ ├── lion-parcel.controller.js
│ │ │ ├── jt-cargo.controller.js
│ │ │ ├── anteraja.controller.js
│ │ │ └── sapx.controller.js
│ │ ├── auth/ # Authentication controllers
│ │ ├── check-fee/ # Fee calculation logic
│ │ ├── driver-app/ # Driver mobile app
│ │ ├── finance/ # Financial operations
│ │ ├── incoming-scans/ # Receiving, delivery, problems
│ │ ├── marketplace/ # Marketplace integrations
│ │ ├── outgoing-scans/ # Packing, handover operations
│ │ ├── quality-management/ # Weight, POD, POP
│ │ ├── reports/ # Report generation
│ │ ├── trucking/ # Trucking operations
│ │ └── waybill/ # Waybill CRUD operations
│ │
│ ├── middleware/ # Express middleware
│ │ ├── authJwt.js # JWT token verification
│ │ ├── passport.js # Passport strategies
│ │ └── error_param_handler.js # Error handling
│ │
│ ├── models/ # Sequelize ORM models (52+ models)
│ │ ├── index.js # Model aggregation
│ │ ├── scans.model.js # Tracking status records
│ │ ├── partners.model.js # Courier partner data
│ │ ├── user.model.js # User accounts
│ │ ├── waybill_numbers.model.js # AWB tracking
│ │ ├── resi_3p.model.js # 3P waybill mapping
│ │ └── [48+ other models]
│ │
│ ├── routes/ # API route definitions
│ │ ├── auth.routes.js # Authentication endpoints
│ │ ├── waybill/ # Waybill routes
│ │ ├── incoming_scans/ # Incoming scan routes
│ │ ├── outgoing_scans/ # Outgoing scan routes
│ │ ├── reports/ # Report routes
│ │ ├── 3p.routes.js # 3P integration webhooks
│ │ └── [35+ route files]
│ │
│ ├── schemas/ # JSON validation schemas (AJV)
│ │ └── [validation definitions]
│ │
│ ├── schedulers/ # Cron job definitions
│ │ ├── update-resi-status.js
│ │ └── transaction-terminator.js
│ │
│ ├── status/ # Status mapping JSON files
│ │ └── [courier status mappings]
│ │
│ ├── utility/ # Helper utilities
│ │ ├── check-fee.util.js # Fee calculation helpers
│ │ ├── service.util.js # Service utilities
│ │ ├── waybill.util.js # Waybill helpers
│ │ └── web-hook.js # Webhook utilities
│ │
│ ├── maping/ # Data mapping files
│ │ └── jntcargo-special-pricing.json
│ │
│ └── fonts/ # Custom fonts for PDF generation
│
├── assets/ # Static assets
├── resources/ # Resource files
│ └── temp/ # Temporary files
│ ├── img/ # Image uploads
│ │ ├── pickup/
│ │ ├── delivery/
│ │ ├── pickup_eatsok/
│ │ ├── delivery_eatsok/
│ │ └── agent/
│ └── [generated files]
│
├── scripts/ # Utility scripts
├── tests/ # Test files
├── check_fee_test.js # Fee calculation tests
├── check_price.js # Price checking script
└── debug_provinces.js # Province debugging utility
Database Architecture
The application uses two PostgreSQL databases:
-
OSAS Database (Primary)
- Main operational database
- Contains waybills, scans, users, partners, etc.
-
ONMART Database (Secondary)
- Marketplace-specific operations
- Separate schema for marketplace data
Key Database Models
Core Operational Models
| Model | Purpose | Key Fields |
|---|---|---|
scans |
Tracking status history | waybill_id, status, location, timestamp |
waybill_numbers |
Shipment records | awb_number, origin, destination, weight |
partners |
3P courier partners | name, api_token, webhook_url |
resi_3p |
3P waybill mapping | internal_awb, partner_awb, partner_id |
user |
User accounts | username, password_hash, role_id, agent_id |
Scanning Models
| Model | Purpose |
|---|---|
delivery_scan |
Delivery completion records |
handover_scan |
Hub-to-hub transfers |
receiving_scan |
Package arrivals |
problem_scan |
Exception tracking |
packing_scan |
Package preparation |
Financial Models
| Model | Purpose |
|---|---|
billing_vip_config |
VIP customer pricing |
xendit_payment |
Payment gateway records |
xendit_payout |
Payout transactions |
agent_commission |
Commission calculations |
Master Data Models
| Model | Purpose |
|---|---|
agent_locations |
Agent location mapping |
agent_customer |
Customer-agent relationships |
awb_books |
AWB number allocation |
courier_partners |
Courier configurations |
service_types |
Available services |
Additional Models (52 total)
- Manifest management (
manifest_pcp,manifest_pos) - Quality management (
alter_weight,pod_record,pop_record) - Trucking operations (
trucking_shipment,trucking_config) - Location master data (
all_location_migration) - Marketplace integration models
- Report configuration models
Database Relationships
User ──┐
├─→ Agent_Locations → Waybill_Numbers
└─→ Role
Waybill_Numbers ──┬─→ Scans (1:many)
├─→ Resi_3p
└─→ Delivery_Scan / Problem_Scan
Partners ─→ Resi_3p ─→ Waybill_Numbers
Agent_Customer ─→ Waybill_Numbers
Connection Pooling
// From db.config.js
pool: {
max: DB_POOL_MAX, // Maximum connections
min: DB_POOL_MIN, // Minimum connections
acquire: DB_POOL_ACQUIRE, // Connection acquisition timeout
idle: DB_POOL_IDLE // Idle timeout
}
Authentication and security
Authentication Methods
1. JWT Token Authentication (Primary)
Usage: Protected API endpoints for authenticated users
Implementation:
- Middleware:
authJwt.verifyToken - Header:
Authorization: Bearer <token> - Token includes:
id,agentId,username,role,location_id,name
Example:
// Route protection
router.post('/api/waybill/create',
[authJwt.verifyToken],
controller.createWaybill
);
Token Payload:
{
id: 123,
agentId: 456,
username: "john.doe",
role: "admin",
location_id: 789,
name: "John Doe"
}
2. Passport HTTP Basic Authentication
Usage: 3rd-party API integrations (webhooks, external calls)
Strategies:
-
eatsok- EatSOK food delivery partner -
anteraja- AnteRaja courier integration -
linked- Linked account authentication -
integrationproc- Integration processor
Implementation:
// Basic Auth header: Authorization: Basic base64(username:password)
passport.authenticate('eatsok', { session: false })
Credentials Validated Against:
-
EATSOK_SECRET_KEY_ONDEL -
ANTERAJA_SECRET_KEY_ONDEL -
LINKED_ACCOUNT_SECRET_KEY -
INTEGRATION_PROC_KEY
Security Features
Rate Limiting
Configuration:
windowMs: RATE_LIMIT_WINDOW_MS || 10000, // 10 seconds
max: RATE_LIMIT_MAX || 20, // 20 requests per window
message: "You are sending requests too quickly. Please wait 1 second."
Applied to: All routes globally
CORS Protection
cors({
origin: ORIGIN_CORS.split(','), // Whitelist from env
allowedHeaders: ['Content-Type', 'Authorization']
})
Helmet Security Headers
- XSS protection
- Content Security Policy
- DNS prefetch control
- Frame options
- HSTS (HTTP Strict Transport Security)
Additional Security
Password Security:
- Hashing:
bcryptjswith salt rounds - No plaintext password storage
Input Validation:
- JSON Schema validation via AJV
- Request parameter sanitization
- File upload size limits (10MB)
Permission Headers:
Permissions-Policy:
geolocation=(self),
camera=(),
microphone=(),
fullscreen=(self),
payment=(self)
File Access Control:
Cross-Origin-Resource-Policy: cross-origin
Role-Based Access Control (RBAC)
Role Model:
- Stored in
roletable - Associated with
userviarole_id
Common Roles:
- Admin
- Agent
- Driver
- Warehouse Staff
- Finance
API Endpoints
Authentication Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/auth/signup |
None | Register new user |
| POST | /api/auth/signin |
None | Login and get JWT token |
| GET | /api/auth/profile |
JWT | Get user profile |
| GET | /api/auth/agents |
JWT | List all agents |
Waybill Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/waybill/create |
JWT | Create new waybill |
| GET | /api/waybill/:id |
JWT | Get waybill details |
| PUT | /api/waybill/:id |
JWT | Update waybill |
| DELETE | /api/waybill/:id |
JWT | Cancel waybill |
| GET | /api/waybill/track/:awb |
JWT | Track waybill by AWB |
| POST | /api/waybill/bulk |
JWT | Bulk waybill creation |
| GET | /api/waybill/view-img/:id |
JWT | View waybill image |
Check Fee Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/check-fee |
JWT | Calculate shipping fee |
| POST | /api/check-fee/bulk |
JWT | Bulk fee calculation |
| GET | /api/check-fee/services |
JWT | Get available services |
Scanning Endpoints
Outgoing Scans:
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/scan/packing |
JWT | Record packing scan |
| POST | /api/scan/handover |
JWT | Record handover scan |
| GET | /api/scan/handover/:id |
JWT | Get handover details |
Incoming Scans:
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/scan/receiving |
JWT | Record receiving scan |
| POST | /api/scan/delivery |
JWT | Record delivery scan |
| POST | /api/scan/problem |
JWT | Record problem scan |
| GET | /api/scan/delivery/:id |
JWT | Get delivery details |
Courier Partner Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/partners |
JWT | List all partners |
| GET | /api/partners/:id |
JWT | Get partner details |
| POST | /api/partners |
JWT | Add new partner |
| PUT | /api/partners/:id |
JWT | Update partner |
| DELETE | /api/partners/:id |
JWT | Remove partner |
3rd-Party Integration Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/3p/jne/webhook |
Basic | JNE status webhook |
| POST | /api/3p/lionparcel/webhook |
Basic | Lion Parcel webhook |
| POST | /api/3p/jtcargo/webhook |
Basic | JT Cargo webhook |
| POST | /api/3p/anteraja/webhook |
Basic | AnteRaja webhook |
| POST | /api/3p/sicepat/webhook |
Basic | Sicepat webhook |
Reports Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/reports/monitoring-pickup |
JWT | Pickup monitoring report |
| GET | /api/reports/monitoring-delivery |
JWT | Delivery monitoring report |
| GET | /api/reports/manifest |
JWT | Manifest report |
| GET | /api/reports/sla |
JWT | SLA performance report |
| GET | /api/reports/billing |
JWT | Billing report |
| GET | /api/reports/billing-vip |
JWT | VIP billing report |
| GET | /api/reports/commission |
JWT | Commission report |
| GET | /api/reports/finance |
JWT | Finance report |
| GET | /api/reports/courier-performance |
JWT | Courier performance |
Quality Management Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/qm/alter-weight |
JWT | Record weight alteration |
| POST | /api/qm/pod |
JWT | Upload proof of delivery |
| POST | /api/qm/pop |
JWT | Upload proof of pickup |
| GET | /api/qm/pod/:awb |
JWT | Get POD for waybill |
| GET | /api/qm/pop/:awb |
JWT | Get POP for waybill |
Driver App Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/driver/tasks |
JWT | Get assigned tasks |
| POST | /api/driver/pickup |
JWT | Complete pickup |
| POST | /api/driver/delivery |
JWT | Complete delivery |
| GET | /api/driver/marketplace/orders |
JWT | Get marketplace orders |
Marketplace Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/marketplace/pickup |
JWT | Record marketplace pickup |
| POST | /api/marketplace/receiving |
JWT | Record marketplace receiving |
| GET | /api/marketplace/orders |
JWT | Get marketplace orders |
Administration Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/admin/users |
JWT | List users |
| POST | /api/admin/users |
JWT | Create user |
| PUT | /api/admin/users/:id |
JWT | Update user |
| DELETE | /api/admin/users/:id |
JWT | Delete user |
| GET | /api/admin/customers |
JWT | List customers |
| POST | /api/admin/feed-info |
JWT | Post system notification |
Finance Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/finance/billing-vip |
JWT | Get VIP billing configs |
| POST | /api/finance/billing-vip |
JWT | Create VIP billing config |
| PUT | /api/finance/billing-vip/:id |
JWT | Update VIP billing config |
File Download
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/file/download/:filename |
None | Download generated file |
Note: File is automatically deleted after download.
Courier Partner Integrations
Supported Courier Partners
The system integrates with multiple courier partners in Indonesia:
1. JNE (Jalur Nugraha Ekakurir)
Features:
- Status webhook integration
- Status code mapping to internal codes
- Real-time tracking updates
Controller: app/controllers/3p/jne.controller.js
2. Lion Parcel
Features:
- Scheduled pickup requests via cron job
- Bearer token authentication
- Automatic pickup scheduling
Configuration:
// Environment variable
LIONPARCEL_PICKUP_CRON="*/30 * * * *" // Every 30 minutes
LIONPARCEL_BEARER_TOKEN="<token>"
Controller: app/controllers/3p/lion-parcel.controller.js
3. JT Cargo (J&T Cargo)
Features:
- Full API integration
- Special pricing support
- Database-driven pricing lookup
- Fallback to JSON mapping
Special Pricing:
- Primary:
jnt_cargo_special_pricestable - Fallback:
app/maping/jntcargo-special-pricing.json
Controller: app/controllers/3p/jt-cargo.controller.js
4. AnterAja
Features:
- Webhook integration
- Access key authentication
- Status synchronization
Authentication:
- Access Key ID:
ANTERAJA_ACCESS_KEY_ID - Secret Access Key:
ANTERAJA_SECRET_ACCESS_KEY
Controller: app/controllers/3p/anteraja.controller.js
5. Sicepat
Features:
- Status webhook support
- Tracking integration
Controller: app/controllers/3p/sicepat.controller.js
6. Sap Express (SAPX)
Features:
- API integration
- Shipment creation
Controller: app/controllers/3p/sapx.controller.js
7. POS Indonesia
Features:
- Indonesian postal service integration
- Manifest generation
- Token-based authentication
Routes: app/routes/pos_indo.routes.js
8. PCP Express
Features:
- PCP carrier network
- Manifest management
Routes: app/routes/pcp_express.routes.js
9. Laris Cargo
Features:
- Regional courier integration
Routes: app/routes/laris_cargo.routes.js
Integration Pattern
All courier integrations follow a similar pattern:
// 1. Receive webhook from partner
POST /api/3p/{partner}/webhook
// 2. Validate authentication (Basic Auth or API Key)
passport.authenticate('{partner}Strategy')
// 3. Parse partner status code
parsePartnerStatus(partnerStatusCode)
// 4. Map to internal status code
const internalStatus = statusMapping[partnerStatusCode]
// 5. Update internal tracking
await updateScan(awb, internalStatus)
// 6. Trigger internal webhooks (if configured)
await triggerWebhook(waybillData)
// 7. Return acknowledgment
return { success: true }
Status Mapping
Each courier has status mappings in app/status/ directory:
- Maps partner-specific status codes to internal OnDelivery codes
- Ensures consistent tracking across all partners
- Stored as JSON configuration files
Example Status Flow:
Partner: "DELIVERED"
→ Internal: "DLV"
→ Display: "Delivered to Customer"
Resi 3P Mapping
Purpose: Link internal AWB numbers to partner AWB numbers
Table: resi_3p
Fields:
-
internal_awb- OnDelivery waybill number -
partner_awb- Partner's tracking number -
partner_id- Courier partner ID -
status- Current status -
created_at- Mapping creation time
Usage:
// When creating shipment with partner
const mapping = await Resi3P.create({
internal_awb: "ONX1234567890",
partner_awb: "JNE0987654321",
partner_id: 1 // JNE
});
// When receiving webhook
const waybill = await findWaybillByPartnerAwb(
webhookData.awb,
partnerConfig.id
);
Business Workflows
Workflow 1: Waybill Creation & Booking
┌─────────────┐
│ User Input │
└──────┬──────┘
│
▼
┌────────────────────┐
│ Validate Origin/ │
│ Destination │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Calculate Fee │
│ (check-fee util) │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Reserve AWB Number │
│ (from AWB Book) │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Create Waybill │
│ Record in DB │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Create Initial Scan│
│ Status: BOOKED │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Generate Label PDF │
└──────┬─────────────┘
│
▼
┌────────────────────┐
│ Return AWB to User │
└────────────────────┘
Workflow 2: Package Tracking Lifecycle
Outgoing Phase:
BOOKED → PACKED → HANDOVER → DEPARTURE
Transit Phase:
DEPARTURE → [TRANSIT] → ARRIVAL
Delivery Phase:
ARRIVAL → RECEIVING → OUT_FOR_DELIVERY → DELIVERED
→ PROBLEM
Exception Handling:
ANY_STATUS → PROBLEM → [PROBLEM_RESOLVED]
→ RETURN → [RETURN_COMPLETE]
→ CANCEL
Status Codes:
-
BKD- Booked -
PKD- Packed -
HND- Handover -
DPT- Departure -
ARV- Arrival -
RCV- Receiving -
OFD- Out for Delivery -
DLV- Delivered -
PRB- Problem -
RTN- Return -
CNL- Cancel
Workflow 3: 3rd-Party Integration
┌──────────────────┐
│ Partner Webhook │
└────────┬─────────┘
│
▼
┌─────────────────────┐
│ Authenticate Request│
│ (Basic Auth/API Key)│
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Parse Partner AWB │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Lookup in resi_3p │
│ Get internal AWB │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Map Partner Status │
│ to Internal Status │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Update Scan Record │
│ in Database │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Trigger Internal │
│ Webhooks (optional) │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Send Acknowledgment │
│ to Partner │
└─────────────────────┘
Workflow 4: Fee Calculation
┌─────────────────────┐
│ Origin & Destination│
│ Location Codes │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Get Location Details│
│ (Province, City) │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Check Service │
│ Availability │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Get Base Price │
│ (by weight/distance)│
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Apply Special │
│ Pricing (if VIP) │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Add Surcharges │
│ (remote area, etc.) │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Calculate Insurance │
│ (if requested) │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Return Total Fee │
│ with Breakdown │
└─────────────────────┘
Workflow 5: Scanning Operations
Packing Scan:
1. Scan AWB number
2. Verify waybill exists
3. Check current status (must be BOOKED)
4. Record packing details (weight, dimensions)
5. Update status to PACKED
6. Generate packing list
Handover Scan:
1. Create handover manifest
2. Scan multiple AWBs
3. Verify all AWBs are PACKED
4. Record handover details (from/to location)
5. Update all AWBs to HANDOVER status
6. Generate handover manifest PDF
7. Print manifest for courier
Receiving Scan:
1. Scan incoming AWBs
2. Match with expected manifest
3. Record arrival time
4. Update status to RECEIVING
5. Flag any discrepancies
6. Assign to delivery driver
Delivery Scan:
1. Driver scans AWB
2. Capture POD (photo/signature)
3. Record delivery details
4. Update status to DELIVERED
5. Send customer notification
6. Update commission records
Problem Scan:
1. Scan AWB with issue
2. Select problem type (damaged, lost, refused, etc.)
3. Capture photos
4. Add notes
5. Update status to PROBLEM
6. Trigger problem resolution workflow
7. Notify relevant parties
Workflow 6: Multi-Courier Consolidation
┌─────────────────────┐
│ Multiple Couriers │
│ Deliver to Hub │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Receiving Scan │
│ by Partner │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Consolidate by │
│ Destination │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Create Manifest │
│ for DC │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Handover Scan │
│ to Next Hub/DC │
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Final Delivery │
│ to Customer │
└─────────────────────┘
Workflow 7: Quality Management
Weight Discrepancy Handling:
1. Package weighed at receiving
2. Compare with declared weight
3. If difference > threshold:
- Capture photo evidence
- Record actual weight
- Create alter_weight record
- Calculate price adjustment
- Notify customer
4. Update billing if needed
Proof of Delivery (POD):
1. Driver completes delivery
2. Capture recipient signature (digital)
3. Take delivery photo
4. Record GPS coordinates
5. Upload to server
6. Link to waybill
7. Status → DELIVERED
Proof of Pickup (POP):
1. Driver arrives at pickup location
2. Take package photos
3. Capture sender signature
4. Record GPS coordinates
5. Upload to server
6. Link to waybill
7. Status → BOOKED
External API Integrations
Configured External APIs
1. Agent Management System
Purpose: Manage agent locations and configurations
Configuration:
- Base URL:
API_URL_AGENT_ONAGENT - Authentication: JWT token
- Usage: Agent CRUD operations
2. User State Management
Purpose: Track user session and state
Configuration:
- Base URL:
API_URL_USERSTATE - Authentication: JWT token
- Usage: User activity tracking
3. User OnDelivery System
Purpose: User profile management
Configuration:
- Base URL:
API_URL_USERONDELIV - Authentication: JWT token
- Usage: User profile operations
4. Sunshine Location Service
Purpose: Location and area data
Configuration:
- Base URL:
API_URL_SUNSHINE - Authentication: API key
- Usage: Location lookup, province/city data
5. APISAT
Purpose: Satellite tracking (purpose unclear from code)
Configuration:
- Base URL:
API_URL_APISATandAPISAT_LINK - Authentication: API key
- Usage: External tracking integration
6. EatSOK
Purpose: Food delivery partner integration
Configuration:
- Base URL:
API_EATSOK - Authentication: Basic Auth
- API Key:
EATSOK_API_KEY - Secret:
EATSOK_SECRET_KEY_ONDEL
- API Key:
- Special Features:
- Separate image directories
- Custom scanning workflow
7. Xendit Payment Gateway
Purpose: Payment processing and payouts
Features:
- Payment collection
- Payout disbursement
- Transaction tracking
Models:
-
xendit_payment- Payment records -
xendit_payout- Payout records
8. Blibli Marketplace
Purpose: E-commerce integration
Configuration:
- Webhook Key:
BLIBLI_WEBHOOK_KEY - Authentication: Webhook signature validation
- Features: Order notifications, fulfillment
9. OnMarket Platform
Purpose: Marketplace platform integration
Configuration:
- Webhook Key:
ONMARKET_WEBHOOK_KEY - Authentication: Webhook signature validation
- Features: Multi-marketplace aggregation
API Utility Modules
Location: app/config/api.js
Purpose: Centralized API endpoint configuration
Usage:
const api = require('./config/api');
// Make external API call
const response = await axios.get(api.AGENT_SYSTEM + '/agents');
Webhook Handling
Incoming Webhooks:
-
Courier Partner Webhooks
- Endpoint:
/api/3p/{partner}/webhook - Authentication: Basic Auth or API Key
- Purpose: Status updates from couriers
- Endpoint:
-
Marketplace Webhooks
- Endpoint:
/api/marketplace/webhook - Authentication: Webhook signature
- Purpose: New order notifications
- Endpoint:
Outgoing Webhooks:
Utility: app/utility/web-hook.js
Purpose: Notify external systems of status changes
Configuration:
- Configured per partner/customer
- Triggered on status updates
- Includes retry logic
Example:
// Trigger webhook on status change
await triggerWebhook({
awb: "ONX1234567890",
status: "DELIVERED",
timestamp: new Date(),
location: "Jakarta"
});
Environment Variables
Required Environment Variables
Database Configuration
# PostgreSQL - OSAS Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DBS=osas_db
DB_DIALECT=postgres
# Connection Pool
DB_POOL_MAX=5
DB_POOL_MIN=0
DB_POOL_ACQUIRE=30000
DB_POOL_IDLE=10000
# ONMART Database
ONMART_DB_HOST=localhost
ONMART_DB_PORT=5432
ONMART_DB_USER=postgres
ONMART_DB_PASSWORD=your_password
ONMART_DBS=onmart_db
Application Configuration
# Server
PORT=4220
BASEURL=http://localhost:4220
# JWT Authentication
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRATION=86400 # 24 hours in seconds
# Custom Configuration
CUSTOM_ALPHABET=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Security Configuration
# Rate Limiting
RATE_LIMIT_WINDOW_MS=10000 # 10 seconds
RATE_LIMIT_MAX=20 # 20 requests per window
# CORS
ORIGIN_CORS=http://localhost:3000,https://yourdomain.com
External API URLs
# Internal Services
API_URL_AGENT_ONAGENT=http://agent-system/api
API_URL_USERONDELIV=http://user-service/api
API_URL_USERSTATE=http://user-state/api
API_URL_SUNSHINE=http://sunshine-api/api
API_URL_APISAT=http://apisat/api
APISAT_LINK=http://apisat-link/api
# Partner APIs
API_EATSOK=https://eatsok-api.com
Courier Partner Credentials
# JNE
JNE_API_KEY=your_jne_api_key
JNE_USERNAME=your_jne_username
JNE_PASSWORD=your_jne_password
# Lion Parcel
LIONPARCEL_BEARER_TOKEN=your_lion_parcel_token
LIONPARCEL_PICKUP_CRON=*/30 * * * * # Every 30 minutes
# AnteRaja
ANTERAJA_URL=https://anteraja-api.com
ANTERAJA_ACCESS_KEY_ID=your_access_key
ANTERAJA_SECRET_ACCESS_KEY=your_secret_key
ANTERAJA_SECRET_KEY_ONDEL=your_webhook_secret
# JT Cargo
JTCARGO_API_KEY=your_jtcargo_key
JTCARGO_USERNAME=your_jtcargo_username
JTCARGO_PASSWORD=your_jtcargo_password
Authentication Keys
# Partner Integration Authentication
EATSOK_API_KEY=your_eatsok_api_key
EATSOK_SECRET_KEY_ONDEL=your_eatsok_secret
LINKED_ACCOUNT_SECRET_KEY=your_linked_secret
INTEGRATION_PROC_KEY=your_integration_key
Marketplace Webhooks
# Blibli
BLIBLI_WEBHOOK_KEY=your_blibli_webhook_key
# OnMarket
ONMARKET_WEBHOOK_KEY=your_onmarket_webhook_key
Payment Gateway
# Xendit
XENDIT_API_KEY=your_xendit_api_key
XENDIT_SECRET_KEY=your_xendit_secret
Optional Environment Variables
# Email Configuration (Nodemailer)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your_email@gmail.com
EMAIL_PASSWORD=your_app_password
EMAIL_FROM=OnDelivery <noreply@ondelivery.com>
# File Upload Limits
MAX_FILE_SIZE=10485760 # 10MB in bytes
# Logging
LOG_LEVEL=info # error, warn, info, debug
Environment Variable Loading
The application uses dotenv for environment variable management:
require('dotenv').config();
Best Practices:
- Use
.envfile for local development - Use environment-specific
.env.production,.env.development - Never commit
.envfiles to version control - Use
dotenv-vaultfor secure environment management (as mentioned in README)
Vault Management:
# Push to dotenv-vault
npx dotenv-vault@latest push