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

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

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


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

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

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

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

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

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

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


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

تقریباً تمام موجودیت‌ها در اقتصاد مجازی یک «آیتم مجازی» (VirtualItem) هستند. انواع مختلفی از آیتم‌های مجازی وجود دارند. بطور مثال "کالا‌ها"، "پکیج‌ها" و "واحد پول مجازی" از انواع آیتم مجازی هستند.

«آیتم‌های مجازی» علاوه بر دیگر ویژگی‌ها، دو تابع نیز برای آسان کردن  تعامل با آن‌ها دارند: تابع Give و تابع Take.
از این توابع برای مقداردهی و مقدارسنجیِ یک «آیتم مجازی» می‌توانید استفاده کنید. (برای این منظور می‌توانید از کلاس StoreInventory نیز استفاده کنید. هر دو روش قابل استفاده است.)

پارامترهای VirtualItem

پارامتر‌های Name و Description به ترتیب اسم و توضیحِ یک «آیتم مجازی» (VirtualItem) هستند.
هر آیتم مجازی یک پارامتر ItemId نیز دارد. ItemId یک رشته متنی (String) یکتا (Unique) است که سوملا از آن برای ایجاد تمایز بین آیتم‌های مجازی مختلف استفاده می‌کند.
نکته: پارامتر ItemId متعلق به هر آیتم مجازی باید مطابق «شناسه‌ی کالا» (ProductId) که برای آن در مارکت بازار تعریف می‌کنید، باشد.

آیتم مجازی قابل خرید (PurchasableVirtualItem)

لزوماً تمامی «آیتم‌های مجازی»، قابل خرید نیستند. برای مثال، یک «واحد پول مجازی» (VirtualCurrency) قابل خرید نیست اما یک «بسته‌ی پول مجازی» (VirtualCurrencyPack) قابل خرید است. «آیتم‌های مجازی قابل خرید» تابعی با نام Buy دارند. این تابع، خرید را با «روش خرید» (PurchaseType) مشخص شده انجام می‌دهد. پارامتر PurchaseType، روش خرید «آیتم مجازی قابل خرید» را تعیین می‌کند.

روش‌ خرید (PurchaseType)

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

درحال حاضر دو نوع «روش خرید» (PurchaseType) داریم:

  • «خرید از طریق بازار» (PurchaseWithMarket):
    هنگامی یک آیتم مجازی قابل خرید (PurchasableVirtualItem) از این روش خرید استفاده می‌کند که قرار است توسط مارکت بازار خریداری شود. زمانی که یک شئ جدید از کلاس PurchaseWithMarket ایجاد می‌کنید، باید پارامتر MarketItem مربوط به آن را نیز تخصیص دهید. MarketItem شامل قیمت و شناسه‌ی کالای (ProductId) تعریف شده در مارکت بازار است. شما باید آیتم مجازی مربوطه را در پنل مارکت بازار تعریف کنید و شناسه‌ی کالای آن را در فرآیند پرداخت درون‌برنامه‌ای بازی خود استفاده کنید.
  • «خرید از طریق آیتم مجازی» (PurchaseWithVirtualItem):
    یک آیتم مجازی قابل خرید (PurchasableVirtualItem) می‌تواند توسط هر آیتم مجازی دلخواهی (مثلاً آیتم «الماس» تعریف شده درون بازی) خریداری شود. برای این منظور بایستی این نوع پرداخت را برای آن آیتم استفاده کنید.

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

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

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

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

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

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

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

  1. یک بار مصرف (Single Use)
  2. بسته‌ی یک بار مصرف (Single Use Pack)
  3. همیشگی (Lifetime)
  4. قابل تجهیز (Equippable)
  5. قابل ارتقاء (Upgradable)

کالای مجازیِ یک بار مصرف (SingleUseVG)

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

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

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

بسته‌ی کالای مجازیِ یک بار مصرف (SingleUsePackVG)

گاهی می‌خواهید یک بسته کالای مجازیِ یک بار مصرف را بفروشید. برای این منظور می‌توانید از «بسته‌ی کالای مجازیِ یک بار مصرف» استفاده کنید که در واقع دسته‌ای از کالا‌های مجازیِ یک بار مصرف هستند.
مشخصات این بسته‌ها عبارتند از:

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

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

کالای مجازیِ دارای اعتبار همیشگی (LifetimeVG)

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

کالای مجازیِ ارتقاء (UpgradeVG)

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

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

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

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

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


اشیاء دیگر

دسته‌بندی مجازی (VirtualCategory)

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

آیتم قابل فروش (MarketItem)

«آیتم قابل فروش» نمایشی از یک آیتم در مارکت بازار است. آیتم قابل فروش فقط برای روش خرید «خرید از طریق بازار» (PurchaseWithMarket) استفاده می‌شود.

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


اطلاعات فروشگاه (StoreInfo)

کلاس StoreInfo تمامی آیتم‌های مجازی را نگه می‌دارد. می‌توانید توسط آن وضعیت آیتم‌های مجازی مختلف را با دادن ItemId شان به تابع GetItemByItemId جویا شوید.
این کلاس داده‌های شما را در یک پایگاه داده‌ی محلی نگه می‌دارد. زمانی که بازی شما برای اولین بار اجرا می‌شود، متا‌داده‌ی اقتصاد مجازی ذخیره می‌شود و از آن پس از پایگاه داده خوانده می‌شود. در صورتی که بخواهید متاداده را تغییر دهید باید عدد تابع 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 اندرویدتان ۱۹ به بالا باشد.


راهنمای تعریف دارایی‌های برنامه

فرض کنید اسکریپت ExampleAssetsای داریم که در آن دارایی‌های بازی را تعریف می‌کنیم. در این بازی، سکه به عنوان یک VirtualCurrency می‌باشد. تعریف این پول مجازی را به شکل زیر در نظر بگیرید:

public static VirtualCurrency COIN_CURRENCY = new VirtualCurrency("Coin", // name
			"", // description
			COIN_CURRENCY_ITEM_ID // item id
	);

 در این صورت اسکریپت ExampleAssets، بایستی شامل تابع زیر جهت دانستن VirtualCurrencyهای بازی باشد:

public VirtualCurrency[] GetCurrencies() {
    return new VirtualCurrency[]{COIN_CURRENCY};
}

کاربر بازی می‌تواند بسته‌های ۱۰، ۱۰۰ و ۱۰۰۰ تایی سکه را از مارکت بازار خریداری کند و به تعداد سکه‌های خود اضافه کند. این بسته‌ها را در اسکریپت ExampleAssets به شکل زیر تعریف می‌کنیم:

public static VirtualCurrencyPack TENCOIN_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(TENCOIN_PACK_PRODUCT_ID, 1000));
public static VirtualCurrencyPack HUNDCOIN_PACK = new VirtualCurrencyPack(
			"100 Coins", // name
			"A pack of 100 coins", // description
			"100_coins", // item id
			100, // number of currencies in the pack
			COIN_CURRENCY_ITEM_ID, // the currency associated with this pack
			new PurchaseWithMarket(HUNDCOIN_PACK_PRODUCT_ID, 9000));
public static VirtualCurrencyPack THOUSANDCOIN_PACK = new VirtualCurrencyPack(
			"1000 Coins", // name
			"A pack of 1000 coins", // description
			"1000_coins", // item id
			1000, // number of currencies in the pack
			COIN_CURRENCY_ITEM_ID, // the currency associated with this pack
			new PurchaseWithMarket(THOUSANDCOIN_PACK_PRODUCT_ID, 70000));

در این‌جا ثابت‌های TENCOIN_PACK_PRODUCT_ID، HUNDCOIN_PACK_PRODUCT_ID و THOUSANDCOIN_PACK_PRODUCT_ID بیانگر شناسه‌های کالای تعریف شده در مارکت بازار هستند. مقادیر این ثابت‌ها بایستی دقیقاً با شناسه‌های کالای تعریف شده در مارکت بازار یکسان باشند (10sekke, 100sekke , 1000sekke در شکل زیر).

تعریف محصول در پنل پرداخت بازار

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

در این صورت کلاس ExampleAssets بایستی شامل متد زیر برای برگردادنVirtualCurrencyPack ها باشد.

public VirtualCurrencyPack[] GetCurrencyPacks() {
    return new VirtualCurrencyPack[] {TENCOIN_PACK, HUNDCOIN_PACK, THOUSANDCOIN_PACK};
}

در این بازی کاربر می‌تواند با دادن ۴۵ سکه، یک گالون سوخت (gas) برای ماشین خود خریداری کند. gas مطابق با تعریف کالای SingleUseVG است (کاربر می‌تواند بدون محدودیت آن را خریداری کند. با هر بار خرید آن، مقدارش افزایش پیدا می‌کند و با مصرف آن مقدارش کاهش خواهد یافت). با این فرضیات تعریف این کالا به صورت زیر خواهد بود:

public static VirtualGood GAS_GOOD = new SingleUseVG(
    "Gas", // name
    "Increase your car fuel by 1 gallon", // description
    "gas_fuel", // item id
     new PurchaseWithVirtualItem(COIN_CURRENCY_ITEM_ID, 45));// the way this virtual good is purchased

از آن‌جایی که نسخه رایگان بازی شامل نمایش آگهی است، گزینه‌ی خرید نسخه‌ی بدون آگهی بازی در آن در نظر گرفته شده است. برای تعریف این قابلیت، محصول غیرمصرفی no_ads را به شکل زیر در کلاس ExampleAssets تعریف می‌کنیم: 

public static VirtualGood NO_ADS_GOOD = new LifetimeVG("No Ads", // name
			"No More Ads!", // description
			"no_ads", // item ID
			new PurchaseWithMarket(new MarketItem( // purchase type
					NO_ADS_PRODUCT_ID, // product ID
					MarketItem.Consumable.NONCONSUMABLE, // type
					35000)) // price
	);
توجه: ماهیت LifetimeVGها به گونه‌ای است که هر کاربر فقط یک مرتبه می‌تواند آن را خریداری کند و با خرید این آیتم‌ها کاربر همواره صاحبش خواهد بود (حتی در صورتی که بازی را پاک کرده و مجدد نصب کند). در واقع این نوع خریدِ کاربر درمارکت بازار برای آن حساب کاربری و برای همیشه ذخیره خواهد شد. در این‌جا نیز از آن‌جایی که کاربران فقط یک مرتبه نسخه پولی (بدون نمایش آگهی) بازی را خریداری می‌کنند و پس از آن همیشه خواهند توانست از نسخه ارتقاء یافته بازی استفاده کنند، no_ads را از نوع LifetimeVG تعریف کردیم.

با در نظر گرفتن تمامی این موارد فایل ExampleAssets را مطابق زیر تعریف می‌کنیم:

using UnityEngine;
using System.Collections;

namespace Soomla.Store.Example   														 //Allows for access to Soomla API
{
    public class ExampleAssets : IStoreAssets
    //Extend from IStoreAssets (required to define assets)
    {
        public int GetVersion() { 
             //Get Current Version
             return 0;
   	 }
   	 
   	 public VirtualCurrency[] GetCurrencies() {
         // Get/Setup Virtual Currencies
   	     return new VirtualCurrency[]{COIN_CURRENCY};
   	 }   	 
   	 
   	 public VirtualGood[] GetGoods() {
       	     return new VirtualGood[] {GAS_GOOD, NO_ADS_GOOD};
   	 }
   	 
   	 public VirtualCurrencyPack[] GetCurrencyPacks() {    // Get/Setup Currency Packs
             return new VirtualCurrencyPack[] {TENCOIN_PACK, HUNDCOIN_PACK, THOUSANDCOIN_PACK};
   	 }  	 
    
   	 public VirtualCategory[] GetCategories() {  // Get/ Setup Categories (for In App Purchases)
             return new VirtualCategory[]{};
   	 }

   	 //***********BOILERPLATE ABOVE(modify as you see fit/ if nessisary)************	 
   	 //SETUP AND CREATE AN IN APP PURCHASE ASSET
   	   	    	 
   	 public const string NO_ADS_PRODUCT_ID = "paid_version";   			
   	 public const string COIN_CURRENCY_ITEM_ID  = "currency_coin";   	 
   	 public const string TENCOIN_PACK_PRODUCT_ID = "10sekke";   	 
   	 public const string HUNDCOIN_PACK_PRODUCT_ID = "100sekke";   	 
   	 public const string THOUSANDCOIN_PACK_PRODUCT_ID = "1000sekke";


   	 /** Virtual Currencies **/
         public static VirtualCurrency COIN_CURRENCY = new VirtualCurrency("Coin", // name
			"", // description
			COIN_CURRENCY_ITEM_ID // item id
	 );

   	 /** Virtual Currency Packs **/   	 
   	public static VirtualCurrencyPack TENCOIN_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(TENCOIN_PACK_PRODUCT_ID, 1000));

         public static VirtualCurrencyPack HUNDCOIN_PACK = new VirtualCurrencyPack(
			"100 Coins", // name
			"A pack of 100 coins", // description
			"100_coins", // item id
			100, // number of currencies in the pack
			COIN_CURRENCY_ITEM_ID, // the currency associated with this pack
			new PurchaseWithMarket(HUNDCOIN_PACK_PRODUCT_ID, 9000));
	public static VirtualCurrencyPack THOUSANDCOIN_PACK = new VirtualCurrencyPack(
			"1000 Coins", // name
			"A pack of 1000 coins", // description
			"1000_coins", // item id
			1000, // number of currencies in the pack
			COIN_CURRENCY_ITEM_ID, // the currency associated with this pack
			new PurchaseWithMarket(THOUSANDCOIN_PACK_PRODUCT_ID, 70000));

   	 /** Virtual Goods **/
         public static VirtualGood GAS_GOOD = new SingleUseVG("Gas", // name
			"Increase your car fuel by 1 gallon", // description
			"gas_fuel", // item id
			new PurchaseWithVirtualItem(COIN_CURRENCY_ITEM_ID, 45)); // the way this virtual good is purchased
										
	public static VirtualGood NO_ADS_GOOD = new LifetimeVG("No Ads", // name
			"No More Ads!", // description
			"no_ads", // item ID
			new PurchaseWithMarket(new MarketItem( // purchase type
					NO_ADS_PRODUCT_ID, // product ID
					MarketItem.Consumable.NONCONSUMABLE, // type
					35000)) // price
	);
    }
}

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