التوثيق
سكربت واحد في المتصفح، واستدعاء API واحد من خادمك. كل ما تحتاجه للإطلاق في صفحة واحدة.
البدء السريع
تحتاج إلى مفتاحك العام (pk_...) للمتصفح ومفتاحك السري (sk_...) لخادمك. تجد كليهما في لوحة التحكم ضمن المواقع والمفاتيح.
1. أضف السكربت
ضع هذا الوسم في الصفحات التي يسجّل فيها المستخدمون أو يدخلون أو ينقرون على العروض أو يطلبون السحب. يهيّئ نفسه تلقائيًا من data-key
<script src="https://cashoutguard.com/v1/agent.js" data-key="pk_live_YOUR_PUBLIC_KEY" async></script>
2. اجمع request_id وأرسله إلى خادمك
استدعِ collect() في اللحظة المهمة مع اسم الحدث. تُرجع النتيجة { request_id, visitor_id }
const { request_id } = await CashoutGuard.collect({ event: 'cashout' });
لا يُرفض collect() أبدًا. عند الفشل (حظر، أو انقطاع الاتصال، أو انتهاء المهلة) يُرجع request_id: null مع نص الخطأ. أرسل النموذج على أي حال ودع خادمك يقرر.
3. اطلب القرار من خادمك
أرسل الحدث بطلب POST إلى /v1/evaluate مع مفتاحك السري في الترويسة Authorization: Bearer sk_live_...
لا تضع المفتاح السري أبدًا في كود المتصفح أو في تطبيق جوال. يجب أن يستدعي خادمك وحده /v1/evaluate.
طلب التقييم
POST https://cashoutguard.com/v1/evaluate يقيّم حدثًا واحدًا لحساب واحد، ويربطه بجهازه وشبكته وعنوان السحب، ويُرجع قرارًا. أرسل البيانات بصيغة JSON.
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
event | string | مطلوب | signup أو login أو offer_click أو conversion أو cashout أو custom. |
account_id | string | مطلوب | معرّف المستخدم لديك، بحد أقصى 191 حرفًا. استخدم معرّفًا مبهمًا، لا بريدًا إلكترونيًا. |
request_id | string | اختياري | من collect() في المتصفح. صالح لمدة ساعة واحدة. بدونه لا تتوفر لدينا إلا بيانات الشبكة. |
ip | string | اختياري | عنوان IP الخاص بالمستخدم. مطلوب فقط عندما لا يتوفر request_id، مثلًا في الـ postbacks. |
email | string | اختياري | يُخزَّن كقيمة مُجزَّأة (hash). يكشف النطاقات المؤقتة والبريد المشترك بين الحسابات. |
payout_address | string | اختياري | بريد PayPal أو المحفظة أو الحساب الذي تذهب إليه الأموال. يُخزَّن كقيمة مُجزَّأة (hash). |
payout_method | string | اختياري | نص حر مثل paypal أو usdt أو giftcard. |
amount | number | اختياري | مبلغ السحب أو التحويل. |
currency | string | اختياري | رمز العملة، مثل USD. القيمة الافتراضية USD لطلبات السحب. |
offer_id | string | اختياري | معرّف العرض، لـ offer_click وconversion. يُستخدم لقياس سرعة إكمال العرض. |
offer_country | string | اختياري | البلد الذي يدفع العرض مقابله (رمز ISO مثل US) في التحويلات. يُعلَّم المستخدم الموجود في بلد آخر. |
geo_country | string | اختياري | تحديدك الخاص لموقع عنوان IP للمستخدم (رمز ISO). إذا اختلف عن تحديدنا فالعنوان غالبًا مخرج بروكسي. |
transaction_id | string | اختياري | معرّف المعاملة لدى الشبكة الخاص بالتحويل. يُستخدم لكشف التكرار. |
offer_name | string | اختياري | عنوان العرض كما يراه مستخدموك. يظهر في لوحة التحكم بدل المعرّف الخام. |
click_id | string | اختياري | معرّف النقرة لديك. أرسل القيمة نفسها في offer_click وفي التحويل لربطهما. |
source | string | اختياري | مصدر الحدث، مثل اسم الـ Offerwall أو الشبكة. |
meta | object | اختياري | حتى 20 حقلًا نصيًا إضافيًا تُحفظ مع الحدث (مثل معرّفات sub). |
الاستجابة
للاستجابة دائمًا الشكل نفسه. الحقول غير المنطبقة تكون قيمتها null.
scoreقيمتها من 0 إلى 100. تُدمج الأسباب بحيث تتراكم عدة إشارات متوسطة دون أن تتجاوز 100.reasonsتسرد كل إشارة تم رصدها، من الأقوى إلى الأضعف، مع وزنها وتفاصيلها وتسمية واضحة بالإنجليزية يمكنك عرضها كما هي.device.confidenceتوضح مدى تفرّد الجهاز. يمكن انتحال البصمات، لذا لا ندّعي اليقين أبدًا.linked_accountsتسرد الحسابات الأخرى التي تتشارك مع هذا الحساب جهازًا أو عنوان سحب أو بريدًا إلكترونيًا.cashoutيُعيَّن فقط لأحداث السحب ويوضح الحالة في قائمة المراجعة لديك.
القرارات والإجراءات
اعتمد على حقل action، لا على decision. الحدود أدناه هي القيم الافتراضية ويمكن تغييرها لكل موقع من لوحة التحكم.
| القرار | الدرجة (افتراضي) | action في وضع الظل | action في وضع التنفيذ | ما يجب فعله |
|---|---|---|---|---|
allow | 0-49 | allow | allow | تابع كالمعتاد. |
review | 50-79 | allow | review | علّق طلب السحب أو اطلب تحققًا إضافيًا. سيظهر في قائمة المراجعة لديك. |
block | 80-100 | allow | block | أوقف الإجراء. جمّد الرصيد أو ارفض التسجيل. |
في وضع الظل تكون قيمة action دائمًا allow، لذا يمكنك إطلاق الكود نفسه بأمان قبل التنفيذ. وعند الانتقال إلى وضع التنفيذ لا يتغير شيء في الكود.
أنواع الأحداث
أرسل الأحداث المتوفرة لديك. التسجيل والسحب هما الأهم، والتحويلات تغذّي فحوص سرعة إكمال العروض.
| الحدث | متى يُرسل | ما الذي يكشفه |
|---|---|---|
signup | إنشاء حساب | الحسابات المتعددة، والبوتات، والتسجيل عبر VPN، والبريد المؤقت |
login | تسجيل دخول ناجح | مشاركة الحسابات، وتغيّر البلد، والأجهزة الجديدة |
offer_click | المستخدم يفتح عرضًا | يبدأ حساب الوقت لقياس سرعة إكمال العرض |
conversion | postback من الـ offerwall أو الشبكة | العروض المكتملة بسرعة مفرطة، والمعاملات المكررة، وموجات التحويلات |
cashout | المستخدم يطلب سحبًا | عناوين السحب المشتركة، ووتيرة السحب، والسحب من حسابات جديدة |
custom | أي شيء آخر تريد تقييمه | إشارات الجهاز والشبكة |
Offerwall وإشعارات postback
تصل تحويلات الـ Offerwall عبر postback من خادم إلى خادم دون متصفح. يربط CashoutGuard كل تحويل بالنقرة التي بدأته، فيُقيَّم بجهاز وشبكة تلك النقرة.
1. عندما يفتح المستخدم عرضًا
اجمع البيانات في المتصفح وأرسل offer_click مع العرض ومعرّف النقرة.
2. عندما يصل الـ postback
أرسل conversion من معالج الـ postback بنفس account_id وclick_id. لا حاجة إلى request_id. مرّر عنوان IP للمستخدم إذا وفّره الـ Offerwall.
تُفحص التحويلات بحثًا عن: إكمال أسرع من اللازم للعرض، تحويل بلا نقرة، نقرة وتحويل من دولتين مختلفتين، أرباح أعلى بكثير من اليوم المعتاد للحساب، ومعرّفات معاملات مكررة.
شبكات Offerwall
إذا كنت تدير شبكة بها ناشرون كثيرون، فأرسل معرّفات حسابات تتضمن الناشر وفعّل "وضع شبكة Offerwall" في المواقع. عندها تُربط الحسابات داخل الناشر نفسه فقط، لأن استخدام شخص واحد لعدة مواقع من ناشريك أمر طبيعي. الصيغة: publisher_id:user_id
كتالوج العروض
POST /v1/offers يرسل أسماء عروضك (حتى 1,000 في كل طلب). ستعرض الأحداث السابقة والقادمة الاسم الحقيقي حتى لو حملت المعرّف فقط.
رموز الأسباب
تظهر هذه الرموز في reasons[].code. اعرض النص للمشرفين لديك، واستخدم الرمز في منطق الكود.
| الرمز | المعنى | المجموعة | الوزن |
|---|---|---|---|
ip_tor | عقدة خروج Tor | الشبكة | 60 |
ip_vpn | اتصال عبر VPN | الشبكة | 45 |
ip_datacenter | عنوان IP لمركز بيانات أو استضافة | الشبكة | 40 |
timezone_mismatch | المنطقة الزمنية للمتصفح لا تطابق موقع عنوان IP | الشبكة | 20 |
webrtc_ip_leak | تسرّب عنوان IP الحقيقي من بلد آخر | الشبكة | 30 |
ip_multi_timezone | نفس عنوان IP مع مناطق زمنية كثيرة (مخرج بروكسي) | الشبكة | 50 |
proxy_farm_ip | عدة حسابات على عنوان IP واحد، كلها بساعة البلد الأجنبي نفسه (بروكسي مشترك) | الشبكة | 60 |
provider_rotation | مزودو إنترنت كثيرون في أيام قليلة، مع ساعة بلد آخر (بروكسي سكني متناوب) | الشبكة | 45 |
privacy_relay | iCloud Private Relay (ميزة خصوصية) | الشبكة | 5 |
proxy_headers | وصل الطلب عبر بروكسي | الشبكة | 20 |
geo_sources_disagree | مصادر تحديد الموقع غير متطابقة | الشبكة | 45 |
ip_shared_with_accounts | نفس عنوان IP استخدمته حسابات أخرى اليوم | الشبكة | 25 |
country_changed | تغيّر البلد | الشبكة | 15 |
impossible_travel | سفر مستحيل: عناوين IP من بلدين بعيدين خلال ساعات | الشبكة | 50 |
locale_country_mismatch | لغة متصفح من بلد آخر | الشبكة | 30 |
phone_country_mismatch | هاتف من دولة غير دولة الـ IP | الشبكة | 20 |
ip_flagged_on_network | IP محظور في مواقع أخرى | الشبكة | 25 |
device_shared_with_accounts | جهاز مشترك مع حسابات أخرى | الجهاز | 55 |
automation_detected | بوت أو أداة أتمتة | الجهاز | 70 |
auto_clicker | نقر تلقائي على الهاتف | الجهاز | 55 |
scripted_behavior | استخدام الصفحة بواسطة سكربت | الجهاز | 45 |
emulator_or_vm | محاكي أو جهاز افتراضي | الجهاز | 45 |
browser_tampering | تلاعب بالمتصفح أو انتحال | الجهاز | 35 |
device_rooted | هاتف عليه صلاحيات روت | الجهاز | 25 |
incognito | تصفح خاص | الجهاز | 10 |
device_spoofed | طراز هاتف مزيّف | الجهاز | 55 |
emulator_profile | ملف محاكي افتراضي | الجهاز | 60 |
cloud_phone | هاتف سحابي | الجهاز | 60 |
phone_farm_display | شاشة مزرعة هواتف | الجهاز | 45 |
device_market_mismatch | هاتف صيني فقط خارج الصين | الجهاز | 25 |
storage_cleared_reappeared | مسح ملفات تعريف الارتباط ثم عاد | الجهاز | 15 |
no_device_data | لم تُرسل بيانات الجهاز | الجهاز | 15 |
request_reused | رمز الجهاز أعاد استخدامه حساب آخر | الجهاز | 40 |
device_farm_proxy | مزرعة هواتف عبر بروكسيات سكنية | الجهاز | 85 |
device_clones | نسخ الجهاز: هاتف واحد يعيد ضبط هويته لينتحل صفة حسابات جديدة كثيرة على شبكة واحدة | الجهاز | 55 |
payout_address_shared | عنوان السحب مستخدم في حسابات أخرى | الحساب | 70 |
email_disposable | بريد إلكتروني مؤقت | الحساب | 25 |
email_invalid | بريد إلكتروني لا يمكنه استقبال الرسائل (نطاق بريد غير موجود) | الحساب | 35 |
email_shared | نفس البريد الإلكتروني لحساب آخر | الحساب | 50 |
phone_shared | رقم هاتف مشترك مع حسابات أخرى | الحساب | 50 |
phone_voip | رقم VoIP أو افتراضي | الحساب | 40 |
phone_invalid | رقم هاتف غير صالح | الحساب | 30 |
many_devices_per_account | أجهزة كثيرة جدًا على حساب واحد | الحساب | 20 |
flagged_on_network | مُعلَّم على مواقع أخرى يحميها CashoutGuard | الحساب | 45 |
face_same_person | الوجه نفسه كحسابات أخرى | الحساب | 0 |
offer_completed_too_fast | إكمال العرض بسرعة مستحيلة | السلوك | 40 |
slow_after_click | تحويل بعد النقرة بوقت طويل | السلوك | 0 |
conversion_velocity | تحويلات كثيرة جدًا في الساعة | السلوك | 30 |
conversion_without_click | تحويل بلا نقرة من جدار العروض | السلوك | 35 |
click_conversion_country_mismatch | نقرة من دولة وتحويل من أخرى | السلوك | 30 |
offer_country_mismatch | بلد العرض يختلف عن بلد المستخدم | السلوك | 45 |
click_velocity | نقرات كثيرة على العروض خلال دقائق | السلوك | 35 |
earnings_spike | أرباح تفوق المستخدم العادي بكثير | السلوك | 30 |
source_high_reversals | مصدر بكثير من الاستردادات | السلوك | 45 |
offer_high_reversals | عرض بكثير من الاستردادات | السلوك | 35 |
duplicate_transaction | معرّف معاملة مكرر | السلوك | 60 |
offer_repeated_other_publisher | العرض نفسه أُنجز سابقًا عبر ناشر آخر | السلوك | 85 |
offer_repeated_other_account | العرض نفسه أنجزه حساب آخر على هذا الجهاز | السلوك | 85 |
offer_farm_burst | موجة مزرعة: حسابات جديدة كثيرة بأجهزة مزارع على هذا العرض خلال ساعات | السلوك | 30 |
signup_burst | دفعة تسجيلات: عدة حسابات سُجّلت خلال ثوانٍ من عناوين IP مختلفة | السلوك | 25 |
face_check_required | فحص الوجه مطلوب ولم يُجرَ بعد | السلوك | 0 |
face_check_failed | فشل فحص الوجه | السلوك | 0 |
publisher_farm_wave | موجة مزرعة لدى ناشره: معظم الحسابات الجديدة التي أرسلها إلى هذا العرض جاءت من هواتف سحابية أو محاكيات | السلوك | 55 |
cashout_velocity | طلبات سحب كثيرة جدًا في اليوم | السلوك | 30 |
new_account_cashout | سحب من حساب جديد تمامًا | السلوك | 20 |
blocklisted | في قائمة الحظر لديك | قوائمك | 100 |
تُدمج الأوزان بطريقة noisy-OR: score = 100 x (1 - product of (1 - weight/100)). إشارتان بوزن 40 تعطيان 64، لا 80. أي تطابق مع قائمة الحظر يعطي دائمًا 100.
Webhooks
عيّن رابط webhook في لوحة التحكم. نرسل طلب POST لكل حدث مُقيَّم بـ block (event.blocked)، وعندما يتحول حساب إلى block (account.blocked)، وعندما يقرر فريقك بشأن سحب (cashout.decided). تجاهل الأنواع التي لا تستخدمها.
كل طلب موقّع بسر الـ webhook الخاص بك. قيمة HMAC-SHA256 بالصيغة الست عشرية للمحتوى الخام موجودة في الترويسة X-CashoutGuard-Signature
ردّ بأي حالة 2xx. تُعاد محاولة التسليم الفاشل حتى 5 مرات: بعد 10 ثوانٍ، ثم دقيقة، ثم 5 دقائق، ثم 15 دقيقة.
حالة الحساب
GET /v1/accounts/{account_id} يُرجع تقييم المخاطر الحالي للحساب دون إنشاء حدث.
POST /v1/accounts/{account_id}/status يتيح لأدوات الإشراف الخاصة بك تغيير حالة الحساب.
active: تقييم عادي.allowlisted: تبقى الدرجات دون حد المراجعة. للمستخدمين الموثوقين والموظفين.blocked: كل حدث يُرجع block بدرجة 100.
الإلغاءات والدقة
POST /v1/outcomes يُبلغ بما حدث للتحويلات بعد تقييمها: ألغاها العرض أو المعلن (chargeback) أو تأكدت صحتها. نطابق معرفاتك مع التحويلات ونقيس المحرك على زياراتك في صفحة الدقة.
بدون برمجة: ارفع ملف الإلغاءات الشهري من شبكات العروض (CSV أو Excel) في صفحة الدقة، ونجد عمود المعرفات تلقائيًا.
PHP وNode.js وPython وAndroid
لا حاجة إلى SDK. يكفي استدعاء HTTP عادي بمهلة قصيرة. مثال كامل لطلب سحب:
- cashoutguard.php: PHP 7.4+، ملف واحد، بدون Composer. استدعه بـ require فقط.
- composer require cashoutguard/cashoutguard-php: عميل PHP نفسه مع ملف README لمجلد vendor لديك.
- npm install @cashoutguard/node: Node 18+ مع أنواع TypeScript.
- cashoutguard-wordpress.zip: إضافة ووردبريس: سكربت المتصفح في كل الصفحات، وتقييم التسجيلات وتسجيلات الدخول، وخطافات للسحب وتحويلات جدران العروض والإلغاءات.
الأخطاء والحدود
| HTTP | المحتوى | المعنى |
|---|---|---|
| 401 | missing_or_invalid_secret_key | المفتاح السري مفقود أو خاطئ أو ملغى. يذكر الرد السبب في "reason" (missing وpublic_key وunknown_secret وplaceholder وmalformed) وطريقة الإصلاح في "hint". |
| 404 | not_found | الحساب غير موجود (نقاط نهاية الحسابات). |
| 422 | { "message", "errors" } | محتوى غير صالح. يسرد errors كل حقل. |
| 429 | Too Many Requests | تم بلوغ حد الطلبات. تسمح واجهة API للخادم بـ 3,000 طلب في الدقيقة لكل موقع. |
| 401 · agent.js | unknown_public_key | قيمة data-key ليست مفتاحًا عامًا لأي موقع. انسخ pk_live_... مجددًا من صفحة التثبيت. |
| 403 · agent.js | origin_not_allowed | نطاق الصفحة غير موجود ضمن المصادر المسموح بها للموقع. أضفه من صفحة المواقع أو اترك القائمة فارغة. يعمل localhost دائمًا. يشرح agent.js ذلك أيضًا في وحدة تحكم المتصفح. ترسل WebViews في التطبيقات الأصل "null": أضف null إلى القائمة لقبولها. لا تحتاج حزمة Android الأصلية إلى أي شيء. |
| 403 | account_suspended | الحساب موقوف، غالبًا بسبب فاتورة غير مدفوعة. راجع الفوترة. |
| 503 | temporarily_unavailable | انقطاع قصير من جهتنا. اسمح بالإجراء وأعد المحاولة لاحقًا. |
الفشل المفتوح: إذا انتهت مهلة الاستدعاء أو حدث خطأ، اسمح بالإجراء وسجّله. لا تدع أي انقطاع لدينا يوقف مستخدميك.