<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های امید پاکدل</title>
        <link>https://virgool.io/feed/@pakdel</link>
        <description>توسعه دهنده نرم افزار</description>
        <language>fa</language>
        <pubDate>2026-06-17 13:10:13</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/224994/avatar/sx4YQA.jpg?height=120&amp;width=120</url>
            <title>امید پاکدل</title>
            <link>https://virgool.io/@pakdel</link>
        </image>

                    <item>
                <title>تفاوت Transient, Scoped و Singleton در تزریق وابستگی ( Dependency Injection ) دات نت کور</title>
                <link>https://virgool.io/@pakdel/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-transient-scoped-%D9%88-singleton-%D8%AF%D8%B1-di-%D8%AF%D8%A7%D8%AA-%D9%86%D8%AA-%DA%A9%D9%88%D8%B1-lc1aam6fcurh</link>
                <description>سلام، تو این پست میخوام به ساده ترین شکل ممکن فرق بین این سه نوع service lifetime رو بگم که چجوری کار میکنه.وقتی که یک سرویس رو داریم register میکنیم، باید نوع lifetime رو مشخص کنیم :Singletonاین سرویس ها کلا یک بار و همون ابتدا ساخته میشن و برای کلِ سیستم از همون instance استفاده میشه. چون یکبار ساخته میشن و از همون instance در همه جای اپلیکیشن استفاده میشه، مصرف منابع مناسبی دارند.Transientسرویسی که با این نوع ریجستر بشه، هر بار که اون سرویس درخواست بشه، یه instance ازشون ساخته میشه. چون با هر ریکوئست مجدد ساخته میشن مموری و منابع بیشتری مصرف میکنن و میتونن روی پرفورمنس تاثیر بذارن.Scopedبا هر درخواست سمت وب سرویس، یه instance ازشون ساخته میشه، یعنی اگر یه سرویسی رو چند جا بخوایم استفاده کنیم از همون instance ای که همون ابتدای درخواست ساخته شده استفاده میشه. مختصرا یعنی همون singleton اما داخل یک ریکوئست بجای کل اپلیکیشن.حالا برای مفهوم بهتر یک مثال رو از خودِ مایکروسافت میریم جلو تا بیشتر جا بیفته. یک کنسول اپلیکیشن با دات نت کور ۳ به بعد میسازیم.یک اینترفیس میسازیم که فقط یک id داشته باشه.حالا به ترتیب برای اون نوع lifetime هایی که گفتیم اینترفیس میسازیم.یک کلاس میسازیم تا عملیات تولید Guid رو انجام بده.با ساختن این کلاس تمام اینترفیس هایی که ساختیم هم مقادیرشون پر میشه.حالا یک سرویس مینویسیم که تمام اینترفیس هامون رو نیاز داشته باشه.اگه تو پروژتون این موارد پایین وجود نداشت حتما اون هارو اضافه کنید:Microsoft.Extensions.DependencyInjectionMicrosoft.Extensions.Hostingحالا نوبت ریجستر کردن سرویسمونِ که ببینیم چطوری کار میکنه، کلاس Program.cs رو به این شکل تغییرش میدیم.تو اینجا اومدیم میگیم بیا سرویس رو Call کن، با دوتا Scope متفاوت ( ابتدای اون متود ExemplifyScoping یه Scope جدید میسازیم.) و دوتا ریکوست متفاوت که قشنگ مشخص باشه چه اتفاقی میفته.خب همینطوری که میبینید تو عکس Id هایی که تولید شدن برای Singleton همیشه یکی هستند. ما دوتا Scope ساختیم اما همونطوری که قبلا گفتم برای کل اپلیکیشن یکی هستند. سرویسی که با Transient ریجستر شده بود همیشه متفاوت هست، چون با هر ریکوئست ساخته میشه. و سرویسی که با Scoped ریجستر شده بود فقط با تغییر Scope ساخته میشه.در نهایت کد های بالا اینجاست :)امیدوارم این پست براتون مفید باشه، اگر تو بهبود مطلب هم نظری داشتین خوشحال میشم بدونم :)</description>
                <category>امید پاکدل</category>
                <author>امید پاکدل</author>
                <pubDate>Tue, 21 Sep 2021 20:12:22 +0430</pubDate>
            </item>
                    <item>
                <title>پیاده سازی درگاه پرداخت بانک ملی (سداد) در پایتون</title>
                <link>https://virgool.io/@pakdel/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%AF%D8%B1%DA%AF%D8%A7%D9%87-%D9%BE%D8%B1%D8%AF%D8%A7%D8%AE%D8%AA-%D8%A8%D8%A7%D9%86%DA%A9-%D9%85%D9%84%DB%8C-%D8%B3%D8%AF%D8%A7%D8%AF-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-d0j1ldh2oooq</link>
                <description>عکس از گوگلسلام، تو یکی از پروژه ها که با پایتون و جنگو رست بود قرار بود درگاه پرداخت پیاده سازی کنم که یکم دردسر داشت چون که خود بانک چیزی نداشت براش و پکیج اقای زاهدی که تو گیت هابشون هم بود اون چیزی نبود اما خیلی کمکم کرد.یادتون نره اگر خواستین ازین درگاه پرداخت استفاده کنین حتما علاوه بر درگاه پرداختی که برای خودتون میگیرین یه درگاه پرداخت تست هم بگیرین. چون ایپی و پورت میگیرن برای تست کردن شاید به مشکل بخورین. زنگ بزنین پشتیبانیشون به ایمیلتون یه درگاه پرداخت تست میدن و هرچقدرم پرداخت داشته باشین بهش برگشت داده میشه. داکیومنتی هم که خدا بانک داره یجوریه ( حداقل برای من ) و خودم برای گرفتن تاییدیه پرداخت یک صفحه از داکیومنت رو بالغ بر ۲۰ بار خوندم.بگذریم این مسیری هست که من رفتم گفتم شاید برای یکی مفید باشه بتونه ازش استفاده کنه و دردسر کمتری براش داشته باشه. کاری که من کردم دوتا ویو نوشتم یکی از سمت کلاینت صدا زده میشد و یک url ساخته میشد که اون رو میدادم به بچه های فرانتمون و کاربر رو پاس میدادن بهش (هرچند خودمم میتونستم ریدایرکت کنم.) و پرداختش رو کاربر انجام میداد و بعدش اون ویو دومیه از سمت بانک صدا زده میشد و تاییدیه پرداخت رو میگرفت از بانک و بعدش اینجا من به یه صفحه ای ریدایرکت میکردم که جزيیات پرداخت رو نشون میداد.از نوشتن ویو ها صرف نظر میکنم و فقط متود های کار رو نشون میدم.خب اول از همه شما باید برای پرداختتون یک شماره سفارش بسازین ( اینطور که بانک میگه نباید تکراری باشه ) من اول اومدم از تابع رندوم پایتون یه عدد ۱۰ رقمی ساختم بعد پکیج اقای زاهدی ( قبلن بهش اشاره کردم‌) نگاه کردم چیکار کردن و بنظرم بهتر اومد که اینطوری شماره سفارش ساخته میشه.import uuidtracking_code = int(str(uuid.uuid4().int)[-1 * 16:])من اینجا عدد ذخیره کردم اما شما میتونید اون int اول رو بردارید و همونطوری استرینگ ذخیره کنید.بعدش باید این عدد رو با مبلغ سفارش و شماره ترمینال ( ۳ پارامتر‌ ) رمزنگاری کنید. def pad(text, pad_size=16):
    text_length = len(text)
    last_block_size = text_length % pad_size
    remaining_space = pad_size - last_block_size
    text = text + (remaining_space * chr(remaining_space))
    return text


def encrypt_des3(text):
    secret_key_bytes = base64.b64decode(&amp;quotTERMINAL ID&amp;quot)
    text = _pad(text, 8)
    cipher = DES3.new(secret_key_bytes, DES3.MODE_ECB)
    cipher_text = cipher.encrypt(str.encode(text))
    return base64.b64encode(cipher_text).decode(&amp;quotutf-8&amp;quot)این متودای رمزنگاری که برای بانک استفاده کردم که خب بکمک پکیج اقای زاهدی بوده. با متود پایینی پارامتر SignData که از ورودی های درخواست اولیه بانک هستش رو میسازم.def encrypt_request_payment_data(terminal_id, tracking_code, amount):
    text = terminal_id + &#039;;&#039; + str(tracking_code) + &#039;;&#039; + str(amount)
    sign_data = encrypt_des3(text)
    return sign_dataحالا که رمز نگاری بانک رو هم انجام دادیم باید دیتا رو اماده کنیم تا به بانک بفرستیم.class PaymentRequestInput:
    def __init__(self, merchant_id, terminal_id, amount, order_id, date, return_url, sign_data, additional_data, mobile,
                 ):
        self.MerchantId = merchant_id
        self.TerminalId = terminal_id
        self.Amount = amount
        self.OrderId = order_id
        self.LocalDateTime = date
        self.ReturnUrl = return_url
        self.SignData = sign_data
        self.AdditionalData = additional_data
        self.UserId = mobile

    def to_json(self):
        return json.dumps(self, default=lambda o: o.__dict__)
پارامترا مشخصه چی باید باشن
یه ابجکت که از کلاس ساختین اخرش یه
to_json()
بزنید کار تمومهآدرس بازگشت ( یا ReturnUrl ) همون ادرسیه که بانک بعد از پرداخت چه موفق چه ناموفق به همراه یک سری اطاعات بهش درخواست میزنه ( POST ) من برای این پارامتر ویو دومی که نوشتم رو بهش پاس دادم.  بعد ازین نوبته ارسال درخواست به بانکه که توکن برای ما بسازه تا بتونیم پرداخت انجام بدیم. از پکیج requests استفاده کردم.&amp;quothttps://sadad.shaparak.ir/api/v0/Request/PaymentRequest&amp;quot
response = requests.post(&amp;quotURL&amp;quot, data=data, headers={&#039;Content-Type&#039;: &#039;application/json&#039;})و اینو هرجا خواستم به بانک درخواست بزنم صداش زدم. بعد ازین که به بانک درخواست زدین اگر درخواستتون اوکی بشه، بهتون تو رسپانس ResCode = &#039;0&#039;Token = &#039; *** &#039;که اون سه تا ستاره یه توکن طولانیه که باید برای پرداخت ازش استفاده کنین.https://sadad.shaparak.ir/Purchase?Token=***کاربر رو به این صفحه انتقالش میدید اگر پرداخت رو انجام میده حالا چه پرداخت موفقیت امیز باشه چه نباشه برمیگرده به اون ReturnUrl که تو ریکوست اول پرش کردیم. ( **جالبیه این قسمت اینه که اگه یادتون باشه یه شماره سفارش اول کار ساختیم بانک به ما یه شماره سفارش دیگه برمیگردونه، نمیدونم شاید این درسته و من اشتباه میکنم ولی عجیب بود برام ) وقتی برگرده به اون ReturnUrl یه سری مقدار همراهش هست که توی اون ها ResCode و token و OrderId از همه مهم ترن. اولی که نتیجه تراکنشه اگر صفر باشه ینی پرداخت انجام شده اگر -۱ ( منهای یک باشه ) ینی پرداخت انجام نشده.ResCode == &#039;0&#039; یا ResCode == &#039;-1&#039;شما بعد اینجا میتونین به بانک درخواست بزنید و از صحت پرداخت مطمين بشید. فقط لازم توکن دریافتی از بانک چه تو مرحله اول چه تو بازگشت از بانک رو به بانک درخواست بزنید تا بهتون اطلاعات رو بده برای درخواستش هم به این شکله :sign_data = _encrypt_verify_data(token=self.token)
data = {
    &#039;Token&#039;: token,
    &#039;SignData&#039;: sign_data,
}
&amp;quothttps://sadad.shaparak.ir/api/v0/Advice/Verify&amp;quot
response = requests.post(&amp;quotURL&amp;quot, data=data, headers={&#039;Content-Type&#039;: &#039;application/json&#039;})اگر پرداخت انجام شده باشه همون پارامتر ResCode مثه دفه های قبل &#x27;0&#x27; برمیگرده و بهمراهش یه سری دیتا مثه شماره کارت، شماره پیگیری، شماره مرجع تراکنش برمیگرده اگر پرداخت انجام نشده باشه مقدار &#x27;-1&#x27; به همراه نال (null) برای مقادیری که گفتم پر میشه.امیدوارم کمکتون کنه. سوالی بود درخدمتم. اگر هم جاییش ابهام یا مشکل داشت بهم بگید رفعش کنم. ممنون ازتون.امید پاکدلاسفند ۹۹</description>
                <category>امید پاکدل</category>
                <author>امید پاکدل</author>
                <pubDate>Sat, 06 Mar 2021 22:51:26 +0330</pubDate>
            </item>
            </channel>
</rss>