<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های میلاد کیان مهر</title><link>https://virgool.ir/feed/@milad.kian</link><description>برنامه نویس، کارشناس ارشد فناوری اطلاعات</description><language>fa</language><pubDate>2026-11-11 10:47:33</pubDate><image><url>https://files.virgool.ir/upload/users/14380/avatar/YWaWep.jpg</url><title>میلاد کیان مهر</title><link>https://virgool.ir/@milad.kian</link></image><item><title>چطور هکرنیوز بلاگ را ساختم</title><link>https://virgool.ir/@milad.kian/چطور-هکرنیوز-بلاگ-را-ساختم-rjb1r6kqvun6</link><description>می‌خواهم داستان یک پروژهٔ کوچک را تعریف کنم که برای خودم خیلی جذاب بود: هکرنیوز بلاگ؛ سایتی که خبرهای داغ Hacker News را هر روز، خودکار، کوتاه و به فارسی منتشر می‌کند. نه ترجمهٔ ماشینی خشک و کلمه‌به‌کلمه، بلکه طوری که انگار یک رفیق فنی کنارت نشسته و می‌گوید «ببین امروز چه اتفاقی افتاده».اول، یک عادت قدیمیسال‌ها برنامه‌نویس بودم و بعدش مدیر یک تیم فنی شدم. در تمام این سال‌ها یک چیز ثابت ماند: هر روز صبح سر زدن به Hacker News. برای من HN مثل روزنامهٔ صبح است؛ هم خبر دارد، هم بحث‌های داغ، هم آدم‌هایی که واقعاً می‌دانند دربارهٔ چه حرف می‌زنند.و همیشه یک حسرت کوچک داشتم: چرا نسخهٔ فارسی‌اش نیست (یا هرچی سرچ کردم اون چیزی که میخواستم پیدا نشد)؟ خیلی از بچه‌های خوب جامعهٔ فنی ما یا وقت ندارند هر روز ده‌ها لینک انگلیسی را بخوانند، یا حوصله‌اش را. یک خلاصهٔ فارسی خوب می‌توانست کلی وقت‌شان را آزاد کند.سه بار شکستوقتی موج هوش مصنوعی و «وایب‌کدینگ» راه افتاد، گفتم وقتش است. نشستم که یک سیستم خودکار ترجمهٔ هکرنیوز بسازم.بار اول شکست خوردم. بار دوم هم. بار سوم هم.هر بار یک جای کار می‌لنگید: یا کیفیت ترجمه افتضاح بود، یا معماری وسط کار به هم می‌ریخت، یا آن‌قدر وصله‌پینه می‌شد که دیگر خودم هم نمی‌فهمیدم چه خبر است. آن موقع ابزارها هنوز به جایی نرسیده بودند که بشود یک سیستم کامل را با آن‌ها بالا آورد، نه فقط یک تکه کد.بار چهارمبار چهارم با Claude Code و مدل Opus 5.5 نشستم پای کار. جالبش این‌جاست که حتی سطح تلاش (effort) را روی بالاترین حالت هم نگذاشته بودم؛ فقط medium.و هستهٔ اصلی کل ایده در کمتر از سی دقیقه ساخته شد. هنوز هم وقتی به آن فکر می‌کنم برایم عجیب است.البته بگذارید صادق باشم: سی دقیقه برای ساختن «ایده» بود، یعنی سیستمی که خبر را بخواند، انتخاب کند، ترجمه کند و منتشر کند. بعدش سه چهار روز نشستم و صیقلش دادم؛ همان کاری که هر برنامه‌نویسی می‌داند همیشه بیشتر از ساختن طول می‌کشد. فرقش این بود که این بار صیقل دادن هم سریع پیش می‌رفت.الان چه کار می‌کند؟اگر کنجکاوید زیر کاپوت چه خبر است، این خلاصه‌اش است:هر نیم ساعت داغ‌ترین خبرهای هکرنیوز خوانده می‌شود. اول یک درخواست، فهرست خبرهای برتر را می‌گیرد و بعد یک fetcher آن‌ها را یکی‌یکی (و هشت‌تا هشت‌تا موازی) بار می‌کند.هوش مصنوعی مهم‌ترین‌ها را انتخاب می‌کند، ترجمه و خلاصه می‌کند و برچسب می‌زند.خبرها یکی‌یکی و با فاصله منتشر می‌شوند، نه یک‌جا و سیل‌وار. سایت، تلگرام و X هر کدام صف، ساعت کاری و آستانهٔ خودشان را دارند.هر صبح یک پادکست کوتاه از مهم‌ترین خبرهای دیروز ساخته می‌شود، با ویدیویی که صحنه‌هایش دقیقاً با مکث‌های واقعی گوینده هماهنگ است.صفحهٔ اول سایت استوری‌هایی شبیه اینستاگرام دارد، با انیمیشن مکعب سه‌بعدی بین روزها که دنبال انگشت‌تان می‌آید. (بله، این یکی را فقط چون دلم خواست ساختم)کل سایت به شکل استاتیک خروجی گرفته می‌شود و روی فضای ابری می‌رود. پس سریع است و سرور اصلی هیچ‌وقت جلوی بازدیدکننده نیست.یک پنل مدیریت هم هست که همه‌چیز از آن‌جا تنظیم می‌شود.چند داستان کوچک از مسیرویدیو ۱۶ دقیقه‌ای که شد ۱ دقیقه. ساختن ویدیوی روزانه روی سرور اول ۱۶ دقیقه طول می‌کشید. راه‌حل؟ به جای رندر کردن انیمیشن فریم‌به‌فریم، صحنه‌ها به شکل تصویرهای ثابتِ از پیش ساخته‌شده کنار هم چیده شدند. نتیجه: حدود یک دقیقه.توییتی که لینک داشته باشد، گران است. وقتی انتشار در X را اضافه کردیم، فهمیدیم X برای پستی که لینک داشته باشد حدود ۱۳ برابر بیشتر پول می‌گیرد. برای همین پیش‌فرض شد توییت بدون لینک. یک سقف سخت‌گیرانه هم گذاشتیم، و اگر موجودی حساب تمام شود، انتشار خودش متوقف می‌شود و خبرها در صف می‌مانند.جستجو در سایتی که سرور ندارد. وقتی سایت کاملاً استاتیک باشد، اولین سؤال این است که «جستجو را چه کنیم؟» نه دیتابیسی هست که کوئری بزنی، نه سروری که جواب بدهد. سرویس‌های جستجوی آماده هم یا پولی‌اند یا یک وابستگی خارجی دیگر. راه‌حل Pagefind بود. هر بار که سایت خروجی گرفته می‌شود، Pagefind همهٔ صفحه‌های خبر را می‌خواند و یک ایندکس جستجو می‌سازد که کنار بقیهٔ فایل‌ها روی فضای ابری آپلود می‌شود. جستجو کاملاً داخل مرورگر خواننده انجام می‌شود، و فقط تکه‌هایی از ایندکس دانلود می‌شوند که برای همان کلمه لازم‌اند؛ نه کل ایندکس. چند ریزه‌کاری هم دارد: عنوان خبر وزن بیشتری از متن دارد، عنوان انگلیسی اصلی هم ایندکس شده (پس «Rust» را هم پیدا می‌کند، نه فقط «راست» را)، دکمه‌های اشتراک و بنرها از ایندکس بیرون گذاشته شده‌اند تا نتیجه‌ها شلوغ نشوند، و برچسب‌ها به شکل فیلتر قابل استفاده‌اند. صفر سرور، صفر هزینه، و سریع.صفحهٔ ۷ در گوگل! همین امروز دیدم وقتی «هکرنیوز» را گوگل می‌کنم، صفحهٔ ۲ یا ۷ سایت بالا می‌آید، نه صفحهٔ اصلی. اولین فکرم این بود که canonical را خراب کرده‌ایم و باید همه را به صفحهٔ اصلی وصل کنیم. پرسیدم و جواب این بود که نه، canonical درست است و اتفاقاً وصل کردن همه به صفحهٔ اصلی کار را بدتر می‌کند. مشکل این بود که صفحه‌های عمیق محتوای ثابت‌تری دارند. راه‌حل این شد: صفحه‌های ۳ به بعد noindex, follow بگیرند و از sitemap هم بیرون بروند.چطور با هوش مصنوعی حرف می‌زنم؟این بخش شاید برای خیلی‌ها جالب‌ترین قسمت باشد، چون همه می‌پرسند «پرامپتت چی بود؟»راستش را بخواهید، هیچ پرامپت جادویی‌ای در کار نیست. من با Claude درست مثل یک همکار ارشد حرف می‌زنم. کوتاه، خودمانی، گاهی با غلط تایپی، و بیشتر وقت‌ها به شکل سؤال، نه دستور:«فهمیدم با اضافه شدن هر پست جدید، چون صفحه‌بندی جابه‌جا می‌شود، همهٔ صفحه‌ها باید دوباره رندر شوند… درست می‌گویم؟ بهترین روش برای جلوگیری از این چیست؟ بگو.»چند چیز را از این مسیر یاد گرفتم:اول بپرس، بعد بگو بساز. خیلی وقت‌ها چیزی که فکر می‌کنم مشکل است، مشکل نیست. ماجرای canonical دقیقاً همین بود. اگر مستقیم گفته بودم «همه را به صفحهٔ اصلی وصل کن»، یک مشکل واقعی ساخته بودم.راه فرار بگذار. جملهٔ «اگر ایدهٔ خوبی نیست بگو» خیلی مهم است. به مدل اجازه می‌دهد بگوید «نه، این کار را نکن»، به جای این‌که چشم‌بسته کاری را انجام دهد.کارهای کوچک و پشت‌سرهم. هر تغییر یک کامیت است. ۳۵ کامیت در چهار روز. هر کدام یک قدم کوچک و قابل‌فهم.تست، تست، تست. هر تغییری که داده می‌شود با تست همراه است. من وقتم را صرف خواندن کد خط‌به‌خط نمی‌کنم. صرف این می‌کنم که مطمئن شوم تست‌ها چیز درستی را می‌سنجند.تصمیم با من است. هوش مصنوعی پیشنهاد می‌دهد، توضیح می‌دهد، حتی مخالفت می‌کند، اما این‌که سایت چه شکلی باشد و چه کاری بکند را من تعیین می‌کنم.و یک اعتراف: متن صفحهٔ «دربارهٔ ما» سایت را هم من ننوشته‌ام. از روی حرف‌های من نوشته شد. این مقاله هم همین‌طور 🙂 فقط داستانش مال من است.حرف آخربه‌عنوان کسی که سال‌ها کد زده و تیم فنی اداره کرده، حسم این است که برنامه‌نویسی به شکلی که می‌شناختیم دارد تمام می‌شود. ولی کار تمام نمی‌شود، شکلش عوض می‌شود. چیزی که الان ارزش دارد این است که بدانی چه می‌خواهی بسازی، چرا، و بتوانی درست سؤال بپرسی.من سه بار شکست خوردم. بار چهارم ابزار بهتر شده بود، ولی من هم یاد گرفته بودم چطور با آن کار کنم.اگر شما هم یک ایدهٔ قدیمی در کشوی ذهن‌تان دارید که چند بار سراغش رفته‌اید و نشده، شاید الان وقت بار چهارم است.از هوش مصنوعی استفاده کنید، خلاق باشید و از آن لذت ببرید. ✌️</description><category>میلاد کیان مهر</category><author>میلاد کیان مهر</author><pubDate>Tue, 20 Oct 2026 19:47:19 +0330</pubDate></item><item><title>مدیریت پورت های داکر با Iptables</title><link>https://virgool.ir/@milad.kian/docker-compose-iptables-port-block-بلاک-کردن-پورت-داکر-با-iptable-f58wuwbwxdy7</link><description>زمانی که با استفاده از docker یا docker-compose یک پورتی رو expose میکنید، دیگه شاید به راحتی نتونید اون ها رو با firewall های لینوکس مثل iptables محدودش کنید و هرکسی میتونه بهشون وصل بشه. با دوتا کامند خیلی ساده روی Iptables میتونید پورت های داکر رو محدود کنید.مدیریت پورت های داکر با استقاده از firewall iptables سعی کنید در مورد iptables بخونید و ازش نترسید. هدف من آموزش iptables نیست و پیشنهاد میکنم حتما کمی در موردش سرچ کنید.فرض کنید که با داکر کامپوز یک دیتابیس postgres اجرا کردید و پورتش رو به 9999 مپ کردیدpostgres:&#xA;image: &#39;postgres:13&#39;&#xA;ports:&#xA;     - &#34;9999:5432&#34;حالا میخواید که پورت ۹۹۹۹ رو برای یک یا چند آی پی خاص محدود کنید. اگر سعی کنید که پورت ۹۹۹۹ یا ۵۴۳۲ رو به روش های معمول iptable ببندید عملا موفق نخواهید شد. دلیلش رو پایین تر توضیح دادم. برای این کار دوتا مرحله داریم:۱- ابتدا آی پی هایی که اجازه دارند به پورت شما وصل بشن رو مشخص کنید۲-کلا اون پورت رو برای هر آی پی دیگه ای ببندید اجازه وصل شدن به یک پورت برای یک آی پیاین کامند به آی پی 8.8.8.8 اجازه میده که به پورت 9999 شما متصل بشهiptables -I DOCKER-USER -i eth0 -s 8.8.8.8 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j ACCEPTشما میتونید برای آی پی های مختلف و پورت های مختلف هر چند بار این دستور رو وارد کنیدتوضحیات:-I DOCKER-USERداکر یک سری chain درست میکنه که رول های خودش رو داخل اون قرار میده ولی با هر بار ریست شدن داکر اون ها تغییر میکنن. برای همین DOCKER-USER رو درست کرده که شما دستورات خودتون که مربوط به داکر هستند رو داخل اون ست کنید تا داکر اون ها رو خراب نکنه-i eth0این آپشن میگه هرکس از اینترفیس eth0 اومد این رول رو براش اجرا کن. پس دقت کنید اگر اسم اینترفیس شما چیز دیگه ای هست این مقدار رو تغییر بدید. ما کاری با اینترفیس های دیگه نداریم و در واقع هدفمون محدود کردن ورودی های خارج از ماشینمون هست-s 8.8.8.8مقدار آی پی مورد نظر ما رو نشون میده که باید با مقدار خودتون عوضش کنید. اینجا میتونید حالت های دیگه مثل رنج و چند آی پی و .. هم بدید-p tcpاین یعنی داریم در مورد پروتکل tcp صحبت میکنیم-m conntrack --ctorigdstport 9999خب اینم اصل داستان که داره پورت ۹۹۹۹ رو مشخص میکنه. شاید بگید که چرا --dport رو استفاده نکردم. دلیلش مکانزیم مپ کردن پورت های داکر هست که اگر از این آپشن استفاده کنید مجبورید پورت ۵۴۳۲ رو محدود کنید. اون وقت اگر دوتا پسترگس داشته باشید دسترسی به هردو محدود میشه-j ACCEPTخب این هم که مشخص داره کانکشن رو قبول میکنهبستن پورت برای همهاین کامند پورت شما رو برای همه میبنده ولی چون کامند قبلی رو زودتر وارد کردید اگر آی پی شما با قبلی مچ بشه اجازه ورود داره.iptables -A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j DROPتفاوتش با بالایی اینه که میگه: هرکس از اینترفیس eth0 اومد و خواست از طریق tcp به پورت 9999 متصل بشه رو drop کن. پس اگر قبل از این رولی داشته باشید که اجازه ورود رو بده، آی پی شما با این رول مواجه نمیشه. کسی به این رول میرسه که رول های دیگه رو رد کرده باشه و باهاشون مچ نشده باشه.دقت کنید که این دوتا رول باید بالای DOCKER-USER قرار بگیرند! پایین تر توضیح دادم چطوری این کار رو بکنید.ذخیره کردن دستورت Iptablesشما باید حتما از دستورات خودتون بکاپ بگیرید. اونم به روش خیلی خیلی ساده. من حتی از این روش برای ادیت رول ها هم استفاده میکنم.با دستور زیر میتونید لیست تمام رول های خودتون رو داخل یک فایل بریزید:sudo iptables-save &gt; iptables.txtشما میتونید این فایل رو باز کنید و تغییرات خودتون رو داخلش وارد کنید یا ترتیب اون ها رو تغییر بدید.با دستور زیر هم میتونید رول های ذخیره شده رو لود کنید:sudo iptables-restore &lt; iptables.txtنکته نهایی:دقت کنید که خود داکر داخل DOCKER-USER یک رول داره و دو رول شما باید بالای اون قرار بگیره. میتونید با ویرایش فایلی که درست کردید ترتیب اون رو تغییر بدید:-A DOCKER-USER -s 8.8.8.8/32 -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j ACCEPT-A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j DROP-A DOCKER-USER -j RETURN</description><category>میلاد کیان مهر</category><author>میلاد کیان مهر</author><pubDate>Thu, 05 May 2022 02:40:15 +0430</pubDate></item><item><title>ماژول اتصال به درگاه های پرداخت ایرانی برای لاراول (لاراپی)</title><link>https://virgool.ir/laravel-community/ماژول-اتصال-به-درگاه-های-پرداخت-ایرانی-برای-لاراول-لاراپی-v9rjfubyjpbi</link><description>لاراپی ماژول لاراول برای پرداخت درگاه های بانکی ایرانیتقریبا بزرگترین مشکلی که تمام برنامه نویس ها حداقل یک بار در طول مدت کارشون باهاش مواجه میشن، اتصال به درگاه های پرداخت هستش. هر بانکی روش خاص خودش رو برای استفاده از درگاهش داره و معمولا مستندات هم خیلی دقیق و به روز نیستند. از طرف دیگه هیچ امکان تست هم جز روی سروری که به بانک معرفی کردید وجود نداره. بدترین قسمت داستان هم زمانیه که پروژه آماده نیست و هنوز درگاه پرداخت ندارید و باید کد پرداخت رو آماده کنید! حالا ما اومدیم یک پکیج برای لاراول آماده کردیم که با کمترین زمان بتونید پرداخت آنلاین رو به پروژه خودتون استفاده کنید و اون را با  banktest.ir تست کنید.بانک تست چیه؟ سایت بانک تست تمام درگاه های پرداخت رو شبیه سازی کرده و می تونید به راحتی به جای اتصال به درگاه واقعی از بانک تست استفاده کنید. لاراپی هم این قابلیت رو پیاده سازی کرده و در زمان توسعه به صورت پیش فرض به بانک تست وصل خواهد شد.همین ابتدا بگم که پروژه های مشابه برای لارول وجود داره ولی ما سعی کردیم این ماژول رو رو خیلی به روز تر و با معماری دقیق تر پیاده سازی کنیم. استفاده از ساختار Morph در پایگاه داده و Trait باعث شده خیلی راحت و مثل ماژول های Spatie  بتونید این ماژول رو به پروژه اضافه کنید.نصبپروژه به صورت متن باز روی گیت هاب قرار گرفته و میتونید علاوه بر مشاهده کد و مستندات ما رو در توسعه لاراپی هم کمک کنید. همراه لاراپی یه پکیج دیگه استفاده شده به اسم XLog که یه سری قابلیت جدید به لاگ لاراول اضافه میکنه.با این دستور آخرین نسخه از لاراپی رو به composer پروژه اضافه کنید.composer require tartan/laravel-online-paymentاین دوتا کلاس رو به config/app.php انتهای قسمت providers اضافه کنید:Tartan\Larapay\LarapayServiceProvider::class,&#xA;Tartan\Log\XLogServiceProvider::class,این دو خط هم به قسمت alias همون فایل اضافه کنید:&#39;Larapay&#39; =&gt; Tartan\Larapay\Facades\Larapay::class,&#xA;&#39;XLog&#39;    =&gt; Tartan\Log\Facades\XLog::class,لاراپی یک سری assets داره که باید با این دستور اون ها رو به پروژه خودتون اضافه کنید:php artisan vendor:publish --provider=&#34;Tartan\Larapay\LarapayServiceProvider&#34;بعد این دستور رو اجرا کنید تا دیتابیس لاراپی به اسم larapay_transactions توی دیتابیس ساخته بشه:php artisan migrateتنظیماتاگر مراحل نصب رو تکمیل کرده باشید، فایل larapay.php به پوشه config پروژه اضافه شده. تمام کانفیگ های لاراپی توی این فایل موجوده و ما بخشی از اون رو توضیح میدیم:برای اینکه به بانک تست وصل بشید باید حالت development و درصورتی که اتصال به بانک حالت production رو برای LARAPAY_MODE تو فایل .env انتخاب کنید#Banktest Mode&#xA;LARAPAY_MODE=development&#xA;#Producation Mode&#xA;LARAPAY_MODE=productionاطلاعات بانک هم به این صورت باید به .env اضافه کنید. این پارامتر ها رو وقتی از بانک درگاه  یا از بانک تست اکانت گرفتید در اختیار دارید. تمام این تنظیمات داخل larapay.php هستند.  دو نمونه بانک سامان و ملت این شکلی هستند:&#xA;SAMAN_MERCHANT_ID=bmcf****&#xA;SAMAN_MERCHANT_PASS=98221***&#xA;&#xA;MELLAT_USERNAME=user***&#xA;MELLAT_PASSWORD=80714***&#xA;MELLAT_TERMINAL_ID=747ساخت callback route بانکبعد از برگشت کاربر از بانک نیاز به یک route دارید و اون رو هم باید به بانک اعلام کنید که بعد از عملایت پرداخت کاربر روی اون route به سایت شما برگرده تا شما از وضعیت پرداخت با خبر بشید. برای این کار یک متد در کنترلر دلخواهتون بنویسید و براش یک route داخل مسیر route/web.php بسازید و یک اسم براش انتخاب کنید. به عنوان مثال:Route::any(&#39;payment/callback&#39;, &#39;YourController@handleCallback&#39;)-&gt;name(&#39;payment.callback&#39;);بعد از اون اسم route خودتون رو به .env اضافه کنید:LARAPAY_PAYMENT_CALLBACK=payment.callbackبا این کار لاراپی متوجه میشه که زمانی ارسال به بانک باید کدوم route رو به عنوان callback به بانک معرفی کنه. شما میتونید چندتا route مختلف داشته باشید (مثلا بانک ها رو تفکیک کنید) و زمان ارسال کاربر به بانک route مختلفی رو استفاده کنید ولی این تنظیم به صورت پیش فرض استفاده میشه.استفادهآماده سازی مدلشما باید یک مدلی داشته باشید که پرداخت برای اون مدل انجام میشه. مثلا پروژه شما یک مدلی به اسم سفارش داره که قرار برای اون سفارش پرداخت انجام بشه. یا اینکه مدل کاربر میتونن اکانت خودش رو شارژ کنه که تو این حالت User  میشه مدلی که قرار پرداخت براش ثبت بشه. برای این کار برای trait Payable تو کلاس مدلتون استفاده کنید. همچنین اگر سفارشتون مدل محاسبه قیمت ثابت داره، میتونید با پیاده سازی getAmount قیمتش رو به لاراپی برگردونید. درصورتی که قیمت مشخصی ندارید نیازی به این کار نیست. برای مثال:use Tartan\Larapay\Payable;&#xA;&#xA;class Order extends Model &#xA;{&#xA;    use Payable;&#xA;&#xA;    public function getAmount(){&#xA;        return intval($this-&gt;amount) * 10;&#xA;    }   &#xA;&#xA;}ساخت تراکنشزمانی که کاربر شما اقدام به پرداخت میکنه، باید برای اون یک تراکنش ثبت کنید. مثلا کاربر سفارش خودش رو انتخاب میکنه و گزینه پرداخت رو میزنه. شما ابتدا سفارش رو پید میکنید و مثل مراحل زیر اقدام به ایجاد یک تراکنش می کنید:use Tartan\Larapay\Models\Enum\Bank;&#xA;&#xA;class BankController extends Controller&#xA;{&#xA;    public function index()&#xA;{&#xA;    //your logic and prepare your order&#xA;    // ...&#xA;&#xA;    //if you implement getAmount() method you can set amount to null&#xA;    $amount = 1200000;  //Rial at least 1000 &#xA;    //order or user description&#xA;    $description = &#39;I pay my order with Larapay &lt;3&#39;;&#xA;    //some additional data that you need store on transaction&#xA;    $additionalData = [];&#xA;    //create transaction &#xA;    $transaction = $order-&gt;createTransaction(Bank::MELLAT, $amount, $description, $additionalData);&#xA;    //auto submit bank form and transfer user to gateway&#xA;$autoSubmit = true;&#xA;//callback route name. if you set it on your .env file you can set this to null&#xA;$callbackRouteName = &#39;payment.callback&#39;;&#xA;//adapter config&#xA;$adapterConfig = [];&#xA;//generate bank form&#xA;$form = $transaction-&gt;generateForm($autoSubmit, $callbackRouteName, $adapterConfig);&#xA;    }&#xA;}شما ابتدا برای $order یک تراکنش میسازید. بعد از تراکنشتون میخواید که فرم بانک براتون درست کنه و بهتون برگردونه. فرم ارسال به بانکاگر دقت کرده باشید تمام سایت ها قبل از ارسال شما به بانک صفحه ای به شما نشون میدن که درحال انتقال به بانک هستید. شما هم باید همچین صفحه ای رو درست کنید و فرمی که تو مرحله قبل درست کردید رو داخل اون نشون بدید. پارامتر autoSubmit تو مرحله قبل مشخص میکنه که فرم اتوماتیک به سمت بانک پست بشه و اگر false باشه کاربر حتما باید دکمه انتقال به بانک رو بزنه.داخل فایل view خودتون می تونید فرم رو این شکلی نمایش بدید:&lt;div&gt;&#xA;    {!! $form !!}&#xA;&lt;/div&gt;اگر دوست داشتید که فرمت فرم خروجی رو تغییر بدید میتونید از این مسیر نمونه فرم بانک خودتون رو عوض کنید: resources/views/vendor/larapyبازگشت از بانکبعد از اتمام مرحله پرداخت، کاربر به سمت route که در ابتدا ساخته بودیم هدایت میشه و اطلاعات تراکنش هم به این مسیر ارسال میشه. کاری که تو این مرحله می کنیم تایید وضعیت پرداخت هست. اگر تایید تراکنش با Exception رو به رو بشه یعنی پرداخت موفق نبوده و اگر هم که نه تراکنش در جواب اون به شما برمیگرده و از اون میتونید به مدل برسید:use Illuminate\Http\Request;&#xA;use Tartan\Larapay\Facades\Larapay;&#xA;&#xA;class YourController extends Controller&#xA;{&#xA;    public function handleCallback(Request $request)&#xA;    {&#xA;         try{&#xA;            $adapterConfig = [];&#xA;            $transaction = Larapay::verifyTransaction($request, $adapterConfig);&#xA;            $order = $transaction-&gt;model;&#xA;            //transaction done. payment is successful         &#xA;         } catch (\Exception $e){&#xA;            // transaction not complete!!!&#xA;            // show error to your user&#xA;         }&#xA;    }&#xA;}بعد از اینکه تراکنش با موفقیت انجام شد حالا باید سرویس خودتون رو به مشتری ارائه کنید. مثلا سفارشش رو به حالت پرداخت شده دربیارید. در صورتی که موفق به این کار نشدید، در صورتی که بانک شما قابلیت بازگشت وجه رو داشته باشه می تونید از این روش پول رو به کاربر برگردونید:$transaction-&gt;reverseTransaction();متد هامدلی که Paybel اضافه شده یکسری متد داره. برای مثال:$order-&gt;transactions` : get all transactions of this model&#xA;$order-&gt;accomplishedTransactions`: get all accomplished transactions&#xA;$order-&gt;isPaid()`: return true if this model has at least one accomplished transaction&#xA;$order-&gt;paidAmount()`همچنین تراکنش هم یکسری متد دارن که میتونید تو پروژه استفاده کنید:$transaction-&gt;model`: return the model that create this transaction. for example `$order`&#xA;$transaction-&gt;reverseTransaction()`: reverse transaction and get back money to user. (if bank support reverse transaction)&#xA;$transaction-&gt;generateForm($autoSubmit = false, $callback = null)`: generate bank transfer form&#xA;$transaction-&gt;gatewayHandler()`: get gatewayHandler for advance use.کلام آخرتلاش ما این بوده که بتونیم ماژولی رو درست کنیم که تمام مشکلاتی که دربارش صحبت کردیم رو حل کنه. لاراپی در خیلی از پروژه ها در حاله استفاده هست و تراکنش های میلیونی داره. در صورتی که پیشنهادی دارید خوشحال میشیم روی گیت هاب پروژه با ما درمیون بذارید.</description><category>میلاد کیان مهر</category><author>میلاد کیان مهر</author><pubDate>Sun, 31 Oct 2021 18:24:25 +0330</pubDate></item><item><title>دسترسی به گیت(gitlab) از طریق Proxy</title><link>https://virgool.ir/Software/gitlab-y3ndheokrqdr</link><description> gitlab.comخبر بدی که چند هفته پیش بهش برخوردیم مهاجرت Gitlab.com از سرویس مایکروسافت آژر به سرویس ابری گوگل بود. البته این خبر تنها برای ما و چندتا کشور مثل کره شمالی و کریمه و ... خبر بدی محسوب میشد. حالا چرا این خبر بده؟  از زمان مهاجرت دسترسی به پروژه هامون تقریبا داره گرفته میشه و باید پروژه هامون رو به سرویس مشابه دیگه ای منتقل کنیم یا مثل تمام سرویس های دیگه که تو ایران عزیزمون در دسترس نیست از proxy استفاده کنیم و تحریم رو دور بزنیم!راه حلساده ترین راه حل اینه که هر برنامه ای که کامپیوتر شما رو از فیلتر رد میکنه اجرا کنید و از گیت لب استفاده کنید ولی این کار خیلی برای من راحت نبود. من دوست نداشتم تمام کامپیوترم رو proxy کنم و تصمیم گرفتم راه حل خودم رو اینجا بنویسم.۱- راه اندازی Socks5اگر خودتون از هر طریقی دسترسی به Socks5 دارید دیگه نیازی به این تنظیمات نیست و  به مرحله بعدی برید.من از طریق یک سرور لینوکسی که خارج از ایران دارم به راحتی تونستم با استفاده از ترمینال و این تنظیمات روی کامپیوتر خودم یه Socks5 درست کنم:ssh -D 1080 -N -C username@serverدستور بالا یه Ssh Tunnel برای من درست میکنه و تمام اطلاعات که از کامپیوتر من به پورت ۱۰۸۰ میره رو از سرور خارج از ایران من رد میکنه. تنظیماتی هم که استفاده کردم به این معنی هستند:پارامتر -D برای بایند کردن پورت ۱۰۸۰ کامپیوتر خودم.پارامتر -N باعث میشه روی سرور من هیچ دستوری اجرا نشه و فقط به عنوان Proxy استفاده بشه.پارامتر -C تمام اطلاعات رفت و برگشت بین من و سرور رو فشرده میکنه.پارامتر username نام کاربری یا همون یوزر سرورم هستش.پارامتر server هم آی پی سرور یا اسم دومین سرور هستش.  مثلا google.com.پارامتر های username و server رو تو دستور بالا با اطلاعات خودتون تغییر بدید و توی ترمینال اجراش کنید. بعد از اجرا پسورد سرور رو وارد کنید و ترمینال رو نبندید چون proxy شما از کار میافته. ۲- تنظیمات git proxy برای httpsبرای استفاده از گیت میتونید از دوحالت https یا ssh استفاده کنید. برای اینکه بفهمید الان دارید از کدوم استفاده میکنید، کافیه یه نگاه به تنظیمات گیت پروژه بندازید. برای این کار فایل تنظیمات رو با یه ویرایش گر باز کنید. من از داخل پروژه با vi این کار رو کردم:vi .git/config چیزی که باید دنبالش بگردید [&#34;remote &#34;origin] یا هر اسمی دیگه که شما به عنوان origin ازش استفاده می کنید. دو حالت ممکنه وجود داشته باشه. حالت اول به صورت https:[remote &#34;origin&#34;]&#xA;        url = https://gitlab.com/milad/milad.git&#xA;        fetch = +refs/heads/*:refs/remotes/origin/*حالت دوم به صورت ssh:[remote &#34;origin&#34;]       &#xA;        url = git@gitlab.com:milad/milad.git&#xA;        fetch = +refs/heads/*:refs/remotes/origin/*اگر از حالت اول استفاده میکنید کار خیلی سادست. دستور زیر رو وارد کنید تا تمام git شما در حالت https از proxy که ایجاد کردید رد بشه:git config --global https.proxy &#39;socks5://127.0.0.1:1080&#39;یا میتونید با یک ویرایشگر اون رو به تنظیمات گیت خودتون اضافه کنید:vi ~/.gitconfigبعد اطلاعات پروکسی رو  به تنظیمات اضافه کنید و فایل رو ذخیره کنید: [https]&#xA;        proxy = socks5://127.0.0.1:1080هر موقع پشیمون شدید میتونید این تنظیمات رو پاک کنید و تمام. مثل روز اول از گیت استفاده کنید. ۳- تنظیمات git proxy برای sshاگر آدرس origin شما با git@gitlab شروع میشه پس شما دارید از حالت ssh استفاده میکنید. برای اینکار کافی تنظیمات ssh خودتون رو ویرایش کنید و تنظیمات رو بهش اضافه کنید.با استفاده از ویرایشگر فایل زیر رو باز کنید:vi ~/.ssh/configتنظیمات زیر رو بهش اضافه کنید و اون رو ذخیره کنید:Host gitlab.com&#xA;    User     git&#xA;    ProxyCommand    nc -x localhost:1080 %h %pتو این حالت هم اگر خواستید این تنظیمات رو پاک کنید و به حالت اولیه برگردید.امیدوارم یه روزی همه به اینترنت آزاد دسترسی داشته باشیم!تمام.</description><category>میلاد کیان مهر</category><author>میلاد کیان مهر</author><pubDate>Sun, 05 Aug 2018 13:33:44 +0430</pubDate></item></channel></rss>