وثائق نبوكس ناو API
مقدمة
تم تصميم انبوكس ناو API للتكامل السلس مع موقع التجارة الإلكترونية الخاص بك مع نظام انبوكس ناو، مما يمكّن من حسابات أسعار الشحن التلقائية وإدارة الطلبات. عند التكامل، س يتمكن المستخدمون من:
- استرداد أسعار الشحن في الوقت الفعلي من انبوكس ناو بناءً على أبعاد المنتج ووجهات الشحن.
- دفع معلومات المتجر والطلبات إلى انبوكس ناو للتنفيذ المبسط وخدمات الشحن.
من خلال الاستفادة من هذا API، يمكن للتجار تحسين سير عمل الشحن وتقليل المعالجة اليدوية وضمان المعالجة الفعالة للطلبات.
عناوين URL الأساسية
استخدم عنوان URL الأساسي المناسب حسب بيئتك:
- مباشر (الإنتاج):
https://nbox.now/api - التجريبي (الاختبار):
https://staging.nbox.now/api
مجموعة Postman
قم بتنزيل مجموعة Postman الخاصة بنا لاختبار والتكامل بسرعة مع واجهة برمجة تطبيقات NBox. قم باستيراد ملف JSON إلى Postman للبدء. تتضمن المجموعة جميع نقاط النهاية مع رؤوس المصادقة المُعدة مسبقاً وأمثلة على نصوص الطلبات.
فيما يلي قائمة بـ APIs التي ستستخدمها للتكامل مع انبوكس ناو. تسمح هذه النقاط النهائية بالمصادقة وإدارة المواقع واسترداد أسعار الشحن والتعامل مع الطلبات داخل النظام.
API تسجيل الدخول
سجل الدخول إلى النظام عن طريق استدعاء نقطة نهاية المصادقة:
يتم إرجاع رمز مميز عند نجاح المصادقة ويجب استخدامه في طلبات API الأخرى.
الطريقة: POST
نقطة النهاية: POST https://{base_url}/login
الطلب
يجب تضمين المعاملات التالية في نص الطلب:
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| String | Required | عنوان البريد الإلكتروني للمستخدم (مثال: juan.delacruz@email.com) | |
| password | String | Required | كلمة مرور المستخدم (مثال: *******) |
| shopId | String | Required | المعرف الفريد للمتجر (النطاق) (مثال: nbox.now) |
| shopName | String | Required | اسم المتجر (مثال: Nbox Store) |
| platform | String | Required | منصة التجارة الإلكترونية (مثال: WooCommerce، Shopify، Magento، مخصص) (مثال: woocommerce) |
| url | String | Required | رابط المتجر (مثال: https://store.nbox.now) |
| locations | Array of Objects | Optional | حقل اختياري ويمكن أن يتضمن مواقع تنفيذ المتجر. مواقع المتجر (مثال: address: 143 Missing Street, Unknown area, city: Al Rayyan, state: Qatar, countryCode: QA, zip: 0000, country: Qatar) |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
API المواقع
لإدارة المواقع في نظام انبوكس ناو، يمكنك استخدام نقاط النهاية التالية. كلاهما يقبل نفس نص الطلب الذي يحتوي على مصفوفة من معلومات الموقع.
تأكد من تضمين الرمز المميز ونطاق المتجر في رؤوس الطلب. سيقوم API بالتحقق من صحة هذه لضمان أن الطلب قادم من متجر مخول. يمكن توفير المواقع في معلومة واحدة أو مصفوفة من معلومات الموقع، اعتماداً على المنصة. lat و lng الحقول اختيارية ولكن يمكن تضمينها إذا كانت الإحداثيات الجغرافية للموقع معروفة.
الطريقة: POST
POST https://{base_url}/locations/add- إضافة مواقع جديدة.POST https://{base_url}/locations/update- تحديث المواقع الموجودة.
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجار ة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الطلب
| الاسم | النوع | مطلوب | الوصف (مع مثال) |
|---|---|---|---|
| refId | String | Required | معرف مرجعي فريد للموقع (مثال: "loc123") |
| refName | String | Required | اسم مرجعي فريد لعرض الموقع (مثال: "المستودع الرئيسي") |
| address | String | Required | عنوان الشارع للموقع (مثال: "123 Main St") |
| city | String | Required | مدينة الموقع (مثال: "نيويورك") |
| state | String | Required | الولاية أو المحافظة للموقع (مثال: "نيويورك") |
| countryCode | String | Required | رمز البلد المكون من حرفين (مثال: "US") |
| country | String | Optional | اسم البلد (مثال: "الولايات المتحدة") |
| zip | String | Required | الرمز البريدي للموقع (مثال: "10001") |
| longitude | Number | Optional | خط الطول للموقع (مثال: "-73.935242") |
| latitude | Number | Optional | خط العرض للموقع (مثال: "40.730610") |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أ و غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
API التفعيل
الطريقة: POST
نقطة النهاية: POST https://{base_url}/activation
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الطلب
| الاسم | النوع | مطلوب | الوصف (مع مثال) |
|---|---|---|---|
| activate | Boolean | Required | ما إذا كان سيتم تفعيل المتجر (صحيح أو خطأ) (مثال: true |
| locations | Array | Optional | مصفوفة من معلومات الموقع المراد تفعيلها (مثال: [{"refId": "loc123", "refName": "Main Warehouse", "address": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "countryCode": "US", "country": "United States"}]) |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
أسعار API
الطريقة: POST
نقطة النهاية: POST https://{base_url}/rates
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الوصف
يحسب هذا API أسعار الشحن بناءً على تفاصيل المنتج والمنشأ والوجهة. يحسب النظام بذكاء الأبعاد والوزن من المنتجات الفردية لحساب دقيق للأسعار. معاملات الوزن/الحجم القديمة مدعومة للتوافق مع الإصدارات السابقة.
الطلب
موصى به: استخدم المنتجات مصفوفة لحسابات الوزن الأبعاد الدقيقة. سيحسب النظام الوزن والحجم الإجمالي من مواصفات المنتجات الفردية.
هيكل الطلب الرئيسي
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| products | Array | Recommended | قائمة المنتجات مع الأبعاد والوزن للحساب الدقيق |
| volume | Number | Legacy | (Legacy) حجم الطرد بالوحدات المكعبة (مثال:Legacy) 1.5 |
| weight | Number | Legacy | (Legacy) وزن الطرد بالكيلوغرام (مثال:Legacy) 2.5 |
| origin | Object | Required | معلومات موقع المنشأ (انظر معلومات المنشأ والوجهة أدناه) |
| destination | Object | Required | معلومات موقع الوجهة (انظر معلومات المنشأ والوجهة أدناه) |
| type | String | Optional | نوع الشحن (مثال: "non_document", "document", إلخ. الافتراضي هو "non_document"غير وثائقي |
Product Object (Recommended)
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| name | String | Required | اسم المنتج |
| quantity | Number | Required | كمية المنتج |
| price | Number | Required | سعر الوحدة الواحدة من المنتج |
| grams | Number | Required | وزن المنتج بالغرام |
| length | Number | Required | طول المنتج بالسنتيمتر |
| width | Number | Required | عرض المنتج بالسنتيمتر |
| height | Number | Required | ارتفاع المنتج بالسنتيمتر |
| volume | Number | Required | حجم المنتج بالسنتيمتر المكعب (سم³) |
| currency | String | Required | عملة سعر المنتج |
معلومات المنشأ والوجهة
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| address | String | Required | العنوان الكامل، بما في ذلك سطور العنوان وأي معلومات عنوان إضافية |
| city | String | Required | المدينة |
| state | String | Optional | الولاية أو المحافظة (يقبل null للمناطق بدون ولايات) |
| countryCode | String | Required | رمز البلد (مثال: "US"، "QA") |
| country | String | Optional | اسم البلد (مثال: "الولايات المتحدة"، "قطر") |
| zip | String | Required | الرمز البريدي |
| longitude | Number | Optional | خط الطول للعنوان (يدعم تنسيقي longitude و lng) |
| latitude | Number | Optional | خط العرض للعنوان (يدعم تنسيقي latitude و lat) |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملي ة التفعيل |
نص الاستجابة
سيحتوي نص الاستجابة على مصفوفة من معلومات الأسعار، بالهيكل التالي:
| الاسم | النوع | الوصف |
|---|---|---|
| id | String | معرف فريد للسعر (مثال: "f9d17f56-7eeb-44ad-bc7e-b95f61d5d2ed" |
| logo | String | رابط شعار مقدم الخدمة (مثال: "/images/nbox-logistics.png" |
| pickup_dropoff_method | String | طريقة الاستلام والتسليم (مثال: "Door to Door" |
| service_name | String | اسم خدمة الشحن (مثال: "NBOX Express Local Delivery" |
| service_code | String | رمز خدمة الشحن (مثال: "NBOX" |
| total_price | Number | السعر الإجمالي للخدمة بالعملة المحددة (مثال: 20.00 |
| description | String | وصف للخدمة، مثل وقت التسليم (مثال: "Estimate Time of Delivery: 3 hours" |
| currency | String | عملة السعر الإجمالي (مثال: "QAR" |
طلب API
الطريقة: POST
نقطة النهاية: POST https://{base_url}/order
الوصف
يتم استدعاء هذا API أثناء عملية الدفع في موقع التجارة الإلكترونية. يدفع تفاصيل الطلب من متجر التجارة الإلكترونية إلى نظام انبوكس ناو للمعال جة. سيتعامل النظام مع مهام مثل حساب تكلفة الشحن وتحديث حالة الطلب وإنشاء إشعارات البريد الإلكتروني لفريق العمليات والمستخدم.
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الطلب
يجب أن يحتوي نص الطلب على تفاصيل الطلب، بما في ذلك الناقل وتفاصيل العميل والوجهة ومعلومات المنتج. فيما يلي هيكل بيانات الطلب:
هيكل المعلومات الرئيسي
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| order | Object | Required | تفاصيل الطلب بما في ذلك الناقل ورقم الطلب والمجموع الفرعي ورسوم الشحن. |
| customer | Object | Required | معلومات العميل، بما في ذلك الاسم والبريد الإلكتروني والهاتف. |
| origin | Object | Required | عنوان منشأ متجر التجارة الإلكترونية (المتجر). يتضمن العنوان والمدينة والولاية والرمز البريدي. |
| destination | Object | Required | تفاصيل وجهة الشحن، بما في ذلك عنوان المستلم والمدينة والولاية والرمز البريدي. |
| products | Array | Required | قائمة المنتجات في الطلب مع خصائص مثل الاسم والسعر والكمية والوزن والأبعاد والحجم. |
معلومات الطلب
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| shopDomain | String | Required | نطاق متجر التجارة الإلكترونية |
| carrier | String | Optional | ناقل الشحن للطلب NEW: Auto-selects cheapest carrier if not provided |
| subTotal | Number | Required | Sum of all product prices (quantity × price for each product). This is the product value only, excluding tax, discount, and shipping. |
| tax | Number | Optional | Tax amount to add to the order. Defaults to 0. Used in COD calculation: orderValue = subTotal + tax - discount |
| discount | Number | Optional | Discount amount to subtract from the order. Defaults to 0. Used in COD calculation: orderValue = subTotal + tax - discount |
| orderNumber | Number | Required | رقم الطلب الفريد |
| orderReference | String | Required | رقم مرجعي للطلب |
| total | Number | Required | Final order total as calculated by your platform. Typically: subTotal + tax - discount + shippingFee. This is for your records; NBox recalculates shipping server-side. |
| currency | String | Required | عملة الطلب |
| shippingFee | Number | Optional | Shipping fee charged to your customer (what they pay for shipping). Used in collectionAmount calculation for COD orders. NBox still charges merchant based on actual calculated rate.Tip: If your shipping fee differs from NBox's rate, provide it here so COD collection is accurate. |
| paymentStatus | String | Optional | طريقة دفع العميل: 'prepaid' (دفع العميل للبائع عبر الإنترنت مسبقاً) أو 'postpaid' (الدفع عند الاستلام - COD). الافتراضي 'prepaid'. إذا كان 'postpaid'، سيتم حساب رسوم خدمة COD بناءً على المجموع الفرعي للطلب. Values: "prepaid" (default) or "postpaid" (COD) |
| paymentMethod | String | Optional | طريقة الدفع المستخدمة من قبل العميل (مثل 'credit_card'، 'cod'، 'online_payment'). حد أقصى 50 حرفاً. حقل اختياري لأغراض التتبع. |
| collectionAmount | Number | Optional | Amount to collect from customer at delivery (COD orders only). Use this when: Customer made partial prepayment, shipping fee differs from calculated rate, or any scenario where collection amount ≠ order total. If not provided, defaults to: (subTotal + tax - discount) + customerShippingFeeImportant: This value appears on the AWB label for delivery drivers. |
💡 Understanding Order Financial Fields
subTotal = Sum of product prices (e.g., 200 QAR) + tax = Tax amount (e.g., 20 QAR) - discount = Discount applied (e.g., 10 QAR) ───────────────────────────────────────────── = orderValue = Product value for customer (210 QAR) + shippingFee (from your platform, for reference) ───────────────────────────────────────────── = total = Final order total (e.g., 230 QAR)
If collectionAmount is PROVIDED:
→ Uses your specified value (e.g., 150 QAR if partial prepayment)
If collectionAmount is NOT provided:
→ Calculated as: orderValue + customerShippingFee
→ Where customerShippingFee priority:
1. Your shippingFee (if provided)
2. NBox displayRate (if markup rule exists)
3. NBox actualRate (fallback)collectionAmount: 130 (remaining 100 + 30 shipping) so the driver collects the correct amount.معلومات العميل
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| firstName | String | Required | الاسم الأول للعميل |
| lastName | String | Required | اسم العائلة للعميل |
| String | Required | عنوان البريد الإلكتروني للعميل | |
| phone | String | Optional | رقم هاتف العميل |
معلومات المنشأ والوجهة
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| address | String | Required | العنوان الكامل، بما في ذلك سطور العنوان وأي معلومات عنوان إضافية |
| city | String | Required | المدينة |
| state | String | Optional | الولاية أو المحافظة (يقبل null للمناطق بدون ولايات) |
| countryCode | String | Required | رمز البلد (مثال: "US"، "QA") |
| country | String | Optional | اسم البلد (مثال: "الولايات المتحدة"، "قطر") |
| zip | String | Required | الرمز البريدي |
| longitude | Number | Optional | خط الطول للعنوان (يدعم تنسيقي longitude و lng) |
| latitude | Number | Optional | خط العرض للعنوان (يدعم تنسيقي latitude و lat) |
Product Object
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| name | String | Required | اسم المنتج |
| quantity | Number | Required | كمية المنتج |
| price | Number | Required | سعر الوحدة الواحدة من المنتج |
| grams | Number | Required | وزن المنتج بالغرام |
| length | Number | Required | طول المنتج بالسنتيمتر |
| width | Number | Required | عرض المنتج بالسنتيمتر |
| height | Number | Required | ارتفاع المنتج بالسنتيمتر |
| volume | Number | Required | حجم المنتج بالسنتيمتر المكعب (سم³) |
| currency | String | Required | عملة سعر المنتج |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
نص الاستجابة
سيحتوي نص الاستجابة على الحقول التالية:
| الاسم | النوع | الوصف |
|---|---|---|
| status | String | Status of the request: "success" or "failed" |
| message | String | رسالة الحالة التي تشير إلى النجاح أو الفشل |
| orderId | String | معرف الطلب الفريد |
| orderReference | String | Order reference number |
| shipment_id | String | 🔑 IMPORTANT: NBox shipment reference ID (e.g., "ORD-NB-11132") Use this ID for: AWB downloads ( /api/awb/:shipment_id), webhook correlation, and shipment tracking. This same field appears in all webhook payloads. |
| awb | String|null | Air Waybill tracking number (same as shipment_id initially, updated after carrier pickup) null until shipment is picked up by carrier |
| tracking_url | String|null | Customer tracking URL (e.g., "https://nbox.now/track/ORD-NB-11132") null until shipment is picked up, share this with customers for real-time tracking |
| nbox | Object | Additional correlation data Contains: shipment_detail_id (internal UUID), shop_id (your shop identifier) |
| carrier | String | Selected carrier service code (e.g., "aramex", "fedex", "NBOX") NEW: Shows which carrier was selected |
| carrierName | String | Human-readable carrier name NEW: Display-friendly carrier name |
| carrierWasAutoSelected | Boolean | Indicates if carrier was auto-selected by NBox NEW: true = NBox selected, false = user specified |
| actualRate | Number | Actual shipping rate charged to merchant |
| displayRate | Number | Display rate (if rate display rule applied, otherwise null) |
| hasDisplayRule | Boolean | Indicates if a rate display rule was applied |
| errorDetails | String | أي تفاصيل خطأ إذا لم تتم معالجة الطلب بنجاح |
Example Success Response
{
"status": "success",
"message": "order processed",
"orderId": 11132,
"orderReference": "NB-11132",
"shipment_id": "ORD-NB-11132",
"awb": "ORD-NB-11132",
"tracking_url": "https://nbox.now/track/ORD-NB-11132",
"nbox": {
"shipment_detail_id": "af825ce0-6fd0-4777-8d28-0dfbccc20771",
"shop_id": "f79e11b7-a9df-4023-8609-ce55a4c64a7c"
},
"carrier": "NBOX",
"carrierName": "NBOX Express Local Delivery",
"carrierWasAutoSelected": false,
"actualRate": 16,
"displayRate": 16,
"hasDisplayRule": false
}Important Notes
- 🔑 shipment_id Field: This is the most important identifier returned in the response. Store this value to:
- Download AWB labels via
GET /api/awb/:shipment_id - Correlate webhook events with your orders (included in all webhook payloads)
- Track shipments and reference them in support queries
- Download AWB labels via
- awb & tracking_url: Initially set to
shipment_idvalue, but becomenulluntil the shipment is picked up by the carrier. You'll receive updated values via theshipment.pickupwebhook event. See Webhooks and Customer Tracking sections. - COD Service Fee: For orders with
paymentStatus: "postpaid", a COD service fee is calculated as:collectionAmount × 2%
IfcollectionAmountis not provided, fee is based on:(subTotal + tax - discount + customerShippingFee) × 2% - Carrier Auto-selection: If no carrier is specified, NBox automatically selects the cheapest available carrier for the route
- Shipping Fee Recalculation: NBox always recalculates shipping costs server-side, regardless of the
shippingFeeparameter - Backward Compatibility: All new fields are optional. Existing integrations continue to work without modifications
API الإنجاز
الطريقة: POST
نقطة النهاية: POST https://{base_url}/fulfilled
الوصف
يتم استدعاء هذا API عندما يتم إنجاز الطلب (شحنه). يدفع حالة إنجاز الطلب من متجر التجارة الإلكترونية إلى نظام انبوكس ناو لمزيد من المعالجة، مثل تحديث حالة الطلب أو إخطار العميل.
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الطلب
يجب تضمين المعاملات التالية في نص الطلب:
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| orderNumber | Number | Required | رقم الطلب الفريد |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
نص الاستجابة
| الاسم | النوع | الوصف |
|---|---|---|
| message | String | رسالة الحالة التي تشير إلى النجاح أو الفشل |
| orderId | String | معرف الطلب الفريد |
| errorDetails | String | أي تفاصيل عن الأخطاء في حال عدم معالجة التنفيذ بنجاح |
إلغاء API
الطريقة: POST
نقطة النهاية: POST https://{base_url}/order/cancelled
الوصف
يتم استدعاء هذا API عندما يتم إلغاء الطلب. يرسل حالة الإلغاء من متجر التجارة الإلكترونية إلى نظام نبوكس ناو لمزيد من المعالجة، مثل تحديث حالة الطلب وإخطار العميل بالإلغاء.
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
الطلب
| الاسم | النوع | مطلوب | الوصف |
|---|---|---|---|
| orderNumber | Number | Required | رقم الطلب الفريد |
الاستجابة
| الحالة | الوصف |
|---|---|
| 200 OK | نجح أو فشل التفعيل بناءً على المعاملات المقدمة |
| 400 Bad Request | معاملات مفقودة أو غير صالحة |
| 401 Unauthorized | رمز مميز و/أو نطاق متجر غير صالح |
| 500 Internal Server Error | خطأ في الخادم أثناء عملية التفعيل |
Return Shipment
Method: POST
Endpoint: POST https://{base_url}/return-shipment
Description
Creates a return shipment from an existing delivered order or shipment. This API reverses the origin and destination addresses, allowing the package to be returned to the original sender.
The return shipment uses the actual delivery coordinates from the completed delivery task for accurate pickup location.
Key Features
- Auto Address Swap: Origin becomes destination, destination becomes origin
- Contact Reversal: Sender info becomes receiver info and vice versa
- Accurate Pickup: Uses actual delivery GPS coordinates from driver completion
- One Return Per Original: Each shipment can only have one return created
- Actual Rate Calculation: Shipping rates are calculated using the rate engine (not hardcoded)
- Auto Carrier Selection: Cheapest available carrier is auto-selected if not specified
- Contact Overrides: Optional pickup and return contact info can be specified
الرؤوس
| الاسم | الوصف |
|---|---|
x-nbox-shop-token | الرمز المميز المسترد من API تسجيل الدخول. هذا الرمز يصادق على المستخدم. |
x-nbox-shop-domain | نطاق موقع التجارة الإلكترونية (مثال: nbox.nowمرتبط بالمتجر. |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| shipment_id | String | Required | The unified reference ID of the original shipment to return. Example: "ORD-NB-11132" (from order) or "SN000001" (from ShipNow) |
| returnReason | String | Optional | Reason for the return request. Examples: "Customer requested return", "Wrong item delivered", "Damaged product" |
| carrier | String | Optional | Carrier service code for the return shipment. Auto-selects cheapest available carrier if not provided |
| notes | String | Optional | Additional notes for the return shipment. Example: "Handle with care", "Fragile items" |
| pickupContactInfo | Object | Optional | Override contact info for the pickup location (customer returning the package). Fields: firstName, lastName, phone, email |
| returnContactInfo | Object | Optional | Override contact info for the return destination (warehouse receiver). Fields: firstName, lastName, phone, email |
Example Request (Basic)
POST /api/return-shipment
Content-Type: application/json
x-nbox-api-token: your_api_token
x-nbox-shop-domain: your-shop.myshopify.com
{
"shipment_id": "ORD-NB-11132",
"returnReason": "Customer requested return",
"notes": "Handle with care - fragile items"
}Example Request (With Contact Overrides)
POST /api/return-shipment
Content-Type: application/json
x-nbox-api-token: your_api_token
x-nbox-shop-domain: your-shop.myshopify.com
{
"shipment_id": "ORD-NB-11132",
"returnReason": "Customer requested return",
"carrier": "nbox_local",
"pickupContactInfo": {
"firstName": "John",
"lastName": "Doe",
"phone": "55512345",
"email": "john@example.com"
},
"returnContactInfo": {
"firstName": "Warehouse",
"lastName": "Manager",
"phone": "55567890",
"email": "warehouse@shop.com"
}
}Response
The response structure matches the Create Order API for consistency:
| Name | Type | Description |
|---|---|---|
| status | String | Status of the request: "success" or "error" |
| message | String | Human-readable response message |
| shipment_id | String | Return shipment reference ID (e.g., "RTN-ORD-NB-11132") |
| original_shipment_id | String | Reference to the original shipment |
| awb | String | Air Waybill / tracking number (same as shipment_id) |
| tracking_url | String | URL to track the return shipment |
| carrier | String | Selected carrier service code |
| carrierName | String | Human-readable carrier name |
| carrierWasAutoSelected | Boolean | True if carrier was auto-selected (cheapest available) |
| actualRate | Number | Calculated shipping rate for the return |
| displayRate | Number | Display rate (same as actualRate for returns) |
| hasDisplayRule | Boolean | Always false for returns (no markup applied) |
| nbox | Object | Correlation IDs: shipment_detail_id, return_shipment_id |
| paymentStatus | String | "unpaid" for prepaid accounts, "postpaid" for contract accounts |
| returnShipment | Object | Detailed return shipment object (see below) |
Return Shipment Object
| Name | Type | Description |
|---|---|---|
| id | String | Unique identifier for the return shipment |
| unifiedRefId | String | Return shipment reference ID Format: "RTN-{originalRefId}" (e.g., "RTN-ORD-NB-11132") |
| original_shipment_id | String | Reference to the original shipment |
| status | String | Shipment status (initially "new") |
| paymentStatus | String | Payment status for the return shipment "unpaid" for prepaid accounts, "postpaid" for contract accounts |
| rate | Object | Rate information with: actualRate, displayRate, currency Shipping cost for the return journey |
| origin | Object | Pickup location (customer's delivery address) Uses actual GPS coordinates from delivery completion |
| destination | Object | Delivery location (original sender's address) Where the return package will be delivered |
| dimensions | Object | Package dimensions (weight, length, width, height) |
| returnReason | String|null | The provided reason for return |
| createdAt | DateTime | Timestamp when the return shipment was created |
Example Success Response
{
"status": "success",
"message": "Return shipment created successfully",
"shipment_id": "RTN-ORD-NB-11132",
"original_shipment_id": "ORD-NB-11132",
"awb": "RTN-ORD-NB-11132",
"tracking_url": "https://nbox.now/track/RTN-ORD-NB-11132",
"carrier": "nbox_local",
"carrierName": "NBOX Express Local Delivery",
"carrierWasAutoSelected": true,
"actualRate": 16,
"displayRate": 16,
"hasDisplayRule": false,
"nbox": {
"shipment_detail_id": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
"return_shipment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"paymentStatus": "unpaid",
"returnShipment": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"shipmentDetailId": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
"unifiedRefId": "RTN-ORD-NB-11132",
"original_shipment_id": "ORD-NB-11132",
"status": "new",
"paymentStatus": "unpaid",
"rate": {
"actualRate": 16,
"displayRate": 16,
"currency": "QAR"
},
"origin": {
"firstName": "John",
"lastName": "Customer",
"phone": "55512345",
"email": "john@example.com",
"address": {
"address": "123 Customer Street, West Bay",
"city": "Doha",
"country": "Qatar",
"countryCode": "QA",
"lat": 25.3284,
"lng": 51.5310
}
},
"destination": {
"firstName": "Shop",
"lastName": "Owner",
"phone": "55567890",
"email": "shop@example.com",
"address": {
"address": "456 Warehouse Road, Industrial Area",
"city": "Doha",
"country": "Qatar",
"countryCode": "QA",
"lat": 25.2654,
"lng": 51.4875
}
},
"dimensions": {
"weight": 2.5,
"length": 30,
"width": 20,
"height": 15,
"volumeWeight": 1.8
},
"returnReason": "Customer requested return",
"createdAt": "2025-11-29T10:30:00.000Z"
}
}Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | NOT_DELIVERED | The original shipment must be delivered before creating a return |
| 400 | MISSING_FIELD | Required field "shipment_id" is missing |
| 401 | UNAUTHORIZED | Authentication required (invalid or missing API token) |
| 403 | UNAUTHORIZED | Not authorized to create return for this shipment |
| 404 | ORIGINAL_NOT_FOUND | The specified original shipment was not found |
| 409 | RETURN_EXISTS | A return shipment already exists for this original shipment |
| 400 | INVALID_CARRIER | The specified carrier is not available for this route |
| 400 | RATE_UNAVAILABLE | No carriers available for the return route |
| 500 | RATE_CALCULATION_FAILED | Failed to calculate shipping rate for the return |
Example Error Response
{
"status": "error",
"code": "NOT_DELIVERED",
"message": "Shipment must be delivered before creating return. Current status: in_transit"
}Check Return Eligibility
Before creating a return, you can check if a shipment is eligible for return:
Method: GET
Endpoint: GET https://{base_url}/return-shipment?shipment_id={refId}
Example Request
GET /api/return-shipment?shipment_id=ORD-NB-11132 x-nbox-api-token: your_api_token x-nbox-shop-domain: your-shop.myshopify.com
Example Response (Eligible)
{
"status": "success",
"eligible": true,
"reason": null,
"code": null
}Example Response (Not Eligible)
{
"status": "success",
"eligible": false,
"reason": "Shipment must be delivered before creating return. Current status: in_transit",
"code": "NOT_DELIVERED"
}Important Notes
- Eligibility Requirements: Only shipments with status "delivered" can have returns created
- One Return Per Original: Each original shipment can only have one return shipment. Attempting to create a second return will result in a RETURN_EXISTS error
- Rate Calculation: Shipping rates are calculated dynamically using the rate engine based on the original package dimensions and reversed route. No display rules/markup are applied to returns
- Auto Carrier Selection: If no carrier is specified, the cheapest available carrier for the route is automatically selected. The response includes carrierWasAutoSelected: true in this case
- Billing: Return shipments are marked as "unpaid" for prepaid accounts (payment processed later) or "postpaid" for contract accounts (billed monthly)
- GPS Accuracy: The return pickup location uses the actual GPS coordinates captured when the delivery driver completed the original delivery, ensuring accurate pickup
- Reference ID Format: Return shipment reference IDs are prefixed with "RTN-" followed by the original reference (e.g., "RTN-ORD-NB-11132")
- Contact Overrides: Use pickupContactInfo to override the pickup contact (customer) and returnContactInfo to override the delivery contact (warehouse). Both support partial overrides (only specify fields to change)
- After Creation: The return shipment follows the same workflow as regular shipments - payment processing, pickup scheduling, and delivery tracking
Webhooks
Overview
Configure webhook endpoints to receive real-time updates about your shipments. Webhooks are automatically triggered when shipment status changes occur.
Available Events
| Event | Description | Trigger |
|---|---|---|
shipment.pickup | Shipment picked up by carrier | When order status changes to "pickup" |
shipment.intransit | Shipment is in transit for delivery | When order status changes to "in_transit" (driver started delivery) |
shipment.completed | Shipment delivered successfully | When order status changes to "delivered" |
shipment.failed | Shipment returned to sender | When order status changes to "return_to_sender" |
Webhook Payload Structure
All webhook requests include these headers:
| Header | Description |
|---|---|
X-NBox-Signature | HMAC-SHA256 signature for verification |
X-NBox-Timestamp | ISO 8601 timestamp |
X-NBox-Event-Type | Event type (e.g., shipment.completed) |
X-NBox-Delivery-ID | Unique delivery attempt ID |
Sample Payloads by Event Type
1. shipment.pickup
Triggered when carrier picks up the shipment:
{
"event": "shipment.pickup",
"timestamp": "2025-11-26T08:15:00.000Z",
"data": {
"shipment_id": "SHP-2025-001234",
"shipment_detail_id": "abc123-def456",
"shop_id": "shop_xyz",
"order_reference": "ORD-1234",
"awb": "NB-1234567890",
"tracking_url": "https://nbox.now/track/NB-1234567890",
"carrier": "aramex",
"status": "pickup",
"pickup_time": "2025-11-26T08:15:00.000Z",
"destination": {
"city": "Doha",
"country": "Qatar"
}
}
}2. shipment.intransit
Triggered when driver starts the delivery (pickup complete, now heading to customer):
{
"event": "shipment.intransit",
"timestamp": "2025-11-26T09:00:00.000Z",
"data": {
"shipment_id": "SHP-2025-001234",
"shipment_detail_id": "abc123-def456",
"shop_id": "shop_xyz",
"order_reference": "ORD-1234",
"awb": "NB-1234567890",
"tracking_url": "https://nbox.now/track/NB-1234567890",
"carrier": "aramex",
"status": "in_transit",
"intransit_time": "2025-11-26T09:00:00.000Z",
"destination": {
"city": "Doha",
"country": "Qatar"
}
}
}4. shipment.completed (Basic)
Triggered when shipment is successfully delivered:
{
"event": "shipment.completed",
"timestamp": "2025-11-26T10:30:00.000Z",
"data": {
"shipment_id": "SHP-2025-001234",
"shipment_detail_id": "abc123-def456",
"shop_id": "shop_xyz",
"order_reference": "ORD-1234",
"awb": "NB-1234567890",
"tracking_url": "https://nbox.now/track/NB-1234567890",
"carrier": "aramex",
"status": "delivered",
"completion_time": "2025-11-26T10:30:00.000Z"
}
}5. shipment.failed
Triggered when shipment is returned to sender:
{
"event": "shipment.failed",
"timestamp": "2025-11-26T14:45:00.000Z",
"data": {
"shipment_id": "SHP-2025-001235",
"shipment_detail_id": "xyz789-abc321",
"shop_id": "shop_xyz",
"order_reference": "ORD-1235",
"awb": "NB-0987654321",
"tracking_url": "https://nbox.now/track/NB-0987654321",
"carrier": "fedex",
"status": "return_to_sender",
"failure_time": "2025-11-26T14:45:00.000Z",
"failure_reason": "Customer refused delivery"
}
}6. shipment.completed (With OnFleet Performance Data)
When delivery includes OnFleet tracking, additional performance metrics are included:
{
"event": "shipment.completed",
"timestamp": "2025-11-26T16:20:00.000Z",
"data": {
"shipment_id": "SHP-2025-001236",
"shipment_detail_id": "def456-ghi789",
"shop_id": "shop_xyz",
"order_reference": "ORD-1236",
"awb": "NB-1122334455",
"tracking_url": "https://nbox.now/track/NB-1122334455",
"carrier": "aramex",
"status": "delivered",
"completion_time": "2025-11-26T16:20:00.000Z",
"onfleet_data": {
"task_id": "onfleet_task_123",
"driver_name": "Ahmed Al-Mansouri",
"driver_phone": "+974XXXXXXXX",
"completion_details": {
"success": true,
"notes": "Left with receptionist"
},
"distance_traveled_km": 12.5,
"time_on_route_minutes": 35
}
}
}Common Payload Fields
| Field | Type | Description |
|---|---|---|
event | String | Event type identifier |
timestamp | ISO 8601 | When the event occurred |
data.shipment_id | String | NBox shipment reference number (same as shipment_id from order creation response)Use this value for AWB downloads: GET /api/awb/{shipment_id} |
data.shipment_detail_id | String | Internal shipment detail ID |
data.shop_id | String | Your shop identifier |
data.order_reference | String | Your original order reference |
data.awb | String | Air Waybill tracking number (available after pickup event) - see AWB Download API |
data.tracking_url | URL | Customer tracking page URL (available after pickup event) - see Customer Tracking |
data.carrier | String | Carrier name (aramex, fedex, ems, qpost, waba) |
data.status | String | Current shipment status |
data.onfleet_data | Object | Optional: Included when OnFleet tracking is available |
Managing Webhooks
Via Dashboard
- Navigate to Dashboard → Integrations
- Click "Create Webhook"
- Enter your HTTPS webhook URL
- Select events to subscribe to
- Save and copy your secret key
- Use "View Delivery History" button to monitor all webhook deliveries
Delivery History
View comprehensive delivery history for all your webhooks by clicking "View Delivery History"in the Integrations dashboard. The delivery history page shows:
- Summary Statistics: Active webhooks count, total deliveries, total failures, and success rate
- All Delivery Attempts: View up to 100 most recent deliveries across all your webhook endpoints
- Delivery Details: Event type, HTTP status, delivery status (delivered/failed/pending), timestamps, and error messages
- Test Webhooks: Test webhook deliveries are also tracked and visible in history for debugging
GET /api/webhooks/:id/deliveries endpoint (see API Reference below).Via API
Endpoint: POST /api/webhooks
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| url | String | Yes | Webhook URL (must use HTTPS) |
| events | Array | Yes | Array of event types to subscribe to |
Example Request
POST /api/webhooks
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
{
"url": "https://your-domain.com/webhooks/nbox",
"events": [
"shipment.pickup",
"shipment.intransit",
"shipment.completed",
"shipment.failed"
]
}Example Response
{
"status": "success",
"webhook": {
"id": "wh_abc123",
"url": "https://your-domain.com/webhooks/nbox",
"secret": "whsec_abc123...",
"events": ["shipment.pickup", "shipment.intransit", "shipment.completed", "shipment.failed"],
"is_active": true,
"created_at": "2025-11-26T10:30:00Z"
}
}Security - Signature Verification
All webhooks are signed with HMAC-SHA256. You must verify the signature to ensure the webhook came from NBox.
Verification Steps
- Extract
X-NBox-SignatureandX-NBox-Timestampfrom headers - Construct signed payload:
timestamp + "." + raw_body - Compute HMAC-SHA256 using your webhook secret
- Compare signatures using timing-safe comparison
- Verify timestamp is recent (within 5 minutes)
Node.js Example
const crypto = require('crypto');
function verifyWebhookSignature(req, secret) {
const signature = req.headers['x-nbox-signature'];
const timestamp = req.headers['x-nbox-timestamp'];
const rawBody = req.rawBody; // Must be raw string
// Check timestamp (5 minute window)
const timestampAge = Date.now() - new Date(timestamp).getTime();
if (timestampAge > 5 * 60 * 1000) {
throw new Error('Webhook timestamp too old');
}
// Compute signature
const signedPayload = `${timestamp}.${rawBody}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload, 'utf8')
.digest('hex');
// Timing-safe comparison
const isValid = crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
if (!isValid) {
throw new Error('Invalid webhook signature');
}
return true;
}Retry Logic
Failed webhook deliveries are automatically retried up to 5 times with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 15 minutes |
| 5 | 30 minutes |
| 6 | 1 hour |
Best Practices
- Return 200 immediately: Respond within 10 seconds to acknowledge receipt
- Process asynchronously: Use job queues for long-running operations
- Implement idempotency: Store delivery IDs to prevent duplicate processing
- Log all webhooks: Keep audit logs for debugging
- Use HTTPS: Webhook URLs must use HTTPS (HTTP is not supported)
Testing
Test your webhook endpoint to ensure it can receive and process notifications correctly. Test webhooks create persistent delivery records that you can review in the delivery history.
Via Dashboard: Click the "Send Test" button on any webhook endpoint
Via API:
POST /api/webhooks/{webhook_id}/test
Authorization: Bearer YOUR_API_TOKENTest deliveries appear in your webhook delivery history with event type shipment.test, allowing you to verify signature validation and response handling.
API Reference
| Endpoint | Method | Description |
|---|---|---|
/api/webhooks | GET | List all webhooks |
/api/webhooks | POST | Create webhook |
/api/webhooks/:id | GET | Get webhook details |
/api/webhooks/:id | PATCH | Update webhook |
/api/webhooks/:id | DELETE | Delete webhook |
/api/webhooks/:id/regenerate | POST | Regenerate secret |
/api/webhooks/:id/test | POST | Send test webhook |
/api/webhooks/:id/deliveries | GET | Get delivery history |
AWB Download API
shipment_id value from the create order API response to download the AWB label. This is available immediately after order creation.Download AWB Label (PDF)
Download the Air Waybill label as a PDF document for printing and attaching to packages.
Endpoint
GET /api/awb/{shipment_id}Parameters
| Parameter | Type | Location | Description |
|---|---|---|---|
shipment_id | String | URL Path | Shipment ID from create order response (e.g., ORD-NB-11132) |
Response
- Content-Type:
application/pdf - Status Code: 200 (Success), 404 (Not Found), 500 (Server Error)
- File Name:
AWB_{shipment_id}_{date}.pdf
Example Request
GET https://nbox.now/api/awb/ORD-NB-11132 Response: - HTTP/1.1 200 OK - Content-Type: application/pdf - Content-Disposition: attachment; filename="AWB_ORD-NB-11132_2025-11-26.pdf" - (Binary PDF data)
Notes
- No Authentication Required: This endpoint is publicly accessible
- Use Case: Programmatically download AWB labels for automated printing systems
- Format: Standard A4 PDF format with 10mm margins, optimized for printing
- Availability: AWB labels are generated after the shipment reaches "pickup" status
Error Responses
// 404 - Record Not Found
{
"status": "failed",
"message": "Record not found"
}
// 500 - Generation Error
{
"status": "failed",
"message": "Failed to generate AWB PDF",
"error": "Error details (development only)"
}Integration Example
Option 1: Download immediately after creating order:
// After creating order
const orderResponse = await fetch('https://nbox.now/api/order', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_TOKEN' },
body: JSON.stringify(orderData)
});
const order = await orderResponse.json();
const { shipment_id } = order;
// Download AWB label immediately
const awbUrl = `https://nbox.now/api/awb/${shipment_id}`;
const awbResponse = await fetch(awbUrl);
const pdfBuffer = await awbResponse.buffer();
// Save or print the AWB label
await saveAWBLabel(shipment_id, pdfBuffer);Option 2: Download after receiving pickup webhook:
// Webhook handler
app.post('/webhooks/nbox', async (req, res) => {
const webhook = req.body;
if (webhook.event === 'shipment.pickup') {
// Extract shipment_id from webhook payload
const { shipment_id } = webhook.data;
// Download AWB label
const awbUrl = `https://nbox.now/api/awb/${shipment_id}`;
const response = await fetch(awbUrl);
const pdfBuffer = await response.buffer();
// Save or print the AWB label
await saveAWBLabel(shipment_id, pdfBuffer);
// Respond to webhook
res.status(200).send('OK');
}
});Customer Tracking
tracking_url field becomes available when you receive the shipment.pickup webhook event. Share this URL with your customers for real-time shipment tracking.Overview
NBox provides public tracking URLs that allow customers to track their shipments in real-time without authentication. These URLs redirect to the carrier's tracking portal and provide comprehensive delivery information.
Tracking URL Format
Format: https://{environment_url}/track/{awb}
Production Example: https://nbox.now/track/NB-1234567890
Staging Example: https://staging.nbox.now/track/NB-1234567890Getting the Tracking URL
You'll receive the tracking URL in the shipment.pickup webhook event:
{
"event": "shipment.pickup",
"timestamp": "2025-11-26T08:15:00.000Z",
"data": {
"shipment_id": "SHP-2025-001234",
"order_reference": "ORD-1234",
"awb": "NB-1234567890",
"tracking_url": "https://nbox.now/track/NB-1234567890",
"carrier": "aramex",
"status": "pickup",
"pickup_time": "2025-11-26T08:15:00.000Z"
}
}Use Cases
- Customer Notifications: Include the tracking URL in order confirmation and shipping notification emails
- Order Status Pages: Display the tracking link on your website's order status/history pages
- Customer Support: Share the tracking URL with customers who inquire about their shipment status
- Mobile Apps: Embed the tracking URL in push notifications or in-app order details
Tracking Information Provided
When customers visit the tracking URL, they can see:
- Current shipment status
- Delivery timeline and estimated delivery date
- Carrier information
- Delivery location updates
- Driver information (when available via OnFleet)
- Real-time GPS tracking (for OnFleet-tracked deliveries)
- Delivery photos and signatures (when captured)
Integration Examples
Email Notification
// Send tracking email after receiving pickup webhook
app.post('/webhooks/nbox', async (req, res) => {
const webhook = req.body;
if (webhook.event === 'shipment.pickup') {
const { order_reference, tracking_url, awb } = webhook.data;
await sendEmail({
to: customer.email,
subject: 'Your order has been shipped!',
html: `
<h2>Your Order #${order_reference} is on its way!</h2>
<p>Tracking Number: <strong>${awb}</strong></p>
<p>
<a href="${tracking_url}"
style="background: #007bff; color: white; padding: 10px 20px;
text-decoration: none; border-radius: 5px;">
Track Your Shipment
</a>
</p>
<p>Or copy this link: ${tracking_url}</p>
`
});
res.status(200).send('OK');
}
});Order Status Page
<!-- HTML Example -->
<div class="order-status">
<h3>Order #{{ order.reference }}</h3>
<div class="tracking-info">
<p><strong>Status:</strong> Shipped</p>
<p><strong>Tracking #:</strong> {{ order.awb }}</p>
<p>
<a href="{{ order.tracking_url }}"
target="_blank"
class="btn btn-primary">
<i class="icon-location"></i>
Track Your Package
</a>
</p>
</div>
</div>SMS Notification
// Send SMS with tracking link
const message = `
Your order #${order_reference} has shipped!
Track it here: ${tracking_url}
- YourStore
`;
await sendSMS(customer.phone, message);Best Practices
- Immediate Notification: Send tracking information as soon as you receive the pickup webhook
- Multiple Channels: Share tracking via email, SMS, and on your website for maximum visibility
- Clear Instructions: Explain that customers can click the link to see real-time updates
- Proactive Updates: Consider sending additional notifications when delivery status changes (using completed/failed webhooks)
- Mobile-Friendly: Ensure tracking links work well on mobile devices
- Save Tracking Data: Store the tracking URL and AWB in your database for future reference
Notes
- Public Access: Tracking URLs are publicly accessible and don't require authentication
- Shareable: Customers can share the tracking link with others (e.g., gift recipients)
- Persistent: Tracking URLs remain active even after delivery for historical reference
- Redirect Behavior: URLs redirect to the appropriate carrier tracking portal or OnFleet tracking page