دليل المطورين

أكّد الطلبات على واتساب من أي منصة

متجرك مش على شوبيفاي أو سلة أو زد أو ووكومرس أو إيزي أوردرز؟ ابعت طلباته لـ REST API يودوو. يودوو بيبعت رسالة التأكيد على واتساب وكل الأتوميشن اللي مشغّلها، وبيبلّغ منصتك أول ما العميل يأكد أو يلغي.

الرابط الأساسيhttps://app.yudoo.io/api/v1

كل اللي محتاجه عشان تبني تأكيد الطلبات على واتساب

بداية سريعة

أول رسالة تأكيد على واتساب في دقايق.

  1. 1

    اربط متجرك: تطبيق يودوو ← الإعدادات ← منصات المتجر ← منصة أخرى (API). انسخ مفتاح الـ API (بيبدأ بـ wp_live_).

  2. 2

    ابعت طلب: POST /orders برقم العميل وتفاصيل الطلب.

  3. 3

    استقبل الرد: ضيف رابط الـ webhook بتاعك واتعامل مع order.confirmed وorder.cancelled.

POST /orders
curl -X POST https://app.yudoo.io/api/v1/orders \
  -H "Authorization: Bearer wp_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1042",
    "number": "1042",
    "status": "pending",
    "customer": { "name": "Mohamed Ali", "phone": "201001234567", "email": "[email protected]" },
    "currency": "EGP",
    "total": 540,
    "shipping_total": 40,
    "payment_method": "cod",
    "shipping_address": { "address1": "12 Tahrir St", "city": "Cairo", "province": "Cairo", "country": "EG" },
    "items": [
      { "name": "Cotton T-shirt", "variant": "White / L", "quantity": 1, "price": 250, "sku": "TS-WH-L" },
      { "name": "Sport socks", "quantity": 2, "price": 125 }
    ],
    "note": "Please deliver after 5 pm"
  }'

01بيشتغل إزاي

  1. 1

    منصتك تبعت كل طلب جديد على POST /orders.

  2. 2

    يودوو يبعت رسالة التأكيد على واتساب من رقم واتساب الأعمال بتاعك، بزرارين «تأكيد» و«إلغاء»، ومعاها كل الأتوميشن اللي مشغّلها للمتجر (المتابعة، تحديث الشحن، طلب التقييم…).

  3. 3

    العميل يدوس تأكيد أو إلغاء. يودوو يرد عليه على واتساب ويبعت order.confirmed أو order.cancelled لرابط الـ webhook بتاعك.

  4. 4

    منصتك تحرّك الطلب (تشحنه أو تلغيه). ولما يتشحن، اعمل PATCH للطلب برقم التتبع ورسالة تحديث الشحن توصل للعميل.

الرسايل والأزرار والمواعيد هي أتوميشن المتجر في تطبيق يودوو، زي متجر شوبيفاي أو سلة بالظبط: الـ API بس بيدخّل الطلبات وبيطلّع الردود.

02البداية

  1. 1

    ادخل تطبيق يودوو (app.yudoo.io) واربط رقم واتساب الأعمال بتاعك.

  2. 2

    الإعدادات ← منصات المتجر ← منصة أخرى (API): اكتب اسم المتجر ورابطه ودوس ربط.

  3. 3

    انسخ مفتاح الـ API وسر التوقيع. المفتاح بيظهر المرة دي بس؛ خلّي الاتنين على السيرفر بتاعك، وأبداً مش في المتصفح أو تطبيق.

  4. 4

    شغّل الأتوميشن اللي عايزه (تأكيد الدفع عند الاستلام الأول) من صفحة الأتوميشن.

  5. 5

    ضيف رابط الـ webhook في كارت المتجر، ودوس «ابعت حدث تجريبي».

GET/api/v1/me

اتأكد إن المفتاح شغال: بيرد بالمتجر اللي المفتاح تبعه.

bash
curl https://app.yudoo.io/api/v1/me -H "Authorization: Bearer wp_live_your_api_key"

{
  "store": { "name": "My Store", "url": "https://mystore.com", "connected_at": "2026-11-04T09:00:00.000Z" },
  "webhook": { "url": "https://mystore.com/yudoo/webhook", "events": ["order.confirmed", "order.cancelled"] }
}

03التوثيق

كل طلب لازم يكون فيه مفتاح الـ API بتاع المتجر في هيدر Authorization. وكمان X-API-Key: wp_live_… مقبول.

http
Authorization: Bearer wp_live_your_api_key
  • مفتاح واحد لكل متجر. تقدر تعمل مفتاح جديد من كارت المتجر في أي وقت، والقديم بيبطل يشتغل فوراً.
  • الطلبات على HTTPS بس، والردود JSON.
  • أقصى حاجة 120 طلب في الدقيقة لكل متجر (بعدها 429 rate_limited).

ماتحطش المفتاح أبداً في صفحات المتجر أو تطبيق موبايل أو JavaScript في المتصفح: أي حد معاه المفتاح يقدر يبعت طلبات باسم متجرك.

04إنشاء طلب

POST/api/v1/orders

ابعت كل طلب أول ما يتعمل. يودوو بيحفظه ويشغّل أتوميشن الطلبات بتاعة المتجر: رسالة التأكيد المناسبة لطريقة الدفع الأول. لو بعت نفس الـ id تاني الطلب بيتحدّث بدل ما يتعمل طلب تاني، فإعادة الإرسال دايماً آمنة.

curl -X POST https://app.yudoo.io/api/v1/orders \
  -H "Authorization: Bearer wp_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1042",
    "number": "1042",
    "status": "pending",
    "customer": { "name": "Mohamed Ali", "phone": "201001234567", "email": "[email protected]" },
    "currency": "EGP",
    "total": 540,
    "shipping_total": 40,
    "payment_method": "cod",
    "shipping_address": { "address1": "12 Tahrir St", "city": "Cairo", "province": "Cairo", "country": "EG" },
    "items": [
      { "name": "Cotton T-shirt", "variant": "White / L", "quantity": 1, "price": 250, "sku": "TS-WH-L" },
      { "name": "Sport socks", "quantity": 2, "price": 125 }
    ],
    "note": "Please deliver after 5 pm"
  }'
الحقلالنوعالوصف
idstringمطلوب. رقم الطلب عندك في منصتك. لو بعت نفس الـ id تاني، الطلب ده بيتحدّث.
customer.phonestringمطلوب. بالصيغة الدولية بكود الدولة، أرقام بس (201001234567). رسايل واتساب بتروح للرقم ده.
customer.namestringاسم العميل ({{customer_first_name}} في الرسايل).
customer.emailstringاختياري.
numberstringالرقم اللي العميل عارفه ("1042" ← #1042). لو مابعتوش بيبقى #id.
statusstringpending (الافتراضي)، processing، shipped، delivered، cancelled… شوف حالات الطلب.
payment_methodstringcod، bank_transfer، instapay، vodafone_cash، card… بيحدد رسالة التأكيد اللي الطلب ياخدها. شوف طرق الدفع.
currencystringكود ISO من 3 حروف: EGP، SAR، AED، USD…
totalnumberإجمالي الطلب شامل الشحن.
shipping_totalnumberمصاريف الشحن.
items[]arrayلحد 200 سطر: name (مطلوب)، quantity، price، variant، sku، product_id، image_url (https).
shipping_addressobjectaddress1، address2، city، province، postal_code، country (كود من حرفين أو الاسم).
notestringملاحظة العميل على الطلب.
trackingobjectnumber، url، carrier — لو الطلب اتشحن خلاص.
placed_atstringتاريخ ISO 8601. لو مابعتوش بيبقى وقت وصول الطلب ليودوو.

الرد بيبقى 201 Created ومعاه الطلب (200 لو الـ id اتبعت قبل كده):

json
{
  "order": {
    "id": "1042",
    "number": "#1042",
    "status": "pending",
    "confirmation": { "status": "pending", "at": null, "cancel_reason": null },
    "customer": { "name": "Mohamed Ali", "phone": "201001234567", "email": "[email protected]" },
    "currency": "EGP",
    "total": 540,
    "payment_method": "cod",
    "items": [
      { "name": "Cotton T-shirt", "variant": "White / L", "quantity": 1, "price": 250, "sku": "TS-WH-L", "product_id": null },
      { "name": "Sport socks", "variant": null, "quantity": 2, "price": 125, "sku": null, "product_id": null }
    ],
    "tracking": null,
    "created_at": "2026-11-04T10:00:00.000Z",
    "updated_at": "2026-11-04T10:00:00.000Z"
  }
}

05قراءة طلب

GET/api/v1/orders/{id}

اقرا طلب بالـ id بتاعك، ورد العميل في confirmation.

bash
curl https://app.yudoo.io/api/v1/orders/1042 \
  -H "Authorization: Bearer wp_live_your_api_key"
confirmation.statusالمعنى
pendingلسه مفيش رد.
confirmedالعميل (أو انت من يودوو) أكد الطلب.
cancelledالعميل (أو انت) لغى الطلب؛ وcancel_reason فيه السبب اللي اختاره لو قاله.

06تحديث طلب

PATCH/api/v1/orders/{id}

ابعت اللي اتغيّر بس: الحالة، التتبع، المنتجات أو الإجمالي. الحالة الجديدة بتشغّل الأتوميشن المناسب (تحديث الشحن، جاهز للاستلام، إلغاء الطلب…)، ورقم التتبع بيدّي رسالة تحديث الشحن اللينك بتاعها.

bash
curl -X PATCH https://app.yudoo.io/api/v1/orders/1042 \
  -H "Authorization: Bearer wp_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "shipped",
    "tracking": { "number": "7845120963", "url": "https://track.example.com/7845120963", "carrier": "Bosta" }
  }'

07حالات الطلب وطرق الدفع

ابعت الكلمات اللي منصتك بتستخدمها: يودوو بيفهمها بالإنجليزي والعربي. دي اللي بيفهمها:

الحالةأمثلة بيفهمها يودوو
جديدpending، new، placed، awaiting، unpaid، جديد
قيد التجهيزprocessing، confirmed، preparing، packed، on hold، قيد التجهيز
جاهز للاستلامready for pickup، ready to collect، جاهز للاستلام
تم الشحنshipped، out for delivery، in transit، تم الشحن
تم التوصيلdelivered، completed، fulfilled، تم التوصيل
فشل التوصيلfailed delivery، undelivered، فشل التوصيل
ملغيcancelled، canceled، rejected، refunded، ملغي
مرتجعreturned، rto، مرتجع
payment_methodرسالة التأكيد اللي بتتبعت
cod، cash on deliveryتأكيد الدفع عند الاستلام (تأكيد / إلغاء)
bank_transfer، instapay، depositتأكيد التحويل البنكي (إرسال إثبات الدفع)
vodafone_cash، wallet، manual، pay laterتأكيد الدفع اليدوي
card، paid، أي حاجة تانيةتأكيد الطلب المدفوع

08الـ Webhooks

ضيف رابط الـ webhook بتاعك في كارت المتجر في يودوو (https بس). يودوو بيبعت عليه حدث JSON كل ما طلب ياخد رد:

الحدثإمتى
order.confirmedالعميل داس تأكيد، أو انت أكدت الطلب من يودوو (data.by = customer / merchant).
order.cancelledالعميل داس إلغاء، أو انت لغيته من يودوو. السبب لو اتقال في data.order.confirmation.cancel_reason.
webhook.testدوست «ابعت حدث تجريبي»، أو استخدمت POST /webhooks/test.
http
POST https://mystore.com/yudoo/webhook
Content-Type: application/json
Yudoo-Event: order.cancelled
Yudoo-Delivery: evt_k3j9x2m1q8w7e6r5t4y3u2i1
Yudoo-Signature: t=1793782800,v1=5f2b8c…e91a

{
  "id": "evt_k3j9x2m1q8w7e6r5t4y3u2i1",
  "type": "order.cancelled",
  "created_at": "2026-11-04T10:20:00.000Z",
  "data": {
    "by": "customer",
    "order": {
      "id": "1042",
      "number": "#1042",
      "status": "pending",
      "confirmation": { "status": "cancelled", "at": "2026-11-04T10:19:58.000Z", "cancel_reason": "Changed my mind" },
      "customer": { "name": "Mohamed Ali", "phone": "201001234567", "email": "[email protected]" },
      "…": "the same order object as GET /orders/{id}"
    }
  }
}
  • رد بأي 2xx خلال 10 ثواني، واعمل الشغل التقيل بعد ما ترد.
  • لو الإرسال فشل بنعيده بعد دقيقة، 5 دقايق، 30 دقيقة، ساعتين، 6 ساعات، 12 ساعة و24 ساعة، وبعدها بيتعلّم فاشل. كارت المتجر بيعرض آخر الإرساليات.
  • نفس الحدث ممكن يوصل مرتين (إعادة بعد timeout): لو الـ id اتعامل معاه قبل كده تجاهله.
  • اتأكد من التوقيع دايماً قبل ما تثق في أي حدث.

POST/api/v1/webhooks/test

bash
curl -X POST https://app.yudoo.io/api/v1/webhooks/test -H "Authorization: Bearer wp_live_your_api_key"

{ "delivery": { "id": "evt_…", "delivered": true, "error": null } }

09التحقق من التوقيع

كل webhook معاه هيدر Yudoo-Signature: الـ t هو وقت الإرسال (ثواني Unix) والـ v1 هو HMAC-SHA256 لـ "t.raw_body" بسر التوقيع بتاعك، بالـ hex.

http
Yudoo-Signature: t=1793782800,v1=5f2b8c0d…e91a
  1. 1

    اقرا الـ body الخام قبل ما تحوّله لـ JSON.

  2. 2

    احسب HMAC-SHA256(signing_secret, t + "." + raw_body) بالـ hex.

  3. 3

    قارنه بالـ v1 بمقارنة ثابتة الوقت، وارفض أي t أقدم من 5 دقايق.

import crypto from "node:crypto";
import express from "express";

const app = express();
// Read the RAW body: the signature is over the exact bytes Yudoo sent.
app.post("/yudoo/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("Yudoo-Signature") ?? "";
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto
    .createHmac("sha256", process.env.WHATPRO_SIGNING_SECRET)
    .update(`${t}.${req.body}`)
    .digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  if (!fresh || !v1 || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) {
    return res.status(400).send("bad signature");
  }
  const event = JSON.parse(req.body);
  // event.type: "order.confirmed" | "order.cancelled" | "webhook.test"
  res.sendStatus(200);
});

10الأخطاء

الطلب اللي بيفشل بيرد بـ HTTP status وكائن خطأ واحد:

http
HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "missing_field",
    "message": "`customer.phone` is required, in international format with the country code (e.g. 201001234567).",
    "field": "customer.phone"
  }
}
Statuscodeالمعنى
400invalid_jsonالـ body مش JSON object.
401missing_api_key / invalid_api_keyمفيش مفتاح، أو المفتاح غلط أو اتغيّر، أو المتجر اتفصل.
404order_not_foundمفيش طلب بالـ id ده اتبعت للمتجر ده.
405method_not_allowedالـ method غلط للـ endpoint ده.
409no_webhook_urlالحدث التجريبي محتاج رابط webhook الأول.
413body_too_largeالـ body أكبر من 64 KB.
422missing_field / invalid_field / invalid_orderحقل ناقص أو غلط؛ الحقل مكتوب في field.
429rate_limitedأكتر من 120 طلب في الدقيقة للمتجر.
500server_errorالطلب ماتحفظش؛ ابعته تاني.

واقف في حاجة، أو محتاج حقل مش موجود؟ فريقنا بيرد على واتساب.