معرفی API
با API میتوانید بدون ورود به پنل شمارههای اقتصادی را مدیریت کنید، ماندهی اعتبار را بخوانید، صورتحساب را بهصورت تکی یا گروهی ارسال کنید، وضعیتشان را استعلام بگیرید و گزارش ارسالیها و خطاها را بخوانید. برای اتصال نرمافزار حسابداری، فروشگاهساز یا هر سیستم داخلی شما مناسب است.
- آدرس پایه:
https://api.tpinta.com/v1(فقط HTTPS) - قالب داده: JSON با کدگذاری UTF-8؛ نام فیلدها camelCase است و زمانها UTC و ISO 8601 هستند.
- مرجع کامل: api.tpinta.com/docs، بههمراه کالکشن آمادهی Postman.
همهی پاسخها یک قالب ثابت دارند:
{ "success": true, "data": { ... } }
{ "success": false, "error": { "code": "validation_failed", "message": "...", "field": "name" }, "traceId": "00-4bf9..." }
در برنامهی خودتان error.code را بررسی کنید (ثابت است)؛ message فارسی است و برای نمایش به انسان. هنگام گزارش مشکل به پشتیبانی traceId را هم بفرستید.
پیشنیازها
- شماره اقتصادی. در پنل ثبت کنید (برای تمرین، محیط آزمایشی). راهنمای ثبت شماره اقتصادی
- اعتبار. هزینهی هر صورتحساب از اعتبار حساب کم میشود. راهنمای افزایش اعتبار
- کلید API. از منوی «کلید API» پنل بسازید (با رمز پنل). کلید با
ei_شروع میشود، فقط یکبار نمایش داده میشود و هر حساب حداکثر ۵ کلید فعال دارد. راهنمای کلید API
قدم اول: دریافت توکن
با سه مورد وارد میشوید: موبایل پنل، رمز پنل و کلید API. این سه فقط برای گرفتن توکن لازماند؛ بعد از آن در همهی درخواستها فقط توکن میفرستید.
POST/v1/auth/token
بدون نیاز به توکن
curl -X POST https://api.tpinta.com/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"mobile":"09120000000","password":"رمز-پنل","apiKey":"ei_..."}'
{
"success": true,
"data": { "accessToken": "CfDJ8...", "tokenType": "Bearer", "expiresIn": 3600 }
}
- توکن را در هدر
Authorization: Bearer ACCESS_TOKENهمهی درخواستهای بعدی بفرستید. - اعتبار توکن پیشفرض ۶۰ دقیقه است (
expiresInبر حسب ثانیه). برای هر درخواست توکن جدید نگیرید؛ توکن را نگه دارید و تا پایان اعتبارش استفاده کنید. - تغییر رمز پنل همهی توکنهای قبلی را باطل میکند و لغو کلید در پنل توکنهای آن را حداکثر ظرف حدود ۳۰ ثانیه از کار میاندازد.
- ۵ بار تلاش ناموفق برای یک کلید در ۱۵ دقیقه، آن کلید را موقتاً مسدود میکند (
429 too_many_attempts). این مسدودسازی ورود به پنل را تحتتأثیر قرار نمیدهد.
قدم دوم: تست اتصال و گرفتن شناسهها
قبل از ارسال صورتحساب، این سه درخواست ساده را بزنید:
curl https://api.tpinta.com/v1/me -H "Authorization: Bearer ACCESS_TOKEN"
curl https://api.tpinta.com/v1/credit/balance -H "Authorization: Bearer ACCESS_TOKEN"
curl https://api.tpinta.com/v1/economic-ids -H "Authorization: Bearer ACCESS_TOKEN"
/v1/me: سالم بودن توکن را نشان میدهد./v1/credit/balance: ماندهی اعتبار، هزینهی هر صورتحساب و تعداد صورتحساب قابل ارسال./v1/economic-ids: فهرست شمارههای اقتصادی شما.
{ "success": true, "data": { "balance": 1500000, "invoiceFee": 3000, "remainingInvoices": 500 } }
{
"success": true,
"data": { "items": [ { "id": 12, "code": "10101234567", "isTest": true, "active": true, "...": "..." } ] }
}
economicId همان id در این فهرست است (مثلاً ۱۲)، نه خود کد اقتصادی (مثلاً ۱۰۱۰۱۲۳۴۵۶۷).اگر هنوز شمارهای ثبت نکردهاید، items خالی است. شمارهی اقتصادی را از پنل یا با POST /v1/economic-ids ثبت کنید (حذف شماره فقط از پنل ممکن است).
قدم سوم: ارسال اولین صورتحساب
POST/v1/invoices
سقف: ۶۰ درخواست در دقیقه برای هر توکن
POST https://api.tpinta.com/v1/invoices
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"clientRef": "INV-2026-000123",
"economicId": 12,
"subject": 1,
"pattern": 1,
"type": 1,
"buyerType": 2,
"buyer": { "tinb": "10101234567" },
"headerExtra": { "setm": 1 },
"items": [
{ "sstid": "1234567890123", "sstt": "خدمات نمونه", "am": 2, "fee": 1000000, "vra": 10 }
]
}
{
"success": true,
"data": { "taxId": "A12B34C0000000123456XY", "clientRef": "INV-2026-000123", "status": "queued", "duplicate": false }
}
فیلدهای اصلی
| فیلد | توضیح |
|---|---|
clientRef | شناسهی یکتای درخواست (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -). مثلاً شمارهی فاکتور خودتان. در بخش «جلوگیری از ارسال تکراری» توضیح داده شده. |
economicId | شناسهی شماره اقتصادی صادرکننده (فیلد id در فهرست شمارهها). |
subject | موضوع: ۱ اصلی · ۲ اصلاحی · ۳ ابطالی · ۴ برگشت از فروش. |
pattern · type | الگو (مثلاً ۱ فروش) و نوع صورتحساب (۱ نوع اول · ۲ نوع دوم · ۳ نوع سوم). |
buyerType · buyer | نوع شخص خریدار (۱ حقیقی · ۲ حقوقی · ۳ مشارکت مدنی · ۴ اتباع غیرایرانی) و اطلاعات او: tinb شماره اقتصادی، bid شناسه/کد ملی، bpc کد پستی. اطلاعات لازم به الگو و نوع خریدار بستگی دارد و پیام خطا دقیق میگوید. |
headerExtra | فیلدهای سربرگ مخصوص الگو؛ مثلاً setm روش تسویه (۱ نقدی · ۲ نسیه · ۳ نقدی/نسیه) که در نوع اول لازم است. |
items | اقلام (حداکثر ۵۰۰ ردیف): sstid شناسهی ۱۳ رقمی کالا/خدمت، sstt شرح، am تعداد، fee مبلغ واحد (ریال)، dis تخفیف، vra نرخ مالیات بر ارزش افزوده (درصد). |
issuedAt | اختیاری؛ زمان صدور بهصورت ISO 8601. خالی یعنی همین الان و زمان آینده پذیرفته نمیشود. |
payment | اختیاری؛ اطلاعات پرداخت (برای نوع سوم لازم است). |
ackAmountWarning | اختیاری؛ تأیید هشدار «مبلغ غیرعادی» (پایینتر). |
مبالغ محاسباتی هر ردیف (مثل prdis، adis، vam، tsstam) را لازم نیست خودتان حساب کنید؛ سرور با همان فرمول پنل حساب میکند. اگر خودتان بفرستید، مقدار شما راستیآزمایی میشود و در صورت اشتباه خطای دقیق میگیرید. شناسهی کالا/خدمت را از جستجوی شناسه کالا و خدمت پیدا کنید.
taxId (۲۲ نویسه) را برای استعلام و گزارش نگه دارید.اگر صورتحساب رد شد
اعتبارسنجی سرور همان قواعد پنل را دارد. اگر مشکلی باشد هیچچیز ثبت نمیشود و اعتباری کم نمیشود و همهی خطاها یکجا در details میآید:
{
"success": false,
"error": {
"code": "invoice_invalid",
"message": "اعتبارسنجی صورتحساب ناموفق بود",
"details": [ "ردیف 1: شناسه کالا/خدمت در فهرست یافت نشد", "..." ]
},
"traceId": "00-4bf92f35..."
}
| پاسخ | معنی و کار درست |
|---|---|
400 validation_failed | فیلدی در بدنه ناقص یا نامعتبر است؛ نام آن در field میآید. |
422 invoice_invalid | قواعد صورتحساب رعایت نشده؛ خطاهای details را اصلاح و دوباره بفرستید (همان clientRef قابل استفاده است). |
402 insufficient_credit | اعتبار کافی نیست؛ از پنل شارژ کنید. |
409 amount_warning | مبلغ نسبت به سابقهی همین شماره اقتصادی یا سقف تعیینشده در پنل غیرعادی است. اگر مبلغ درست است، همان درخواست را با "ackAmountWarning": true دوباره بفرستید. |
404 not_found | شماره اقتصادی پیدا نشد یا متعلق به حساب شما نیست. |
قدم چهارم: پیگیری وضعیت
وضعیت نهایی را با استعلام میگیرید. وضعیت از دیتابیس تیپینتا خوانده میشود و ارسال خودکار آن را بهروز میکند؛ پس بعد از ثبت، چند ثانیه تا چند دقیقه طول میکشد تا queued به success یا failed برسد.
GET/v1/invoices/{{taxId}}
GET/v1/invoices/by-ref/{{clientRef}}
وقتی پاسخ ارسال به دست شما نرسیده و taxId ندارید
curl https://api.tpinta.com/v1/invoices/A12B34C0000000123456XY -H "Authorization: Bearer ACCESS_TOKEN"
curl https://api.tpinta.com/v1/invoices/by-ref/INV-2026-000123 -H "Authorization: Bearer ACCESS_TOKEN"
{ "success": true, "data": { "taxId": "A12B34C0000000123456XY", "status": "success", "message": null, "referenceNumber": "1234567890123456" } }
| status | معنی |
|---|---|
pending | فقط در استعلام با clientRef: شناسه رزرو شده ولی صورتحساب هنوز ثبت نشده است (حدود یک دقیقه بعد همان درخواست را دوباره بفرستید). |
queued | ثبت شده و در صف ارسال است. |
processing | در حال ارسال یا پیگیری در سامانه مودیان. |
success | سامانه مودیان تأیید کرده؛ referenceNumber شمارهی پیگیری است. |
failed | رد یا ناموفق؛ علت در message آمده است. |
هر ۱۰ تا ۳۰ ثانیه یکبار استعلام کنید، نه پشتسرهم. برای وضعیت چند صورتحساب همزمان از استعلام گروهی (POST /v1/invoices/status، حداکثر ۱۰۰ مورد) استفاده کنید.
جلوگیری از ارسال تکراری با clientRef
اگر درخواست ارسال را بفرستید ولی بهخاطر قطعی شبکه یا timeout پاسخی نگیرید، نمیدانید صورتحساب ثبت شده یا نه. ارسال دوبارهی بیاحتیاط میتواند دو صورتحساب بسازد و دو بار اعتبار کم کند. برای همین هر ارسال یک clientRef یکتا دارد:
| حالت | نتیجه |
|---|---|
| اولین ارسال | 201 و صورتحساب ثبت میشود. |
| تکرار با همان clientRef و همان محتوا | 200 با duplicate: true و هدر Idempotent-Replayed: true؛ صورتحساب تازهای ساخته نمیشود و همان taxId و وضعیت فعلی برمیگردد. |
| همان clientRef با محتوای دیگر | 409 idempotency_conflict |
| درخواست قبلی هنوز در جریان است | 409 request_in_progress با هدر Retry-After؛ کمی بعد دوباره بفرستید. |
| ارسال قبلی رد شده (مثلاً 422) | چیزی ثبت نشده؛ همان clientRef را با محتوای اصلاحشده دوباره استفاده کنید. |
GET /v1/invoices/by-ref/{clientRef} بپرسید. فقط وقتی مطمئنید صورتحساب قبلی ثبت نشده، clientRef جدید بسازید.ارسال گروهی
برای چند صورتحساب در یک درخواست (حداکثر ۵۰ مورد، بدنه تا ۵ مگابایت). هر مورد دقیقاً مثل ارسال تکی پردازش میشود و شکست یک مورد بقیه را متوقف نمیکند. سقف: ۱۰ درخواست در دقیقه برای هر توکن.
POST/v1/invoices/batch
POST https://api.tpinta.com/v1/invoices/batch
{
"invoices": [
{ "clientRef": "INV-2026-000201", "economicId": 12, "subject": 1, "pattern": 1, "type": 1, "buyerType": 2,
"buyer": { "tinb": "10101234567" }, "headerExtra": { "setm": 1 }, "items": [ { "...": "..." } ] },
{ "clientRef": "INV-2026-000202", "...": "..." }
]
}
{
"success": true,
"data": {
"summary": { "total": 3, "accepted": 1, "replayed": 1, "failed": 1 },
"results": [
{ "index": 0, "clientRef": "INV-2026-000201", "ok": true, "taxId": "A12B...XY", "status": "queued", "duplicate": false },
{ "index": 1, "clientRef": "INV-2026-000202", "ok": true, "taxId": "A12B...XZ", "status": "success", "duplicate": true },
{ "index": 2, "clientRef": "INV-2026-000203", "ok": false, "error": { "code": "invoice_invalid", "message": "...", "details": [ "..." ] } }
]
}
}
- کد
200یعنی «درخواست پردازش شد»، نه «همه ثبت شدند». موفقیت هر مورد را درresults[i].okبررسی کنید. - ترتیب
resultsبا ترتیبinvoicesیکی است.duplicate: trueیعنی قبلاً با همان clientRef ثبت شده بود. - اگر اعتبار وسط دسته تمام شود، موارد اول ثبت و بعدیها با
402رد میشوند؛ قبل از دستههای بزرگ ماندهی اعتبار را بخوانید. - پردازش پشتسرهم است. timeout سمت خودتان را حداقل ۶۰ ثانیه بگذارید و برای شروع دستههای ۱۰ تا ۲۰ تایی را امتحان کنید.
- اگر پاسخ کل درخواست به دست شما نرسید، همهی clientRefها را با استعلام گروهی بررسی کنید:
POST https://api.tpinta.com/v1/invoices/status
{ "clientRefs": [ "INV-2026-000201", "INV-2026-000202" ] }
اصلاحی، ابطالی و برگشت از فروش
صورتحساب ارسالشده ویرایش نمیشود؛ سند جدید با همان مسیر POST /v1/invoices میفرستید و در آن subject و referenceTaxId (شماره مالیاتی صورتحساب مرجع) را میگذارید.
subject: 2: اصلاحی.subject: 3: ابطالی؛ الگو، نوع، خریدار و اقلام از صورتحساب مرجع گرفته میشود و فقطreferenceTaxIdلازم است.subject: 4: برگشت از فروش؛ در اقلام «ماندهی فروش پس از برگشت» را بفرستید، نه تعداد برگشتی را.
{
"clientRef": "RET-2026-000045",
"economicId": 12,
"subject": 4,
"referenceTaxId": "A12B34C0000000123456XY",
"pattern": 1, "type": 1, "buyerType": 2,
"buyer": { "tinb": "10101234567" },
"headerExtra": { "setm": 1 },
"items": [ { "sstid": "1234567890123", "sstt": "خدمات نمونه", "am": 1, "fee": 1000000, "vra": 10 } ]
}
مرجع باید با موفقیت ثبت شده و متعلق به حساب شما باشد.
گزارشها
دو گزارش فقطخواندنی دارید که فقط دادهی حساب صاحب توکن را برمیگردانند:
GET https://api.tpinta.com/v1/reports/invoices?from=2026-10-01&to=2026-11-01&status=failed&size=25&page=1
GET https://api.tpinta.com/v1/reports/errors?from=2026-10-01&to=2026-11-01&source=submit
/v1/reports/invoices: همهی صورتحسابها با هر کانالی (ویزارد، اکسل یا API). فیلترها:status،economicId،subject،pattern،channel(۱ ویزارد · ۲ اکسل · ۳ API)،qوsort./v1/reports/errors: صورتحسابهای ردشده با علت.source:validation(کنترلهای سامانه پیش از ارسال)،submit(رد هنگام ارسال) یاinquiry(رد در استعلام نهایی).- بازهی تاریخ بر اساس تاریخ صدور است (میلادی و UTC).
fromشامل خودش وtoبدون خودش است. اگر نفرستید ۳۰ روز اخیر برمیگردد و طول بازه حداکثر ۹۲ روز است. - صفحهبندی:
pageاز ۱ وsizeبین ۱ تا ۱۰۰ (پیشفرض ۱۰). پاسخtotalوitemsدارد؛ تعداد صفحههاceil(total / size)است.
خطاها و محدودیتها: چطور واکنش نشان دهیم
| پاسخ | کار درست |
|---|---|
401 unauthorized | یکبار توکن جدید بگیرید و همان درخواست را دوباره بفرستید. اگر باز 401 گرفتید، کلید لغو شده یا رمز پنل عوض شده است؛ بینهایت تلاش نکنید. |
429 rate_limited | تا مقدار هدر Retry-After (اگر بود) صبر کنید و دوباره بفرستید. تعداد درخواستها را کم کنید یا از ارسال گروهی استفاده کنید. |
5xx، 503 یا timeout | با فاصلهی رو به افزایش (مثلاً ۱، ۲، ۴ ثانیه و حداکثر چند بار) دوباره بفرستید. در ارسال صورتحساب همان clientRef را بفرستید. |
سایر 4xx | تکرار بیفایده است؛ error.message و field را بخوانید و درخواست را اصلاح کنید. |
سقف نرخ (پیشفرض)
| محدوده | سقف |
|---|---|
| دریافت توکن | ۲۰ درخواست در ۱۰ دقیقه برای هر IP |
| درخواستهای خواندنی | ۱۲۰ درخواست در دقیقه برای هر توکن |
| ارسال صورتحساب | ۶۰ درخواست در دقیقه برای هر توکن |
| ارسال گروهی | ۱۰ درخواست در دقیقه برای هر توکن |
| ثبت و ویرایش شماره اقتصادی | ۳۰ درخواست در ۱۰ دقیقه برای هر توکن |
| کل درخواستها | ۶۰۰ درخواست در دقیقه برای هر IP |
سقفها ممکن است در آینده تغییر کنند؛ برنامهی شما باید با 429 کمی صبر کند و دوباره تلاش کند. فهرست کامل کدهای خطا در مرجع API است.
نکات امنیتی
- رمز و کلید API را در متغیر محیطی یا گنجینهی اسرار سرور نگه دارید، نه در کد یا Git. بدنهی درخواست دریافت توکن و هدر
Authorizationرا در لاگهای خودتان ننویسید. - API را مستقیم از مرورگر یا اپ موبایل صدا نزنید. CORS باز نیست و رمز و کلید نباید دست کاربر نهایی باشد.
- چرخش کلید: در پنل کلید جدید بسازید، برنامهی خود را روی آن ببرید و بعد کلید قدیمی را لغو کنید.
- اعتبار گواهی TLS سرور را در کلاینت خود غیرفعال نکنید.
- برای رهگیری و امنیت، از هر درخواست فقط متد، مسیر (بدون query)، کد پاسخ، مدت پردازش، IP، traceId و clientRef نگهداری میشود. بدنهی درخواست، توکن، رمز و کلید ذخیره نمیشوند.
نمونهی کامل: توکن، ارسال و پیگیری
این نمونهها فقط برای فهم جریان کار هستند. در برنامهی واقعی توکن را نگه دارید و دوباره استفاده کنید، خطاها را طبق جدول بالا مدیریت کنید و رمز و کلید را از تنظیمات امن سرور بخوانید.
Python
import time
import requests
BASE = "https://api.tpinta.com/v1"
# ۱) توکن (در برنامهی واقعی تا پایان اعتبارش نگه دارید و دوباره استفاده کنید)
r = requests.post(f"{BASE}/auth/token", timeout=30, json={
"mobile": "09120000000", "password": "رمز-پنل", "apiKey": "ei_..."})
r.raise_for_status()
H = {"Authorization": "Bearer " + r.json()["data"]["accessToken"]}
# ۲) ارسال صورتحساب. clientRef را از شمارهی فاکتور خودتان بسازید
invoice = {
"clientRef": "INV-2026-000123",
"economicId": 12,
"subject": 1, "pattern": 1, "type": 1, "buyerType": 2,
"buyer": {"tinb": "10101234567"},
"headerExtra": {"setm": 1},
"items": [{"sstid": "1234567890123", "sstt": "خدمات نمونه", "am": 2, "fee": 1000000, "vra": 10}],
}
try:
res = requests.post(f"{BASE}/invoices", json=invoice, headers=H, timeout=30)
except requests.Timeout:
# نمیدانیم ثبت شده یا نه: همین بدنه را با همین clientRef دوباره بفرستید (یا استعلام با clientRef)
raise
body = res.json()
if not body["success"]:
err = body["error"]
print(err["code"], err["message"], err.get("details"))
raise SystemExit(1)
tax_id = body["data"]["taxId"]
# ۳) پیگیری وضعیت نهایی: هر ۳۰ ثانیه، حداکثر حدود ۱۰ دقیقه
for _ in range(20):
time.sleep(30)
s = requests.get(f"{BASE}/invoices/{tax_id}", headers=H, timeout=30).json()["data"]
if s["status"] in ("success", "failed"):
print(s["status"], s.get("referenceNumber"), s.get("message"))
breakC#
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
var http = new HttpClient { BaseAddress = new Uri("https://api.tpinta.com/v1/") };
// ۱) توکن
var tokenRes = await http.PostAsJsonAsync("auth/token",
new { mobile = "09120000000", password = "رمز-پنل", apiKey = "ei_..." });
var tokenDoc = await tokenRes.Content.ReadFromJsonAsync<JsonElement>();
var token = tokenDoc.GetProperty("data").GetProperty("accessToken").GetString();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
// ۲) ارسال صورتحساب
var invoice = new
{
clientRef = "INV-2026-000123",
economicId = 12, subject = 1, pattern = 1, type = 1, buyerType = 2,
buyer = new { tinb = "10101234567" },
headerExtra = new { setm = 1 },
items = new[] { new { sstid = "1234567890123", sstt = "خدمات نمونه", am = 2, fee = 1000000, vra = 10 } }
};
var res = await http.PostAsJsonAsync("invoices", invoice);
var body = await res.Content.ReadFromJsonAsync<JsonElement>();
if (!body.GetProperty("success").GetBoolean()) { Console.WriteLine(body); return; }
// ۳) پیگیری وضعیت
var taxId = body.GetProperty("data").GetProperty("taxId").GetString();
for (var i = 0; i < 20; i++)
{
await Task.Delay(TimeSpan.FromSeconds(30));
var s = await http.GetFromJsonAsync<JsonElement>($"invoices/{taxId}");
var status = s.GetProperty("data").GetProperty("status").GetString();
if (status is "success" or "failed") { Console.WriteLine(s); break; }
}JavaScript (Node.js)
const BASE = 'https://api.tpinta.com/v1'; // فقط روی سرور خودتان (Node.js)، نه در مرورگر
const t = await fetch(BASE + '/auth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ mobile: '09120000000', password: 'رمز-پنل', apiKey: 'ei_...' })
});
const { data } = await t.json();
const H = { Authorization: 'Bearer ' + data.accessToken, 'Content-Type': 'application/json' };
const res = await fetch(BASE + '/invoices', {
method: 'POST', headers: H,
body: JSON.stringify({
clientRef: 'INV-2026-000123', economicId: 12, subject: 1, pattern: 1, type: 1, buyerType: 2,
buyer: { tinb: '10101234567' }, headerExtra: { setm: 1 },
items: [{ sstid: '1234567890123', sstt: 'خدمات نمونه', am: 2, fee: 1000000, vra: 10 }]
})
});
console.log(await res.json());برای امتحان سریع بدون کدنویسی، کالکشن Postman را بگیرید، متغیرهای mobile، password و apiKey را پر کنید و «دریافت توکن» را اجرا کنید؛ توکن خودکار ذخیره میشود.
سؤالات متداول
برای شروع به چه چیزهایی نیاز دارم؟
یک شماره اقتصادی ثبتشده (پیشنهاد میشود اول آزمایشی)، مقداری اعتبار در پنل و یک کلید API که از منوی «کلید API» پنل میسازید. با موبایل و رمز پنل و کلید API توکن میگیرید.
چرا بعد از ارسال، وضعیت success نمیگیرم؟
پاسخ 201 یعنی صورتحساب ثبت و در صف ارسال قرار گرفته است. ارسال به سامانه مودیان و تأیید بعداً و خودکار انجام میشود؛ وضعیت نهایی را با استعلام بگیرید و هر ۱۰ تا ۳۰ ثانیه یکبار بپرسید.
اگر هنگام ارسال timeout شد چه کنم؟
همان درخواست را با همان clientRef و همان بدنه دوباره بفرستید، یا وضعیت را با GET /v1/invoices/by-ref/{clientRef} بپرسید. با clientRef جدید دوباره نفرستید، چون ممکن است دو صورتحساب ساخته شود.
آیا میتوانم API را از مرورگر یا اپ موبایل صدا بزنم؟
خیر. رمز پنل و کلید API نباید دست کاربر نهایی باشد و CORS هم باز نیست. API را فقط از سرور خودتان صدا بزنید.
توکن تا کی اعتبار دارد؟
بهطور پیشفرض ۶۰ دقیقه؛ مقدار دقیق در فیلد expiresIn (ثانیه) میآید. با خطای 401 یکبار توکن جدید بگیرید و همان درخواست را دوباره بفرستید.
مستندات کامل و کالکشن Postman کجاست؟
مرجع کامل همهی مسیرها و فیلدها در api.tpinta.com/docs است و کالکشن آمادهی Postman را هم از همان صفحه میتوانید بگیرید.
آمادهاید وصل شوید؟
کلید API بسازید، توکن بگیرید و اولین صورتحساب را در محیط آزمایشی بفرستید.
تیپینتا سامانهی رسمی سازمان امور مالیاتی نیست. مبالغ و شناسههای داخل نمونهها فرضیاند؛ مقادیر واقعی خودتان را بگذارید.