تکنولوژی

BillingMeld: چرا خرید باید توسط سرور بررسی شود نه برنامه

BillingMeld منبع مرکزی اطلاعات درباره خریدها و اشتراک‌ها است. او عملیات را از طریق App Store و Google Play تأیید می‌کند، تغییرات وضعیت آن‌ها را رصد می‌کند و سرویس‌های متصل فقط با وضعیت تایید شده BillingMeld کار می‌کنند.

خرید درون برنامه موبایل معمولاً تنها برای کاربر ساده به نظر می‌رسد. او روی دکمه کلیک می‌کند، پرداخت را تأیید می‌کند، به قابلیت یا اشتراک دسترسی می‌یابد — و انتظار دارد که در ادامه همه چیز به صورت خودکار پیش برود.

برای توسعه‌دهنده، پشت این دکمه فرآیند بسیار پیچیده‌تری قرار دارد. باید خود خرید را تأیید کند، تمدیدها، پایان اشتراک، استردادها، بررسی عملیات، تغییر دستگاه و تفاوت‌های فروشگاه‌های Apple و Google را در نظر بگیرد.

مشکل اصلی زمانی رخ می‌دهد که سرور شروع به حساب کردن برنامه کلاینت به عنوان منبع حقیقت می‌کند.

اگر برنامه اعلام کند: «خرید انجام شد»، سرور دسترسی را باز می‌کند و بر وضعیت دریافتی در یک بار تکیه می‌کند. اما چرخه حیات خرید در اینجا پایان نمی‌یابد.

اشتراک ممکن است تمدید شود، تمدید خودکار غیرفعال شود، پرداخت بازگردانده شود، یا خود عملیات توسط فروشگاه لغو شود.

به همین دلیل است که در BillingMeld، تأیید خرید نه برنامه، بلکه سرور است.

کاربر اطلاعات می‌دهد، اما تصمیم نمی‌گیرد

در معماری BillingMeld، برنامه موبایل منبع اصلی اطلاعات درباره خرید نیست.

کاربر ممکن است اطلاعات عملیات انجام شده را ارسال کند، اما این تنها پایه‌ای برای بررسی است. تصمیم نهایی توسط قسمت سرور BillingMeld گرفته می‌شود، که این اطلاعات را از زیرساخت‌های Apple یا Google بررسی می‌کند.

این تفاوت بنیادی است.

برنامه روی گوشی ممکن است با وضعیت قدیمی کار کند، تغییر بعدی را به موقع دریافت نکند یا داده‌هایی را ارسال کند که دیگر با وضعیت فعلی خرید مطابقت ندارد.

علاوه بر این، کاربر نباید بتواند خودش تصمیم بگیرد که چه کسی حق پرداخت دریافت کند.

BillingMeld بررسی می‌کند، برای نمونه:

  • آیا چنین خریدی واقعاً انجام شده است؛

  • آیا مربوط به برنامه و محصول مورد نظر است؛

  • آیا دوره پرداخت‌کننده جاری است؛

  • آیا تمدید بعدی صورت گرفته است؛

  • آیا تمدید خودکار غیرفعال شده است؛

  • آیا بازگشتی انجام شده است؛

  • آیا عملیات لغو شده است؛

  • آیا دوره پرداخت‌شده پایان یافته است.

بنابراین، پیام کاربر نه اثباتی بر خرید است، بلکه دلیلی برای بررسی وضعیت واقعی آن است.

منبع واحد حقیقت برای سرورها

سرویس‌های متصل نیازی به پیاده‌سازی کامل تمام ادغام‌ها همزمان با Apple و Google ندارند.

آن‌ها با BillingMeld تماس می‌گیرند و وضعیت خرید نرمال‌شده را دریافت می‌کنند.

برای نمونه: دسترسی فعال است، دوره پرداخت به پایان رسیده، تمدید بعدی تأیید شده، تمدید خودکار غیرفعال شده یا خرید لغو شده است.

این جداسازی مسئولیت‌ها را واضح می‌کند.

Apple و Google منابع وضعیت عملیات فروشگاه هستند. BillingMeld این داده‌ها را بررسی، به یک مدل مشترک تبدیل و وضعیت جاری را نگهداری می‌کند. در نهایت، تصمیم‌گیری درباره دسترسی بر اساس وضعیت BillingMeld انجام می‌شود.

برای سرورهای محصولات، این به معنای قرارداد واحد به جای چندین ادغام مستقل است.

نیازی نیست در هر سرویس جداگانه قوانین App Store و Google Play را پیاده‌سازی کنید و سپس تلاش کنید فرمت‌ها، رویدادها و وضعیت‌های مختلف را به یک منطق واحد تبدیل کنید.

چرا نباید کاملاً به کاربر اعتماد کرد

برنامه کاربر روی دستگاه کاربر اجرا می‌شود.

می‌توان آن را بست، راه‌اندازی مجدد کرد، از نسخه پشتیبان بازیابی کرد، بعداً به‌روزرسانی یا روی دستگاه دیگری اجرا کرد. ممکن است مدت زمانی با وضعیت قدیمی کار کند یا رویدادی را که پس از خرید اولیه رخ داده است، دریافت نکند.

حتی بدون مداخله کاربر، این برنامه منبع ضعیفی برای وضعیت نهایی اشتراک است.

برای نمونه، کاربر اشتراک را فعال می‌کند و به آن دسترسی می‌یابد. بعدها ممکن است خرید بازگردانده یا عملیات توسط فروشگاه لغو شود.

اگر سرور فقط درباره پیام اولیه کاربر اطلاع داشته باشد، خرید را فعال می‌داند.

در وضعیت دیگر، کاربر ممکن است تمدید خودکار را غیرفعال کند. در این حالت، دوره پرداخت‌شده باید تا پایان تاریخ آن فعال باقی بماند.

اگر سیستم تنها وضعیت ابتدایی «اشتراک وجود دارد / وجود ندارد» را دارد، ممکن است دسترسی را زودتر قطع کند یا پس از اتمام حق، آن را باقی بگذارد.

BillingMeld بر اساس منطق دیگری ساخته شده است: کاربر حقوق خود را تأیید نمی‌کند. او رویداد را گزارش می‌دهد، و سرور وضعیت واقعی خرید را تعیین می‌کند.

خرید فقط یک رویداد نیست

یکی از اشتباهات اصلی در معماری بلیتینگ، تصور خرید به عنوان یک رویداد واحد است.

در واقع، چرخه حیات دارد.

در ابتدا عملیات رخ می‌دهد و تأیید می‌شود. برای اشتراک، دوره پرداخت آغاز می‌شود. بعدها ممکن است تمدید بعدی صورت گیرد.

کاربر ممکن است تمدید خودکار را غیرفعال کند، اما همچنان به اشتراک ادامه دهد تا پایان دوره پرداخت‌شده.

پرداخت می‌تواند هنگام تمدید بعدی انجام نشود.

ممکن است بازگشتی انجام شود.

در موارد خاص، خرید ممکن است لغو شود.

بنابراین، فقط «این خرید در زمانی وجود داشت» کافی نیست.

برای سرور مهم است که بفهمد در حال حاضر چه اتفاقی برای آن می‌افتد.

لغو خرید و پایان دسترسی — تفاوت دارند

در اینجا تفاوت مهمی وجود دارد.

اگر کاربر تمدید خودکار را غیرفعال کند، به معنای آن نیست که دسترسی باید بلافاصله قطع شود.

دوره پرداخت‌شده جاری ممکن است ادامه یابد.

در این صورت، BillingMeld باید اطلاعات مربوط به غیرفعال‌سازی تمدید بعدی را نگه دارد و همزمان تاریخ پایان دوره پرداخت‌شده را بداند.

و پس از پایان آن، اگر تمدید جدید تایید نشده است، دسترسی دیگر فعال نباشد.

این یکی از دلایلی است که مقدار بولی ساده subscription = true برای تعادل‌سازی صحیح کافی نیست.

وضعیت اشتراک همیشه مرتبط با زمان و رویدادهای چرخه حیات آن است.

تمدید نیز یک بررسی جداگانه است

اشتراک پس از اولین پرداخت به پایان نمی‌رسد.

سرور باید بفهمد آیا تمدید بعدی انجام شده است و آیا دوره پرداخت تایید شده است.

BillingMeld این تغییرات را رصد می‌کند و وضعیت اشتراک را به‌روزرسانی می‌کند.

اگر تمدید تأیید شده باشد، حق دسترسی ادامه می‌یابد.

اگر پرداخت بعدی انجام نشود یا فروشگاه دوره بعدی را تأیید نکند، سیستم نباید صرفاً با فرض صحت تمدید، دسترسی را تمدید کند.

برای کاربر، این منطقی طبیعی است: دسترسی تا پایان اشتراکی که واقعاً فعال است، ادامه می‌یابد.

برای توسعه‌دهندگان، این به معنی عدم نیاز به پیاده‌سازی مجدد همان منطق تمدید در هر برنامه است.

نمونه سناریوی عادی چگونه است

کاربر در برنامه موبایل اشتراک می‌گیرد.

کلیپنت اطلاعات خرید را دریافت و داده‌های لازم را به BillingMeld منتقل می‌کند. اما این پیام خودش هنوز دلیل قطعی برای تأیید نهایی خرید نیست.

BillingMeld عملیات را از طریق فروشگاه مربوط بررسی می‌کند.

اگر App Store یا Google Play خرید را تأیید کند و وضعیت آن با قوانین محصول مطابقت داشته باشد، BillingMeld حق فعال را ثبت می‌کند.

در ادامه، سرویس متصل امکانات پرداخت‌شده را در اختیار کاربر قرار می‌دهد.

چرخه وضعیت دیگر مستقل از پیام اولیه کاربر ادامه دارد.

اگر اشتراک تمدید شود، BillingMeld دوره جدید را در نظر می‌گیرد.

اگر کاربر تمدید خودکار را غیرفعال کند، دوره جاری تا پایان ادامه می‌یابد.

در صورت بازگشت یا لغو عملیات، وضعیت دوباره تغییر می‌کند.

در این سناریو، برنامه وضعیت «حقیقت» خود درباره خرید ندارد. بلکه با وضعیت تأیید شده و ذخیره شده توسط BillingMeld کار می‌کند.

در صورت تغییر دستگاه چه اتفاقی می‌افتد

مدل سرور بسیار مفید است وقتی کاربر گوشی را عوض می‌کند یا برنامه را مجدداً نصب می‌کند.

حقوق خرید نباید تنها به دلیل اینکه نمونه خاصی از برنامه قبلاً تراکنش موفقی دیده است، وجود داشته باشد.

و بالعکس، نصب مجدد برنامه نباید حقوق تأیید شده کاربر را نابود کند.

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

این یکی دیگر از دلایلی است که نباید منطق دسترسی را صرفاً در برنامه موبایل نگهداری کرد.

این چه مزایایی برای توسعه‌دهندگان دارد

برای تیم‌هایی که چندین برنامه موبایل منتشر می‌کنند یا با iOS و Android همزمان کار می‌کنند، بلیتینگ به سرعت به یک زیرساخت مجزای مشکل تبدیل می‌شود.

باید موارد زیر را در نظر گرفت:

  • فرمت‌های داده متفاوت اپل و گوگل؛

  • تأیید خرید اولیه؛

  • تمدید اشتراک‌ها؛

  • پایان دوره پرداخت‌ها؛

  • غیرفعال‌سازی تمدید خودکار؛

  • بازگشت‌ها؛

  • لغو عملیات‌ها؛

  • نصب مجدد برنامه؛

  • تغییر دستگاه؛

  • بازگردانی خریدها؛

  • تغییری در وضعیت بدون دخالت کاربر.

BillingMeld این منطق را در یک لایه تخصصی جداگانه قرار می‌دهد.

سرورها با قرارداد واحد با آن کار می‌کنند و نباید جزئیات هر فروشگاه را به صورت مستقل تفسیر کنند.

این کاهش تکرار کد و همچنین کاهش احتمال تفاوت در فهم یک سناریوی پرداخت یکسان در برنامه‌های مختلف یک شرکت است.

کلید، نه چک، بلکه حقوق جاری

مهم‌ترین چیزی که در این معماری جذب من شد، انتقال از بررسی یک خرید جداگانه به کنترل وضعیت جاری است.

واقعیت پرداخت اولیه، به تنهایی، جواب اصلی سؤال محصول را نمی‌دهد:

آیا کاربر حالا حق دریافت تابع پرداختی دارد؟

ممکن است خرید اولیه موفق صورت گرفته باشد، اما دوره به پایان رسیده باشد.

ممکن است تمدید خودکار غیرفعال شده باشد، اما مدت پرداخت‌شده همچنان فعال است.

تمدید تأیید شده وجود داشته است.

بازگشتی انجام شده است.

فروشگاه عملیات را لغو کرده است.

بنابراین، عنصر اصلی دیگر چک یا پاسخ اولیه کاربر نیست، بلکه حق واقعی کاربر است که بر اساس وضعیت تأیید شده خرید تعیین می‌شود.

دقیقاً این وضعیت است که BillingMeld به سایر سرویس‌ها منتقل می‌کند.

BillingMeld به عنوان مرز بین فروشگاه‌ها و محصولات

در نتیجه، یک مرز معماری بسیار واضح ظاهر می‌شود.

از یک سو، App Store و Google Play با قالب‌ها، رویدادها، قوانین و چرخه زندگی خود قرار دارند.

از سوی دیگر — برنامه‌ها و سرویس‌های داخلی، که در اکثر موارد، نیاز به پاسخ بسیار ساده‌تری دارند: چه حقوقی در حال حاضر در دسترس است؟

در بین آن‌ها، BillingMeld قرار دارد.

او داده‌های فروشگاه را دریافت، بررسی، به مدل خود تبدیل و نتیجه نرمال‌شده را در اختیار زیرساخت‌های دیگر قرار می‌دهد.

این باعث می‌شود نیازی به دانستن تمام جزئیات هر پلتفرم پرداخت نباشد.

اهمیت این موضوع برای کاربر

برای کاربر، معماری صحیح بلیتینگ باید در اصل نامحسوس باقی بماند.

اگر خرید تأیید شده باشد و دوره پرداخت فعال باشد، باید دسترسی وجود داشته باشد.

اگر کاربر تمدید خودکار را غیرفعال کند، مدت پرداخت‌شده نباید زودتر از موعد پایان یابد.

اگر تمدید جدیدی انجام شده است، دسترسی باید ادامه یابد.

اگر فروشگاه بازگشت یا لغو را تأیید کند، سیستم باید تغییر حقوق را صحیح منعکس کند.

در صورت تغییر دستگاه یا نصب مجدد برنامه، نباید نیاز باشد هر قسمت از زیرساخت به صورت دستی اثبات کند که خرید واقعاً وجود دارد.

در نهایت، قانون ساده است:

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

به همین دلیل است که BillingMeld تنها یک ماژول پرداخت دیگر نیست.

این لایه سروری اعتماد است بین برنامه موبایل، فروشگاه‌های اپل و گوگل و محصولات، که باید بدانند چه حقوق پرداختی در این لحظه متعلق به کاربر است.

برای اطلاعات بیشتر در مورد پروژه، به billingmeld.de مراجعه کنید.