REST API نسخه ۲ · سریع، امن و غیرهمزمان

ارسال صورتحساب مودیان
مستقیم از نرم‌افزار شما

برای هر شرکت یک توکن مستقل دریافت کنید، صورتحساب را با یک درخواست JSON در صف ارسال قرار دهید و وضعیت تأیید سازمان امور مالیاتی را استعلام کنید.

۱. خرید اشتراکAPI فقط برای شرکت دارای اشتراک خریداری‌شده فعال می‌شود.
۲. ساخت توکنتوکن به شرکت فعال متصل است و به شرکت دیگری دسترسی ندارد.
۳. ارسال امنصورتحساب اتمیک ثبت و در صف پردازش قرار می‌گیرد.

معماری و تضمین‌های API

  • هر توکن مشتری فقط به یک شرکت متصل است و در هر درخواست وضعیت اشتراک همان شرکت بررسی می‌شود.
  • توکن کامل در دیتابیس ذخیره نمی‌شود؛ فقط هش غیرقابل‌بازیابی آن نگهداری می‌شود.
  • هر ارسال به Idempotency-Key نیاز دارد تا retry شبکه هیچ‌گاه صورتحساب تکراری نسازد.
  • مبالغ مالیات، تخفیف و جمع کل روی سرور محاسبه می‌شوند و به جمع ارسالی کلاینت اعتماد نمی‌شود.
  • شناسه‌های کالا و خدمات قبل از ثبت، یکجا از کاتالوگ فعال کنترل می‌شوند.
  • ثبت صورتحساب، خریدار و ردیف‌ها در transaction انجام و ارسال واقعی از طریق صف پردازش می‌شود.
API از HTTPS استفاده می‌کند. توکن را در کد سمت مرورگر، اپ موبایل عمومی یا Git ذخیره نکنید؛ آن را فقط در backend یا secret manager نگه دارید.

احراز هویت با Bearer Token

از پنل مشتری ← «API صورتحساب» توکن بسازید. مقدار کامل فقط یک‌بار نمایش داده می‌شود.

Authorization: Bearer mdm_company_xxxxxxxxxxxxxxxx.YOUR_SECRET

برای بررسی اتصال:

GEThttps://mizan-hesab.ir/api/v2/health
curl "https://mizan-hesab.ir/api/v2/health" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json"

ارسال صورتحساب

POSThttps://mizan-hesab.ir/api/v2/invoices
curl -X POST "https://mizan-hesab.ir/api/v2/invoices" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Idempotency-Key: accounting-invoice-1405-000123" \ -H "Content-Type: application/json" \ --data @invoice.json
Idempotency-Key را برای هر صورتحساب یکتا و ثابت نگه دارید. در retry همان صورتحساب دقیقاً همان کلید و همان JSON را ارسال کنید.

نمونه کامل invoice.json

{ "external_id": "INV-1405-000123", "invoice_type": 1, "invoice_subject": 1, "issue_date": "2026-07-20T10:30:00+03:30", "settlement_type": 1, "buyer": { "type": "legal", "name": "شرکت خریدار نمونه", "national_id": "10101234567", "economic_code": "41111111111111", "postal_code": "1234567890" }, "items": [ { "stuff_id": "2330004397645", "description": "خدمات نرم‌افزاری", "unit_code": "1627", "quantity": 1, "unit_price": 15000000, "discount_amount": 0, "vat_rate": 10 } ], "notes": "ثبت خودکار از نرم‌افزار حسابداری", "auto_send": true }

کدهای عددی اصلی

فیلد۱۲۳
invoice_typeنوع اول B2Bنوع دوم B2Cنوع سوم صادراتی
invoice_subjectاصلیاصلاحیابطالی
settlement_typeنقدینسیه

نوع خریدار

real حقیقی، legal حقوقی، civil_partnership مشارکت مدنی، foreign خارجی و final_consumer مصرف‌کننده نهایی است. برای مصرف‌کننده نهایی نیازی به شناسه خریدار نیست و نوع صورتحساب به‌طور خودکار B2C می‌شود.

برای اصلاحی و ابطالی، مقدار original_tax_id را برابر شناسه مالیاتی صورتحساب مرجع بفرستید. برای نسیه نیز settlement_date الزامی است.

پاسخ پذیرش

کد HTTP برابر 202 Accepted یعنی صورتحساب ثبت و وارد صف شده است؛ به معنی تأیید نهایی سازمان نیست.

{ "message": "صورتحساب در صف ارسال قرار گرفت.", "code": "invoice_accepted", "invoice": { "external_id": "INV-1405-000123", "uid": "...", "tax_id": null, "reference_number": null, "status": "pending", "grand_total": 16500000 } }

در تکرار امن درخواست، هدر Idempotent-Replayed: true برگردانده می‌شود.

استعلام وضعیت

GEThttps://mizan-hesab.ir/api/v2/invoices/{external_id}
curl "https://mizan-hesab.ir/api/v2/invoices/INV-1405-000123" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json"
وضعیتمعنی
pending / sendingدر صف یا در حال ارسال
sentبه سازمان ارسال و شماره پیگیری دریافت شده
successتأیید نهایی
failedناموفق؛ جزئیات در error

نمونه پیاده‌سازی

PHP با Laravel HTTP Client

$response = Http::withToken(config('services.modiam.token')) ->acceptJson() ->withHeaders(['Idempotency-Key' => $invoice->number]) ->timeout(15) ->retry(3, 300) ->post('https://mizan-hesab.ir/api/v2/invoices', $payload); $response->throw(); $result = $response->json();

Node.js / TypeScript

const response = await fetch('https://mizan-hesab.ir/api/v2/invoices', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.MODIAM_TOKEN}`, 'Idempotency-Key': invoice.externalId, 'Content-Type': 'application/json' }, body: JSON.stringify(invoice) }); if (!response.ok) throw new Error(await response.text()); const result = await response.json();

کدهای پاسخ و خطا

HTTPcodeاقدام
401unauthenticatedتوکن را بررسی یا توکن جدید صادر کنید.
402subscription_requiredاشتراک شرکت را فعال کنید.
403forbiddenscope توکن برای عملیات کافی نیست.
409idempotency_conflictبرای بدنه جدید کلید جدید بسازید.
422invalid_requestفیلدهای errors/details را اصلاح کنید.
429rate_limit_exceededطبق Retry-After با backoff تلاش کنید.
500/503server_errorبا همان Idempotency-Key مجدداً تلاش کنید.