Product added to cart
IntegrationHub API Documentation
Introduction
Important URLs:
Base URL:
Staging URL:
Base URL:
https://edumalls.com/Staging URL:
https://preprod.edumalls.comIntegrationHub is a comprehensive, enterprise-grade REST API solution specifically designed for Edumalls Marketplace Sellers. It serves as a bridge between your external systems (ERP, WMS, third-party services) and your Edumalls Store, enabling seamless automation of order processing, inventory management, and real-time event notifications.
Key Features
Secure Authentication
OAuth 2.0 Bearer token-based authentication with automatic seller verification.
Order Management
View and update orders with control over status, invoicing, and shipments.
Product Management
Update product information, pricing, and inventory levels in real-time.
Webhook Notifications
Receive instant notifications for different order events.
Seller-Scoped Access
Automatic data isolation - each seller can only access their own orders and products.
Paginated Responses
Efficient data retrieval for large datasets with configurable page sizes.
Supported Resources
| Resource | Read | Create | Update | Delete |
|---|---|---|---|---|
| Orders | Yes | No | Yes | No |
| Products | Yes | No | Yes | No |
| Customers | Yes | No | No | No |
Authentication
Overview
Authentication is the foundation of secure API access. IntegrationHub implements OAuth 2.0 Bearer Token authentication, providing a balance between security and ease of implementation.
How Authentication Works
IntegrationHub's authentication system consists of two phases:
- Token Generation Phase:
Seller Credentials → Token Generation → Bearer Token - API Request Phase:
API Request + Token → Token Validation → Seller Identity → Data Access
Every API request goes through:
- System extracts the bearer token from the
Authorizationheader - Verifies the token signature and expiration
- Extracts the seller ID from the token payload and confirms the seller is active
- Ensures the seller can only access their own data
Security Best Practices
- Store Tokens Securely: Preferably encrypted if storing in a database
- Use HTTPS: Always use HTTPS endpoints in production
- Implement Auto Re-authentication: Automatic re-authentication on 4XX errors
Token States
| State | Description |
|---|---|
| Active | Token is valid and can be used for API requests |
| Expired | Token has exceeded its lifetime |
| Revoked | Token has been manually invalidated |
| Invalid | Token signature is invalid or token format is incorrect |
Handling Expired Tokens
When a token expires, you'll receive a 4XX error:
{
"success": false,
"message": "Bearer token is revoked."
}Solution: Generate a new token using the authentication endpoint.
Authentication
Generate Bearer Token
Endpoint
POST /rest/V1/integration/seller/token
Authentication: None (Public endpoint)
Request Body
{
"username": "[email protected]",
"password": "SellerPassword@123"
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
username | string | ✔️ | Seller E-mail Address |
password | string | ✔️ | Seller Account Password |
Success Response
Status Code: 200
"eyJraWQiOiIxIiwiYW...."Error Responses
Invalid Credentials
{
"success": false,
"message": "Invalid customer credentials."
}Not an Active Seller
{
"success": false,
"message": "Access denied. Customer is not a seller."
}Integration Disabled
{
"success": false,
"message": "Integration is currently disabled. Please contact support for more details."
}Using the Bearer Token
Include the token in the Authorization header of all API requests:
curl -X POST "https://edumalls.com/rest/V1/integration/seller/order" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{...}'Order API
Introduction
The Order API is the core of IntegrationHub, providing comprehensive access to Edumalls Marketplace Orders for sellers. Whether you're building an order management system, integrating with a fulfillment warehouse, or creating custom reporting tools, this API gives everything you need to work with orders programmatically.
Key Capabilities
- View Orders: Retrieve Orders with rich filtering and pagination options
- Order Details: View complete order information, including items, customer, addresses, shipments, and payment details
- Update Status: Change the order status to reflect your workflow
- Create Shipment: Mark items as shipped and add tracking information
- Cancel Order: Cancel the order that cannot be fulfilled
- Add Comment: Add a comment and notify the customer
Available Actions
| Action | Description | When to use |
|---|---|---|
view_order_list | List all orders with pagination and filtering | You need to see all your orders, optionally filtered by status/state |
view_order_data | Retrieve a single order by ID or order number | You need complete details for a specific order |
update_order_status | Update order status | You want to change order status without other updates |
update_order_invoice | Create an invoice for an order | Payment has been received and you need to generate an invoice |
update_order_shipment | Create a shipment for an order | Items have been shipped and you want to notify the customer |
update_order_cancel | Cancel an order | Order cannot be fulfilled (out of stock, customer request, etc.) |
update_order_comment | Add a new comment to the order history | You need to direct a message or send an update to the customer |
Order API
Order Object
Complete Order Structure
{
"order_id": 123,
"increment_id": "1000000123",
"state": "complete",
"status": "delivered",
"store_code": "sa_en",
"currency_code": "SAR",
"created_at": "2026-01-15 10:30:00",
"updated_at": "2026-01-15 14:20:00",
"grand_total": 182,
"subtotal": 158.26,
"tax_amount": 23.74,
"discount_amount": 0,
"shipping_amount": 0,
"shipping_description": "Flat Rate - Fixed",
"total_paid": 182,
"total_refunded": null,
"total_due": 0,
"total_invoiced": 182,
"total_canceled": null,
"total_qty_ordered": 1,
"weight": 0.25,
"coupon_code": null,
"payment_method": "cpayonline",
"shipping_method": "flatrate_flatrate",
"customer": {
"id": 456,
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"is_guest": 0,
"classera_id": "123",
"username": "cera123",
"school_id": "123",
"school_name": "test school",
"school_group_id": "2",
"school_group_name": "Classera Test",
"created_at": "2024-07-24 16:00:00"
},
"invoice": {
"increment_id": "10000000001",
"state": "paid",
"grand_total": 182,
"subtotal": 158.26,
"tax_amount": 23.74,
"shipping_amount": 0,
"discount_amount": 0,
"created_at": "2026-01-15 11:00:00",
"updated_at": "2026-01-15 11:00:00"
},
"shipment": {
"increment_id": "10000000001",
"total_qty": 1,
"created_at": "2026-01-15 14:00:00",
"updated_at": "2026-01-15 14:00:00",
"tracking": [
{
"carrier_code": "*SLK* - Starlinks Domestic",
"title": "SLK - Starlinks Domestic",
"track_number": "S0000000001"
}
]
},
"billing_address": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"street": "7811 Abdullah Bukhari",
"city": "JEDDAH",
"telephone": "05555678",
"region": "Others",
"postcode": null,
"country_id": "SA",
"shortaddress": "JCZB7811"
},
"shipping_address": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"street": "7811 Abdullah Bukhari",
"city": "JEDDAH",
"telephone": "05555678",
"region": "Others",
"postcode": null,
"country_id": "SA",
"shortaddress": "JCZB7811"
},
"items": [
{
"product_id": 789,
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"product_options": null,
"qty_ordered": 1,
"qty_invoiced": 1,
"qty_shipped": 1,
"qty_refunded": 0,
"qty_canceled": 0,
"qty_backordered": null,
"price": 158.26,
"discount_amount": 0,
"discount_percent": null,
"discount_invoiced": null,
"tax_amount": 23.74,
"tax_percent": null,
"tax_invoiced": null,
"amount_refunded": null,
"weight": 0.25,
"is_virtual": null,
"free_shipping": null,
"gift_message_id": null,
"gift_message_available": null,
"applied_rule_ids": null,
"created_at": "2026-01-15 10:30:00",
"status": "delivered",
"updated_at": "2026-01-15 14:20:00"
}
]
}Field Definitions
Base Order Fields
| Field | Type | Description |
|---|---|---|
order_id | integer | Internal order ID |
increment_id | string | Human-readable order number (e.g., "000000123") |
state | string | Order state |
status | string | Order status |
store_code | string | Store view code |
currency_code | string | Currency code |
created_at | string | Order creation timestamp |
updated_at | string | Last update timestamp |
grand_total | float | Total order amount including tax and shipping |
subtotal | float | Subtotal before tax and shipping |
tax_amount | float | Total tax amount |
discount_amount | float | Total discount amount |
shipping_amount | float | Shipping cost |
shipping_description | string | Shipping method description |
total_paid | float | Amount paid |
total_refunded | float | Amount refunded |
total_due | float | Amount due |
total_invoiced | float | Amount invoiced |
total_canceled | float | Amount canceled |
total_qty_ordered | integer | Total quantity of items ordered |
weight | float | Total order weight |
coupon_code | string|null | Applied coupon code |
payment_method | string | Payment method code |
shipping_method | string | Shipping method code |
Customer Object Fields
| Field | Type | Description |
|---|---|---|
id | integer | Customer ID (0 for guest) |
email | string | Customer email |
firstname | string | Customer first name |
lastname | string | Customer last name |
is_guest | boolean | Whether customer is guest |
Additional Customer Fields (Registered Customers Only)
| Field | Type | Description |
|---|---|---|
classera_id | integer | Student ID |
username | string | Student username |
school_id | integer | School ID |
school_name | string | School name |
school_group_id | integer | School group ID |
school_group_name | string | School group Name |
created_at | string | Customer creation timestamp |
Invoice Object Fields
| Field | Type | Description |
|---|---|---|
increment_id | string | Invoice number |
state | integer | Invoice state (1=pending, 2=paid, 3=canceled) |
grand_total | float | Invoice total |
subtotal | float | Invoice subtotal |
tax_amount | float | Tax amount |
shipping_amount | float | Shipping amount |
discount_amount | float | Discount amount |
created_at | string | Invoice creation timestamp |
updated_at | string | Invoice update timestamp |
Shipment Object Fields
| Field | Type | Description |
|---|---|---|
increment_id | string | Shipment number |
total_qty | integer | Total quantity shipped |
created_at | string | Shipment creation timestamp |
updated_at | string | Shipment update timestamp |
tracking | array | Array of tracking information objects |
Address Object Fields
| Field | Type | Description |
|---|---|---|
email | string | Email address |
firstname | string | First name |
lastname | string | Last name |
street | string | Street address |
city | string | City |
region | string | State/Province/Region |
country_id | string | Country code (ISO 3166-1 alpha-2) |
postcode | string | Postal/ZIP code |
telephone | string | Phone number |
company | string|null | Company name |
fax | string|null | Fax number |
Item Object Fields
| Field | Type | Description |
|---|---|---|
product_id | integer | Product ID |
sku | string | Product SKU (seller prefix removed) |
name | string | Product name |
product_options | string|null | JSON-encoded product options |
qty_ordered | integer | Quantity ordered |
qty_invoiced | integer | Quantity invoiced |
qty_shipped | integer | Quantity shipped |
qty_refunded | integer | Quantity refunded |
qty_canceled | integer | Quantity canceled |
qty_backordered | integer | Quantity backordered |
price | float | Item price |
discount_amount | float | Discount amount for item |
discount_percent | float | Discount percentage |
discount_invoiced | float | Invoiced discount amount |
amount_refunded | float | Refunded amount |
weight | float | Item weight |
is_virtual | boolean | Whether product is virtual |
free_shipping | boolean | Whether item has free shipping |
gift_message_id | integer|null | Gift message ID |
gift_message_available | boolean | Whether gift message is available |
applied_rule_ids | string|null | Comma-separated cart rule IDs |
created_at | string | Item creation timestamp |
status | string | Item status |
updated_at | string | Item last update timestamp |
Order API
Order Lifecycle
Order State vs Order Status
- There are multiple statuses for a single state, allowing for custom workflow stages.
- State: System-defined order state
newprocessingcompleteclosedcancelholded
- Status: Configurable order status
pendingpending paymentprocessingreadytoshipsenttostarlinkssenttobostacompleteoutfordeliveryfaileddeliverydeliveredenrolledrefundedcanceled
Physical Order Lifecycle
Note: The following diagram shows the typical flow for physical products (shippable items).
graph TD A[NEW ORDER] B[PENDING PAYMENT] C[PAYMENT RECEIVED] D[CREATE INVOICE] F[READY TO SHIP] G[Create Shipment] H[Shipped] I[Delivered] J[Canceled] K[Delivery Failed] L[Create CreditMemo] M[Refunded] A --> |state: 'new'
status: 'pending'| B B --> |state: 'new'
status: 'pending_payment'| C C --> D D --> |state: 'processing'
status: 'readytoship'| F F --> G G --> |state: 'complete'
status: 'shipped'| H H --> |state: 'complete'
status: 'delivered'|I A -.-> |state: 'canceled'
status: 'canceled'|J B -.-> |state: 'canceled'
status: 'canceled'|J H -.-> |state:'complete'
status: 'failedtodeliver'|K I -.-> L K -.-> L L -.-> |state: 'closed'
status: 'refunded'|M style D fill:#90EE90,stroke:#28a745,stroke-width:2px style G fill:#90EE90,stroke:#28a745,stroke-width:2px style J fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style K fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style M fill:#FFB6C1,stroke:#dc3545,stroke-width:2px
status: 'pending'| B B --> |state: 'new'
status: 'pending_payment'| C C --> D D --> |state: 'processing'
status: 'readytoship'| F F --> G G --> |state: 'complete'
status: 'shipped'| H H --> |state: 'complete'
status: 'delivered'|I A -.-> |state: 'canceled'
status: 'canceled'|J B -.-> |state: 'canceled'
status: 'canceled'|J H -.-> |state:'complete'
status: 'failedtodeliver'|K I -.-> L K -.-> L L -.-> |state: 'closed'
status: 'refunded'|M style D fill:#90EE90,stroke:#28a745,stroke-width:2px style G fill:#90EE90,stroke:#28a745,stroke-width:2px style J fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style K fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style M fill:#FFB6C1,stroke:#dc3545,stroke-width:2px
Virtual Order Lifecycle
Note: The following diagram shows the typical flow for virtual products (digital courses, downloads, etc.).
graph TD A[NEW ORDER] B[PENDING PAYMENT] C[PAYMENT RECEIVED] D[CREATE INVOICE] E[READY FOR ACCESS] F[COURSE ENROLLED] G[CONTENT DOWNLOADED] J[CANCELED] L[CREATE CREDIT MEMO] M[REFUNDED] A --> |state: 'new'
status: 'pending'| B B --> |state: 'new'
status: 'pending_payment'| C C --> |state: 'processing'
status: 'processing'| D D --> |state: 'processing'
status: 'ready_for_access'| E E --> |state: 'complete'
status: 'enrolled'| F E --> |state: 'complete'
status: 'downloaded'| G A -.-> |state: 'canceled'
status: 'canceled'| J B -.-> |state: 'canceled'
status: 'canceled'| J C -.-> |state: 'canceled'
status: 'canceled'| J F -.-> |Customer Request| L G -.-> |Customer Request| L L -.-> |state: 'closed'
status: 'refunded'| M style D fill:#90EE90,stroke:#28a745,stroke-width:3px style E fill:#FFD700,stroke:#FFA500,stroke-width:3px style F fill:#87CEEB,stroke:#4682B4,stroke-width:3px style G fill:#87CEEB,stroke:#4682B4,stroke-width:3px style J fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style M fill:#FFB6C1,stroke:#dc3545,stroke-width:2px
status: 'pending'| B B --> |state: 'new'
status: 'pending_payment'| C C --> |state: 'processing'
status: 'processing'| D D --> |state: 'processing'
status: 'ready_for_access'| E E --> |state: 'complete'
status: 'enrolled'| F E --> |state: 'complete'
status: 'downloaded'| G A -.-> |state: 'canceled'
status: 'canceled'| J B -.-> |state: 'canceled'
status: 'canceled'| J C -.-> |state: 'canceled'
status: 'canceled'| J F -.-> |Customer Request| L G -.-> |Customer Request| L L -.-> |state: 'closed'
status: 'refunded'| M style D fill:#90EE90,stroke:#28a745,stroke-width:3px style E fill:#FFD700,stroke:#FFA500,stroke-width:3px style F fill:#87CEEB,stroke:#4682B4,stroke-width:3px style G fill:#87CEEB,stroke:#4682B4,stroke-width:3px style J fill:#FFB6C1,stroke:#dc3545,stroke-width:2px style M fill:#FFB6C1,stroke:#dc3545,stroke-width:2px
Key Actions
| Action | State Change | Status Change |
|---|---|---|
| Create Invoice | new → processing | pending_payment → processing |
| Create Shipment | processing → complete | readytoship → shipped |
| Cancel Order | Any → canceled | Any → canceled |
| Refund | complete → closed | Any → refunded |
Order API
List Orders
Retrieve a paginated list of orders belonging to the authenticated seller.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "view_order_list",
"data": {
"filter": {
"status": {
"eq": "processing"
}
},
"include_shipments": true,
"include_invoices": true,
"sort": "DESC",
"page_size": 20,
"page": 1
}
}Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
sort | string | ❌ | DESC | Sort Direction: ASC or DESC (by created_at) |
page | integer | ❌ | 1 | Page number (must be ≥ 1) |
page_size | integer | ❌ | 10 | Items per page (1-50) |
include_invoices | boolean | ❌ | false | Include invoice data in response |
include_shipments | boolean | ❌ | false | Include shipment data in response |
filter | object | ❌ | null | Filter criteria |
Filter Options
You can filter orders by state or status:
{
"filter": {
"status": {
"eq": "processing"
}
}
}Available Filter Operators
| Operator | Description | Example |
|---|---|---|
eq | Equals | {"status": {"eq": "pending"}} |
in | In array | {"status": {"in": ["pending", "processing", "complete"]}} |
neq | Not equals | {"status": {"neq": "canceled"}} |
Success Response
Status Code: 200
{
"success": true,
"message": "5 order(s) retrieved successfully",
"total_count": 5,
"page_size": 10,
"page": 1,
"orders": [
{
"order_id": 123,
"increment_id": "1000000123",
"state": "complete",
"status": "delivered",
...
}
]
}Order API
Retrieve Order
Retrieve a single order by order_id or increment_id.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body by Order ID
{
"action": "view_order_data",
"data": {
"order_id": 123
}
}Request Body by Increment ID
{
"action": "view_order_data",
"data": {
"increment_id": "1000000001"
}
}Parameters
You must provide either order_id or increment_id (not both).
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
Success Response
Status Code: 200
{
"success": true,
"message": "Order retrieved successfully",
"order": {
"order_id": 123,
"increment_id": "000000123",
"state": "processing",
"status": "processing",
...
}
}Error Responses
Order Not Found
{
"success": false,
"message": "Order not found or you do not have permission to access it."
}Order API
Update Order Status
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_order_status",
"data": {
"increment_id": "10000000123",
"state": "complete",
"status": "delivered",
"comment": "order has been shipped",
"notify": true
}
}Parameters
You must provide either order_id or increment_id (not both).
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
state | string | ❌ | Order State |
status | string | ✔️ | Order Status |
comment | string | ❌ | Add comment to the order |
notify | boolean | ❌ | Notify customer by email |
Success Response
Status Code: 200
{
"success": true,
"message": "Order status updated successfully.",
"order": {
"order_id": 123,
"increment_id": "10000008911",
"state": "complete",
"status": "delivered",
...
}
}Order API
Create Shipment
Create a shipment for an order with optional tracking information.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_order_shipment",
"data": {
"increment_id": "10000000123",
"state": "complete",
"status": "outfordelivery",
"comment": "order has been shipped",
"tracking": [{
"title": "Aramex",
"carrier_code": "aramex",
"track_number": "12345"
}],
"notify": true
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
state | string | ❌ | Order State |
status | string | ❌ | Order Status |
tracking | array | ❌ | Array of tracking information |
comment | string | ❌ | Shipment comment |
notify | boolean | ❌ | Notify customer by email |
Tracking Object
| Field | Type | Required | Description |
|---|---|---|---|
title | string | ✔️ | Carrier name |
carrier_code | string | ✔️ | Carrier code |
track_number | string | ✔️ | Tracking number |
Success Response
Status Code: 200
{
"success": true,
"message": "Order shipped successfully.",
"order": {
"order_id": 123,
"increment_id": "10000000123",
"state": "complete",
"status": "outfordelivery",
"shipment": {
"increment_id": "10000000001",
"total_qty": 1,
"tracking": [...]
},
...
}
}Order API
Create Invoice
Create an invoice for an order.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_order_invoice",
"data": {
"order_id": 24123,
"paid": 161,
"state": "processing",
"status": "processing",
"comment": "Invoiced",
"notify": true
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
paid | float | ✔️ | Amount Paid |
state | string | ❌ | Order State |
status | string | ❌ | Order Status |
comment | string | ❌ | Invoice comment |
notify | boolean | ❌ | Notify customer by email |
Success Response
Status Code: 200
{
"success": true,
"message": "Order invoiced successfully.",
"order": {
"order_id": 24123,
"increment_id": "1000000123",
"state": "processing",
"status": "processing",
"invoice": {
"increment_id": "10000000001",
"state": "paid",
"grand_total": 161,
...
},
...
}
}Order API
Cancel Order
Cancel an order that cannot be fulfilled.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_order_cancel",
"data": {
"increment_id": "10000000123",
"comment": "Order has been canceled",
"notify": true
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
comment | string | ❌ | Cancel comment |
notify | boolean | ❌ | Notify customer by email |
Success Response
Status Code: 200
{
"success": true,
"message": "Order cancelled successfully.",
"order": {
"order_id": 123,
"increment_id": "10000008910",
"state": "canceled",
"status": "canceled",
...
}
}Error Responses
Order Cannot Be Canceled
{
"success": false,
"message": "This action is not allowed."
}Order API
Add Comment
Add a comment to an order's history and optionally notify the customer.
Endpoint
POST /rest/V1/integration/seller/order
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_order_comment",
"data": {
"increment_id": "10000008910",
"comment": "Your order is being processed",
"notify": true
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id or increment_id | integer/string | ✔️ | Order Identifier |
comment | string | ✔️ | Comment text |
notify | boolean | ❌ | Notify customer by email |
Success Response
Status Code: 200
{
"success": true,
"message": "Order comment added successfully.",
"order": {
"order_id": 123,
"increment_id": "10000008910",
...
}
}Product API
Introduction
The Product API enables sellers to manage their product catalog programmatically. You can retrieve product information, update pricing, manage inventory levels, and modify product attributes through a simple, unified interface.
Key Capabilities
- View Products: Retrieve products with pagination and filtering by stock status.
- Product Details: View complete product information including pricing, inventory, and attributes.
- Update Data: Modify product name, description, and short description.
- Update Price: Change product price, special price, and promotional dates.
- Update Stock: Manage product quantities and stock status.
Supported Product Types
- Simple Products: Standard products without variations
- Virtual Products: Digital products (courses, downloads, etc.)
- Configurable Products: Products with variations (size, color, etc.)
Available Actions
| Action | Description | When to use |
|---|---|---|
view_product_list | List all products with pagination and filtering | You need to see all your products, optionally filtered by status/stock |
view_product_data | Retrieve a single product by ID or SKU | You need complete details for a specific product |
update_product_data | Update product attributes | You want to change product name, description, or short description |
update_product_stock | Update product quantities and stock status | You need to update inventory levels |
update_product_price | Update product prices and special prices | You want to change pricing or set up promotions |
Product API
Product Object
Complete Product Structure
{
"product_id": 123,
"type_id": "simple",
"sku": "KSA-6958428553391",
"name": "Product Name",
"description": "Product full description",
"short_description": "Product short description",
"price": "9.560000",
"special_price": "6.020000",
"special_from_date": "2023-12-13 00:00:00",
"special_to_date": "2023-12-31 23:59:59",
"quantity_and_stock_status": {
"is_in_stock": false,
"qty": 20
},
"status": "1",
"visibility": "1",
"has_options": "0",
"tax_class_id": "12",
"required_options": "0",
"url_key": "product-url-slug",
"created_at": "2023-03-17 09:25:20",
"updated_at": "2026-01-13 00:32:39"
}Field Definitions
| Field | Type | Description |
|---|---|---|
product_id | integer | Internal product ID |
type_id | string | Product type (simple, virtual, configurable, etc.) |
sku | string | Product SKU |
name | string | Product name |
description | string | Full product description |
short_description | string | Short product description |
price | float | Regular price |
special_price | float|null | Special/Sale price |
special_from_date | string|null | Special price start date |
special_to_date | string|null | Special price end date |
quantity_and_stock_status | object | Stock information object containing is_in_stock (boolean) and qty (integer) |
status | string | Product status ("1" = enabled, "2" = disabled) |
visibility | integer | Product visibility ("1"=Not Visible, "2"=Catalog, "3"=Search, "4"=Catalog+Search) |
has_options | string | Whether product has custom options ("0"=no, "1"=yes) |
tax_class_id | float | Tax class ID |
required_options | string | Whether product has required options ("0"=no, "1"=yes) |
url_key | string | Product URL slug |
created_at | string | Product creation timestamp |
updated_at | string | Last update timestamp |
Note: The exact fields returned depend on which product attributes are marked as "Visible in IntegrationHub" in the admin configuration. The fields above represent commonly returned attributes.
Product API
List Products
Endpoint
POST /rest/V1/integration/seller/product
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "view_product_list",
"data": {
"filter": {
"in_stock": true,
"status": true
},
"sort": "ASC",
"page_size": 20,
"page": 1
}
}Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | ❌ | 1 | Page number (must be ≥ 1) |
page_size | integer | ❌ | 10 | Items per page (1-50) |
sort | string | ❌ | DESC | Sort Direction: ASC or DESC (by product_id) |
filter | object | ❌ | null | Filter criteria |
Filter Options
| Field | Type | Description |
|---|---|---|
in_stock | boolean | Filter by stock status (true = in stock, false = out of stock) |
status | boolean | Filter by product status (true = enabled, false = disabled) |
Success Response
Status Code: 200
{
"success": true,
"message": "15 Product(s) retrieved successfully",
"total_count": 15,
"page_size": 10,
"page": 1,
"products": [
{
"product_id": 123,
"type_id": "simple",
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"price": "99.990000",
"quantity_and_stock_status": {
"is_in_stock": true,
"qty": 100
},
"status": "1",
...
}
]
}Product API
Retrieve Product
Endpoint
POST /rest/V1/integration/seller/product
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body by SKU
{
"action": "view_product_data",
"data": {
"sku": "PRODUCT-SKU-001"
}
}Request Body by Product ID
{
"action": "view_product_data",
"data": {
"product_id": 123
}
}Parameters
You must provide either product_id or sku (not both).
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id or sku | integer/string | ✔️ | Product Identifier |
Success Response
Status Code: 200
{
"success": true,
"message": "Product retrieved successfully",
"product": {
"product_id": 123,
"type_id": "simple",
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"description": "Product full description",
"short_description": "Product short description",
"price": "99.990000",
"special_price": "79.990000",
"quantity_and_stock_status": {
"is_in_stock": true,
"qty": 100
},
"status": "1",
"visibility": "4",
...
}
}Error Responses
Missing Identifier
{
"success": false,
"message": "Product 'sku' or 'product_id' is required."
}Both Identifiers Provided
{
"success": false,
"message": "Please provide either 'sku' or 'product_id', not both."
}Product Not Found
{
"success": false,
"message": "Product not found or you do not have permission to access it."
}Product API
Update Product Data
Update product attributes such as name, description, and short_description.
Endpoint
POST /rest/V1/integration/seller/product
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_product_data",
"data": {
"sku": "PRODUCT-SKU-001",
"name": "Updated Product Name",
"description": "Updated full description",
"short_description": "Updated short description"
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id or sku | integer/string | ✔️ | Product Identifier |
name | string | ❌ | Product name |
description | string | ❌ | Product description |
short_description | string | ❌ | Product short description |
Note: At least one of the following fields must be provided:
name, description, short_description.Success Response
Status Code: 200
{
"success": true,
"message": "Product data updated successfully.",
"product": {
"product_id": 123,
"type_id": "simple",
"sku": "PRODUCT-SKU-001",
"name": "Updated Product Name",
"description": "Updated full description",
"short_description": "Updated short description",
"price": "99.990000",
"quantity_and_stock_status": {
"is_in_stock": true,
"qty": 100
},
...
}
}Error Responses
No Fields Provided
{
"success": false,
"message": "At least one of the following fields must be provided: 'name', 'description', 'short_description'."
}Product Not Found
{
"success": false,
"message": "Product not found or you do not have permission to update it."
}Product API
Update Product Price
Update product pricing, including regular price and special promotional pricing.
Endpoint
POST /rest/V1/integration/seller/product
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_product_price",
"data": {
"sku": "PRODUCT-SKU-001",
"price": 99.99,
"special_price": 79.99,
"special_from_date": "2026-01-01 00:00:00",
"special_to_date": "2026-12-31 23:59:59"
}
}Parameters
You must provide either product_id or sku (not both).
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id or sku | integer/string | ✔️ | Product Identifier |
price | float | ❌ | Regular price |
special_price | float | ❌ | Special/Sale price |
special_from_date | string | ❌ | Special price start date (format: "YYYY-MM-DD HH:MM:SS") |
special_to_date | string | ❌ | Special price end date (format: "YYYY-MM-DD HH:MM:SS") |
Note: At least one pricing field must be provided.
Success Response
Status Code: 200
{
"success": true,
"message": "Product price updated successfully.",
"product": {
"product_id": 123,
"type_id": "simple",
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"price": "99.990000",
"special_price": "79.990000",
"special_from_date": "2026-01-01 00:00:00",
"special_to_date": "2026-12-31 23:59:59",
"quantity_and_stock_status": {
"is_in_stock": true,
"qty": 100
},
...
}
}Error Responses
No Fields Provided
{
"success": false,
"message": "At least one of the following fields must be provided: 'price', 'special_price', 'special_from_date', 'special_to_date'."
}Invalid Price
{
"success": false,
"message": "Field 'price' must be a positive number."
}Product API
Update Product Stock
Update product inventory quantities and stock status.
Endpoint
POST /rest/V1/integration/seller/product
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "update_product_stock",
"data": {
"sku": "PRODUCT-SKU-001",
"qty": 150,
"is_in_stock": true
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id or sku | integer/string | ✔️ | Product Identifier |
qty | integer | ❌ | Available quantity |
is_in_stock | boolean | ❌ | Stock status (true = In Stock, false = Out of Stock) |
Note: At least one of
qty or is_in_stock must be provided.Success Response
Status Code: 200
{
"success": true,
"message": "Product stock updated successfully.",
"product": {
"product_id": 123,
"type_id": "simple",
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"price": "99.990000",
"quantity_and_stock_status": {
"is_in_stock": true,
"qty": 150
},
"status": "1",
...
}
}Error Responses
No Fields Provided
{
"success": false,
"message": "At least one of the following fields must be provided: 'qty', 'is_in_stock'."
}Invalid Quantity
{
"success": false,
"message": "Field 'qty' must be a positive integer."
}Invalid Stock Status
{
"success": false,
"message": "Field 'is_in_stock' must be a boolean."
}Customer API
Introduction
The Customer API provides read-only access to customer information for sellers. You can retrieve lists of customers who have purchased from your store, helping you understand your customer base and manage relationships.
Key Capabilities
- View Customers: Retrieve customers who have purchased from your store.
- Customer Details: Access customer information, including contact details and purchase history.
Access Restrictions
- Sellers can only access customers who have placed orders with them
- Customer-sensitive data is filtered based on privacy settings
- Read-only access - no modifications allowed
Available Actions
| Action | Description | When to use |
|---|---|---|
view_customer_list | List all customers with pagination | You need to see all customers who have ordered from your store |
view_customer_groups | View customer groups | You need to understand customer segmentation |
Customer Object Structure
{
"id": 456,
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"is_guest": 0,
"classera_id": "123",
"username": "cera123",
"school_id": "123",
"school_name": "test school",
"school_group_id": "2",
"school_group_name": "Classera Test",
"created_at": "2024-07-24 16:00:00"
}Customer API
Customer Object
Complete Customer Structure
{
"id": 456,
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"is_guest": 0,
"classera_id": "123",
"username": "cera123",
"school_id": "123",
"school_name": "test school",
"school_group_id": "2",
"school_group_name": "Classera Test",
"created_at": "2024-07-24 16:00:00"
}Field Definitions
Customer Object Fields
| Field | Type | Description |
|---|---|---|
id | integer | Customer ID (0 for guest) |
email | string | Customer email |
firstname | string | Customer first name |
lastname | string | Customer last name |
is_guest | boolean | Whether customer is guest |
Additional Customer Fields (Registered Customers Only)
| Field | Type | Description |
|---|---|---|
classera_id | integer | Student ID |
username | string | Student username |
school_id | integer | School ID |
school_name | string | School name |
school_group_id | integer | School group ID |
school_group_name | string | School group Name |
created_at | string | Customer creation timestamp |
Customer API
List Customers
Endpoint
POST /rest/V1/integration/seller/customer
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "view_customer_list",
"data": {
"sort": "DESC",
"page_size": 20,
"page": 1
}
}Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | ❌ | 1 | Page number (must be ≥ 1) |
page_size | integer | ❌ | 10 | Items per page (1-50) |
sort | string | ❌ | DESC | Sort Direction: ASC or DESC (by customer ID) |
Success Response
Status Code: 200
{
"success": true,
"message": "10 Customer(s) retrieved successfully",
"total_count": 10,
"page_size": 20,
"page": 1,
"customers": [
{
"id": 456,
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"is_guest": 0,
"classera_id": "123",
"username": "cera123",
"school_id": "123",
"school_name": "test school",
"school_group_id": "2",
"school_group_name": "Classera Test",
"created_at": "2024-07-24 16:00:00"
},
...
]
}No Customers Found
{
"success": true,
"message": "No customers found for this seller",
"total_count": 0,
"page_size": 20,
"page": 1,
"customers": []
}Error Responses
Invalid Page Number
{
"success": false,
"message": "Field 'page' must be an integer greater than or equal to 1.",
"total_count": 0,
"page_size": 20,
"page": 1,
"customers": []
}Customer API
Customer Groups
Customer groups allow you to segment your customers for better understanding of your customer base and targeted marketing.
Endpoint
POST /rest/V1/integration/seller/customer
Request Headers
Content-Type: application/json
Authorization: Bearer YOUR_TOKENRequest Body
{
"action": "view_customer_groups",
"data": {}
}Success Response
Status Code: 200
{
"success": true,
"message": "Customer groups retrieved successfully",
"customer_groups": [
{
"id": 1,
"code": "general",
"tax_class_id": 3,
"tax_class_name": "Retail Customer"
},
{
"id": 2,
"code": "wholesale",
"tax_class_id": 4,
"tax_class_name": "Wholesale"
},
{
"id": 3,
"code": "retailer",
"tax_class_id": 5,
"tax_class_name": "Retailer"
}
]
}Customer Group Object Fields
| Field | Type | Description |
|---|---|---|
id | integer | Customer group ID |
code | string | Customer group code |
tax_class_id | integer | Tax class ID associated with this group |
tax_class_name | string | Tax class name |
Note: Customer groups help you understand customer segmentation and can be used for targeted marketing campaigns and pricing strategies.
Webhook & Notifications
Introduction
IntegrationHub's Webhook system provides real-time notifications about order events, enabling your system to react immediately to changes without polling the API. When an order event occurs (like payment received or shipment created), IntegrationHub sends an HTTP POST request to your configured webhook URL.
System Architecture
graph TD Seller["Seller System"] IHub["IntegrationHub"] Edumalls["Edumalls Marketplace"] Seller <-->|"REST API
HTTP POST"| IHub IHub <-->|"Internal API"| Edumalls Edumalls -.->|"Order Events"| IHub IHub -.->|"Webhook
HTTP POST"| Seller style Seller fill:#e1f5ff style IHub fill:#fff3cd style Edumalls fill:#f8d7da
HTTP POST"| IHub IHub <-->|"Internal API"| Edumalls Edumalls -.->|"Order Events"| IHub IHub -.->|"Webhook
HTTP POST"| Seller style Seller fill:#e1f5ff style IHub fill:#fff3cd style Edumalls fill:#f8d7da
Key Features
- Real-Time Notifications: Receive instant updates about order changes
- Event Filtering: Configure which events you want to receive
- Security: Verify webhook authenticity using signatures
- Logging: Complete audit trail of all webhook deliveries
How It Works
When an order event occurs, the following process takes place:
sequenceDiagram participant Order as Order Event participant IHub as IntegrationHub participant Webhook as Your Webhook URL participant Log as Webhook Log Order->>IHub: Event Triggered IHub->>IHub: Check if Notifier Enabled IHub->>IHub: Filter Order Data IHub->>Webhook: POST Webhook Payload Webhook->>IHub: HTTP 200 OK IHub->>Log: Record Success Note over IHub,Webhook: On Failure Webhook->>IHub: HTTP 500 Error IHub->>Log: Record Failure IHub->>Webhook: Retry After Delay
Note: Your webhook endpoint should return a 200 OK status code within 10 seconds. If your endpoint takes longer or returns an error, IntegrationHub will retry the delivery.
Webhook & Notifications
Order Events
IntegrationHub can notify you about the following order events:
Available Events
| Event Code | Description |
|---|---|
110 | Order has been placed successfully |
210 | Payment has been received for the order |
290 | Payment failed or was canceled |
310 | Invoice has been paid |
340 | Invoice has been created for the order |
390 | A credit memo has been issued (refund processed) |
460 | Order has been shipped |
490 | Tracking information has been added to the shipment |
510 | Order has been placed on hold |
540 | Order has been released from hold |
590 | Order has been canceled |
600 | Order status has been updated |
Configuration: You can configure which events you want to receive in your seller dashboard under IntegrationHub settings.
Webhook & Notifications
Payload
Payload Structure
{
"event_code": 460,
"event_message": "Order has been shipped.",
"order": {
"order_id": 24123,
"increment_id": "10000000123",
"state": "processing",
"status": "processing",
"store_code": "sa_en",
"currency_code": "SAR",
"created_at": "2026-01-18 19:06:41",
"updated_at": "2026-01-18 19:09:45",
"grand_total": "161.0000",
"subtotal": "121.7400",
"tax_amount": "18.2600",
"discount_amount": "0.0000",
"shipping_amount": "18.0000",
"shipping_description": "Ship To Home - Receive order in Home",
"total_paid": "161.0000",
"total_refunded": null,
"total_due": 0,
"total_invoiced": "161.0000",
"total_canceled": null,
"total_qty_ordered": "5.0000",
"weight": "1.7650",
"coupon_code": null,
"payment_method": "cashondelivery",
"shipping_method": "flatrate_flatrate",
"order_customer_email": "[email protected]",
"customer": {
"id": 456,
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"is_guest": 0,
"classera_id": "123",
"username": "cera123",
"school_id": "123",
"school_name": "test school",
"school_group_id": "2",
"school_group_name": "Classera Test",
"created_at": "2024-07-24 16:00:00"
},
"invoice": {
"increment_id": "10000000001",
"state_label": "paid",
"grand_total": 161,
"subtotal": 121.74,
"tax_amount": 18.26,
"shipping_amount": 18,
"discount_amount": 0,
"created_at": "2026-01-18 19:09:42",
"updated_at": "2026-01-18 19:09:42"
},
"shipment": {
"increment_id": "10000004370",
"total_qty": 5,
"created_at": "2026-01-18 19:31:06",
"updated_at": "2026-01-18 19:31:06"
},
"billing_address": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"street": ["123 Main Street"],
"city": "Riyadh",
"telephone": "+966501234567",
"region": "Riyadh Region",
"postcode": null,
"country_id": "SA",
"shortaddress": null
},
"shipping_address": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"street": ["123 Main Street"],
"city": "Riyadh",
"telephone": "+966501234567",
"region": "Riyadh Region",
"postcode": null,
"country_id": "SA",
"shortaddress": null
},
"items": [
{
"product_id": 123,
"sku": "PRODUCT-SKU-001",
"name": "Product Name",
"product_options": null,
"qty_ordered": 5,
"qty_invoiced": 5,
"qty_shipped": 5,
"qty_refunded": 0,
"qty_canceled": 0,
"qty_backordered": null,
"price": 24.3500,
"discount_amount": 0,
"discount_percent": 0,
"discount_invoiced": 0,
"amount_refunded": 0,
"weight": "0.3530",
"is_virtual": "0",
"free_shipping": "0",
"gift_message_id": null,
"gift_message_available": "0",
"applied_rule_ids": null,
"created_at": "2026-01-18 19:06:41",
"description": null,
"updated_at": "2026-01-18 19:09:45"
}
]
}
}Payload Fields
| Parameter | Type | Description |
|---|---|---|
event_code | integer | Numeric event code (see Order Events section) |
event_message | string | Human-readable event description |
order | object | Complete Order Object with all configured fields |
Note: The webhook payload structure contains
event_code and event_message at the root level, followed by the complete order object with all configured fields. The order object structure is identical to the Order API response.Webhook & Notifications
Security
Security is a critical aspect of webhook integration. IntegrationHub provides several mechanisms to ensure the authenticity and integrity of webhook payloads.
Webhook Signature Verification
Each webhook request includes a signature header that you can use to verify the request came from IntegrationHub.
Signature Header
X-IntegrationHub-Signature: sha256=abc123def456...Verification Process
- Extract the signature from the
X-IntegrationHub-Signatureheader - Compute the HMAC SHA256 hash of the raw request body using your webhook secret
- Compare the computed hash with the signature from the header
- If they match, the webhook is authentic
Example Verification (PHP)
<?php
$secret = 'your_webhook_secret';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_INTEGRATIONHUB_SIGNATURE'] ?? '';
$hash = substr($signature, 7);
$expectedHash = hash_hmac('sha256', $payload, $secret);
if (hash_equals($expectedHash, $hash)) {
$data = json_decode($payload, true);
} else {
http_response_code(401);
exit('Invalid signature');
}
?>Example Verification (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hash = signature.replace('sha256=', '');
const expectedHash = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(hash, 'hex'),
Buffer.from(expectedHash, 'hex')
);
}
const signature = req.headers['x-integrationhub-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}Security Best Practices
- Always Verify Signatures: Never process webhooks without verifying the signature
- Use HTTPS: Always configure webhook URLs with HTTPS to encrypt data in transit
- Store Secrets Securely: Store your webhook secret in environment variables or secure configuration
- Implement Idempotency: Handle duplicate webhook deliveries gracefully
- Validate Payload: Always validate the webhook payload structure before processing
- Rate Limiting: Implement rate limiting to prevent abuse
- Logging: Log all webhook requests for audit and debugging purposes
Webhook Retry Policy
IntegrationHub implements an automatic retry mechanism for failed webhook deliveries:
- Initial delivery attempt
- Retry after 1 minute if failed
- Retry after 5 minutes if failed
- Retry after 15 minutes if failed
- Retry after 1 hour if failed
- Maximum 5 retry attempts
Important: Your webhook endpoint should return a 200 OK status code within 10 seconds. If your endpoint takes longer or returns an error, IntegrationHub will retry the delivery.
Webhook Logging
All webhook delivery attempts are logged in IntegrationHub. You can view the delivery status, response codes, and error messages in your seller dashboard.
Common Security Issues
| Issue | Solution |
|---|---|
| Signature mismatch | Verify you're using the correct webhook secret and computing the hash correctly |
| Replay attacks | Implement idempotency keys and timestamp validation |
| Man-in-the-middle | Always use HTTPS for webhook URLs |
| Payload tampering | Always verify signatures before processing payloads |
