ادمج صفحة توقيع كاملة داخل منتجك: بشعارك وألوانك ونطاقك أنت. تُصدِر من خادمك جلسة توقيع قصيرة العمر، تُضمّنها في iframe أو تُعيد التوجيه إليها، وتستقبل الأحداث لحظيًا عبر postMessage والـWebhooks — بينما يبقى المفتاح السرّي في خادمك وحده. التوقيع، وتأكيد الهوية، والتوقيع المؤهّل، كلّها داخل تدفّق واحد لا يغادر تطبيقك.
الأساس واحد في الثلاثة: أنت تنشئ signature_request على خادمك، ثم تحصل على رابط توقيع للموقّع. يختلف النموذج في كيف يصل المستخدم إلى ذلك الرابط.
حوّل المستخدم إلى signing_url الجاهز في حقل الموقّع. أسرع طريقة للإطلاق: صفحة توقيع كاملة تستضيفها «وثائق» على نطاقك المخصّص، بلا كود واجهة.
sign.yourbrand.comأصدِر signing_session قصيرة العمر وحمّلها داخل iframe في صفحتك. يبقى المستخدم في مكانه تمامًا، وتستقبل أحداثه لحظيًا عبر postMessage.
wthaiq:viewed / signed / declinedحوّل المتصفّح إلى صفحة التوقيع، ثم أعِده تلقائيًا إلى success_url بعد التوقيع أو cancel_url عند الإلغاء. حلٌّ وسط بين البساطة والتحكّم.
iframeلا تُرسِل مفتاحك السرّي إلى المتصفّح أبدًا. بدلًا من ذلك، يستدعي خادمك هذه النقطة لسكّ رمز جلسة مؤقّت وموقّع واحد فقط، آمن للإرسال إلى الواجهة.
يسكّ رابط توقيع مُضمَّنًا ورمز عميل قصير العمر لموقّع بعينه، ضمن نمط White-label.
| المُعامِل | الوصف |
|---|---|
| mode string اختياري | نمط الجلسة: embedded (افتراضي، للتضمين في iframe) أو redirect (لإعادة التوجيه). |
| allowed_origins string[] اختياري | قائمة النطاقات المسموح لها بتضمين الجلسة. تُرفض أي أصول (origins) خارجها. مطلوبة عمليًا مع embedded. |
| success_url string اختياري | رابط العودة بعد التوقيع في نمط redirect. يدعم القالب {signature_request}. |
| cancel_url string اختياري | رابط العودة عند إلغاء المستخدم أو انتهاء الجلسة. |
| expires_in integer اختياري | عمر الرمز بالثواني (بين 300 و 3600، الافتراضي 3600). كلّما قصُر كان أأمن. |
sk_ يملك صلاحية كاملة على حسابك — إنشاء طلبات، تنزيل مستندات موقّعة، إدارة الـWebhooks. لو تسرّب من المتصفّح لتحكّم فيه أي طرف. أمّا رمز الجلسة فمقيّد بموقّع واحد، وبصلاحية «التوقيع» فقط، ولمدة دقائق معدودة، وعلى نطاقات محدّدة — فحتى لو التُقِط، لا يفتح إلا ما سُكّ لأجله ثم ينتهي. 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 '{
"mode": "embedded",
"allowed_origins": ["https://app.acme-pay.com"],
"expires_in": 900
}'import Wthaiq from '@wthaiq/node';
const wt = new Wthaiq(process.env.WTHAIQ_SECRET_KEY);
// على الخادم فقط — المفتاح السرّي لا يغادر خادمك
const session = await wt.signers.createSigningSession('sgr_9fA2', {
mode: 'embedded',
allowed_origins: ['https://app.acme-pay.com'],
expires_in: 900
});
// أرسِل هذا فقط إلى المتصفّح — لا شيء غيره
res.json({ signing_url: session.signing_url });{
"object": "signing_session",
"signer": "sgr_9fA2",
"signature_request": "sr_3n8Kd2Qa1V",
"signing_url": "https://sign.acme-pay.com/s/uZ8xR2Kq?t=cst_live_9aF2xQ7bV3",
"client_token": "cst_live_9aF2xQ7bV3",
"mode": "embedded",
"expires_at": 1754000900,
"created_at": 1754000000
}صفحة التوقيع لك بالكامل. تُضبط إعدادات العلامة على مستوى الحساب افتراضيًا، ويمكن تجاوزها لكل طلب توقيع عبر كائن branding داخل جسم الطلب.
{
"branding": {
"logo_url": "https://cdn.acme-pay.com/logo.svg",
"brand_color": "#0B5FFF",
"signing_domain": "sign.acme-pay.com",
"email_from_name": "Acme Pay",
"email_from_address": "sign@acme-pay.com",
"remove_wthaiq_branding": true,
"locale": "ar",
"support_email": "support@acme-pay.com"
}
}| الحقل | الوصف |
|---|---|
| logo_url | شعارك المعروض أعلى صفحة التوقيع وفي رأس رسائل البريد. يُفضَّل SVG أو PNG شفّاف. |
| brand_color | لون علامتك الأساسي (HEX)؛ يُطبَّق على الأزرار والروابط ومؤشّرات التقدّم. |
| signing_domain | نطاق التوقيع المخصّص، مثل sign.acme-pay.com. يُثبَت عبر سجل CNAME وشهادة TLS تُصدَر تلقائيًا. |
| email_from_name | اسم المُرسِل الظاهر في رسائل الدعوة والتذكير — يظهر باسم علامتك لا باسم «وثائق». |
| email_from_address | عنوان المُرسِل على نطاقك، بعد ضبط سجلّات SPF وDKIM لضمان التسليم. |
| remove_wthaiq_branding | عند true تُزال عبارة «مدعوم من وثائق» من الصفحة والبريد (متاح للخطط التي تدعم White-label الكامل). |
| locale | لغة الواجهة الافتراضية للموقّع، مثل ar. |
| support_email | عنوان الدعم الذي يظهر للموقّع عند احتياجه المساعدة. |
sign.acme-pay.com بدل نطاق «وثائق» — فلا يرى المستخدم أي إشارة إلى مزوّد خارجي في أي لحظة من رحلة التوقيع. لا يغادر المستخدم إطارك ليؤكّد هويته أو يوقّع بشهادة مؤهّلة. تظهر هاتان الخطوتان مضمّنتين قبل التوقيع مباشرة، وهذا ما يراه المستخدم في كلٍّ منهما.
عند تفعيل require_identity على الموقّع، يعرض الإطار خطوة تحقّق كاملة قبل أن تُفتح صفحة التوقيع — ويُربط قرار التحقّق بالتوقيع نفسه.
identity_verified.للتوقيع المؤهّل (method: "token")، يجري التوقيع على شهادة الأجهزة عبر وكيل محلّي على جهاز المستخدم عند 127.0.0.1:8899 — المفتاح الخاص لا يغادر التوكن إطلاقًا (PAdES مؤجّل/مُجزّأ).
signedAttributes (بصمة SHA-256 للمستند) ويرسل الهاش فقط — لا مفتاح خاص هنا.CMS، فيدمجها الخادم في المستند ويُكمل PAdES حتى LTA.// 1) الخادم يجهّز signedAttributes (هاش المستند) — لا مفتاح خاص
const prep = await wt.signers.prepareTokenSignature('sgr_9fA2');
// 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 wt.signers.completeTokenSignature('sgr_9fA2', { cms: signed.cms });رحلة تضمين واحدة كاملة: أنشئ الطلب على خادمك، ضمِّن التوقيع، انتظر إشارة الاكتمال الموثوقة، ثم نزّل المستند المختوم.
على خادمك، أنشئ signature_request بموقّعيه ومصدره وسويّته القانونية.
خذ signing_url من الموقّع، أو اسكّ signing_session قصيرة العمر للتضمين.
حمّل الرابط في iframe واستمع لأحداث postMessage لتحديث الواجهة.
يؤكّد هويته (AES) عند اللزوم ثم يوقّع داخل إطارك دون مغادرة تطبيقك.
يستقبل خادمك حدث الاكتمال — هذه هي الإشارة النهائية لتفعيل ما بعد التوقيع.
signature_request.completedاطلب نسخة الـPDF النهائية بعد اكتمال الطلب؛ ودليلها التشفيري المستقل هو محضر الأدلّة المختوم (Ed25519 + ختم RFC 3161).
GET /v1/signature_requests/{id}/downloadcurl -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-000123",
"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" \
-o agreement-signed.pdf
# الناتج: application/pdf نهائي مختوم · الدليل التشفيري المستقل: محضر الأدلّة عبر GET /api/evidence.php?scope=api&doc=<id>التضمين آمن ما دمت تفصل بين ما يبقى على الخادم وما يصل إلى المتصفّح.
sk_ إلى المتصفّح أبدًاالمفتاح السرّي يبقى على الخادم حصريًّا. المتصفّح لا يرى إلا رابط التوقيع ورمز الجلسة القصير.
اجعل expires_in بأقصر مدة كافية (300 إلى 3600 ثانية). الرمز المنتهي عديم الأثر حتى لو التُقِط.
حدّد allowed_origins بنطاقاتك فقط. تُرفض محاولة تضمين الجلسة من أي أصل خارج القائمة.
لا تفعّل إجراءً حسّاسًا بناءً على postMessage وحده؛ اعتمِد الـWebhook الموقّع بـwhsec_ كمصدر الحقيقة.
لا، إن فعّلت White-label الكامل. تظهر صفحة التوقيع بشعارك وألوانك وعلى نطاقك المخصّص sign.yourbrand.com، وتُرسل رسائل البريد باسم علامتك، وتُزال عبارة «مدعوم من وثائق» عند ضبط remove_wthaiq_branding: true. يبقى المستخدم داخل تجربتك من البداية للنهاية.
signing_session بدل تمرير المفتاح السرّي؟ لأن sk_ يملك صلاحية كاملة على حسابك، ولا يجوز أن يصل إلى المتصفّح إطلاقًا. رمز الجلسة قصير العمر مقيّد بموقّع واحد وبصلاحية التوقيع فقط ولنطاقات محدّدة ولدقائق معدودة — فحتى لو التُقِط، لا يفتح إلا ما سُكّ لأجله ثم ينتهي تلقائيًا.
postMessage والـWebhooks؟ أحداث المتصفّح مثل wthaiq:signed لتحديث الواجهة لحظيًا، لكنها قد لا تصل إن أغلق المستخدم التبويب. الـWebhook مثل signature_request.completed يصل إلى خادمك بشكل موثوق وموقّع بـwhsec_، وهو مصدر الحقيقة الذي تبني عليه أي إجراء حسّاس مثل التفعيل.
عبر وكيل توقيع محلّي على جهاز المستخدم عند 127.0.0.1:8899. يجهّز الخادم بصمة signedAttributes ويرسل الهاش فقط، فيُدخل المستخدم رمز التوكن ويوقّع الجهاز محليًّا — المفتاح الخاص لا يغادر التوكن — ثم يُدمج CMS في المستند لإكمال PAdES حتى LTA. هذا هو التوقيع المؤجّل/المُجزّأ.
iframe؟ استخدم نمط redirect: اسكّ الجلسة مع success_url وcancel_url، ثم حوّل المتصفّح إلى signing_url. تعيد «وثائق» المستخدم إلى مسارك تلقائيًا مع المرجع في الرابط. أو استخدم الصفحة المستضافة مباشرة عبر signing_url على نطاقك المخصّص.
ابدأ بجلسة توقيع واحدة خلال دقائق، ثم ضمِّن تجربة توقيع كاملة بعلامتك ونطاقك دون تحويل أي مستخدم إلى موقع خارجي.