وثائق ZolnaPay
دليل نظيف وشامل لقبول المدفوعات ودمج المنصة — من أول طلب إلى Webhooks.
جرّب الـ API مباشرة
طلبات عامة حقيقية من المتصفح — بدون مفتاح سري.
النتائج من api.zolna.app مباشرة. للمدفوعات استخدم مفتاح sk_test_ من لوحة المطوّرين على الخادم.
البدء السريع
أربع خطوات واضحة لأول عملية تجريبية.
أنشئ مشروعاً
من لوحة التاجر، ثم أنشئ مفتاح اختبار.
أنشئ دفعة
استدعِ POST /payments بالمبلغ بالسنتات.
أكّد أو افتح Checkout
تأكيد برمجي، أو جلسة مستضافة جاهزة.
اربط Webhook
استقبل payment.succeeded فوراً على خادمك.
# Create a test payment curl -X POST https://api.zolna.app/v1/payments \ -H "Authorization: Bearer sk_test_..." \ -H 'Content-Type: application/json' \ -d '{"amountCents":2000,"currency":"usd","customerEmail":"buyer@example.com"}'
import { ZolnaPay } from '@zolnapay/sdk'; const zp = new ZolnaPay({ secretKey: process.env.ZOLNAPAY_SECRET_KEY }); const payment = await zp.payments.create({ amountCents: 2000, currency: 'usd', customerEmail: 'buyer@example.com', });
import os, requests r = requests.post( "https://api.zolna.app/v1/payments", headers={"Authorization": f"Bearer {os.environ['ZOLNAPAY_SECRET_KEY']}"}, json={"amountCents": 2000, "currency": "usd", "customerEmail": "buyer@example.com"}, ) print(r.json())
المصادقة
مفتاح سري للخادم، أو JWT لجلسة لوحة التاجر.
إنشاء حساب تاجر. يُرسل رمز تفعيل للبريد.
| الحقل | النوع | |
|---|---|---|
name | string | مطلوب |
email | string | مطلوب |
password | string (≥10) | مطلوب |
locale | ar | en | اختياري |
curl -X POST https://api.zolna.app/v1/auth/register \ -H 'Content-Type: application/json' \ -d '{"name":"Sara","email":"sara@brand.com","password":"SuperSecret123","locale":"ar"}'
تفعيل البريد برمز من 6 أرقام — يعيد جلسة جاهزة.
كلمة المرور ثم رمز البريد، أو TOTP إن وُجد. Google يتجاوز رمز البريد.
POST /v1/auth/login
{ "email": "...", "password": "..." }
POST /v1/auth/login/email-code
{ "ticket": "...", "code": "123456" }
مفاتيح API
أنشئها من صفحة المطورين. الاختبار فوري، والإنتاج بعد تفعيل المشروع.
sk_test_…
مفتاح اختبار — بلا أموال حقيقية.
sk_live_…
مفتاح إنتاج — بعد اعتماد الحساب.
قائمة مفاتيح المشروع الحالي.
إنشاء مفتاح. السر يُعرض مرة واحدة فقط.
{ "type": "secret", "mode": "test" }
المدفوعات
أنشئ، أكّد، واسترد. المبالغ دائماً integer بالسنتات.
إنشاء PaymentIntent. يدعم Idempotency-Key.
| الحقل | النوع | |
|---|---|---|
amountCents | integer | مطلوب |
currency | string | اختياري |
customerEmail | string | اختياري |
description | string | اختياري |
curl -X POST https://api.zolna.app/v1/payments \ -H "Authorization: Bearer $KEY" \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: order-1001' \ -d '{"amountCents":5000,"currency":"usd","customerEmail":"a@x.com"}'
تأكيد الدفع بوسيلة: card / test_card / stripe · mobile_money · paypal · bank_transfer · crypto_btc · crypto_usdt · saved
{
"paymentMethod": {
"type": "paypal",
"email": "buyer@example.com"
}
}
إن رجع requires_action: لـ Stripe استخدم clientSecret ثم /complete. للتحويل البنكي/الكريبتو ارفع إثباتاً عبر /public/payments/:id/proof.
مزامنة الدفع بعد 3DS — عام لصفحة Checkout.
قراءة عامة آمنة للدافع (المبلغ والحالة وaction) بدون مصادقة.
رفع إثبات تحويل بنكي أو كريبتو (multipart). الحالة تصبح pending_review حتى يقرر الأدمن.
curl -X POST https://api.zolna.app/v1/public/payments/$PAY_ID/proof \ -F method=bank_transfer \ -F bankCode=bankak \ -F senderName=Ali \ -F reference=TRX123 \ -F file=@receipt.jpg
أحدث عمليات المشروع.
تصدير CSV للمدفوعات (حتى 90–365 يوماً) للتسوية المحاسبية.
استرداد كامل أو جزئي لعملية ناجحة (Stripe إن وُجدت). يدعم Idempotency-Key.
curl -X POST https://api.zolna.app/v1/payments/$PAY_ID/refund \ -H "Authorization: Bearer $TOKEN" \ -H 'Idempotency-Key: refund-order-1001' \ -H 'Content-Type: application/json' \ -d '{"amountCents":500,"reason":"partial"}'
Webhook وارد من Stripe. فعّل التوقيع عبر webhook_secret في أدمن → المعالجات.
payment_intent.succeeded · payment_intent.payment_failed · charge.dispute.created · charge.dispute.updated · charge.dispute.closed
وسائل الدفع
بطاقة، موبايل موني، PayPal، تحويل بنكي، BTC وUSDT — تُفعَّل من الأدمن وإعدادات التاجر.
PayPal / Card / MM
في test: PayPal ينجح فوراً، البطاقة عبر test/Stripe، وموبايل موني بعد توثيق SMS.
Bank / BTC / USDT
تُرجع requires_action مع تعليمات الإيداع، ثم إثبات → pending_review → قبول الأدمن.
يعيد الوسائل المفعّلة + مفتاح Stripe إن وُجد.
قائمة إثباتات بانتظار المراجعة. القرار عبر POST /admin/payment-proofs/:id/decide مع {"decision":"approve"|"reject"}.
Checkout
صفحة دفع مستضافة على checkout.zolna.app.
تُنشئ جلسة وتعيد رابط توجيه جاهز.
curl -X POST https://api.zolna.app/v1/checkout/sessions \ -H "Authorization: Bearer $KEY" \ -H 'Content-Type: application/json' \ -d '{"amountCents":2000,"currency":"usd","customerEmail":"buyer@example.com"}'
روابط الدفع
روابط ثابتة للمشاركة عبر الواتساب والسوشيال.
الصيغة العامة: https://pay.zolna.app/l/{slug}
{ "title": "Basic plan", "amountCents": 1500 }
عرض الروابط وإحصاءات الاستخدام.
الاشتراكات
منتج ← خطة ← اشتراك، مع تجديد تلقائي.
إنشاء منتج قابل للفوترة.
خطة شهرية أو سنوية.
بدء اشتراك على خطة.
إلغاء فوري أو عند نهاية الفترة.
صفحة إدارة عامة للعميل: فواتير + حالة + إلغاء عند نهاية الفترة.
Disputes
نزاعات محلية + نزاعات Stripe الواردة مع رفع أدلة ومزامنة القرار.
عرض نزاعات التاجر الحالية، بما فيها stripeDisputeId و dueBy.
رفع أدلة محلياً، ومع Stripe أيضاً إن كان النزاع وارداً من Stripe.
لوحة نزاعات الأدمن للمراجعة والحسم.
Audit
أحداث مالية وتشغيلية append-only في /admin/audit.
يشمل الآن تفاصيل before/after لأحداث مثل:
payment.refunded · payout.requested · payout.approved · payout.rejected ·
subscription.canceled · subscription.paused · subscription.dunning_* ·
stripe.dispute_* · dispute.decided.
Hardening
Rate limits + Stripe webhook idempotency.
طلبات متكررة تتجاوز الحد ترجع 429 rate_limited مع رؤوس X-RateLimit-*.
كل event.id يُخزَّن في inbound_webhook_events. إعادة التسليم ترجع duplicate: true دون إعادة المعالجة (مع إعادة محاولة للأحداث الفاشلة أو العالقة).
Smoke E2E: دفع → webhook idempotency → نزاع → استرداد → سحب → audit.
Cron كل دقيقة يعيد تسليم webhooks التجار الفاشلة بتأخير تصاعدي حتى 7 محاولات.
ملفات KYC/الأدلة خاصة: الرفع يعيد رابطاً موقّعاً، والمسار العام /media/private|uploads مرفوض (403).
طلب السحب يتطلب تأكيد بريدي (stage: step_up ثم stepUpCode) قبل الحجز.
نسخ احتياطي يومي لقاعدة Postgres مع احتفاظ 14 يوماً في /var/backups/zolnapay.
يشمل الآن redis وbackup وadminUrl. صفحة الحالة تعرضها مباشرة.
يرسل SMS عبر SMS_PROVIDER (simulation / twilio / http). Live MM charge يبقى معطلاً حتى تكامل المزود.
المحفظة
متاح · معلّق · محجوز — بشفافية كاملة.
{
"availableCents": 125000,
"pendingCents": 4200,
"reservedCents": 0,
"currency": "usd"
}
سجل الحركات المالية.
طلب سحب من الرصيد المتاح.
Webhooks
أحداث فورية عبر HTTPS مع توقيع HMAC.
أضف عنوان HTTPS. السر يُعرض مرة واحدة.
{ "url": "https://example.com/webhooks/zolna", "mode": "test" }
كتالوج عام لأنواع الأحداث — بدون مصادقة.
payment.succeeded·payment.failed·payment.refunded·payment.disputedsubscription.created·renewed·canceled·paused·resumedinvoice.paid·invoice.payment_failed·payout.paid·payout.failed
t=…,v1=HMAC_SHA256.الأخطاء
شكل موحّد لكل الاستجابات الفاشلة.
{ "message": "invalid_credentials" }
invalid_credentialsemail_not_verifiedmerchant_not_liveamount_requiredforbidden_role
JavaScript SDK
نفس عقد الـ API بحزمة خادم بسيطة — مع أنواع TypeScript.
جرّب من SDK على الخادم بمفتاح sk_test_ من صفحة المطورين. لا تضع المفتاح السري في المتصفح.
import { ZolnaPay } from '@zolnapay/sdk'; const zp = new ZolnaPay({ secretKey: process.env.ZOLNAPAY_SECRET_KEY, baseUrl: 'https://api.zolna.app/v1', }); const session = await zp.checkout.sessions.create({ amountCents: 2000, currency: 'usd', }); await zp.payments.confirm(session.id, { type: 'card', card: { number: '4242424242424242', expMonth: 12, expYear: 2030, cvc: '123' }, }); const customers = await zp.customers.list(); await zp.subscriptions.pause(subId); await zp.subscriptions.resume(subId);
الموارد: payments · checkout · paymentLinks · paymentMethods · balance · subscriptions · payouts · customers · disputes · team · webhooks · apiKeys
الاختبار
ادمج بثقة قبل استقبال أموال حقيقية.
بطاقة اختبار
4242 4242 4242 4242
أي تاريخ مستقبلي وأي CVC.
صحة الخدمة
GET /v1/health
والحالة الحية على status.zolna.app
أمثلة وسائل بديلة في test:
{ "paymentMethod": { "type": "bank_transfer", "bankCode": "bankak" } }
{ "paymentMethod": { "type": "crypto_btc" } }
{ "paymentMethod": { "type": "crypto_usdt" } }
{ "paymentMethod": { "type": "paypal", "email": "buyer@example.com" } }