مرجع الواجهة البرمجية لولاءورا
اربط نظام نقاط البيع أو متجرك الإلكتروني أو أي نظام داخلي. البيانات بصيغة JSON عبر HTTPS، ومفتاح مستقل لكل تكامل.
المصادقة
أنشئ مفتاحًا من لوحة التحكم ← الواجهة البرمجية (باقة الأعمال أو المؤسسات) وأرسله مع كل طلب. يُعرض المفتاح مرة واحدة، فألغِه فورًا إن تسرّب. الحد: ١٢٠ طلبًا في الدقيقة لكل مفتاح.
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 خلال ١٠ ثوانٍ، وتُعاد المحاولة الفاشلة بعد دقيقة ثم ٥ دقائق ثم ٣٠ دقيقة ثم ساعتين ثم ١٢ ساعة.
الأحداث
customer.enrolledcard.earnedreward.unlockedreward.redeemedcard.adjustedcustomer.deletedfeedback.receivedpackage.soldpackage.usedperk.usedcoupon.redeemed
التحقق من التوقيع (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 ?? ""));
}