تخطَّ إلى المحتوى
walaoraWalaora

مرجع الواجهة البرمجية لولاءورا

اربط نظام نقاط البيع أو متجرك الإلكتروني أو أي نظام داخلي. البيانات بصيغة JSON عبر HTTPS، ومفتاح مستقل لكل تكامل.

لا ترسل بيانات العملاء إلا بعلمهم، ولا تضبط marketingConsent على true إلا إذا وافق العميل صراحةً.

المصادقة

أنشئ مفتاحًا من لوحة التحكم ← الواجهة البرمجية (باقة الأعمال أو المؤسسات) وأرسله مع كل طلب. يُعرض المفتاح مرة واحدة، فألغِه فورًا إن تسرّب. الحد: ١٢٠ طلبًا في الدقيقة لكل مفتاح.

Authorization: Bearer wl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

نقاط الوصول

Base URL: https://walaora.com/api/v1

GET/programs

عرض برامج الولاء.

GET/customers?phone=0551234567&tag=vip

البحث عن العملاء (٥٠ في الصفحة، ‎?page=2‎…). ‎?tag=vip يعرض العملاء الذين يحملون هذا الوسم، وكل عميل يتضمن وسومه.

POST/customers

تسجيل عميل في برنامج. المحتوى: { programId, name, phone, email?, marketingConsent?, locale? }. يُرجع 201 عند الإنشاء و200 إن كان مسجلًا.

GET/cards/{serial}

البطاقة حسب الرمز الظاهر على بطاقة العميل أو رمز QR.

POST/cards/{serial}/earn

برامج الأختام: { stamps?: 1–10 }. برامج النقاط: { amount } بعملة مساحة العمل. اختياري: { branchId }. البطاقات متعددة الأختام: أرسل setId لإحدى مجموعات البطاقة.

POST/cards/{serial}/redeem

استبدال مكافأة متاحة واحدة، أو أرسل {"rewardId"} لاستبدال مكافأة من الكتالوج بتكلفتها من الأختام/النقاط.

POST/cards/{serial}/sell

الباقات المدفوعة مسبقًا: بيع باقة تُضاف مراتها إلى البطاقة (الدفع عند الكاشير). Webhook: package.sold.

POST/cards/{serial}/use

الباقات المدفوعة مسبقًا: خصم مرة استخدام (يُرفض إذا نفدت أو انتهت الصلاحية). بطاقات الموظفين: تسجيل الميزة ضمن حدها اليومي. Webhooks: package.used وperk.used.

GET/coupons/{code}

التحقق من كوبون دون استخدامه: عرضه، وهل يمكن استخدامه، وإن لم يكن فلماذا (مُستخدم أو منتهٍ أو متوقف مؤقتًا).

POST/coupons/{code}/redeem

استخدام كوبون مرة واحدة. اختياري: { amount } (قيمة البيع بعملة مساحة العمل) و{ branchId }. يُرجع 409 إذا كان مستخدمًا من قبل أو انتهى العرض. Webhook: coupon.redeemed.

GET/coupon-offers

قائمة عروض الكوبونات بقيمتها وتاريخ انتهائها وهل يمكن إنشاء أكواد منها الآن (usable).

POST/coupon-offers/{id}/coupons

إنشاء أكواد من عرض. { customerId } يعطي ذلك العميل كودًا واحدًا (يظهر في صفحة بطاقته)، أو { count: 1–500 } أكواد غير مرتبطة بعميل للطباعة أو المشاركة. يُرجع 201 مع الأكواد، و409 إذا كان العرض متوقفًا أو منتهيًا.

curl -X POST https://walaora.com/api/v1/cards/ABCDE23456/earn \
  -H "Authorization: Bearer wl_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: receipt-10045" \
  -d '{"stamps": 1}'

إعادة المحاولة وعدم التكرار

في طلبات POST أرسل الترويسة Idempotency-Key بقيمة فريدة (مثل رقم الفاتورة). إعادة الطلب بالقيمة نفسها خلال ٢٤ ساعة تُرجع الرد الأول بدل إضافة ختم مرة ثانية.

الأخطاء

تُرجع الأخطاء الصيغة { error: { code, message } } مع رمز HTTP: ‏401 مفتاح غير صالح · 403 الباقة لا تسمح · 404 غير موجود · 409 فترة انتظار أو لا توجد مكافأة أو البرنامج متوقف · 422 بيانات غير صحيحة · 429 تجاوز الحد.

Webhooks

أضف رابط HTTPS من لوحة التحكم واختر الأحداث. كل إرسال طلب POST بصيغة { id, type, createdAt, data } مع الترويسات Walaora-Event وWalaora-Delivery وWalaora-Signature. يجب الرد برمز 2xx خلال ١٠ ثوانٍ، وتُعاد المحاولة الفاشلة بعد دقيقة ثم ٥ دقائق ثم ٣٠ دقيقة ثم ساعتين ثم ١٢ ساعة.

الأحداث

التحقق من التوقيع (Node.js)

import crypto from "node:crypto";

// rawBody: the exact request body string; header: req.headers["walaora-signature"]
export function verifyWalaora(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // replay window
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
}