Page tree
Skip to end of metadata
Go to start of metadata

مقدمه

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

مراحل اضافه کردن پلاگین مایکت به پروژه

 

۱. پلاگین مایکت را از اینجا دانلود کنید و آن را به‌طور کامل، در پروژهٔ خود Import کنید. این کار را می‌توانید با استفاده از مسیر از مسیر Assets> Import Package> Custom Package در یونیتی انجام دهید.

۲. در پوشه‌ٔ Assets، یک prefab با نام MyketUnity وجود دارد که در واقع یک Game Object برای ارتباط با API پرداخت درون‌برنامه‌ای مایکت و دریافت پاسخ‌های آن است. این فایل را به scene خود اضافه نمایید (Drag and drop). توجه کنید که برای برقراری ارتباط میان این آبجکت و مایکت، نام آن را نباید تغییر دهید.
۳. در پوشه Assets> Plugins> Android فایل AndroidManifest وجود دارد که نیاز به دو تغییر زیر دارد:

تغییر اول: تگ Permission پرداخت از مارکت مورد نظر شما، حتما باید در AndroidManifest وجود داشته باشد؛ به عنوان مثال این Permission برای پرداخت درون‌برنامه‌ای از مایکت به صورت زیر خواهد بود:

<uses-permission android:name="ir.mservices.market.BILLING" />

تغییر دوم: در AndroidManifest برنامهٔ خود Activity زیر را اضافه کنید:

<activity 
         android:name="ir.myket.unity.iab.MyketBillingService$IabActivity" 
         android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
         android:configChanges="orientation|screenSize|keyboardHidden"/>


۴. با کلیک بر روی MyketUnity، مشاهده می‌کنید که این آبجکت شامل دو اسکریپت Store Handler و In App Store است که باید تنظیمات مربوط به آن‌ها را کامل کنید. در بخش بعدی، درباره این دو اسکریپت توضیح بیشتری داده‌ایم.

تنظیمات مربوط به Store Handler

برای کامل کردن تنظیمات Store handler باید سه فیلد زیر را پُر کنید:

  • Public Key: کلید عمومی برنامه‌ی شماست که از پنل توسعه‌دهندگان قابل دریافت است. برای اطلاعات بیشتر اینجا را ببینید.
  • Payload: همان developer payload است که با استفاده از آن می‌توان اطلاعات تکمیلی درباره سفارش کاربر فرستاد. توضیحات بیشتر در مورد developer payload را می‌توانید اینجا بخوانید.
  • Market: از این قسمت می‌توانید مارکت مورد نظرتان که می‌خواهید پرداخت درون‌برنامه‌ای را برای آن پیاده‌سازی کنید، انتخاب نمایید. برای مثال در صورتی که می‌خواهید برنامه‌تان را روی مایکت منتشر کنید، کافی است که مایکت را از این منو انتخاب کنید و در صورتی که تصمیم به انتشار برنامهٔ خود روی Google play دارید آن را روی Google play تنظیم کنید. همچنین در صورتی که مایل به اضافه کردن مارکت دیگر هستید، می‌توانید قسمت «اضافه کردن پرداخت درون‌برنامه‌ای برای مارکت‌های دیگر» را ببینید.

تنظیمات مربوط به InApp Store

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

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

آشنایی بیشتر با API پلاگین پرداخت درون‌برنامه‌ای مایکت

همان‌طور که در بخش قبل گفته شد، این پلاگین دارای یک Game Object به نام MyketUnity است که از دو اسکریپت Store Handler و InApp Store تشکیل شده است. اسکریپت Store Handler‌ وظیفه‌ی برقراری ارتباط با مایکت را برعهده دارد بنابراین توجه کنید که شما نیازی به تغییر کد این فایل ندارید. همچنین نباید نام توابع درون آن را تغییر دهید. در اسکریپت InApp Store، شما می‌توانید توابع مورد نیاز خود از مایکت (مانند تابع خرید یا تابع دریافت لیستی از خرید‌های مصرف نشدهٔ کاربر) را به همراه ورودی‌های دلخواه، از Store Handler فراخوانی کنید. پاسخ این توابع، از طریق اینترفیس IBillingListener به InApp Store برمی‌گردد که باید پیاده‌سازی شوند و عملیات مورد انتظار کاربر در آن صورت گیرد. به عبارتی دیگر، وقتی Store Handler با مایکت ارتباط برقرار می‌کند، نیاز دارد که پاسخ دریافت شده از مایکت را به InApp Store اطلاع دهد تا توجه به جواب دریافت شده، عملیات مورد نیاز صورت گیرد؛ این کار با پیاده‌سازی اینترفیس IBillingListener در InApp Store امکان‌پذیر شده است.گ

آشنایی با متد‌های Store Handler

برای اینکه InApp Store بتواند با مایکت ارتباط برقرار کند، نیاز به فراخوانی توابعی از Store Handler دارد. پس از فراخوانی هر کدام از توابع زیر، جواب مورد نظر در اینترفیس IBillingListener به شما باز می‌گردد. در زیر لیست این توابع به همراه عملکرد آن‌ها آمده است:

void SetUpBillingService (IBillingListener listener) :

این تابع، مسئول راه‌اندازی سرویس ارتباط با مایکت است. توجه کنید که این متد حتما باید قبل از فراخوانیِ توابع دیگر، فراخوانی شود. ورودی این تابع همان اینترفیس IBillingListener است. پاسخ این تابع در صورت موفقیت‌آمیز بودن عملیات، به متد OnBillingServiceSetupFinished در اینترفیس IBillingListener ارسال می‌شود.
void UpdatePurchases () :
این تابع، برای گرفتن تمام خرید‌های مصرف نشدهٔ قبلی کاربر است. این خریدها شامل اطلاعات تمام محصولات مصرف‌نشدنی یا اشتراکی هستند که کاربر قبلا خریده است. همچنین اگر کاربر یک محصول مصرف‌شدنی را قبلا خریده باشد اما به هر دلیل موفق به consume (مصرف) آن نشده باشیم، اطلاعات خرید آن محصول در پاسخ این تابع به ما بازگردانده می‌شود. پاسخ این تابع در صورت موفقیت‌آمیز بودن، به صورت لیستی از خرید‌ها، به متد OnPurchasesUpdated از اینترفیس IBillingListener ارسال می‌شود. برای آشنایی بیشتر با منطق متد UpdatePurchases (با همان getPurchases) ویدئوی آموزشی مایکت را ببینید.

 

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

 

 

void UpdatePurchasesAndDetails(Product[] products):

این تابع مانند UpdatePurchases اطلاعات خرید‌های قبلی کاربر را بازمی‌گرداند، به علاوه جزئیات تمام محصولات درون‌برنامه‌ای فعالی را که در پنل توسعه‌دهندگان مایکت تعریف کرده‌اید و در ورودی تابع به آن ارسال می‌کنید، برمی‌گرداند. پاسخ این تابع در صورت موفقیت‌آمیز بودن عملیات، به صورت دو لیست (یکی شامل اطلاعات خرید و دیگری شامل جزئیات محصولات)، به متد OnPurchasesUpdated از اینترفیس IBillingListener ارسال می‌شود.

 

void BuyProduct (string productId, string productType) :
این تابع برای شروع فرایند خرید محصولات استفاده می‌شود. در ورودی اول این تابع، SKU محصول و در دومین ورودی آن، نوع محصول (اشتراکی یا فروشی) باید مشخص شود. اگر محصول مورد نظر اشتراکی باشد، در آرگومان دوم باید رشته‌ی “subs” و اگر محصول فروشی باشد باید “inapp” فرستاده شود. پاسخ این تابع در صورت موفقیت‌آمیز بودن خرید، به همراه اطلاعات خرید، به متد OnPurchaseFinished از اینترفیس IBillingListener ارسال می‌شود. اگر کاربر به هر دلیلی خرید را لغو کند، پیام خطا به متد OnUserCancelPurchase از اینترفیس IBillingListener فرستاده می‌شود.

void ConsumePurchase (string productId, String purchaseToken) :

این تابع برای مصرف کردن یک محصول مصرف‌شدنی استفاده می‌شود. اولین ورودی آن SKU محصول و دومین ورودی، همان توکنی است که همراه با اطلاعات خرید موفق در آبجکت Purchase، به تابع OnPurchaseFinished فرستاده شده است. پاسخ این تابع در صورت موفقیت‌آمیز بودن عملیات، به متد OnConsumeFinished از اینترفیس IBillingListener ارسال می‌شود. توجه کنید که محصولات اشتراکی و مصرف نشدنی را نباید Consume کنید و عملا از این تابع فقط برای محصولات مصرف شدنی استفاده می‌شود.

آشنایی با متدهای IBillingListener

void OnBillingServiceSetupFinished () :

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

 

 

void OnPurchasesUpdated (List<Purchase> purchases) :
این تابع در پاسخ متد UpdatePurchases فراخوانی می‌شود و در ورودی‌ خود خرید‌های مصرف نشدهٔ قبلی کاربر را ارسال می‌کند.

 

 

 

void OnPurchasesAndDetailsUpdated (List<Purchase> purchases, List<ProductDetails> productDetails) :
این تابع در پاسخ متد UpdatePurchasesAndDetails فراخوانی می‌شود و در ورودی‌ خود لیست خرید‌های مصرف نشدهٔ قبلی کاربر، به همراه لیست جزئیات محصولاتی که درخواست کرده‌ بودیم، ارسال می‌کند.

 

 

void OnUserCancelPurchase(string errorMessage) :
این تابع وقتی که کاربر از خرید خود منصرف می‌شود، فراخوانی می‌گردد.

 

 

void OnPurchaseFinished(Purchase purchase) :
این تابع هنگام خرید موفقیت‌آمیز محصول فراخوانی می‌شود. اطلاعات این خرید شامل توکن خرید، شناسه سفارش و ... در قالب آبجکت Purchase به این تابع ارسال شده است.

 

 

void OnConsumeFinished (string productId, string purchaseToken) :
این تابع هنگامی که محصولی با موفقیت مصرف می‌شود، فراخوانی شده و در ورودی‌هایش SKU محصول و توکن خرید را می‌فرستد.

 

 

void OnError (int errorCode, string errorMessage) :
این تابع هنگام بروز هرگونه خطا در عملیات ارتباط با مایکت، فراخوانی می‌شود. معنای کدهای خطای ارسالی به این تابع، به شرح زیر است:
  • کد ۱: یک حالت غیرمجاز رخ داده است.
  • کد ۲: در هنگام راه‌اندازی سرویس درون‌پرداخت مایکت خطا رخ داده است. 
  • کد ۳: کلید عمومی خالی فرستاده شده است.
  • کد ۴: در هنگام گرفتن خرید‌های قبلی کاربر خطا رخ داده است.
  • کد ۵: در هنگام مصرف یک محصول، خطا رخ داده است.
  • کد ۶: در هنگام شروع اکتیویتی مربوط به خرید محصول، خطا رخ داده است.
  • کد ۷: در هنگام خرید محصول، خطا رخ داده است.

 

توضیحاتی درباره اپلیکیشن نمونه

این برنامهٔ نمونه که از اینجا قابل دانلود است، شامل سه دکمه است که هر کدام از این دکمه‌ها برای خرید یک نوع از محصولات (مصرف شدنی، مصرف نشدنی و اشتراکی) هستند:

 

  • دکمه‌ٔ Add 100 Coins برای خرید محصولی مصرف‌شدنی با شناسه test است. پس از خرید این محصول، باید حتما آن را مصرف کنیم و وقتی عملیات مصرف با موفقیت انجام شد، ۱۰۰ سکه به کاربر اضافه کنیم. 
  • دکمه‌ٔ Remove Ad برای خرید محصولی مصرف‌نشدنی با شناسه sku.test.premium است که پس از اتمام خرید، این دکمه را غیرفعال می‌کنیم.
  • دکمه‌ٔ Subscribe برای خرید محصولی اشتراکی با شناسه sku.test.subs است. از آنجا که محصولات اشتراکی، مصرف نمی‌شوند، پس از اتمام عملیات خرید، نیازی به مصرف آن نیست و فقط دکمه‌‌ٔ مربوط به خرید آن غیرفعال می‌شود.

روند راه‌اندازی سیستم پرداخت در این پروژه به صورت زیر در InAppStore‌ پیاده‌سازی شده است (نیازی به تغییر کد StoreHandler نیست):

۱. در تابع Awake، متد SetupBillingService از StoreHandler را فراخوانی کرده‌ایم تا به محض شروع اپلیکیشن، راه‌اندازی سرویس ارتباط با مایکت آغاز گردد. از آنجا که InAppStore اینترفیس IBillingService را پیاده‌سازی کرده‌ است، آن را به عنوان listener به متد SetupBillingService پاس دادیم.

۲. همان‌طور که قبلا هم اشاره شد، هنگامی که راه‌اندازی سرویس ارتباط با مایکت با موفقیت انجام می‌شود، تابع OnBillingServiceSetupFinished صدا زده می‌شود. در این تابع ما متد UpdatePurchasesAndDetails را فراخوانی کردیم تا در ابتدای برنامه، خرید‌های قبلی کاربر را چک کنیم و به او تحویل دهیم. در ورودی این تابع نیز تمام محصولاتی را که از طریق تنظیمات گیم‌آبجکت MyketUnity تعریف کرده بودیم، فرستادیم تا جزئیات آن‌ها را دریافت کنیم.

۳. طبق توضیحات پلاگین پرداخت مایکت، خرید‌های قبلی کاربر و جزئیات محصولاتی که درخواست کرده بودیم در تابع OnPurchasesAndDetialsUpdated به ما تحویل داده شدند. حال باید برای این خریدها، با توجه به نوع محصول‌شان تصمیم‌گیری کنیم. اگر خریدها مربوط به محصولی مصرف‌شدنی بودند، باید آن‌ها را مصرف (Consume) کنیم و در اینجا محصول مصرف‌شدنی ما سکه بود پس باید پس از مصرف محصول، مثلا ۱۰۰ سکه به کاربر بدهیم. اگر مربوط به محصولی مصرف‌نشدنی بود باید آن را به کاربر تحویل دهیم. در این‌جا محصول مصرف‌نشدنی ما Remove Ad بود و اگر کاربر آن را خریده بود، دکمه‌ٔ آن را غیرفعال می‌کنیم. برای محصول اشتراکی‌مان نیز به همین‌ شیوه عمل می‌کنیم و در صورت مشترک بودن کاربر، دکمه اشتراک را غیرفعال می‌کنیم. علاوه بر این، از لیست جزئیات محصولات (details)، برای بروزرسانی عنوان محصول و قیمت آن‌ها روی دکمه‌ها استفاده می‌کنیم.

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

 

اضافه کردن پرداخت درون‌برنامه‌ای برای مارکت‌های دیگر

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


۱. اضافه کردن Permission پرداخت مربوط به آن Market در AndroidManifest.
۲. اضافه کردن یک MarketType در StoreHandler برای آن مارکت (در پروژه نمونه، این تایپ برای فروشگاه گوگل‌پلی اضافه شده است).
۳. اضافه کردن پارامتر‌های ورودی متناسب با آن MarketType در تابع SetUpBillingService در StoreHandler (این مورد نیز برای فروشگاه گوگل‌پلی در پروژه نمونه تعریف شده است).

 

 




  • No labels