Guide: Direct Integration
Custom Store Integration Guide#
This guide is for customers running their own sales channel (a self-built website/app — not Haravan, Shopify, WooCommerce, etc.) who want to push orders into Omisell for fulfillment and receive order-processing status updates back.
1. Integration flow overview#
[Your system] [Omisell]
│
│ (0) Get access token
│ ───────────────────────────────────▶
│
│ (1) shop_id of custom store ◀──── Get Shop List
│
│ (2) Customer places order → Add Order
│ ───────────────────────────────────▶ Order created, returns omisell_order_number
│
│ (3) Order status changes (RTS / Shipped / Completed / Cancelled…)
│ Webhook ◀─────────────────────────── Order Status Push → your callback URL
│
│ (3b) Get Order Detail (fetch full data)
│ ───────────────────────────────────▶
│ Update the order in your own system
│
│ (4) Need to cancel → Cancel Order
│ ───────────────────────────────────▶
Key principle of Omisell webhooks: a webhook only tells you that "this order just changed" — it does not contain the full payload. After receiving a webhook you must call Get Order Detail to fetch the latest data, then update your system.
2. Prerequisites: API Key & Access Token#
2.1. Get the API Key#
⚠️ Keep your API Key secret. Do not commit it to GitHub or expose it client-side. All requests must use HTTPS.
2.2. Get an Access Token#
API domain: https://api.omisell.com
Call the token endpoint (see the Authentication section in the reference). You will receive:
{
"data": {
"expired_time": 1703578845,
"refresh_expired_time": 1704788445,
"refresh_token": "xxxxx",
"token": "xxxxxxxx"
},
"error": false,
"error_code": 201,
"messages": ""
}
Authorization: Omi <token>
Content-Type: application/json
Seller-ID: <your seller_id>
Country: <country code, e.g. VN>
2.4. Refresh Token#
The access token expires daily. Before token expires, use the refresh_token to obtain a new one. If you let the token expire without refreshing, every request will fail authentication. The token remains valid until refresh_expired_time.💡 Recommended: build a service that refreshes the token automatically (e.g. every few hours, or before expired_time) and cache the token for shared use.
3. Step 1 — Identify the custom store (shop_id)#
⚠️ Important: Omisell does not provide a public API to create a custom store. A custom store is created/configured inside the Omisell Console (or by the Omisell/partner team). Once the store exists, you simply retrieve its shop_id.
Use Get Shop List to retrieve the shops and find the shop_id of your custom store:Store this shop_id — you'll pass it in the order payload in the next step.
4. Step 2 — Create an order (Add Order)#
Method / URL: POST https://api.omisell.com/api/v2/public/order/add
4.1. Example request#
4.2. Key fields#
| Field | Meaning / notes |
|---|
order_number | The order code in your system. Keep it unique for later reconciliation. |
shop_id | The shop_id of the custom store (from Step 1). |
pickup_id | Pickup address / warehouse. Retrieve via Get Pickup List (api-5188376). |
shipping_fee | Shipping fee. |
receiver | Recipient info. Province/district/subdistrict names must match Omisell's address system — use the Location APIs (Get Province/District/SubDistrict List) to normalize them. |
invoice_information | Invoicing info (optional, as needed). |
payment_information | payment_type: 1=COD, 2=Bank Transfer, 3=Visa/Master/Amex, 4=Cash, 6=QR Code, 7=Online Banking, 8=Installment. payment_status: 100=Unpaid, 200=Paid, 150=Partially Paid, etc. |
items[].sku | The SKU must already exist in Omisell's catalogue. If not, create it first via Add Product (api-10762725). |
created_time | Order creation time, as epoch (seconds). |
4.3. Response#
On success, the response returns the order data. The most important field is:omisell_order_number — the order code on Omisell's side. Store this in your DB and map it to your own order_number. Every subsequent operation (get detail, cancel, webhook matching) uses omisell_order_number.
status_id, status_name — the initial order status.
In the reference's response example, "error": true is just placeholder data. Check error === false to confirm success.
5. Step 3 — Receive webhooks & update orders#
5.1. Register your callback URL (done in the Console, not via API)#
In the Omisell Console → Push Mechanism / Webhook → Add Hook:1.
Enter your callback URL (your public HTTPS endpoint that receives POST requests).
2.
Select the push type: Order (and Shipment/Return if needed).
3.
You can review delivery history under Push Log.
The Push Hook Order endpoint in the reference is Deprecated and only for PrestaShop/WooCommerce — do not use it for a custom store.
5.2. What Omisell sends to your callback URL#
Method: POST to your callback URL
{
"data": {
"updated_time": 1719638400,
"order_number": "ORD-2024-0001",
"omisell_order_number": "OMI-XXXXX",
"status_id": "500",
"status_name": "Shipped",
"is_fulfilled": true,
"created_time": "1719638000"
},
"event": "order.shipped",
"shop_id": 12345,
"seller_id": 99999,
"platform": "custom",
"timestamp": 1719638401,
"request_id": "xxxx"
}
Order Status Push events:| Event | Meaning |
|---|
order.created | New order created |
order.ready_to_ship | Order ready to ship (RTS) |
order.shipped | Order handed to courier |
order.completed | Order completed |
order.returned | Order returned |
order.cancelled | Order cancelled |
order.reconciled | Order reconciled |
order.return_receive | Returned goods received back into the warehouse |
5.3. Handling a webhook (critical)#
1.
Return HTTP 200 immediately so Omisell knows you received it (otherwise Omisell retries — see the retry schedule below).
2.
(Recommended) Verify the signature in the webhook request's Authorization header to confirm the request truly comes from Omisell and prevent spoofing. The signing mechanism is described in the Push Mechanism section.
3.
Use the omisell_order_number from the payload to call Get Order Detail and fetch the full data.
4.
Update the order status in your system based on that detailed data.
5.
Be idempotent: the same event may arrive multiple times (due to retries). Use request_id, or the combination of (omisell_order_number + status_id + updated_time), to avoid duplicate processing.
Omisell retry schedule (when your callback does not return 200):| Retry | Delay |
|---|
| 1st | 5 minutes |
| 2nd | 10 minutes |
| 3rd | 20 minutes |
| 4th | 40 minutes |
| 5th | 1 hour 20 minutes |
5.4. Get Order Detail#
Method / URL: GET https://api.omisell.com/api/v2/public/order/{omisell_order_number}
The response contains everything: order status, parcels (tracking number courier_tracking_number, courier, shipment status), payment info, recipient, and timestamps (rts_time, shipped_time, completed_time). Use this data to update the order on your side.5.5. Order status map (Order status_id)#
| status_id | Name | Notes |
|---|
| 200 | New | New order, awaiting approval |
| 250 | Awaiting confirmation | |
| 260 | Courier allocation | Waiting for courier allocation |
| 300 | Approved | Approved, awaiting delivery order (DO) |
| 350 | Awaiting Generate Label | Awaiting label |
| 360 | Exception - Ready to Ship | |
| 370 | Cancellation Requested | Cancellation request received |
| 380 | Label Generation Errors | |
| 400 | Processing | In pick & pack |
| 460 | Ready to Ship | Packed successfully |
| 500 | Shipped | Dispatched to courier |
| 600 | Delivering | In delivery |
| 440 | Exceptions | |
| 800 | Returned | Final status |
| 850 | Courier Lost Items | Final — courier lost the parcel |
| 900 | Completed | Final — completed |
| 700 | Cancelled by seller | Final |
| 701 | Cancelled by operator | Final |
| 702 | Cancelled by partner | Final |
| 703 | Cancelled by system | Final |
| 708 | Cancelled by lost items at warehouse | Final |
6. Step 4 — Cancel an order (Cancel Order)#
Method / URL: PATCH https://api.omisell.com/api/v2/public/order/{omisell_order_number}/cancel
Cancellation is only possible while the order has not reached a final status and is not too far along the pipeline (e.g. once Shipped it usually cannot be cancelled — use the Return Order flow instead).
After a successful cancellation, the order moves to one of statuses 700–708, and Omisell also sends an order.cancelled webhook. Prefer updating your status from the webhook + Get Order Detail rather than relying solely on the cancel response, to keep data consistent.
7. Implementation checklist#
8. Quick reference links#
Modified at 2026-06-29 10:57:38