В последнее время пришлось интегрировать внутриигровые покупки в свою игру и встал вопрос, а какой же плагин для этого использовать под Unity3D? Есть такие вещи как OpenIAB, Prime31, Unibill и Soomla. Более мелкие вещи брать в расчет не будем, ибо некоторые из них либо не обновляются вообще, либо имеют какие-то критические проблемы. Кто хочет знать, почему выбор пал именно на Soomla, и как его интегрировать прошу под кат.

Итак, плагинов, как видно, много и по названию топика видно, какую систему я выбрал в итоге, но почему? Давайте рассмотрим каждую систему отдельно.

OpenIAB


Плюсы:
  • Бесплатность
  • Открытость
  • Большое сообщество
  • Простота
  • Неплохая документация
  • Поддержка iOS и Android (Позднее оказалось, что не так)

Минусы:
  • Почти нет информации о работе с iOS
  • Обновления весьма редки (Последнее было 4 месяца назад)

Мнение:
Грешу, я и ранее работал с этой системой, но только под Android, когда же я решил попробовать поработать с стороной iOS, то меня ждало разочарование, OpenIAB просто не работал, т.к. его event'ы не давали отклика, и как на инициализацию магазина, потому от этой системы пришлось отказаться, но стоит отдать ей должное, под Android работала она безупречно, но в этом и не приходилось сомневаться, ведь даже исходная версия на c++ написана только под эту ОС.

Unibill


Плюсы:
  • Поддержка множества магазинов
  • Отличная документация
  • Простота и легкость в освоении

Минусы:
  • Цена (175$)
  • Сообщество, как таковое почти отсутствует

Мнение:
С Unibill все оказалось просто. Сразу были вопросы к цене, 175$ не совсем маленькие деньги, особенно учитывая, что есть более дешевые аналоги, потому сразу нет, но если есть финансы и не хочется тратить много времени, то отличный вариант.

Prime[31]


Плюсы:
  • Отличная документация
  • Простота и легкость в освоении
  • Поддерживает множество магазинов, но с оговоркой.
  • Большое сообщество.

  • Под каждую платформу цена плагина 70 $.

Мнение:
Плагины от prime[31] славятся своим качество, но цена тоже оставляет желать лучшего, 70$ под каждую платформу отдельно совсем не предел мечтаний, но тут уже проверенная технология с огромным сообществом и отличной документацией и т.к. нужен был плагин всего под 2 платформы цена выходила ниже, чем у Unibill, но все равно был выбран не этот вариант, а нижеследующий.

Soomla


Плюсы:
  • Отличная документация
  • Простота и легкость в освоении
  • Поддерживает основные мобильные платформы.
  • Большое сообщество.
  • Бесплатность.

Минусы:
  • Работа через их личный кабинет

Мнение:
Soomla же показался просто отличным вариантом, т.к. у него есть все плюсы плагинов от prime[31], но при этом эта система полностью бесплатна, хоть и смутило то, что придется еще работать через личный кабинет на их сайте, но на самом деле, делать там почти ничего не нужно, потому выбор остановился на этом варианте.

Интеграция в проект


Первое, что нужно сделать (Внезапно!) скачать собственно плагин, можно с Asset Store, можно с официального сайта, разницы нет. И там и там плагин обновляется почти одновременно.

После импорта в проект плагина, первое наперво нужно выставить настройки в editor'е.



В Soomla Secret вы должны указать Game Key, который вы получите при создании приложения в личном кабинете Soomla. Без этого работать ничего не будет!



Debug Native и Debug Unity это на ваш личный выбор. В Android Settings package name определяется автоматически, а дальше вы должны собственно выбрать, какие магазины на Android вы используете. Думаю, API Key понятно откуда брать. Receipt Validation так же на ваш выбор. Все, основу мы настроили, пора переходить к скриптам.

Нам нужно собственно описать в отдельном классе наши товары, для того, чтобы мы могли покупать их, к примеру так:

Инициализация покупок
using Soomla.Store;//Подключаем Soomla
using Soomla;//Подключаем Soomla

public class dataIAP : IStoreAssets  { //Наследуемся от интерфейса IStoreAssets

		public int GetVersion() { //Инициализируем функцию GetVersion, что она возвращает важно, если вы будете смотреть информацию в личном кабинете сумлы
			return 0;
		}

		public VirtualCurrency[] GetCurrencies() { //Указываем все наши валюты, которые мы продаем за реальные деньги 
			return new VirtualCurrency[]{ITEM_OBJECT};
		}

		public VirtualCurrencyPack[] GetCurrencyPacks(){ //Указываем все паки с нашими валютами
			return new VirtualCurrencyPack[]{PACK_1_OBJECT, PACK_2_OBJECT};
		}

		public VirtualGood[] GetGoods() {
			return new VirtualGood[0]; //Виртуальные блага
		}

		public VirtualCategory[] GetCategories() {
			return new VirtualCategory[0]; //Категории виртуальных благ и реальных вещей
		}

		public const string ITEM_ID = "ITEM_ID";// указываем любой удобный ID

		public const string PACK_1 = "ID_PACK_1";// указываем id, который мы указали в магазине (App Store, Google Play) для данного пака
		public const string PACK_2= "ID_PACK_2";// указываем id, который мы указали в магазине (App Store, Google Play) для данного пака

		public static VirtualCurrency ITEM_OBJECT = new VirtualCurrency(//создаем объект нашей виртуальной валюты
			"ITEM_ID ",//Имя валюты									
			"ITEM_COIN", //описание валюты										
			ITEM_ID //id виртуальной валюты
			);

		public static VirtualCurrencyPack PACK_1_OBJECT = new VirtualCurrencyPack(//создаем объект пака с виртуальной валютой
			"PACK_1",//имя пака										
			"",//Описание пака												
			PACK_1 ,// Указываем id пака
			100, //Количество валюты в паке
			ITEM_ID ,//id валюты в паке
			new PurchaseWithMarket(PACK_1 , 1.99) //Первым указываем id пака в магазине, вторым его цену(не критично, если отличается)
			);
		public static VirtualCurrencyPack PACK_2_OBJECT = new VirtualCurrencyPack(//аналогично
			"PACK_2",										
			"",												
			PACK_2,
			200, 
			ITEM_ID ,
			new PurchaseWithMarket(PACK_2, 5.99)
			);
	}

Благодаря комментариям более или менее все понятно, но я пропустил 2 вещи это виртуальные 'блага' и категории, они в основе нужны тем, кто хочет отслеживать продажу даже простых виртуальных покупок, не за реальные деньги, а даже за ту валюту, которую вы продаете за реальные деньги через личных кабинет сумлы, о котором мы поговорим позже.

Итак, мы прописали все наши внутриигровые покупки, но как же теперь передать эти данные плагину и как же совершать покупки?

А это весьма просто:

Инициализация Soomla
using Soomla;
using Soomla.Store;

public class Test {
	
	public Test () {

		SoomlaStore.Initialize (new dataIAP ());//Передаем при инициализации наш объект с данными о паках

        #if UNITY_ANDROID
		SoomlaStore.StartIabServiceInBg (); //Обязательно для Android, без этого ничего работать не будет
		#endif
	}

	public void PayPack_1()
	{
		SoomlaStore.BuyMarketItem (StoreInfo.CurrencyPacks [0].ItemId, "");//Купить первый пак
	}

	public void PayPack_2()
	{
		SoomlaStore.BuyMarketItem (StoreInfo.CurrencyPacks [1].ItemId, "");//Купить второй пак
	}

    public void Quit()
	{
		SoomlaStore.StopIabServiceInBg ();
	}
}


Очень простая инициализация, но нас ведь еще и интересуют события, которые нам доступны, а вот и они(Основные):

События
using System;
using System.Collections.Generic;
using Soomla;
using Soomla.Store;

public class ExampleEventHandler {

	//Подписка на события при создании объекта класса
	public ExampleEventHandler () {
		//Вызывается, когда покупка за реальные деньги совершена
		StoreEvents.OnMarketPurchase += onMarketPurchase;
		//Вызывается, когда покупка за внутриигровую валюту совершена
		StoreEvents.OnItemPurchased += onItemPurchased;
		//Вызывается, если система покупок поддерживается
		StoreEvents.OnBillingSupported += onBillingSupported;
		//Вызывается, если система покупок не поддерживается
		StoreEvents.OnBillingNotSupported += onBillingNotSupported;
		//Вызывается, когда начата покупка за реальные деньги
		StoreEvents.OnMarketPurchaseStarted += onMarketPurchaseStarted;
		//Вызывается, когда начата покупка за внутриигровую валюту
		StoreEvents.OnItemPurchaseStarted += onItemPurchaseStarted;
		//Вызывается, когда покупка за реальные деньги отменена
		StoreEvents.OnMarketPurchaseCancelled += onMarketPurchaseCancelled;
		//Вызывается, когда магазин инициализирован
		StoreEvents.OnSoomlaStoreInitialized += onSoomlaStoreInitialized;
		//Вызывается, когда появился внутрянняя ошибка Soomla
		StoreEvents.OnUnexpectedStoreError += onUnexpectedStoreError;

		//Только для андроид
#if UNITY_ANDROID && !UNITY_EDITOR
		StoreEvents.OnIabServiceStarted += onIabServiceStarted;
		StoreEvents.OnIabServiceStopped += onIabServiceStopped;
#endif
	}
	public void onUnexpectedStoreError(int errorCode) {
		SoomlaUtils.LogError ("ExampleEventHandler", "error with code: " + errorCode);
	}
	public void onMarketPurchase(PurchasableVirtualItem pvi, string payload, Dictionary<string, string> extra) {

	}
	public void onItemPurchased(PurchasableVirtualItem pvi, string payload) {

	}
	public void onBillingSupported() {

	}
	public void onBillingNotSupported() {

	}
	public void onMarketPurchaseStarted(PurchasableVirtualItem pvi) {

	}
	public void onItemPurchaseStarted(PurchasableVirtualItem pvi) {

	}
	public void onMarketPurchaseCancelled(PurchasableVirtualItem pvi) {

	}
	public void onCurrencyBalanceChanged(VirtualCurrency virtualCurrency, int balance, int amountAdded) {

	}
	public void onSoomlaStoreInitialized() {
		
	}

#if UNITY_ANDROID && !UNITY_EDITOR
	public void onIabServiceStarted() {

	}
	public void onIabServiceStopped() {

	}
#endif
}



Вот и все, система полностью готова к работе.

Но теперь немного о личном кабинете Soomla. Там вы можете отслеживать все транзакции ваших пользователей, как с реальными деньгами, так и с внутриигровой валютой, для того и нужны блага и категории, чтобы проще было все отслеживать, но для работы с этой вещью нужно еще поработать с Soomla Highway. Но эта статья не об этом.

И пару слов о тестировании. Тестировать покупки на android просто, залили билд, к примеру, для бета теста и тестируйте на здоровье, но вот на ios обязательно создайте аккаунт для sandbox:

Комментарии (14)


  1. ghaiklor
    31.07.2015 13:34

    Выкладывать API ключи и прочее в открытый доступ — достойно уважения.


    1. OnionFan Автор
      31.07.2015 15:45

      Если вы про Game Key от сумлы, то он от тестового проекта и не сделает никакой погоды


      1. ghaiklor
        01.08.2015 14:48

        Не имеет значения от чего он. Выработайте за привычку, такие вещи вообще не светить.


  1. Maklaud
    31.07.2015 22:17

    Пробовал подключить OpenIAB. Делал по 3 разным их документациям, включая демо-проект. Так и не заставил работать. Писал напрямую в их команду, получил лишь 1 ответ от Карины с глупыми вопросами про коллбэки, потом плюнул и удалил. Планирую попробовать Soomla.


    1. OnionFan Автор
      01.08.2015 09:59

      Если нужно, могу в личку скинуть ссылку на настроенный OpenIAB, он работать будет, но только под Android, iOS я так и не смог заставить работать, неделя была потрачена впустую на это дело.


      1. Maklaud
        01.08.2015 12:42

        Спасибо, наверное не нужно. Я сильно разочаровался в этой команде и их способе вести дела. Не хочу работать с этим плагином ))


  1. Leopotam
    01.08.2015 13:01

    Unibill — нет апи для удаления Consumable предмета — они просто копятся. Удалять можно только локальную базу целиком.
    Prime31 — был адский треш с интеграцией других плагинов в один проект. Поделия prime31 считали что никто кроме них не должен жить в проекте.
    Soomla — единственный вменяемый проект, но тоже не без проблем. Например, когда меняется апи в юнити, то апдейт плагина может наступить через полгода.


    1. Igor_Sib
      01.08.2015 15:04

      +1 по Prime31. Вспоминаю один негатив про них, хоть куплено около десятка их плагинов стараемся земенить их по мере возможности другими.


    1. OnionFan Автор
      01.08.2015 18:23

      Unibill — нет апи для удаления Consumable предмета — они просто копятся. Удалять можно только локальную базу целиком.
      Prime31 — был адский треш с интеграцией других плагинов в один проект. Поделия prime31 считали что никто кроме них не должен жить в проекте.


      Спасибо, даже не знал об этих тонкостях.


  1. Leopotam
    01.08.2015 13:07

    хоть и смутило то, что придется еще работать через личный кабинет на их сайте, но на самом деле, делать там почти ничего не нужно, потому выбор остановился на этом варианте.

    Там вообще ничего делать не нужно, как и регистрироваться — готовые unitypackage-ы (core + iap) можно скачать с гитхаба сумлы и просто импортировать в проект. Гуй магазина (storefront) обычно пилится под каждый проект индивидуально средствами юнити, так что в самом сервисе сумлы смысла нет вообще.


    1. OnionFan Автор
      01.08.2015 18:24

      Сервис сумлы может быть пригоден как небольшая система аналитики по всем покупкам, но лучше, конечно, использовать систему аналитики общую.


  1. avvor
    01.08.2015 15:16

    А оно должно работать если игра в статусе Бета версии в гуглсторе и при этом просто загрузить apk на телефон? Или только если скачиваешь с гуглстора?
    И второй вопрос, как отдебажить на реальном устройстве? Т.к. в юнити в логе пишет что покупки проходят и ошибок нет, а на реальном устройстве падает.
    … Вроде как 3 строчки кода и все как в этом туторе, но почему то падает…


    1. avvor
      01.08.2015 16:52

      А вот нашел способ дебажить, ошибка — java.lang.ClassNotFoundException: com.soomla.store.billing.google.GooglePlayIabService


    1. OnionFan Автор
      01.08.2015 18:25

      А оно должно работать если игра в статусе Бета версии в гуглсторе и при этом просто загрузить apk на телефон? Или только если скачиваешь с гуглстора?

      Только если скачиваешь с гуглстора. Можете использовать хоть как альфа версию, главное качать из магазина.