صورتحساب
مدیریت اشتراک، مشاهده فاکتورها و نظارت بر مصرف
MailLand از Stripe برای مدیریت اشتراک و صورتحساب استفاده میکند. هر فضای کاری اشتراک مستقل خود را با قیمتگذاری مبتنی بر مصرف یا مبتنی بر طرح دارد. هر عضوی میتواند وضعیت صورتحساب را بخواند؛ فقط مالک فضای کاری میتواند آن را تغییر دهد (فراخوانیهای تغییردهنده 403 INSUFFICIENT_PERMISSIONS برمیگردانند و کلیدهای API همیشه در آن نقاط پایانی رد میشوند).
وضعیتهای پرداخت
paymentStatus بهصورت یک رشتهی snake_case بازگردانده میشود، نه یک enum عددی:
| وضعیت | توضیحات |
|---|---|
current | اشتراک فعال، پرداخت بهروز است |
grace_period | پرداخت ناموفق، دوره مهلت فعال است |
overdue | پرداخت معوق، ویژگیها محدود شدهاند |
blocked | حساب به دلیل عدم پرداخت مسدود شده است |
دریافت جزئیات اشتراک
GET https://api.mail.land/v1/account/subscriptioncurl https://api.mail.land/v1/account/subscription \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"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 relay |
campaignCount | ایمیلهای ارسالشده توسط کمپینها |
automationCount | ایمیلهای ارسالشده توسط اتوماسیونها |
inboundForwardCount | ایمیلهای ارسالشده توسط قوانین بازارسال ورودی |
هیچ شمارندهی مصرف برای اعتبارسنجی، دامنه، اعضای تیم یا اتوماسیون در این پاسخ وجود ندارد، فقط شمارندههای ارسال ایمیل.
چه زمانی مصرف ایمیل شمارش میشود
گیرندگان در لحظهای که پذیرش بهطور پایدار ثبت میشود، در برابر مصرف و سهمیهی شما (emailsSentThisMonth / monthlyLimit) شمارش میشوند. گیرندگانی که پیش از پذیرش رد یا سرکوب شوند، هرگز شمارش نمیشوند. یک بازگشت (bounce)، سرکوب پاییندستی، شکست تحویل یا هر نوع عدمتحویل دیگر که پس از پذیرش رخ دهد، بهطور خودکار مصرف یا سهمیه را بازیابی یا پس نمیگیرد، شمارش بهصورت گذشتهنگر تعدیل نمیشود. این بخش تنها حسابداری مصرف را توصیف میکند؛ و بیانگر یا تلویحاً بیانگر قیمتگذاری Stripe به ازای هر ایمیل یا هرگونه حق استرداد نیست، که اینها جداگانه توسط شرایط اشتراک شما اداره میشوند.
سهمیه در هر دورهی صورتحساب Stripe برای پلنهای صورتحسابشده از طریق Stripe، یا در روز اول هر ماه تقویمی UTC برای پلنهای غیر Stripe (Free و پلنهای اعطاشده توسط مدیر) بازنشانی میشود، و همیشه به معنای Stripe از «هر دوره» نیست.
پلنها و نگهداری داده
پلنها عبارتند از Free، Pro و Max. لاگهای پیام به مدت ۳۰ روز در Free، ۹۰ روز در Pro و ۱۸۰ روز در Max نگهداری میشوند.
خلاصه سیاست
وضعیت تأیید فضای کاری و سیاست ارسال را دریافت کنید:
GET https://api.mail.land/v1/account/subscription/policy-summarycurl https://api.mail.land/v1/account/subscription/policy-summary \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."پاسخ واقعی یک شیء تودرتو است، نه مسطح (SubscriptionController.cs:137-200):
{
"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{
"planTierId": "tier_pro_monthly",
"locale": "en",
"businessAttested": true,
"businessAttestationKey": "business-use-v3-button"
}| فیلد | نوع | الزامی | توضیحات |
|---|---|---|---|
planTierId | string | بله | شناسهی عمومی سطح پلن |
locale | string | خیر | زبان صفحهی پرداخت میزبانیشده |
businessAttested | boolean | بله | true تأیید میکند که MailLand را برای استفادهی کسبوکاری یا حرفهای میخرید (از جمله بهعنوان فریلنسر، کاسب مستقل یا برای وبسایت شخصی خودتان). داشبورد آن را روی دکمهی پرداخت میفرستد: برچسب دکمه «پرداخت برای استفادهی کسبوکاری» (Pay for business use) است و یادداشتی یکخطی زیر آن توضیح میدهد که این کلیک چه چیزی را تأیید میکند |
businessAttestationKey | string | بله | نسخهی متنی که تأیید به آن اشاره دارد؛ در حال حاضر business-use-v3-button (business-use-v1، متن قبلی، هنوز پذیرفته میشود) |
درخواستی که businessAttested: true و یک businessAttestationKey پذیرفتهشده نداشته باشد، پیش از هر پرداختی با 400 BUSINESS_ATTESTATION_REQUIRED رد میشود. MailLand ثبت میکند چه کسی، چه زمانی، با کدام متن (کلیدی که فرستادهاید) و با کدام زبان تأیید کرده است. در Stripe Checkout میتوانید شناسهی مالیاتی وارد کنید؛ این کار اختیاری است. قیمتها بدون VAT هستند و MailLand مالیات بر ارزش افزوده دریافت نمیکند؛ شناسهی VAT تأییدشدهی اتحادیهی اروپا (خارج از بریتانیا) یادداشت reverse-charge را به صورتحسابهای شما اضافه میکند.
هیچ فیلد successUrl یا cancelUrl وجود ندارد: آدرسهای موفقیت/لغو توسط فراخواننده ارسال نمیشوند.
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" }'{
"upgraded": false,
"sessionId": "cs_live_abc123...",
"url": "https://checkout.stripe.com/c/pay/cs_live_abc123..."
}کاربر را به url هدایت کنید تا پرداخت را در صفحه پرداخت میزبانیشده Stripe تکمیل کند. اگر فضای کاری از قبل اشتراک فعالی داشته باشد، پلن بهجای باز شدن یک checkout جدید، در همان جا تغییر میکند: پاسخ { "upgraded": true } بدون sessionId/url است و هدایتی وجود ندارد. فقط زمانی هدایت کنید که url وجود داشته باشد.
پورتال صورتحساب
پورتال مشتری Stripe را برای مدیریت خودسرویس باز کنید (بهروزرسانی روش پرداخت، لغو، مشاهده فاکتورها):
POST https://api.mail.land/v1/account/billing/portal{
"locale": "en"
}locale اختیاری است.
curl -X POST https://api.mail.land/v1/account/billing/portal \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{ "locale": "en" }'{
"url": "https://billing.stripe.com/p/session/abc123..."
}کاربر را به url هدایت کنید تا به پورتال Stripe دسترسی داشته باشد.
فهرست فاکتورها
GET https://api.mail.land/v1/account/billing/invoices| پارامتر | نوع | پیشفرض | توضیحات |
|---|---|---|---|
limit | int | 20 | تعداد فاکتورهایی که باید بازگردانده شوند |
cursor | string | - | نشانگر مبهم از nextCursor در پاسخ قبلی |
curl https://api.mail.land/v1/account/billing/invoices \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"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 بود متوقف شوید. اندازهی پیشفرض صفحه ۲۰ است، نه ۱۰؛ نام فیلدها invoiceNumber، amountDue، amountPaid، hostedInvoiceUrl و invoicePdfUrl هستند (نه number، amount، invoiceUrl، invoicePdf).
مبالغ فاکتور بر حسب کوچکترین واحد currency همان فاکتور هستند (سنت برای EUR). برای نمایش بر 100 تقسیم کنید. قیمت پلنها به یورو (EUR) و بدون احتساب مالیات بر ارزش افزوده است.
پاسخهای خطا
| وضعیت | کد | توضیحات |
|---|---|---|
400 | VALIDATION_FAILED | بدنهی درخواست نامعتبر است |
400 | INVALID_REQUEST | سطح پلن وجود دارد اما با Stripe همگامسازی نشده است |
403 | INSUFFICIENT_PERMISSIONS | فقط مالک فضای کاری میتواند این تغییر را انجام دهد (خواندن صورتحساب برای هر عضوی باز است) |
404 | RESOURCE_NOT_FOUND | سطح پلن ناشناخته یا غیرفعال |
502 | STRIPE_ERROR | درخواست Stripe ناموفق بود |
سایر Endpointهای صورتحساب
همچنین در دسترساند و در بالا توضیح داده نشدهاند: POST /v1/account/billing/cancel، POST /v1/account/billing/reactivate، و endpoint عمومی GET /public/plans/catalog.
مراحل بعدی
- فضاهای کاری: مدیریت تنظیمات فضای کاری
- مدیریت تیم: مدیریت اعضای تیم
- محدودیتهای نرخ: درک محدودیتهای نرخ API