یکپارچهسازی استعلام چک صیادی در نرمافزار حسابداری و فروش
در نرمافزار حسابداری، استعلام چک صیادی را در لحظه ثبت بگذارید، پاسخ خام را با زمان ذخیره کنید و «پیدا نشد» را از موفقیت و خطای ورودی جدا بخوانید.
اگر نرمافزار حسابداری یا فروش شما چک صیادی ثبت میکند، بهترین جا برای استعلام لحظهٔ ثبت است، نه یک دکمهٔ جدا که کاربر یادش بماند بزند. شناسه را که وارد کرد، فرم باید خودش مشخصات را بیاورد و فیلدهای دستی را پر کند یا ناهمخوانی را نشان دهد.
این مقاله برای توسعهدهندهای است که میخواهد API استعلام چک صیادی را در چنین جریانی بگذارد. بحث ما درباره کد نیست، درباره تصمیمهایی است که اگر اول درست نگیرید بعداً هزینه دارند: چه چیزی ذخیره شود، با خطاها چه شود، و کدام ستون نباید در جدول شما باشد.
ورودی را چطور بگیریم
فقط یک ورودی دارد: شناسهٔ ۱۶ رقمی صیادی، به نام sayadId. قبل از ارسال، سه کار ساده انجام دهید.
- فاصله، خط تیره و کاراکترهای نامرئی را که از کپی پیامک یا PDF میآیند پاک کنید. API هم فاصله و ارقام فارسی را میپذیرد، ولی اگر خودتان پاکسازی کنید، پیام خطا را پیش از ارسال و بدون رفتوبرگشت شبکه به کاربر نشان دادهاید.
- طول را بسنجید. شانزده رقم، نه کمتر نه بیشتر. ورودی نامعتبر در API هزینه ندارد، ولی تجربهٔ کاربر شما را خراب میکند.
- جلوی اشتباه سری و سریال را بگیرید. زیر فیلد یک تصویر کوچک از برگه بگذارید که نشان دهد شناسه کنار کد QR است و همان بالای برگه چاپ میشود.
ورودی دوم لازم نیست. در نسخهٔ فعلی کد ملی صادرکننده برای این استعلام فرستاده نمیشود؛ اگر یکپارچهسازی قدیمیتان هنوز میفرستد، چیزی نمیشکند ولی در نتیجه هم اثری ندارد.
چه چیزی در پایگاه داده ذخیره شود
دو قاعدهٔ من:
- پاسخ را کامل و خام ذخیره کنید، کنار زمان استعلام. مشخصات چک ثابت نیست، یا دستکم تضمینی ندارد که ثابت بماند. اگر فقط نام و تاریخ را در ستونهای خودتان بریزید، سه ماه بعد نمیتوانید بگویید در آن لحظه سامانه چه گفته بود.
- تاریخ سررسید را nullable بگذارید. در پاسخ میتواند خالی باشد. ستونی که
NOT NULLاست یا مقدار پیشفرض صفر میگیرد، یا استعلام را در چنین مواردی با خطا رد میکند؛ هر دو غلطاند.
یک جدول ساده کافی است: شناسه، زمان استعلام، وضعیت (موفق، پیدا نشد، خطا)، پاسخ خام و شناسهٔ requestId که API برمیگرداند. همان requestId موقع پیگیری با پشتیبانی مهم میشود.
سه وضعیت، سه رفتار
رابط کاربری شما باید بین اینها فرق بگذارد:
| وضعیت | یعنی | هزینه | رفتار پیشنهادی |
|---|---|---|---|
| موفق | چک پیدا شد و مشخصات آمد | دارد | مشخصات را پر کن و ناهمخوانی را نشان بده |
not_found | شناسه معتبر ولی چکی ثبت نشده | دارد | پیام «در سامانه پیدا نشد»، بدون تکرار خودکار |
invalid_input | شناسه ساختار درست ندارد | ندارد | کاربر را به همان فیلد برگردان |
not_found با کد HTTP ۲۰۰ و ok: false برمیگردد. اگر کلاینت شما فقط به کد HTTP نگاه کند، «پیدا نشد» را موفق میخواند و فیلدهای خالی را در فرم میریزد. شرط را روی ok بگذارید، نه روی وضعیت HTTP.
خطاهای شبکه و زمانبر شدن را هم جداگانه ببینید: بابت پاسخ نیامدن سرویس مرجع، هزینهای کسر نمیشود، پس تکرار با فاصلهٔ کوتاه (و سقف) بیخطر است. تکرار بیسقف نه.
نمونهٔ کد برای شرط درست
js const res = await fetch(${BASE}/api/v1/sayad-check/, { method: 'POST', headers: { Authorization: Bearer ${process.env.MELLIAPI_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ sayadId }), }); const out = await res.json();
if (out.ok) return save('found', out); if (out.error?.code === 'not_found') return save('not_found', out); if (out.error?.code === 'invalid_input') return askUserToFix(out.error.message); return retryLater(out.requestId); // خطای موقت ```
به کد خطا تکیه کنید و نه به متن پیام، چون متن ممکن است بهتر شود. فیلد source.stale را هم نگه دارید و اگر درست بود، کنار مشخصات چک برچسب «آخرین پاسخ معتبر، در فلان زمان» نشان دهید.
تکرار فراخوان و ثبت دوباره
کاربر دوبار دکمه را میزند، صفحه رفرش میشود، یا یک کارمند دیگر همان چک را وارد میکند. اگر جلوی تکرار را در سمت خودتان نگیرید، چند بار هزینه میدهید. قبل از فراخوان، جدول بالا را با شناسه بخوانید؛ اگر نتیجهٔ تازهای هست، همان را نشان دهید و بپرسید «استعلام دوباره بگیرم؟». فراخوانهای تکراری ممکن است از کش بیایند و source.cached این را میگوید، ولی اتکا به آن برای صرفهجویی، طراحی نیست.
ناهمخوانی را چطور نشان دهیم
مهمترین کار رابط کاربری، نشاندادن ناهمخوانی است. کاربر نام و تاریخ را تایپ کرده، سامانه چیز دیگری گفته. دو ستون کنار هم بگذارید: «آنچه تایپ شد» و «آنچه سامانه گفت» و فقط ردیفهای ناهمخوان را قرمز کنید. اگر همه سبز باشد، فرم ثبت میشود؛ اگر یکی قرمز باشد، ثبت نیازمند تأیید یک نفر دیگر است. جزئیات مقایسه، بهویژه تاریخ، در مقالهٔ مقایسه با برگه آمده است.
تستهایی که باید بنویسید
برای این یکپارچهسازی چهار آزمون ساده کافی است و هرکدام جلوی یک اشتباه رایج را میگیرد:
- پاسخ موفق با تاریخ سررسید خالی، بدون خطا ذخیره میشود.
- پاسخ
not_foundبا HTTP ۲۰۰، در رابط کاربری «موفق» دیده نمیشود. - شناسهٔ پانزدهرقمی هرگز به شبکه نمیرسد.
- دو بار کلیک پشتسرهم، یک فراخوان میسازد.
آزمون پنجم را هم من اضافه میکنم: یک پاسخ با stale: true که برچسب هشدار را نشان میدهد. اغلب فراموش میشود چون در محیط آزمایشی پیش نمیآید.
چکهای دستهای
بعضی شرکتها آخر ماه صدها چک را یکجا ثبت میکنند. دو قاعده: فراخوانها را با تعداد همزمانی محدود (مثلاً پنج تا) بفرستید، و نتیجه هر ردیف را جدا ذخیره کنید تا خطای یک چک، بقیه را متوقف نکند. در پایان، گزارشی بدهید که چند چک موفق، چند چک «پیدا نشد» و چند چک نیازمند تکرار بود. دستهای کردن هزینه را کم نمیکند، فقط سرعت را بالا میبرد.
آنچه این سرویس نمیکند
- رنگ چک را برنمیگرداند. ستون «رنگ» را در جدول خود نگذارید و از این پاسخ پر نکنید.
- وصولشدن را تضمین نمیکند؛ موجودی حساب در پاسخ نیست.
- مسیر انتقال را نشان نمیدهد. برای آن استعلام زنجیرهٔ انتقال سرویس جداست و ورودی بیشتری دارد.
- سابقهٔ برگشتی صادرکننده را بهصورت یک شمارش قابلاتکا نمیدهد؛ برای آن به استعلام چک برگشتی نگاه کنید.
یک نکته دربارهٔ حریم داده
شناسهٔ صیادی و نام صادرکننده دادهای مالیاند. در لاگ برنامهٔ خودتان کل شناسه را ننویسید؛ چهار رقم آخر برای پیگیری کافی است. ما هم در ثبت سفارش، شناسه را پوشانده نگه میداریم و شما هم همین کار را با لاگهایتان بکنید.
خلاصه برای مرور بعدی
برای استعلام چک صیادی در نرمافزار حسابداری: ورودی را پاکسازی کنید، پاسخ خام را با زمان ذخیره کنید، تاریخ سررسید را خالیپذیر بگیرید، not_found را از موفقیت جدا کنید و ناهمخوانی را دو ستونی نشان دهید. بقیه، جزئیات پیادهسازی است. نمونهٔ درخواست و فیلدها در مستندات آمده و تعرفهٔ روز در صفحهٔ تعرفه.
مشخصات ورودی و خروجی در صفحهٔ API استعلام چک صیادی هم آمده است.
وبسرویس مرتبط با این راهنما
API استعلام چک صیادی
مشخصات ثبتشده چک صیادی را پیش از پذیرش ببینید.
راهنماهای مرتبط
پرسش و تجربه کاربران
اگر این راهنما جوابتان را نداد، همینجا بپرسید. پرسشها را تیمملی ایپیآی پاسخ میدهد و هر نظر پیش از انتشار بررسی میشود.
هنوز پرسشی ثبت نشده، اولین نفر باشید.
