ثبت‌نام کد ۱ وایب‌کدینگ: ۲٫۴ میلیون تومان تخفیف، ۷۵ جا موندهکد ۱: ۲٫۴ میلیون تخفیف، ۷۵ جا۴ قسط ۱٫۴ میلیون تومانی با دیجی‌پی۴ قسط با دیجی‌پیببین چی می‌گیری
مهندسی محصول۹ دقیقه

اتصال درگاه پرداخت به اپ؛ چک‌لیست سفارش، تأیید و تلاش دوباره

چطور پرداخت یک اپ را فراتر از بازشدن درگاه بررسی کنیم؟ راهنمای وضعیت سفارش، تأیید سرور، جلوگیری از تحویل تکراری و پیگیری نتیجهٔ نامعلوم.

محمد فغانیمنتشرشده

قبل از درگاه، سفارش را تعریف کن

در اپی که با هوش مصنوعی می‌سازی، اتصال پرداخت نباید یک دکمهٔ مستقل از بقیهٔ محصول باشد. اول مشخص کن چه چیزی فروخته می‌شود، قیمت معتبر کجا محاسبه می‌شود و بعد از موفقیت چه دسترسی یا سفارشی ایجاد می‌شود. در مثال آموزشی کافه، سفارش یک شناسه، اقلام، تعداد و مبلغ نهایی دارد. اطلاعات از سرور می‌آید؛ مرورگر فقط انتخاب مشتری را می‌فرستد. اگر مشتری قیمت را در درخواست عوض کند، سرور باید همچنان مبلغ درست را حساب کند. این قاعده برای دوره، فایل یا خدمات نیز همان‌قدر مهم است.

برای هر سفارش، تلاش پرداخت را جدا ثبت کن. یک سفارش ممکن است بعد از انصراف یا خطای شبکه چند تلاش داشته باشد؛ این‌ها نباید چند خرید مستقل بسازند. شناسهٔ سفارش برای منطق محصول است و شناسهٔ تراکنش برای پیگیری پرداخت. از ایجنت بخواه این رابطه را پیش از اتصال به درگاه توضیح دهد. اگر همه‌چیز فقط در حافظهٔ مرورگر نگهداری می‌شود، بستن صفحه می‌تواند اطلاعات لازم برای پیگیری را از بین ببرد. مسیر کامل ساخت این نمونه را در راهنمای اولین اپ ببین.

مبلغ، واحد پول و کلید را روشن کن

قیمت نمایشی و مبلغ ارسالی به سرویس پرداخت ممکن است واحد یکسانی نداشته باشند. واحد هر فیلد را در قرارداد مشخص کن و تبدیل را در یک نقطهٔ روشن انجام بده. فرض نکن تمام سرویس‌ها مبلغ را به تومان یا تمام آن‌ها به ریال می‌خواهند؛ مستندات سرویس انتخابی را بررسی کن. یک مبلغ آزمایشی معلوم انتخاب کن و مقدار سفارش، درخواست درگاه و نتیجهٔ تأیید را با هم مقایسه کن. اشتباه در این تبدیل با تغییر متن کنار عدد اصلاح نمی‌شود؛ مقدار واقعی درخواست باید درست باشد.

کلید درگاه فقط در بخش سرور و تنظیمات محیط مربوط نگهداری شود. فرانت‌اند نباید با کلید پذیرنده مستقیماً درخواست پرداخت بسازد. محیط آزمایش و محیط واقعی را با نام و تنظیمات جدا مشخص کن و نتیجهٔ تست را هم با همان محیط ثبت کن. در لاگ‌ها شناسهٔ تلاش و سفارش را بنویس تا پیگیری ممکن باشد، اما کلید و اطلاعات محرمانه را چاپ نکن. قبل از انتشار، بررسی کن آدرس بازگشت به دامنهٔ درست اشاره کند و از مقدار دلخواه فرستاده‌شده توسط کاربر ساخته نشود.

بازگشت مرورگر را با تأیید سرور اشتباه نگیر

بعد از برگشت از درگاه، ممکن است پارامتر موفقیت در آدرس ببینی. این پارامتر برای شروع بررسی مفید است، اما مجوز تحویل محصول نیست. سرور باید با روش رسمی سرویس، تراکنش را تأیید کند و نتیجه را به همان سفارش و مبلغ مورد انتظار وصل کند. نام فیلدها، کدهای پاسخ و رفتار تأیید دوباره در هر سرویس فرق دارد. از ایجنت نخواه آن‌ها را حدس بزند؛ مستندات همان درگاه و پاسخ واقعی محیط آزمایش را مبنا بگذار و خطاهای شناخته‌شده را جدا مدیریت کن.

یک تست لازم این است که آدرس بازگشت را بدون پرداخت واقعی و با پارامتر دست‌کاری‌شده باز کنی. سیستم نباید سفارش را پرداخت‌شده کند. تست دیگر، بازگشت معتبر برای تراکنشی است که به سفارش یا مبلغ دیگری تعلق دارد. تحویل باید فقط وقتی اتفاق بیفتد که رابطهٔ معتبر سفارش و تراکنش تأیید شده است. اگر تأیید به دلیل قطعی سرویس نتیجه نداد، همان لحظه «ناموفق قطعی» ننویس؛ ممکن است کاربر پرداخت کرده باشد و پاسخ تأیید دیر برسد. این حالت نیاز به وضعیت قابل پیگیری دارد.

برای نتیجهٔ نامعلوم، وضعیت مستقل داشته باش

ساده‌ترین مدل ذهنی این است که سفارش در انتظار پرداخت باشد، پرداخت تأیید شود یا نیاز به بررسی داشته باشد. انصراف مشخص کاربر با timeout سرویس یکی نیست. حالت نامعلوم را از شکست قطعی جدا کن تا کاربر بی‌دلیل دوباره پرداخت نکند. متن صفحه باید بگوید چه چیزی معلوم است و قدم بعدی چیست: نتیجه هنوز تأیید نشده و می‌توان آن را دوباره بررسی کرد. اگر کاربر صفحه را ببندد، باید از حساب یا شمارهٔ پیگیری بتواند وضعیت را پیدا کند؛ نتیجه نباید فقط در یک پیام موقت زندگی کند.

هر انتقال وضعیت را تعریف کن. تراکنش موفق نباید با یک پاسخ دیررسِ خطا دوباره ناموفق شود. یک تلاش قدیمی نباید وضعیت تلاش جدید را بی‌دلیل بازنویسی کند. برای بررسی مجدد، از شناسهٔ ذخیره‌شده و رابطهٔ معتبر آن با سفارش استفاده کن و دسترسی کاربر را در سرور بسنج. داشتن شناسهٔ قابل حدس، اجازهٔ دیدن پرداخت دیگران نیست. این منطق را با چند رویداد خارج از ترتیب آزمایش کن؛ ترتیب رسیدن پیام‌ها همیشه همان ترتیبی نیست که در نمودار مسیر خوش‌بینانه کشیده‌ای.

یک پرداخت باید یک بار تحویل بدهد

کاربر می‌تواند صفحهٔ نتیجه را چند بار باز کند و سرویس هم ممکن است یک پیام را دوباره بفرستد. در این حالت نباید دو بار موجودی کیف پول اضافه شود، دو دسترسی ساخته شود یا دو سفارش برای آماده‌سازی برود. مفهوم idempotency یعنی تکرار یک عملیات با همان شناسه، اثر تجاری تازه نسازد. این رفتار باید با قیدهای دیتابیس و انتقال وضعیت کنترل‌شده پشتیبانی شود. یک شرط سادهٔ «اگر هنوز پرداخت نشده» بدون مدیریت هم‌زمانی، در دو درخواست هم‌زمان ممکن است کافی نباشد.

از ایجنت بخواه دو تأیید هم‌زمان را در تست اجرا کند و تعداد واقعی اثرهای ایجادشده را بررسی کند. همچنین قطع‌شدن سرویس میان تأیید تراکنش و تحویل را در نظر بگیر. اگر تأیید ثبت شده ولی دسترسی هنوز ساخته نشده، یک مسیر بازیابی لازم است که بعداً تحویل را کامل کند و اثر تکراری نسازد. برای نسخهٔ کوچک هم می‌توان این وضعیت‌ها را با شناسه و صف پیگیری روشن مدیریت کرد. پنهان‌کردن خطا از صفحه، مشکل تحویل را حل نمی‌کند؛ وضعیت ثبت‌شده باید قابل رسیدگی باشد.

این سناریوها را پیش از پرداخت واقعی تحویل بگیر

  1. پرداخت معتبر: مبلغ و سفارش درست باشند و فقط یک دسترسی یا سفارش نهایی ایجاد شود.
  2. انصراف: کاربر به مسیر قابل فهم برگردد و امکان تلاش مجدد بدون سفارش تکراری داشته باشد.
  3. بازگشت جعلی: تغییر پارامترهای URL یا بازکردن مستقیم صفحهٔ موفقیت، محصول را تحویل ندهد.
  4. بازگشت تکراری و هم‌زمان: نتیجه ثابت بماند و اعتبار یا دسترسی دو برابر نشود.
  5. قطع شبکه بعد از پرداخت: وضعیت نامعلوم قابل پیگیری باشد و با بررسی معتبر بعدی اصلاح شود.
  6. دسترسی غیرمجاز: یک کاربر نتواند نتیجه یا جزئیات پرداخت کاربر دیگر را با تغییر شناسه بخواند.

این فهرست یک قرارداد تحویل برای منطق عمومی پرداخت است و جای مستندات درگاه انتخابی را نمی‌گیرد. نتیجهٔ هر سناریو را با شناسهٔ آزمایشی و نسخهٔ اجراشده ثبت کن. برای مواردی که هنوز تست نشده‌اند، عبارت «آزمایش نشده» دقیق‌تر از موفق اعلام‌کردن کل پرداخت است. هنگام انتشار اپ، آدرس‌ها و تنظیمات واقعی را دوباره بررسی کن و اطلاعات آزمایشی را از دادهٔ واقعی جدا نگه دار. بعد از انتشار، اختلاف میان پرداخت تأییدشده و محصول تحویل‌داده‌شده را هم قابل مشاهده کن تا خطا در سکوت باقی نماند.

فایل‌های همراه این راهنما

پرسش‌های پرتکرار

آیا موفقیت در آدرس بازگشت برای تأیید خرید کافی است؟
نه. سرور باید نتیجه را با روش معتبر همان سرویس پرداخت تأیید کند و رابطهٔ تراکنش، سفارش و مبلغ را بررسی کند. بازکردن مستقیم صفحه یا تغییر پارامتر URL نباید باعث تحویل محصول شود؛ این سناریو باید جداگانه آزمایش شود.
اگر مبلغ کم شد ولی صفحه خطا داد چه وضعیتی نشان بدهیم؟
خطای شبکه یا timeout لزوماً شکست قطعی تراکنش را ثابت نمی‌کند. وضعیت در انتظار بررسی را ثبت کن و امکان پیگیری از مسیر معتبر سرور را فراهم کن. نتیجهٔ نهایی باید از تأیید سرویس بیاید و کاربر برای یافتن وضعیت به بازماندن یک صفحه وابسته نباشد.
چطور جلوی دو بار تحویل بعد از پرداخت را بگیریم؟
تلاش پرداخت را با شناسهٔ یکتا به سفارش وصل کن و تحویل را با قید ماندگار و کنترل هم‌زمانی فقط یک بار انجام بده. تکرار callback، بازکردن دوبارهٔ نتیجه و دو تأیید هم‌زمان باید در تست همان یک اثر تجاری را حفظ کنند.