التوثيق
ابنِ باستخدام SMetaGateway.
كل ما تحتاجه لإنشاء فواتير USDT TRC20 من خادمك، وتوجيه المشترين إلى صفحة الدفع، وتأكيد المدفوعات عبر Webhook موقّع.
نظرة عامة
SMetaGateway طبقة فوترة غير احتجازية لـ USDT على شبكة TRON. يسجّل التجار عنوان استلام عامًا، ويدفع المشترون إليه مباشرةً. تخصص البوابة لكل فاتورة مبلغًا دقيقًا فريدًا، وتتابع حالتها، وتسجّل البيانات المحاسبية، وتُخطر خادمك.
جميع نقاط النهاية تحت المسار /api/v1 على نفس نطاق هذا الموقع. المبالغ دائمًا نصوص عشرية بحد أقصى ست منازل — وليست أبدًا أعدادًا عائمة.
- خادمك → SMetaGateway1POST /api/v1/invoices مع Idempotency-Key
- SMetaGateway → خادمك2فاتورة تتضمن payable_amount وcheckout_url
- خادمك → المشتري3توجيه المشتري إلى checkout_url
- المشتري → SMetaGateway4يفتح المشتري صفحة الدفع ويمسح رمز QR
- المشتري → محفظتك على TRON5يرسل المشتري مبلغ USDT الدقيق إلى عنوانك
- SMetaGateway6تعثر البوابة على المبلغ الدقيق على السلسلة وتؤكد الفاتورة
- SMetaGateway → خادمك7Webhook موقّع invoice.confirmed
- خادمك → SMetaGateway8GET /api/v1/invoices/{id} للتحقق، ثم تنفيذ الطلب
مسار البياناتمسار الأموال
البدء السريع
1. أنشئ مساحة عمل وأضف عنوان استلام على TRON. انسخ معرّف المحفظة.
2. افتح المطورون ← مفاتيح API وأنشئ مفتاحًا مع مدة صلاحية. يبدأ السر بـ smg_ ويُعرض مرة واحدة فقط، لذا احفظه بأمان.
3. أنشئ فاتورة من خادمك بالطلب أدناه. احفظ معرّف الفاتورة وقيمة payable_amount الدقيقة.
4. وجّه المشتري إلى checkout_url. اعتبر الطلب مدفوعًا فقط بعد التحقق من Webhook invoice.confirmed والاستعلام عن الفاتورة من الخادم.
curl -X POST "https://smg.sabco24.com/api/v1/invoices" \
-H "Authorization: Bearer $SMETA_API_KEY" \
-H "Idempotency-Key: order-1001" \
-H "Content-Type: application/json" \
-d '{"merchant_order_id":"1001","amount":"49.95","wallet_id":"WALLET_ID","description":"Example order","expires_in_minutes":20}'المصادقة
تُصادَق تكاملات الخادم بمفتاح API من نوع bearer: Authorization: Bearer smg_…. تحمل المفاتيح النطاقات invoices:read وinvoices:write وledger:read، ويمكن أن تنتهي صلاحيتها بعد 30 أو 90 أو 365 يومًا. يعيد المفتاح المنتهي الخطأ 401 api_key_expired؛ قم بتدويره من لوحة التحكم للحصول على سر جديد. احتفظ بالمفاتيح على خادمك ولا تضعها أبدًا في المتصفحات أو تطبيقات الجوال.
تستخدم لوحة التحكم ملف تعريف ارتباط جلسة HttpOnly. تتطلب إدارة الحساب وتسجيل المحافظ ومفاتيح API وWebhook جلسة المالك هذه، ولا يمكن تنفيذها بمفتاح API.
curl "https://smg.sabco24.com/api/v1/invoices/INVOICE_ID" \
-H "Authorization: Bearer $SMETA_API_KEY"المبالغ والتعريف
أرسل السعر الأساسي كنص عشري مثل "49.95". تضيف البوابة تعديل تعريف موجبًا — من 0.000001 إلى 0.009999 USDT تحت 100 USDT، أو من 0.000001 إلى 0.999999 USDT عند 100 USDT فأكثر — وتعيد base_amount وadjustment وpayable_amount بشكل منفصل.
يُحجز الإجمالي الدقيق لمدة 90 يومًا لنفس الشبكة والرمز وعنوان الاستلام عبر جميع التجار. تُفضَّل الإجماليات غير المستخدمة؛ والإجمالي المُعاد استخدامه يحوّل الفاتورة إلى review بدلًا من التأكيد التلقائي.
محجوز لمدة 90 يومًا لكل شبكة ورمز وعنوان استلام
{
"base_amount": "49.950000",
"adjustment": "0.003821",
"payable_amount": "49.953821"
}الفواتير وعدم التكرار
يتطلب POST /api/v1/invoices ترويسة Idempotency-Key. تكرار الطلب نفسه بالمفتاح نفسه يعيد الفاتورة الأصلية مع idempotent_replay: true؛ وإعادة استخدام المفتاح ببيانات مختلفة تعيد 409 idempotency_conflict.
لكل merchant_order_id فاتورة واحدة. احفظ معرّف الفاتورة وpayable_amount مع طلبك وقارنهما عند وصول Webhook.
POST /invoices + Idempotency-Key- مفتاح جديد201 — إنشاء فاتورة جديدة
- المفتاح نفسه، الجسم نفسهالفاتورة الأصلية، idempotent_replay: true
- المفتاح نفسه، جسم مختلف409 idempotency_conflict
{
"invoice": {
"id": "6f1c…",
"merchant_order_id": "1001",
"base_amount": "49.950000",
"adjustment": "0.003821",
"payable_amount": "49.953821",
"status": "pending",
"mode": "live",
"checkout_url": "https://smg.sabco24.com/checkout/…",
"expires_at": "2026-10-21T12:20:00.000Z",
"reserved_until": "2027-01-19T12:00:00.000Z"
},
"idempotent_replay": false
}صفحة الدفع وحالة الفاتورة
checkout_url رابط صلاحية: كل من يملكه يمكنه رؤية التفاصيل الآمنة للدافع، لذا تعامل معه بسرية. تعرض صفحة الدفع اسم التاجر وتفصيل المبلغ وعنوان الاستلام ورمز QR والصلاحية، دون بياناتك الوصفية أو معرّفاتك الداخلية.
حالة الفاتورة إحدى: pending أو confirmed أو expired أو review. تنتهي صفحة الدفع بعد expires_in_minutes (افتراضيًا 20، وبحد أقصى 1440)؛ ويستمر حجز المبلغ 90 يومًا بشكل مستقل.
pending- استلام المبلغ الدقيق
confirmed - انتهاء وقت الدفع
expired - مبلغ مُعاد استخدامه أو يحتاج فحصًا يدويًا
review
إشعارات Webhook الموقّعة
سجّل نقطة نهاية HTTPS عامة (المنفذ 443) من لوحة التحكم. يُعرض سر التوقيع مرة واحدة. الأحداث: invoice.created وinvoice.confirmed وinvoice.expired وinvoice.review وwebhook.test. تُعاد محاولة التسليم حتى ثماني مرات ويمكن إعادتها يدويًا.
يحمل كل طلب الترويسات X-SMeta-Event-Id وX-SMeta-Timestamp وX-SMeta-Signature. احسب HMAC-SHA256 على timestamp + "." + الجسم الخام، وقارن في زمن ثابت، وارفض الطوابع الأقدم من خمس دقائق، ثم حلّل JSON. عالج كل معرّف حدث مرة واحدة.
- 1اقرأ الجسم الخام وترويسات X-SMeta-*
- 2هل الطابع الزمني ضمن 5 دقائق؟رفض (4xx)
- 3HMAC-SHA256(timestamp + "." + body)
- 4قارن في زمن ثابت مع X-SMeta-Signatureرفض (4xx)
- 5هل عولج معرّف الحدث سابقًا؟أعد 2xx وتجاهل
- 6حدّث الطلب وأعد 2xx
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody: Buffer, headers: Record<string, string>, secret: string) {
const timestamp = headers['x-smeta-timestamp'];
const signature = headers['x-smeta-signature'] ?? '';
if (!/^\d+$/.test(timestamp) || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return null;
const expected = 'sha256=' + createHmac('sha256', secret)
.update(timestamp + '.').update(rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(signature);
if (a.length !== b.length || !timingSafeEqual(a, b)) return null;
const event = JSON.parse(rawBody.toString('utf8'));
return event.id === headers['x-smeta-event-id'] ? event : null;
}الأخطاء وحدود المعدل
تعيد الأخطاء جسم JSON يحتوي error.code وerror.message. الحالات الشائعة: 400 تحقق، 401 مصادقة، 403 صلاحية أو مصدر، 404 غير موجود، 409 تعارض أو مراجعة، 429 تجاوز المعدل.
إنشاء الفواتير محدود بـ 120 طلبًا في الدقيقة لكل تاجر. أعد محاولة استجابات 429 و5xx مع تأخير متزايد وبنفس Idempotency-Key.
{
"error": {
"code": "idempotency_conflict",
"message": "This idempotency key was used with different invoice details."
},
"mode": "live"
}التكاملات
تتضمن لوحة التحكم 32 وصفة جاهزة تغطي Node.js وNestJS وPHP وLaravel وPython وDjango وGo وJava وC# وRuby وReact وNext.js وVue ومنصات تجارة مثل WooCommerce وMagento وShopware. إضافة WooCommerce القابلة للتنزيل إصدار معاينة ولا تقبل مفاتيح API المباشرة بعد.
الوصفات أمثلة وليست حِزم SDK منشورة. أمثلة الواجهة الأمامية تستدعي خادمك الخاص الذي يحتفظ بمفتاح API.
تأكيد الدفع
تقرأ البوابة شبكة TRON الرئيسية عبر TronGrid بحثًا عن تحويلات USDT TRC20 المؤكدة إلى كل عنوان استلام لديه فاتورة مفتوحة، وتعيد التحقق من كل تحويل مقابل إيصال نهائي ناجح. يؤكد تحويل المبلغ الدقيق payable_amount بين إنشاء الفاتورة وانتهائها الفاتورةَ، ويُخزَّن تجزئة المعاملة في tx_hash.
التحويل الذي يصل بعد الانتهاء، أو يطابق مبلغًا استُخدم سابقًا، أو يخص فاتورة قيد المراجعة، يغيّر الحالة إلى review ولا يُؤكَّد تلقائيًا أبدًا. يستغرق الاكتشاف عادة بضع دقائق. لا تُثبت العمولة الصفرية والتصميم غير الاحتجازي وحدهما إعفاءً ضريبيًا أو ترخيصًا تنظيميًا.