متطلبات الأمان
كل تطبيق مثبّت على متجر DZBuild يملك رمزا يصل إلى طلبيات التاجر أو زبائنه أو منتجاته. تنطبق هذه القواعد على كل التطبيقات، في وضع التجربة وبعد الاعتماد. يمكن لـ DZBuild إيقاف التطبيق الذي يخالفها، والتطبيق الموقوف يتلقى 403 app_suspended في كل استدعاء.
عناوين إعادة التوجيه
سجّل من 1 إلى 5 عناوين إعادة توجيه في منصة المطورين. يجب أن يكون كل عنوان:
- بـ
https، - بطول 512 حرفا على الأكثر،
- بلا اسم مستخدم ولا كلمة مرور ولا
#fragment، - بلا حرف البدل
*.
تقارن DZBuild قيمة redirect_uri في كل طلب بالقائمة المسجّلة حرفا بحرف. العنوانان https://app.example.com/callback و https://app.example.com/callback/ مختلفان. لا تقبل منصة المطورين إلا https، لذا اختبر مسار التثبيت على عنوان workers.dev أو عبر نفق https وسجّل عنوانه.
أنشئ قيمة state عشوائية جديدة لكل طلب تفويض، واربطها بجلسة التاجر، وارفض كل عودة لا تطابق فيها state.
سرّ العميل ورموز الوصول
يظهر سرّ العميل (dzas_ يليه 48 حرفا ست عشريا) مرة واحدة، عند إنشاء التطبيق أو تجديد السرّ. لا تحتفظ DZBuild إلا ببصمته. استعمله على خادمك فقط: لا في متصفح، ولا في تطبيق هاتف، ولا في مستودع عام، ولا في سطر سجلّ.
إذا تسرّب السرّ، جدّده في منصة المطورين. يتوقف السرّ القديم فورا، وتبقى رموز الوصول الصادرة من قبل صالحة.
رموز الوصول (dzpk_live_...) تمنح الوصول إلى الواجهة الذي وافق عليه التاجر، دون تاريخ انتهاء. احفظها على الخادم، مشفّرة عند التخزين، رمزا لكل متجر. لا تملك التطبيقات نقطة وصول لإلغاء رمز. إذا تسرّب رمز، اطلب من التاجر إعادة تثبيت تطبيقك على ذلك المتجر: يحلّ الرمز الجديد محلّ القديم فورا. ويمكن للتاجر أيضا إزالة التطبيق، فيُلغى الرمز.
التحقق من توقيع إشعارات webhook
كل إشعار webhook ترسله DZBuild إلى تطبيقك موقّع بمفتاح التوقيع الخاص بالتطبيق، وهو سلسلة ست عشرية من 64 حرفا تستطيع عرضها وتجديدها في منصة المطورين. يحمل الطلب X-DZ-Timestamp و X-DZ-Event و X-DZ-Delivery و:
X-DZ-Signature: t=1758880000,v1=5d41402abc4b2a76b9719d911017c592...
احسب HMAC-SHA256 بمفتاح التوقيع على الطابع الزمني ثم نقطة ثم جسم الطلب الخام، وقارنه بـ v1 بمقارنة ثابتة الزمن، وارفض كل طلب مضى على طابعه الزمني أكثر من 5 دقائق. نقاط استقبال التطبيقات لا تستقبل أبدا الترويسة X-DZ-Token، فالتوقيع هو الدليل الوحيد على أن الطلب صادر من DZBuild. تشرح صفحة إشعارات Webhook المخطط كاملا مع شيفرة بعدة لغات.
سرّ توقيع واحد يغطي كل المتاجر التي ثبّتت تطبيقك. تجديده يغيّر المفتاح لها كلها دفعة واحدة.
التحقق من رموز الفتح
عندما يفتح التاجر تطبيقك من لوحة تحكم DZBuild، تعيد DZBuild توجيه المتصفح إلى عنوان الفتح الخاص بك مع معامل الاستعلام dz_launch. يجب أن يستعمل عنوان الفتح https. المعامل رمز JWT موقّع بخوارزمية HS256 بمفتاح التوقيع الخاص بالتطبيق: السلسلة ذات 64 حرفا كما تعرضها منصة المطورين تماما.
| الحقل | القيمة |
|---|---|
iss | dzbuild |
aud | قيمة client_id الخاصة بك. |
sub | معرّف مستخدم DZBuild الذي فتح التطبيق، كسلسلة نصية. |
store_id | المتجر الذي فُتح منه التطبيق. |
install_id | تثبيتك على ذلك المتجر. |
is_owner | true لمالك المتجر، و false لعضو الفريق. |
iat | وقت الإصدار، بثواني Unix. |
exp | iat زائد 300 ثانية. |
jti | 16 حرفا ست عشريا عشوائيا. |
لا تقبل الرمز إلا إذا طابق التوقيع، وذكرت الترويسة HS256، وكانت iss تساوي dzbuild، و aud تساوي معرّف العميل الخاص بك، ولم يحن exp بعد. ثم ارفض كل jti سبق أن قبلته خلال آخر 5 دقائق. بعد قراءة الرمز، أعد التوجيه إلى عنوان لا يحمله، حتى يبقى خارج سجلّ المتصفح والسجلات.
رمز الفتح يثبت من فتح التطبيق ومن أي متجر. لا يستدعي الواجهة: استعمل رمز الوصول الذي حفظته لـ store_id و install_id هذين.
بلغة PHP:
<?php
/** Claims of a valid dz_launch token, or null. $clientId is your app's client_id. */
function verifyLaunchToken(string $jwt, string $signingSecret, string $clientId): ?array
{
$parts = explode('.', $jwt);
if (count($parts) !== 3) {
return null;
}
[$head, $body, $sig] = $parts;
$b64 = static fn(string $s): string|false => base64_decode(strtr($s, '-_', '+/'), true);
$expected = rtrim(strtr(base64_encode(hash_hmac('sha256', "$head.$body", $signingSecret, true)), '+/', '-_'), '=');
if (!hash_equals($expected, $sig)) {
return null;
}
$header = json_decode((string) $b64($head), true);
$claims = json_decode((string) $b64($body), true);
if (($header['alg'] ?? '') !== 'HS256' || !is_array($claims)) {
return null;
}
$now = time();
if (($claims['iss'] ?? '') !== 'dzbuild' || ($claims['aud'] ?? '') !== $clientId
|| !is_int($claims['exp'] ?? null) || $claims['exp'] < $now || ($claims['iat'] ?? 0) > $now + 60) {
return null;
}
return $claims; // Then refuse a jti you have already seen in the last 5 minutes.
}
بلغة Node.js:
const crypto = require('node:crypto');
// Claims of a valid dz_launch token, or null. clientId is your app's client_id.
function verifyLaunchToken(jwt, signingSecret, clientId) {
const parts = String(jwt).split('.');
if (parts.length !== 3) return null;
const [head, body, sig] = parts;
const expected = crypto.createHmac('sha256', signingSecret).update(`${head}.${body}`).digest();
const given = Buffer.from(sig, 'base64url');
if (given.length !== expected.length || !crypto.timingSafeEqual(given, expected)) return null;
const header = JSON.parse(Buffer.from(head, 'base64url').toString('utf8'));
const claims = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
const now = Math.floor(Date.now() / 1000);
if (header.alg !== 'HS256' || claims.iss !== 'dzbuild' || claims.aud !== clientId) return null;
if (!Number.isInteger(claims.exp) || claims.exp < now || claims.iat > now + 60) return null;
return claims; // Then refuse a jti you have already seen in the last 5 minutes.
}
حذف بيانات المتجر بعد إزالة التطبيق
عندما يزيل التاجر تطبيقك، تلغي DZBuild رمز المتجر، وتُسقط إرساليات webhook التي كانت لا تزال تنتظر ذلك التثبيت، وترسل حدثا واحدا app.uninstalled إلى عنوان webhook الخاص بك إذا تم التحقق منه وكان نشطا:
{
"id": "evt_...",
"event": "app.uninstalled",
"created_at": "2026-09-26T10:15:00+01:00",
"store_id": 141,
"data": {
"install_id": 57,
"client_id": "dzapp_0123456789abcdef0123",
"store_id": 141,
"uninstalled_at": "2026-09-26T09:15:00+00:00"
}
}
احذف البيانات التي تحتفظ بها لذلك المتجر خلال 30 يوما من الحدث: الطلبيات والزبائن والمنتجات وكل نسخة من رمز الوصول. إذا لم يكن لتطبيقك عنوان webhook تم التحقق منه، فالرد 401 على رمز المتجر هو إشارتك.
اطلب أقل الصلاحيات
اطلب فقط الصلاحيات التي تستعملها ميزاتك: لا صلاحية كتابة على بيانات تكتفي بقراءتها، ولا customers:read لتطبيق لا يعرض أي زبون. تقارن DZBuild الصلاحيات المطلوبة بما تقوله بطاقة تطبيقك عنه، ويرى التاجر في شاشة الموافقة سطرًا واحدًا لكل مورد قبل أن يوافق.
لا استخراج آلي للبيانات
لا تصل إلى بيانات المتجر إلا عبر واجهة REST وإشعارات webhook. لا تؤتمت لوحة تحكم DZBuild، ولا تدخل بحساب التاجر، ولا تستخرج صفحات لوحة التحكم أو واجهة المتجر. لا تطلب أبدا من التاجر كلمة مرور DZBuild ولا مفتاح API خاصا بالتاجر.
الرد على بريد الدعم
سجّل عنوان بريد دعم تقرؤه فعلا، وأجب التجار الذين يراسلونه. تعرضه شاشة الموافقة وصفحة التطبيق في لوحة تحكم التاجر. أما قرارات المراجعة فترسلها DZBuild إلى بريد حسابك، لا إلى هذا العنوان.