وقّع داخل تطبيقك وبعلامتك أنت، دون تحويل المستخدم لأي موقع خارجي
ادمج صفحة توقيع كاملة في منتجك، بشعارك وألوانك ونطاقك. تُصدِر جلسة توقيع قصيرة العمر من خادمك، ثم تضمّنها في إطار iframe أو تُعيد التوجيه إليها، وتستقبل الأحداث لحظيًا عبر postMessage وإشعارات الأحداث الآلية (Webhooks)، بينما يبقى المفتاح السرّي على خادمك وحده. وتجري خطوات التوقيع وتأكيد الهوية والتوقيع المؤهّل كلّها في مسار واحد لا يغادر تطبيقك.
ثلاث طرق لدمج التوقيع، فاختر ما يناسب تطبيقك
الأساس واحد في النماذج الثلاثة: تُنشئ signature_request على خادمك، ثم تحصل على رابط توقيع للموقّع. يختلف النموذج في كيفية وصول المستخدم إلى ذلك الرابط.
الصفحة المستضافة
حوّل المستخدم إلى signing_url الذي يعود جاهزًا ضمن بيانات الموقّع. وهذه أسرع طريقة للإطلاق: صفحة توقيع كاملة تستضيفها «وثائق» على نطاقك المخصّص، دون أي برمجة للواجهة.
- صفر كود في المتصفّح — رابط مباشر
- يعمل على النطاق المخصّص
sign.yourbrand.com - مثالي للروابط عبر البريد أو الرسائل
التضمين داخل التطبيق
أصدِر signing_session قصيرة العمر، ثم اعرضها داخل إطار iframe في صفحتك. يبقى المستخدم في مكانه تمامًا، وتتلقّى أحداث الجلسة لحظيًّا عبر postMessage.
- أعلى معدّل إكمال دون مغادرة الصفحة
- أحداث
wthaiq:viewed / signed / declined - رمز عميل قصير العمر — لا مفتاح سرّي
إعادة التوجيه
حوّل المتصفّح إلى صفحة التوقيع، ثم أعِده تلقائيًا إلى success_url بعد التوقيع أو cancel_url عند الإلغاء. وهو حلٌّ وسط بين البساطة والتحكّم.
- عودة مضمونة إلى مسار تطبيقك
- مناسب لبيئات لا تسمح بالـ
iframe - يُعاد المرجع في متغيّر الرابط
توليد جلسة توقيع قصيرة العمر
لا تُرسِل مفتاحك السرّي إلى المتصفّح أبدًا، بل يستدعي خادمك نقطة الاتصال هذه ليُصدِر رمز جلسة مؤقّتًا خاصًّا بموقّع واحد، يمكن إرساله إلى الواجهة بأمان.
يُصدِر رابط توقيع مُضمَّنًا صالحًا 30 دقيقة لموقّع محدّد، ضمن نمط التوقيع بعلامتك التجارية.
| المُعامِل | الوصف |
|---|---|
| return_url string اختياري | رابط https كامل على دومين مقبول في حسابك، يُعاد إليه الموقّع بعد إتمام التوقيع، ومتاح في باقة «الأعمال» فأعلى. وصلاحية الجلسة ثابتة: 30 دقيقة. |
sk_ يملك صلاحية كاملة على حسابك: إنشاء الطلبات، وتنزيل المستندات الموقّعة، وإدارة إشعارات الأحداث الآلية. ولو تسرّب عبر المتصفّح لتمكّن أي طرف من التحكّم فيه. أمّا رمز الجلسة فمقيّد بموقّع واحد، وبصلاحية «التوقيع» وحدها، ولمدّة دقائق معدودة، وعلى نطاقات محدّدة؛ فحتى لو التُقِط لا يفتح إلا ما أُصدِر من أجله، ثم تنتهي صلاحيته. curl -X POST https://wthaiq.com/api/v1/signers/sgr_9fA2/signing_session \
-H "Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Wthaiq-Version: 2026-07-01" \
-H "Content-Type: application/json" \
-d '{ "return_url": "https://app.acme-pay.com/signed" }'// على الخادم فقط — المفتاح السرّي لا يغادر خادمك
const r = await fetch('https://wthaiq.com/api/v1/signers/sgr_9fA2/signing_session', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.WTHAIQ_SECRET_KEY}`,
'Wthaiq-Version': '2026-07-01',
'Content-Type': 'application/json'
},
body: JSON.stringify({ return_url: 'https://app.acme-pay.com/signed' })
});
const session = await r.json();
// أرسِل هذا فقط إلى المتصفّح — لا شيء غيره
res.json({ signing_url: session.signing_url });{
"object": "signing_session",
"signer": "sgr_9fA2",
"signing_url": "https://wthaiq.com/embed/sign/9aF2xQ7bV3..",
"expires_at": 1754001800
}التخصيص الكامل للعلامة
صفحة التوقيع لك بالكامل. تُضبط إعدادات العلامة مرّةً واحدة على مستوى الحساب من صفحة «الهوية البصرية» في لوحة المطوّرين، وتُتاح في باقة «الأعمال» وما فوقها، وتُطبَّق تلقائيًّا على كل طلب توقيع تنشئه عبر الواجهة البرمجية؛ فلا يحمل جسم الطلب إعدادات للعلامة.
{
"brand_name": "Acme Pay",
"logo_url": "https://cdn.acme-pay.com/logo.svg",
"brand_color": "#0B5FFF",
"custom_domain": "sign.acme-pay.com",
"from_email": "sign@acme-pay.com",
"hide_powered": true,
"sign_welcome_ar": "مرحبًا بك في Acme Pay. راجع العقد ثم وقّعه.",
"sign_welcome_en": "Welcome to Acme Pay. Review the contract, then sign.",
"sign_button_color": "#0B5FFF"
}| الحقل | الوصف |
|---|---|
| brand_name | اسم علامتك الظاهر في صفحة التوقيع، وهو اسم المُرسِل في رسائل الدعوة والتذكير بعد التحقّق من نطاقك. |
| logo_url | شعارك الذي يظهر أعلى صفحة التوقيع. ويُفضَّل بصيغة SVG أو PNG بخلفية شفّافة. |
| brand_color | اللون الأساسي لعلامتك بصيغة HEX، ويُطبَّق على الأزرار والروابط ومؤشّرات التقدّم. |
| custom_domain | نطاق التوقيع المخصّص، مثل sign.acme-pay.com. ويُفعَّل النطاق الخاص بالتواصل مع فريقنا. |
| from_email | عنوان المُرسِل على نطاقك، بعد ضبط سجلّات SPF و DKIM لضمان وصول الرسائل. |
| hide_powered | عند تفعيله تُخفى عبارة «عبر منصّة وثائق» من صفحة التوقيع في طلبات واجهة الربط. وشهادة التوقيع وصفحة التحقّق العامّة تذكران وثائق دائمًا. |
| sign_welcome_ar sign_welcome_en | جملة ترحيب تظهر للموقّع أعلى صفحة التوقيع بلغة الصفحة، نصًّا عاديًّا حتى 240 حرفًا. |
| sign_button_color | لون الأزرار الأساسية في صفحة التوقيع بصيغة HEX. إن غاب استُعمل لون العلامة، ولا يُقبل لون فاتح لأن نصّ الزرّ أبيض. |
sign.acme-pay.com بدلًا من نطاق «وثائق»، فلا يرى المستخدم أي إشارة إلى مزوّد خارجي في أي مرحلة من مراحل التوقيع. تأكيد الهوية و QES في تدفّق واحد
لا يحتاج المستخدم إلى مغادرة إطارك ليؤكّد هويته أو ليوقّع بشهادة مؤهّلة، إذ تظهر الخطوتان مُضمَّنتين قبل التوقيع مباشرة. وفيما يلي ما يراه المستخدم في كلٍّ منهما.
تأكيد الهوية قبل التوقيع
عند تفعيل require_identity للموقّع، يعرض الإطار خطوة تحقّق كاملة قبل فتح صفحة التوقيع، ويُربط قرار التحقّق بالتوقيع نفسه.
- تصوير المستند الرسمييطلب الإطار تصوير بطاقة الهوية أو جواز السفر بالكاميرا مباشرةً داخل صفحتك.
- مطابقة وجه حيّةيُطلب من المستخدم تحريك وجهه أمام الكاميرا للتأكّد من أنه شخص حقيقي حاضر، ثم يُطابَق وجهه مع صورة المستند.
- «جارٍ التحقّق» ثم اعتماديظهر مؤشّر المعالجة ثم علامة نجاح خضراء، وتصبح حالة الموقّع
identity_verified. - فتح صفحة التوقيعبعد الاعتماد فقط تُتاح منطقة التوقيع، فيوقّع المستخدم وقد ارتبط توقيعه بهوية مؤكّدة.
التوقيع المؤهّل بالتوكن
للتوقيع المؤهّل (method: "token")، يجري التوقيع بالشهادة المحفوظة في التوكن عبر وكيل محلّي يعمل في جهاز المستخدم على العنوان 127.0.0.1:8899 دون أن يغادر المفتاح الخاص التوكن إطلاقًا (توقيع PAdES مؤجّل ومنفصل).
- اكتشاف الوكيل والتوكنتتحقّق الصفحة من أن الوكيل المحلّي يعمل وأن التوكن موصول، ثم تعرض «تمّ اكتشاف التوكن».
- تجهيز التوقيع على الخادميحسب الخادم
signedAttributes(بصمة SHA-256 للمستند)، ثم يرسل البصمة وحدها دون استخدام أي مفتاح خاص. - إدخال رمز PIN على الجهازيطلب الوكيل رمز التوكن، فيُدخله المستخدم ليأذن بعملية توقيع واحدة على الجهاز.
- التوقيع محليًا ثم دمج CMSيوقّع التوكن البصمة ويعيد بنية
CMS، فيدمجها الخادم في المستند ويستكمل صيغة PAdES حتى مستوى LTA.
// 1) الخادم يجهّز signedAttributes (هاش المستند) — لا مفتاح خاص
const prep = await signingPage.prepareTokenSignature();
// prep.digest = SHA-256 لـ signedAttributes (ESS signingCertificateV2)
// 2) داخل المتصفّح: الوكيل المحلّي يوقّع على الجهاز
const signed = await fetch('https://127.0.0.1:8899/sign', {
method: 'POST',
body: JSON.stringify({ digest: prep.digest, alg: 'SHA256withRSA' })
}).then(r => r.json());
// المفتاح لا يغادر التوكن؛ يعيد الوكيل بنية CMS (adbe.pkcs7.detached)
// 3) الخادم يدمج CMS في المستند ويُنهي PAdES (LT/LTA)
await signingPage.completeTokenSignature({ cms: signed.cms });من الطلب إلى المستند الموقّع — خطوة بخطوة
مسار تضمين كامل: أنشئ الطلب على خادمك، ثم ضمِّن التوقيع، وانتظر إشارة الاكتمال الموثوقة، وأخيرًا نزّل المستند المختوم.
- أنشئ طلب توقيع مُضمَّن
على خادمك، أنشئ
POST /v1/signature_requestssignature_requestمع موقّعيه ومصدره ومستواه القانوني. - احصل على رابط التوقيع
استخرج
signers[0].signing_urlsigning_urlمن بيانات الموقّع، أو أصدِرsigning_sessionقصيرة العمر للتضمين. - ضمِّن في صفحتك
افتح الرابط داخل
iframeواستمع إلى أحداثpostMessageلتحديث الواجهة. - يُكمل المستخدم التوقيع
يؤكّد هويته (AES) عند الحاجة، ثم يوقّع داخل إطارك دون أن يغادر تطبيقك.
- استقبل الإشعار الموثوق
يتلقّى خادمك حدث الاكتمال، وهو الإشارة النهائية لبدء إجراءات ما بعد التوقيع.
signature_request.completed - نزّل المستند المختوم
اطلب نسخة PDF النهائية بعد اكتمال الطلب، أمّا دليلها التشفيري المستقل فهو محضر الأدلّة المختوم (Ed25519 + ختم زمني RFC 3161).
GET /v1/signature_requests/{id}/download
curl -X POST https://wthaiq.com/api/v1/signature_requests \
-H "Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Wthaiq-Version: 2026-07-01" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5f3c9c2e-2b7a-4a1e-9c2f-1d3e4f5a6b7c" \
-d '{
"title": "اتفاقية تاجر — Acme Pay",
"source": {"type":"template","template_id":"tpl_merchant_agreement"},
"legal_level": "aes",
"signers": [
{"name":"سلمى حسن","email":"salma@example.com","type":"individual",
"method":"draw","require_identity":true}
],
"metadata": {"merchant_id":"M-88213"}
}'{
"id": "evt_2M8pQ",
"object": "event",
"type": "signature_request.completed",
"created_at": 1754500000,
"livemode": true,
"data": {
"object": {
"id": "sr_3n8Kd2Qa1V",
"object": "signature_request",
"status": "completed",
"reference": "WTQ-1A2B3C4D5E6F",
"download_url": "https://wthaiq.com/api/v1/signature_requests/sr_3n8Kd2Qa1V/download"
}
}
}# متاح فقط بعد أن تصبح الحالة completed
curl https://wthaiq.com/api/v1/signature_requests/sr_3n8Kd2Qa1V/download \
-H "Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Wthaiq-Version: 2026-07-01"
# الناتج: روابط العقد النهائي (JSON) · الدليل التشفيري المستقل: محضر الأدلّة عبر GET /v1/signature_requests/{id}/evidenceقواعد أمان التضمين
التضمين آمن ما دمت تفصل بين ما يبقى على الخادم وما يصل إلى المتصفّح.
لا تُرسِل sk_ إلى المتصفّح أبدًا
يبقى المفتاح السرّي على الخادم حصرًا، ولا يرى المتصفّح إلا رابط التوقيع ورمز الجلسة قصير العمر.
عمر رمز قصير (TTL)
تنتهي صلاحية رابط الجلسة بعد 30 دقيقة من إنشائه، فالرابط المنتهي لا أثر له حتى لو التُقِط؛ فأنشئ الجلسة لحظة حاجة الموقّع إليها.
قائمة نطاقات مسموح بها
حدّد allowed_origins بنطاقاتك وحدها، فتُرفض أي محاولة لتضمين الجلسة من مصدر خارج القائمة.
تحقّق من الأحداث على الخادم
لا تنفّذ أي إجراء حسّاس بناءً على postMessage وحده، بل عوِّل على الإشعار الآلي الموقَّع بـwhsec_ بوصفه المرجع المعتمد.
أسئلة المطوّرين حول التضمين
هل يرى المستخدم أي إشارة إلى «وثائق» أثناء التوقيع؟
لا، إن فعّلت White-label الكامل. تظهر صفحة التوقيع بشعارك وألوانك وعلى نطاقك المخصّص sign.yourbrand.com، وتُرسل رسائل البريد باسم علامتك، وتُزال عبارة «مدعوم من وثائق» عند ضبط hide_powered: true. يبقى المستخدم داخل تجربتك من البداية للنهاية.
لماذا أسكّ signing_session بدل تمرير المفتاح السرّي؟
لأن sk_ يملك صلاحية كاملة على حسابك، ولا يجوز أن يصل إلى المتصفّح إطلاقًا. رمز الجلسة قصير العمر مقيّد بموقّع واحد وبصلاحية التوقيع فقط ولنطاقات محدّدة ولدقائق معدودة — فحتى لو التُقِط، لا يفتح إلا ما سُكّ لأجله ثم ينتهي تلقائيًا.
ما الفرق بين أحداث postMessage والـWebhooks؟
أحداث المتصفّح مثل wthaiq:signed لتحديث الواجهة لحظيًا، لكنها قد لا تصل إن أغلق المستخدم التبويب. الـWebhook مثل signature_request.completed يصل إلى خادمك على نحوٍ موثوق وموقّع بـwhsec_، وهو مصدر الحقيقة الذي تبني عليه أي إجراء حسّاس مثل التفعيل.
كيف يعمل التوقيع المؤهّل QES داخل الإطار؟
عبر وكيل توقيع محلّي على جهاز المستخدم عند 127.0.0.1:8899. يجهّز الخادم بصمة signedAttributes ويرسل الهاش فقط، فيُدخل المستخدم رمز التوكن ويوقّع الجهاز محليًّا — المفتاح الخاص لا يغادر التوكن — ثم يُدمج CMS في المستند لإكمال PAdES حتى LTA. هذا هو التوقيع المؤجّل/المُجزّأ.
ماذا لو لم تسمح بيئتنا باستخدام الـiframe؟
استخدم نمط redirect: اسكّ الجلسة مع success_url و cancel_url، ثم حوّل المتصفّح إلى signing_url. تعيد «وثائق» المستخدم إلى مسارك تلقائيًا مع المرجع في الرابط. أو استخدم الصفحة المستضافة مباشرة عبر signing_url على نطاقك المخصّص.
وقّع داخل تطبيقك وبعلامتك أنت.
ابدأ بجلسة توقيع واحدة خلال دقائق، ثم ضمِّن تجربة توقيع كاملة بعلامتك ونطاقك دون تحويل أي مستخدم إلى موقع خارجي.