MailLandDocs
الحساب

الفوترة

إدارة اشتراكك وعرض الفواتير ومراقبة الاستخدام

تستخدم MailLand Stripe لإدارة الاشتراكات والفوترة. تمتلك كل مساحة عمل اشتراكاً خاصاً بها مع تسعير مبني على الاستخدام أو قائم على الخطة. يمكن لأي عضو قراءة حالة الفوترة؛ يمكن فقط لمالك مساحة العمل تغييرها (تُرجع الاستدعاءات المُغيِّرة 403 INSUFFICIENT_PERMISSIONS، ومفاتيح API تُرفض دائماً في تلك النقاط).

حالات الدفع

paymentStatus تُعاد كسلسلة نصية بصيغة snake_case، وليست تعداداً رقمياً:

الحالةالوصف
currentالاشتراك نشط، الدفع محدّث
grace_periodفشل الدفع، فترة السماح نشطة
overdueالدفع متأخر، الميزات مقيّدة
blockedالحساب محظور بسبب عدم السداد

الحصول على تفاصيل الاشتراك

GET https://api.mail.land/v1/account/subscription
Get subscription details
curl https://api.mail.land/v1/account/subscription \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Subscription response
{
  "planName": "Pro",
  "monthlyEmailLimit": 100000,
  "rateLimitPerSecond": 10,
  "pricePerMonth": 49.00,
  "startDate": "2026-01-15T08:00:00Z",
  "endDate": "2026-03-01T00:00:00Z",
  "status": "Active",
  "paymentStatus": "current",
  "marketingPausedDueToPayment": false,
  "sendingBlockedDueToPayment": false,
  "transactionalDailyLimit": 5000,
  "daysUntilBlocked": null,
  "cancelAtPeriodEnd": false,
  "planFamilyId": "fam_pro",
  "planTierPublicId": "tier_pro_monthly",
  "usage": {
    "emailsSentThisMonth": 45000,
    "monthlyLimit": 100000,
    "percentageUsed": 45.0,
    "transactionalCount": 30000,
    "marketingCount": 12000,
    "apiCount": 40000,
    "smtpCount": 5000,
    "campaignCount": 3000,
    "automationCount": 2000,
    "inboundForwardCount": 500
  }
}

لا يوجد id أو planId أو interval أو currentPeriodStart/currentPeriodEnd، ولا حقول paymentStatus الرقمية أو عدادات استخدام التحقق/النطاقات/الفريق/الأتمتة في هذه الاستجابة، استخدم أسماء الحقول أعلاه. paymentStatus سلسلة نصية بصيغة snake_case: "current" أو "grace_period" أو "overdue" أو "blocked". status بصيغة PascalCase ("Active"، "Suspended"، "Cancelled"): الاستثناء الوحيد هو الاستجابة الاحتياطية عند عدم وجود اشتراك، والتي تُعيد "active" بحروف صغيرة.

حقول الاستخدام

الحقلالوصف
emailsSentThisMonthالرسائل المُرسَلة في دورة الفوترة الحالية
monthlyLimitالحد الأقصى للرسائل في كل دورة
percentageUsedنسبة emailsSentThisMonth من monthlyLimit
transactionalCountالرسائل المعاملاتية المُرسَلة
marketingCountالرسائل التسويقية المُرسَلة
apiCountالرسائل المُرسَلة عبر API
smtpCountالرسائل المُرسَلة عبر ترحيل SMTP
campaignCountالرسائل المُرسَلة بواسطة الحملات
automationCountالرسائل المُرسَلة بواسطة الأتمتة
inboundForwardCountالرسائل المُرسَلة بواسطة قواعد إعادة توجيه البريد الوارد

لا توجد عدادات استخدام للتحقق أو النطاقات أو أعضاء الفريق أو الأتمتة في هذه الاستجابة، فقط عدادات إرسال البريد.

متى يتم احتساب استخدام البريد الإلكتروني

يُحتسب المستلمون ضمن استخدامك وحصتك (emailsSentThisMonth / monthlyLimit) في اللحظة التي يُسجَّل فيها القبول بشكل دائم. المستلمون المرفوضون أو المكبوتون قبل القبول لا يُحتسبون أبداً. أي ارتداد أو كبح لاحق أو فشل تسليم أو أي شكل آخر من عدم التسليم يحدث بعد القبول لا يُعيد أو يسترجع تلقائياً الاستخدام أو الحصة، لا يُعدَّل العدّ بأثر رجعي. يصف هذا القسم محاسبة الاستخدام فقط؛ ولا يُقرّ أو يُلمّح إلى تسعير Stripe لكل رسالة أو أي حق استرداد، فهذه أمور تحكمها شروط اشتراكك بشكل منفصل.

تُعاد الحصة إلى الصفر في كل دورة فوترة من Stripe للخطط المُفوترة عبرها، أو في اليوم الأول من كل شهر تقويمي بتوقيت UTC للخطط غير المُفوترة عبر Stripe (المجانية والخطط الممنوحة من المسؤول): وليست دائماً "لكل دورة" بمعنى Stripe.

الخطط والاحتفاظ بالبيانات

الخطط هي Free وPro وMax. تُحفظ سجلات الرسائل لمدة 30 يوماً في Free، و90 يوماً في Pro، و180 يوماً في Max.

ملخص السياسة

احصل على حالة التحقق من مساحة العمل وسياسة الإرسال:

GET https://api.mail.land/v1/account/subscription/policy-summary
Get policy summary
curl https://api.mail.land/v1/account/subscription/policy-summary \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

الاستجابة كائن متداخل، وليست مسطحة (SubscriptionController.cs:137-200):

Policy summary response
{
  "subscription": {
    "planFamilyId": "fam_pro",
    "planFamilyName": "Pro",
    "planTierId": "tier_pro_monthly",
    "monthlyQuota": 100000,
    "pricePerMonth": 49.00
  },
  "usage": {
    "usedThisMonth": 45000,
    "remainingThisMonth": 55000,
    "percentUsed": 45.0
  },
  "effectiveRates": {
    "transactionalRatePerMin": 600,
    "marketingRatePerMin": 300,
    "isOverridden": false
  },
  "domainWarmup": [
    {
      "domainId": "h4k7m1n9w2p5x8",
      "domainName": "example.com",
      "currentStage": 2,
      "totalStages": 5,
      "todaySentCount": 350,
      "dailyLimit": 500,
      "progressPercent": 70.0,
      "completed": false,
      "bypassed": false
    }
  ],
  "alerts": [
    {
      "type": "warning",
      "code": "QUOTA_WARNING",
      "message": "You have used 80% of your monthly quota. Consider upgrading your plan.",
      "actionUrl": "/billing"
    }
  ],
  "dailySendingLimit": {
    "limit": 5000,
    "usedToday": 1200,
    "remainingToday": 3800,
    "resetsAt": "2026-02-18T00:00:00Z"
  },
  "verification": {
    "level": 2,
    "levelName": "SenderVerified",
    "limits": {},
    "progress": {},
    "nextSteps": []
  }
}
الحقلالوصف
subscriptionعائلة الخطة، الفئة والحصة/السعر الشهري
usageالرسائل المستخدمة، المتبقية والنسبة المستخدمة هذا الشهر
effectiveRatesمعدلات الإرسال الفعلية في الدقيقة وما إذا كانت مُتجاوَزة
domainWarmupتقدم الإحماء لكل نطاق، مُدخل واحد لكل نطاق قيد الإحماء
alertsالتنبيهات النشطة لهذه المساحة (الحصة، الحد اليومي، وما شابه)
dailySendingLimitالحد اليومي للإرسال والمساحة المتبقية، عند الانطباق
verificationمستوى التحقق الحالي، حدوده، تقدمه والخطوات التالية

إنشاء جلسة دفع

ابدأ جلسة Stripe Checkout للاشتراك أو الترقية:

POST https://api.mail.land/v1/account/billing/checkout
Checkout request
{
  "planTierId": "tier_pro_monthly",
  "locale": "en",
  "businessAttested": true,
  "businessAttestationKey": "business-use-v3-button"
}
الحقلالنوعمطلوبالوصف
planTierIdstringنعمالمعرّف العام لمستوى الخطة
localestringلالغة صفحة الدفع المستضافة
businessAttestedbooleanنعمتؤكد القيمة true أنك تشتري MailLand لاستخدام تجاري أو مهني (بما في ذلك العمل الحر أو النشاط الفردي أو موقعك الخاص). تُرسلها لوحة التحكم عبر زر الدفع: تسميته «Pay for business use» وتحته ملاحظة من سطر واحد توضح ما يؤكده النقر
businessAttestationKeystringنعمإصدار الصياغة الذي يشير إليه التأكيد؛ حاليًا business-use-v3-button (ما زال business-use-v1، وهو الصياغة الأقدم، مقبولًا)

يُرفض الطلب الذي لا يتضمن businessAttested: true ومفتاح businessAttestationKey مقبولًا برمز 400 BUSINESS_ATTESTATION_REQUIRED قبل خصم أي مبلغ. يحفظ MailLand من أكّد ومتى وبأي صياغة (المفتاح الذي أرسلته) وبأي لغة. في Stripe Checkout يمكنك إدخال رقم ضريبي؛ وهو اختياري. الأسعار لا تشمل ضريبة القيمة المضافة ولا يحصّل MailLand هذه الضريبة؛ ويضيف رقم ضريبة قيمة مضافة أوروبي تم التحقق منه خارج المملكة المتحدة ملاحظة الاحتساب العكسي إلى فواتيرك.

لا يوجد حقل successUrl أو cancelUrl: روابط النجاح/الإلغاء ليست مقدَّمة من المستدعي.

Create checkout session
curl -X POST https://api.mail.land/v1/account/billing/checkout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ "planTierId": "tier_pro_monthly", "locale": "en", "businessAttested": true, "businessAttestationKey": "business-use-v3-button" }'
Checkout response
{
  "upgraded": false,
  "sessionId": "cs_live_abc123...",
  "url": "https://checkout.stripe.com/c/pay/cs_live_abc123..."
}

أعد توجيه المستخدم إلى url لإتمام الدفع على صفحة دفع Stripe المستضافة. إذا كان لدى مساحة العمل بالفعل اشتراك نشط، يتغير الخطة في مكانها بدلاً من فتح جلسة دفع جديدة: تكون الاستجابة { "upgraded": true } بدون sessionId/url، ولا يوجد إعادة توجيه. لا تُعِد التوجيه إلا عندما تكون url موجودة.

بوابة الفوترة

افتح بوابة عملاء Stripe للإدارة الذاتية (تحديث طريقة الدفع، الإلغاء، عرض الفواتير):

POST https://api.mail.land/v1/account/billing/portal
Portal request
{
  "locale": "en"
}

locale اختياري.

Open billing portal
curl -X POST https://api.mail.land/v1/account/billing/portal \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ "locale": "en" }'
Portal response
{
  "url": "https://billing.stripe.com/p/session/abc123..."
}

أعد توجيه المستخدم إلى url للوصول إلى بوابة Stripe.

قائمة الفواتير

GET https://api.mail.land/v1/account/billing/invoices
المعاملالنوعالافتراضيالوصف
limitint20عدد الفواتير المُراد إرجاعها
cursorstring-مؤشر غامق من nextCursor في استجابة سابقة
List invoices
curl https://api.mail.land/v1/account/billing/invoices \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Invoices response
{
  "items": [
    {
      "publicId": "inv_abc123",
      "invoiceNumber": "INV-2026-0015",
      "stripeInvoiceId": "in_1AbCdEfGhIjKlMn",
      "status": "Paid",
      "amountDue": 4900,
      "amountPaid": 4900,
      "currency": "eur",
      "periodStart": "2026-01-01T00:00:00Z",
      "periodEnd": "2026-02-01T00:00:00Z",
      "paidAt": "2026-01-01T00:05:00Z",
      "hostedInvoiceUrl": "https://pay.stripe.com/invoice/inv_abc123",
      "invoicePdfUrl": "https://pay.stripe.com/invoice/inv_abc123/pdf",
      "createdAt": "2026-01-01T00:00:00Z"
    },
    {
      "publicId": "inv_def456",
      "invoiceNumber": "INV-2026-0014",
      "stripeInvoiceId": "in_2BcDeFgHiJkLmNo",
      "status": "Paid",
      "amountDue": 4900,
      "amountPaid": 4900,
      "currency": "eur",
      "periodStart": "2025-12-01T00:00:00Z",
      "periodEnd": "2026-01-01T00:00:00Z",
      "paidAt": "2025-12-01T00:05:00Z",
      "hostedInvoiceUrl": "https://pay.stripe.com/invoice/inv_def456",
      "invoicePdfUrl": "https://pay.stripe.com/invoice/inv_def456/pdf",
      "createdAt": "2025-12-01T00:00:00Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

هذه استجابة مقسّمة إلى صفحات بمؤشر (cursor)، وليست { "invoices": [...] }: مرر nextCursor كمعامل cursor للحصول على الصفحة التالية، وتوقف عندما تكون hasMore قيمتها false. حجم الصفحة الافتراضي هو 20 وليس 10؛ وأسماء الحقول هي invoiceNumber وamountDue وamountPaid وhostedInvoiceUrl وinvoicePdfUrl (وليست number أو amount أو invoiceUrl أو invoicePdf).

مبالغ الفواتير بأصغر وحدة من currency الخاصة بالفاتورة (السنت بالنسبة لليورو EUR). اقسم على 100 للعرض. أسعار الباقات باليورو (EUR) ولا تشمل ضريبة القيمة المضافة.

استجابات الخطأ

الحالةالرمزالوصف
400VALIDATION_FAILEDنص طلب غير صالح
400INVALID_REQUESTفئة الخطة موجودة لكنها غير متزامنة مع Stripe
403INSUFFICIENT_PERMISSIONSفقط مالك مساحة العمل يمكنه تنفيذ هذا التعديل (قراءة الفوترة متاحة لأي عضو)
404RESOURCE_NOT_FOUNDفئة خطة غير معروفة أو غير نشطة
502STRIPE_ERRORفشل طلب Stripe

نقاط نهاية أخرى للفوترة

متوفرة أيضاً، ولم يتم تفصيلها أعلاه: POST /v1/account/billing/cancel وPOST /v1/account/billing/reactivate والنقطة العامة GET /public/plans/catalog.

الخطوات التالية

في هذه الصفحة