پرداخت درون برنامه‌ای بازار در Unity3d

برای فراهم کردن قابلیت پرداخت درون‌برنامه‌ای در Unity3d، بازار از پروژه‌ی متن باز سوملا که هدف آن کمک به توسعه‌دهندگان بازی موبایل برای داشتن پرداخت درون برنامه‌ای بهتر است، استفاده کرده است. لذا در صورت نیاز به اطلاعات بیشتر می‎توانید به مستندات github و سایت سوملا مراجعه کنید. جهت اطلاع از تغییرات و نسخه‌های جدید بسته پرداخت درون‌برنامه‌ای بازار نیز می‌توانید در گروه گوگل مربوطه عضو شوید.

تعاریف Objectهای مدل اقتصادی

سوملا مدل داده‌ی کاملی برای اقتصادهای مجازی بازی‌ها دارد. معمولاً یک بازی شامل موارد زیر می‌شود:

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

این بخش شامل توضیحات خلاصه‌ای در مورد موجودیت‌های مدل اقتصادی است. جهت کسب اطلاعات بیشتر در مورد نحوه تعریف و استفاده و دیدن مثال‌های کاربردی از این objectها،  تعاریف objectهای مدل اقتصادی، مدل اقتصاد سوملا در Unity3d و مدل اقتصاد کلی سوملا  را ببینید.

مدل اقتصاد سوملا

آیتم‌ مجازی (VirtualItem)

تقریباً تمام موجودیت‌ها در اقتصاد مجازی یک VirtualItem هستند. انواع مختلفی از VirtualItemها وجود دارند. VirtualItemها (Goods, Packs, Currencies ...) علاوه بر دیگر ویژگی‌ها، دو تابع نیز برای آسان کردن  تعامل با آن‌ها دارند: give و take. از این توابع برای دادن (یا گرفتن) مقدار مشخصی از یک VirtualItem به کاربرتان استفاده کنید (برای این منظور می‌توانید از StoreInventory  نیز استفاده کنید...هر دو روش کار خواهد کرد).

پارامترهای VirtualItem

name و description به ترتیب اسم و توضیح virtualItem هستند.
itemId - هر VirtualItem یک itemId دارد. itemId رشته متنی یکتایی است که سوملا از آن برای تمیز دادن بین VirtualItem های مختلف استفاده می‌کند. itemId ربطی به شناسه‌ی کالا (productId) که در مارکت بازار تعریف می‌کنید، ندارد.

PurchasableVirtualItem

تمامی VirtualItemها قابل خرید نیستند. برای مثال، یک VirtualCurrency قابل خرید نیست اما یک VirtualCurrencyPack هست. PurchasableVirtualItemها تابعی به نام buy دارند. این تابع خرید را با  PurchaseType مشخص شده انجام می‌دهد. پارامتر purchaseType، روش خرید PurchasableVirtualItem را تعیین می‌کند.

انواع خرید (PurchaseTypes)

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

  • PurchaseWithMarket (که از PurchaseType ارث می‌برد)
  • PurchasableVirtualItem ای از این نوع PurchaseType استفاده می‌کند که قرار است توسط مارکت بازار خریداری شود. زمانی که یک PurchaseWithMarket جدید ایجاد می‌کنید، باید MarketItem آن را نیز مشخص کنید. MarketItem شامل قیمت و شناسه‌ی کالای (productId) تعریف شده در مارکت بازار است. شما باید VirtualItem مربوطه را در پنل مارکت بازار تعریف کنید و شناسه‌ی کالای آن را در فرآیند پرداخت درون‌برنامه‌ای بازی خود استفاده کنید.
  • PurchaseWithVirtualItem (که از PurchaseType ارث می‌برد)
  • یک PurchasableVirtualItem می‌تواند توسط هر VirtualItem دلخواهی خریداری شود. برای این منظور بایستی نوع پرداخت PurchaseWithVirtualItem را برای PurchasableVirtualItem استفاده کنید.

پول‌های مجازی (VirtualCurrencies)

هر بازی حداقل یک VirtualCurrency دارد و برخی نیز بیشتر از یک VirtualCurrency دارند. از کلاس VirtualCurrency برای ارائه‌ی پول مجازی بازی استفاده کنید. VirtualCurrency یک PurchasableVirtualItem نیست. به این خاطر که مثلاً شما در بازی یک «سکه طلا» یا یک «الماس» نمی‌فروشید بلکه بسته‌ای از آن‌ها را می‌فروشید. لذا کاربران بازی شما می‌توانند بسته‌های VirtualCurrency را با استفاده از VirtualCurrencyPack که در ادامه شرح داده شده، بخرند. 

بسته‌ی پول مجازی (VirtualCurrencyPack)

شما عموماً در بازی‌ فقط یک «سکه طلا» نمی‌خرید، بلکه در عوض یک بسته از پول مجازی (VirtualCurrency) بازی را می خرید. VirtualCurrencyPack دقیقاً نمایانگر این قضیه است: یک بسته از VirtualCurrency.
VirtualCurrencyPack یک PurchasableVirtualItem است و کاربران شما می‌توانند بر اساس PurchaseType ای که برای آن تعریف کرده‌اید آن را خریداری کنند.

اگر به هر دلیلی می‌خواستید مثلاً فقط یک «سکه طلا» یا یک «الماس» در بازی بفروشید می‌توانید از VirtualCurrencyPackای که یک عدد «سکه طلا» یا یک عدد «الماس» دارد، استفاده کنید.

کالاهای مجازی (VirtualGoods)

VirtualGoodها بخش اصلی یک اقتصاد مجازی هستند. آن‌ها objectهایی هستند که می‌خواهید در بازی خود بفروشید. اقتصادهای مجازی زیادی ممکن است وجود داشته باشند که انواع VirtualGood آن‌ها با هم متفاوت است. هر کالای مجازی یک PurchasableVirtualItem است. می‌توانید آن را با VirtualItem دیگر یا توسط مارکت بازا خریداری کنید. انواع VirtualGoodهای ممکن در حال حاضر عبارتند از: 

  1. Single Use
  2. Single Use Pack
  3. Lifetime
  4. Equippables
  5. Upgradables

SingleUseVG

SingleUseVG اساسی‌ترین و رایج‌ترین نوع VirtualGood است. کاربران شما می‌توانند بدون هیچ محدودیتی این نوع کالای مجازی را چندین مرتبه خریداری کنند و چندین مرتبه استفاده کنند.
مشخصات SingleUseVG عبارتند از:

  1. می‌توانند بدون محدودیت خریداری شوند.
  2. مقدار آن در پایگاه داده ذخیره می‌شود. زمانی که کالا را خریداری می‌کنید (توسط تابع buyItem درStoreInventory) یا آن را به کاربر اعطا می‌کنید (توسط تابع GiveItem در StoreInventory)، مقدار آن افزایش می‌یابد. زمانی که آن را از کاربر می‌گیرید (توسط تابع TakeItem درStoreInventory) مقدار آن کاهش می‌یابد.

«کلاه» و «شمشیر» مثال‌هایی از این نوع کالا هستند.

SingleUsePackVG

گاهی می‌خواهید یک بسته SingleUseVG را بفروشید. برای این منظور می‌توانید از SingleUsePackVG استفاده کنید. SingleUsePackVGها در واقع دسته‌ای از SingleUseVGها هستند.
مشخصات SingleUsePackVG ها عبارتند از:

  1. می‌توانند بدون محدودیت چندین مرتبه خریداری شوند. 
  2. مقداری در پایگاه داده ندارند. SingleUseVG مرتبط با این بسته مقدار خودش را دارد. لذا زمانی که کاربرانتان یک SingleUsePackVG را خریداری می‌کنند، مقدار SingleUseVG مرتبط با آن (به اندازه‌ای که در تعریف آن بسته مشخص کرده‌اید) افزایش خواهد یافت. 

«۱۰ شمشیر» و «بسته شکلات» مثال‌های از این نوع کالا هستند.

LifetimeVG

یک LifetimeVG نمایشی از یک آیتم غیرقابل مصرف است. این نوع آیتم‌ها را تنها یک مرتبه می‌توان خریداری کرد و برای همیشه در مارکت بازار برای او نگهداری می‌شوند. برای مثال وقتی کاربر بازی شما نسخه‌ی بدون تبلیغات بازی را خریداری و به آن ارتقاء پیدا می‌کند. 

UpgradeVG

یک UpgradeVG، یک VG (کالای مجازی) در یک سری از UpgradeVG هایی است که یک ترتیب ارتقاء را برای VirtualGood مورد نظر تعیین می‌کنند. VirtualGood مورد نظر هر VirtualGoodای می‌تواند باشد.
این نوع کالای مجازی را با مثال بهتر می‌توان توضیح داد: فرض کنید که یک ویژگی قدرت (strength) کاراکتر در بازی خود داشته باشید و سطوح این قدرت از ۱ تا ۵ باشد. می‌خواهید برای کاربرانتان قابلیت ارتقاء این قدرت را فراهم کنید. در این صورت بایستی موارد زیر را ایجاد کنید:

  1. SingleUseVG برای قدرت
  2. UpgradeVG برای قدرت سطح ۱
  3. UpgradeVG برای قدرت سطح ۲
  4. UpgradeVG برای قدرت سطح ۳
  5. UpgradeVG برای قدرت سطح ۴
  6. UpgradeVG برای قدرت سطح ۵

هنگامی که کاربر این UpgradeVG را می‌خرد، پس ازبررسی و برقراری شرایط مورد نظر، VirtualGood مرتبط به آن ارتقاء پیدا می‌کند.
مشخصات UpgradeVG عبارتند از:

  1. هر زمان که سطح ارتقای جاری نباشند، می‌توانند خریداری شوند.
  2. مقداری در پایگاه داده ندارند.

جهت کسب اطلاعات بیشتر می‌توانید به  مدل اقتصاد سوملا در Unity3d و مدل اقتصاد کلی سوملا مراجعه کنید.

Objectهای دیگر

VirtualCategory

از VirtualCategory برای دسته‌بندی VirtualGoodها استفاده می‌شود. برای مثال بازی شما می‌تواند شامل دسته‌های «نیروبخش‌ها»، «میوه‌ها»، «کلاه‌ها» و… باشد.

MarketItem

MarketItem نمایشی از یک آیتم در مارکت بازار است. MarketItem فقط برای نوع خرید PurchaseWithMarket استفاده می‌شود.

فراموش نکنید که قبلاً MarketItemها را باید در مارکت بازار تعریف کرده باشید.

StoreInfo

StoreInfo تمامی آیتم‌های مجازی را نگه می‌دارد. می‌توانید توسط آن وضعیت آیتم‌های مجازی مختلف را با دادن itemId شان جویا شوید.
StoreInfo داده‌های شمار را در یک پایگاه داده‌ی محلی نگه می‌دارد. زمانی که بازی شما برای اولین بار اجرا می‌شود، متاداده‌ی اقتصاد مجازی ذخیره می‌شود و از آن پس از پایگاه داده خوانده می‌شود. در صورتی که بخواهید متاداده را تغییر دهید باید عدد تابع getVersion در IStoreAssets را افزایش دهید یا بازی را از روی دستگاه خود پاک کنید. هنگامی که قصد دارید برای بازی خود آپدیت‌ بدهید در مورد آن فکر کنید.

 مثال کاربردی

 MuffinRushAssets در پروژه مثال MuffinRush را ببینید. 

در صورت تمایل به کسب اطلاعات بیشتر objectهای مدل اقتصادی سوملا را ببینید. 

اشکال‌زدایی (Debug)

برای این‌که بتوانید تمامی پیغام‌های خطای android-store را ببینید،‌ باید چک‌باکس "Debug Messages" در تنظیمات سوملا (SOOMLA Settings) را به حالت انتخاب شده در آورید. پیغام‌های خطای Unity نیز فقط در حالتی نمایش داده می‌شوند که در پنجره‌ی Build Settings پروژه یونیتی، Development Build انتخاب شده باشد. 

مراحل پیاده‌سازی

  1. بسته uniypackage را از اینجا  دریافت کنید. پس از دانلود روی آن دوبار کلیک کنید. این کار تمامی فایل‌های مورد نیاز را به پروژه شما اضافه می‌کند. 
  2. Prefabهای StoreEvents و CoreEvents موجود درAssets/Soomla/Prefabs را در scene خود بکشید و رها کنید. پس از انجام این کار باید آن را در پنل «Hierarchy» ببینید.

    محیط یونیتی پس از اضافه کردن prefabها

  3. در نوار ابزار بر روی  "Window -> Soomla -> Edit Settings" کلیک کنید و مقادیر زیر را در آن تغییر دهید:
    • Soomla Secret – رمز دلخواهی است که برای امن کردن داده‌های شما استفاده می‌شود. 
    • API Key – کلید عمومی است که مارکت بازار پس از اضافه کردن نسخه‌ی مقدماتی برنامه خود در پنل توسعه‌دهندگان، در اختیارتان قرار می‌دهد. این کلید در پنل پرداخت بازار تحت عنوان کلید RSA آمده است (شکل زیر را ببینید).

    کلید RSA در پنل پرداخت بازار

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

    وارد کردن رمزها در یونیتی

  4.  پیاده‌سازی دلخواه خود از IstoreAssets را برای توصیف دارایی‌های بازیتان ایجاد کنید (راهنمای تعریف دارایی‌ها و مثال سوملا را ببینید). SoomlaStore را با کلاسی که درست کردید، مقداردهی اولیه کنید.

    SoomlaStore.Initialize(new YourStoreAssetsImplementation());
    

    SoomlaStore را فقط یک مرتبه آن هم زمانی که برنامه‌تان بارگزاری می‌شود مقداردهی اولیه (Initialize) کنید.
    SoomlaStore را در تابع “Start” یک ‘MonoBehaviour’ مقداردهی اولیه کنید و نه در تابع “Awake”. سوملا ‘Monobehaviour’ مربوط به خودش را دارد و نیاز دارد که پیش از مقداردهی اولیه توسط شما، “Awakened” شود.

  5.  شما نیاز به یک مدیر رویداد (Event Handler) برای با خبر شدن از رویدادهای مربوط به پراخت درون‌برنامه‌ای دارید. جهت کسب اطلاعات بیشتر به بخش مدیریت رویداد مراجعه کنید. 

با انجام مراحل بالا قابلیت خرید درون‌برنامه‌ای بازار را به بازی خود اضافه کرده‌اید.

گام بعدی: پرداخت درون‌برنامه‌ای

شما می‌توانید به دو صورت به کاربران خود امکان خرید اشیاء در بازیتان را بدهید: 

  • خرید با مارکت بازار (PurchaseWithMarket)
  • خریدی است که در آن کاربران می‌توانند اشیاء مجازی را با بازار خریداری کنند.
  • خرید با اشیاء مجازی (PurchaseWithVirtualItem)
  • خریدی است که در آن کاربران می‌توانند اشیاء مجازی را با دیگر اشیاء مجازی خریداری کنند. به عنوان مثال: خرید 1 شمشیر با 100 الماس.

برای تعریف نحوه خرید اشیاء مجازی خود (کالاها، سکه‌ها و ...)، بایستی پیاده‌سازی از IstoreAsset ایجاد کنید (گام 4 از مراحل پیاده‌سازی گفته شده در بالا). 

فرض کنید VirtualCurrencyPackای به نام TEN_COINS_PACK و یک VirtualCurrency به نام COIN_CURRENCY دارید:

VirtualCurrencyPack TEN_COINS_PACK = new VirtualCurrencyPack(
     "10 Coins",                // name
     "A pack of 10 coins",      // description
     "10_coins",                // item id
     10,                        // number of currencies in the pack
     COIN_CURRENCY_ITEM_ID,     // the currency associated with this pack
     new PurchaseWithMarket("com.soomla.ten_coin_pack", 1.99)
);

 حالا می‌توانید از StoreInventory برای خرید VirtualCurrencyPack جدیدتان استفاده کنید:

StoreInventory.buyItem(TEN_COINS_PACK.ItemId);

کار شما در این مرحله به اتمام رسید. بسته یونیتی بازار می‌داند چگونه به مارکت بازار وصل شده و کاربران شما را به سیستم پرداخت جهت اتمام مراحل خرید هدایت کند. جهت اطلاع از پرداخت‌های موفق یا ناموفق  از کلاس StoreEvents  استفاده کنید (بخش مدیریت رویداد را ببینید).

 Storage & Meta-Data

زمانی که SoomlaStore را مقداردهی اولیه می‌کنید، به صورت خودکار دو کلاس دیگر را مقداردهی اولیه می‌کند: StoreInventory و StoreInfo:

  • StoreInventory کلاسی است که امکان انجام عملیات بر روی VirtualCurrencyها و VirtualGoodها را فراهم می‌کند. می‌توانید از این کلاس جهت واکشی/تغییر توازن VirtualItemها در بازیتان استفاده کنید (با استفاده از ItemId آن‌ها). 
  • StoreInfo جایی است که در آن تمامی متاداده‌های مربوط به بازیتان قابل بازیابی است. با پیاده‌سازی شما از IstoreAssets مقداردهی اولیه می‌شود و می‌توانید از آن برای بازیابی اطلاعات مربوط به بازی خود استفاده کنید.

از آنجایی که سوملا از JNI استفاده می‌کند، باید تا حد امکان فراخوانی‌های کمی را به StoreInfo داشته باشید. به پروژه‌ی مثال برای آشنایی با نحوه ایجاد نوعی حافظه پنهان (cache) جهت نگهداری اطلاعات بازیتان مراجعه کنید. این حافظه پنهان با استفاده از یک مدیر رویداد به‌روز می‌شود (ExampleLocalStoreInfo و ExampleEventHandler را ببینید).

مثال‌ها

به دست آوردن VirtualCurrency  که itemId آن currency_coin است.

VirtualCurrency coin = StoreInfo.GetVirtualCurrencyByItemId("currency_coin");

 دادن 10 پول مجازی که itemId آن currency_coin است به کاربر:

StoreInventory.GiveItem("currency_coin", 10);

گرفتن 10 کالای مجازی که itemId آن green_hat است از کاربر:

StoreInventory.TakeItem("green_hat", 10);

 به دست آوردن مقدار جاری کلاه‌های سبز (کالای مجازی که itemId آن green_hat است):

int greenHatsBalance = StoreInventory.GetItemBalance("green_hat");

مدیریت رویداد

با اضافه کردن listener خود به رویدادهای StoreEvents، می‌توانید از رویدادهای مربوطه آگاه شوید و پیاده‌سازی مختص برنامه خودتان را در هنگام وقوع آن رویدادها داشته باشید. 

پیاده‌سازی listener شما به پیاده‌سازی پیش‌فرض سوملا اضافه می‌شود (آن را جایگزین نمی‌کنید).

 به عنوان مثال، برای گوش دادن به یک رویداد "MarketPurchase":

StoreEvents.OnMarketPurchase += onMarketPurchase;

public void onMarketPurchase(PurchasableVirtualItem pvi, string purchaseToken, string payload) {
    Debug.Log("Just purchased an item with itemId: " + pvi.ItemId);
}

 باید اطمینان پیدا کنید که مدیر رویداد خود را پیش از SoomlaStore مقداردهی اولیه کنید. بنابراین در صورتی که داشته باشید:

private static Soomla.Example.ExampleEventHandler handler;

 بایستی کد زیر:

handler = new Soomla.Example.ExampleEventHandler();

 پیش از کد زیر آمده باشد. 

Soomla.SoomlaStore.Initialize(new Soomla.Example.MuffinRushAssets());

 یعنی چیزی شبیه به کدهای زیر:

public class ExampleWindow : MonoBehaviour {
    ...
    private static ExampleEventHandler handler;

    void Start () {
        ...
        handler = new ExampleEventHandler();
        SoomlaStore.Initialize(new ExampleAssets());
        ...
    }
}

 می‌توانید مثال کاملی از مدیریت رویداد را در اینجا ببینید. 

 نکاتی برای اجرای برنامه

  • در تنظیمات Build Settings یونیتی هنگام سوئیچ کردن بین پلتفرم‌ها، پس از کلیک بر روی «Switch platform» منتظر بمانید تا آیکون دایره‌ای چرخنده در گوشه پایین راستی ویرایشگر ناپدید شود. فقط در این شرایط روی گزینه Build کلیک کنید. در صورتی که خیلی زود بر روی Build کلیک کنید با احتمال زیاد به مشکل بر خواهید خورد.

  • جهت خروجی گرفتن از برنامه و اجرای آن، در تنظیمات Build Settings یونیتی بر روی Build کلیک کنید نه «Build & Run». سوملا یک اسکریپت post-build دارد که باید اجرا شود، و کلیک بر روی Build & Run شانس اجرا شدن را از این اسکریپت می‌گیرد.
  • بهتر است نسخه‌ی buildtools اندرویدتان ۱۹ به بالا باشد.

فهرست منابع و آموزش‌های تصویری