Первый опыт разработки под Windows Phone: In-App Purchasing

в 8:05, , рубрики: in-app purchases, windows phone, разработка под windows phone, метки: , ,

Первый опыт разработки под Windows Phone: In App Purchasing

В данной статье рассмотрена возможность использования внутренних платежей в ваших мобильных Windows Phone 8 приложениях на примере собственного приложения «Ежедневный гороскоп».
Если данная тема интересна, то прошу под кат.

На данный момент в dev.windowsphone.com существует возможность создавать бесплатные, платные, триал/демо-версии приложений, а так же In-App покупки. В свою очередь In-App покупки бывают — расходуемые и постоянные. В моем приложении я использовал «постоянные»(рис.1), то есть пользователь установил приложение, а за дополнительный функционал платит один раз. «Постоянные» так же могут иметь срок своего действия, либо без срочные. Пример «постоянного» это покупка оружия или уникального рецепта, а со сроком действия — подписка на чтение журнала или лицензия. К «расходуемые» можно отнести валюту приложения(кристаллы). Если у вас существует много рецептов, и для того, чтобы не создавать по каждый рецепт «внутренний продукт» для покупки можно воспользоваться расходуемой покупкой, тогда контроль покупки ложится на разработчика. Самое главное при реализации любого кода старайтесь всё, что выполняется продолжительное время делать асинхронными запросами, иначе модераторы не пропустят такое приложение.

Примечание: если у вас триал версия программы, пока пользователь не купит ее — In-App платежи работать не будут.

image
рис. 1 — пример UI In-App Purchasing

Для того, что бы протестировать ваши платежи, вы можете использовать специальную библиотеку MockIAPLib — подробнее [EN], но для простого приложения есть выход намного проще — просто в dev центре опубликуйте свое приложение как Beta, тогда все ваши покупки будут равны 0 руб, а тесты приближены максимально к боевым условиям.

Первый опыт разработки под Windows Phone: In App Purchasing
Рис.2 — покупка в Beta версии

И так, как же создать In-App Purchasing?

1. Зайти в Dev центр WP и перейти по ссылке «Отправка приложения».
2. Заполнить «Сведения о приложении» (в моем случае приложение полностью бесплатно), тут же указывается в разделе «Дополнительные параметры» релиз или бета и т.п…
3. В левом меню выберите пункт «Приложения», находим там вновь созданное. И переходим на вкладку «Продукты», там создаем наш продукт, главное, что нам понадобится — это «Продукт ID».
4. Теперь откройте свой проект, и откройте в нем файл WMAppManifest.xml, далее перейдите на вкладку «Packing». Посмотрите содержимое Product ID, он должен соответствовать тому, что указано в сведениях о вашем приложении в Dev центре WP — «Идентификатор приложения».

Готово, у вас есть заготовка приложения, и продукты этого приложения. Если интересны скриншоты, то можно посмотреть их тут [EN].

Зависимости:

using Windows.ApplicationModel.Store;
using Store = Windows.ApplicationModel.Store;

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

код

private async void btnListAllProducts_Click_1(object sender, RoutedEventArgs e)
  {
    StringBuilder sb = new StringBuilder();
 
    var listing = await CurrentApp.LoadListingInformationAsync();
    foreach (var product in listing.ProductListings)
    {
      sb.AppendLine(string.Format("{0}, {1}, {2},{3}, {4}",
        product.Key,
        product.Value.Name,
        product.Value.FormattedPrice,
        product.Value.ProductType,
        product.Value.Description));
    }
 
    MessageBox.Show(sb.ToString(), "List all products", MessageBoxButton.OK);
  }

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

Реализация постоянной покупки:

код

async private void btnBuy_Click_1(object sender, RoutedEventArgs e)
{
  // загрузим с интернета информацию
  var listing=await CurrentApp.LoadListingInformationAsync();
  var superweapon=
  listing.ProductListings.FirstOrDefault(
    p => p.Value.ProductId == "ТУТ ВАШ ID ТОВАРА" );
  try
    {
//проверка, а нужно ли покупать
      if (CurrentApp.LicenseInformation.ProductLicenses[superweapon.Value.ProductId].IsActive)
    {
      MessageBox.Show("Вы уже покупали!");
    }
    else
    {
//отобразим стандартный UI покупки как на рис. выше
    receipt = await CurrentApp.RequestProductPurchaseAsync(superweapon.Value.ProductId, false);
//получаем лицензию - заканчиваем покупку
                    var productLicenses = CurrentApp.LicenseInformation.ProductLicenses;
                    ProductLicense tokenLicense = productLicenses["ТУТ ВАШ ID ТОВАРА"];
                    if (tokenLicense.IsActive)//смотрим куплено ли приложение
                    {
                     //тут сохраните себе, например в IsolatedStorageSettings, что продукт куплен
                    txtBoughtSW.Visibility=System.Windows.Visibility.Visible;
                    txtBoughtSW.Text="Спасибо за покупку";
                    }
                    else
                    {
                       //пользователь не завершил покупку
                    }

    }
    }
    catch (Exception ex)
    {
    //для пользователя тут покажите что то более внятное
      MessageBox.Show(ex.ToString());
    }          
  }

Как ведите все просто, получили список с информацией и обрабатываем как нам угодно. Показали пользователю UI покупки и ждем результат.

Пример расходуемой покупки:

код

async private void btnBuy50Points_Click_1(object sender, RoutedEventArgs e)
{
  // 50 Points  - запроси информацию о доступных товарах
  var listing=await CurrentApp.LoadListingInformationAsync();
  var fiftypoints=
    listing.ProductListings.FirstOrDefault(
    p => p.Value.ProductId == "ТУТ ВАШ ID ТОВАРА" );
 
  try
  {
//покажем UI покупки
    receipt=await CurrentApp.RequestProductPurchaseAsync(fiftypoints.Value.ProductId, false);
 
  if (CurrentApp.LicenseInformation.ProductLicenses[fiftypoints.Value.ProductId].IsActive)
  {
    //добавим 50 очкнов
    m_pointCount+=50;
    //если все хорошо, отошлем "магазину", что мы обработали покупку и дали пользователю его 50 очков
    CurrentApp.ReportProductFulfillment(fiftypoints.Value.ProductId);
    txtBought50Pts.Visibility=System.Windows.Visibility.Visible;
    txtBought50Pts.Text=
      "Bought 50 Points " + i++ + " times for a total of " + m_pointCount + "!";
  }
}
  catch (Exception ex)
  {
    MessageBox.Show(ex.ToString());
  }         
}

Единственное отличие расходуемой и постоянной покупкой, то что в в расходуемой ОБЯЗАТЕЛЬНО необходимо сообщить «магазину», что вы обработали ответ покупки. Иначе пользователь не сможет купить снова ваш товар(кристаллы) пока вы не выполните команду:

CurrentApp.ReportProductFulfillment(fiftypoints.Value.ProductId);

А так же хранение о покупаемых продуктах ложится на разработчика. Ему необходимо побеспокоится, что пользователь может удалить приложение и поставить его заново, а разработчик должен правильно его идентифицировать.

Пример реализации постоянной покупки в моем приложении:

код

private async void Button_Click(object sender, RoutedEventArgs e)
        {
            //проверяю, доступно ли интернет соединение
            if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
            {
             ******покажите что приложение что то обрабатывает*****
                try
                {
                    //получаем список продуктов по известному ид
                    ListingInformation LicensePremiumID = await Store.CurrentApp.LoadListingInformationByProductIdsAsync(new string[] { "ВАШID" });
                    
                    //покупаем продукты
                    string x = await CurrentApp.RequestProductPurchaseAsync(LicensePremiumID.ProductListings.ToList()[0].Value.ProductId, false);

                    //получаем лицензию 
                    var productLicenses = CurrentApp.LicenseInformation.ProductLicenses;
                    ProductLicense tokenLicense = productLicenses["ВАШID"];

                    if (tokenLicense.IsActive)//смотрим куплено ли приложение
                    {
                        IsolatedStorageSettings.ApplicationSettings["имя переменной"] = "1";//сохранение
                        AppSetting.ApplicationFullVersiy = true;
                        //пошлем донесение, что мы обработали покупку! для постоянной покупки не обязательно
                        //CurrentApp.ReportProductFulfillment(tokenLicense.ProductId);
                        MessageBox.Show("«Ежедневные гороскопы Premium» активировано успешно. Спасибо за покупку!");
                       ***
                    }
                    else
                    {
                        MessageBox.Show("IsActive - false");
                         ***
                    }

                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                    MessageBox.Show("*****");

                }
            }
            else
            {
                MessageBox.Show("Нет интернет соединения...");
            }
        }

Если пользователь уже покупал раньше, то:

код

 private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
            {
                  ***
                try
                {

                    var productLicenses = CurrentApp.LicenseInformation.ProductLicenses;
                    ProductLicense tokenLicense = productLicenses["ВАШID"];

                    if (tokenLicense.IsActive)//смотрим куплено ли приложение
                    {
                        IsolatedStorageSettings.ApplicationSettings["ept"] = "1";//сохранение
                        AppSetting.ApplicationFullVersiy = true;

                         ****
                        MessageBox.Show("«Ежедневные гороскопы Premium» активировано успешно.");
                    }
                    else
                    {
                        MessageBox.Show("«Ежедневные гороскопы Premium» не активировано.");
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                    MessageBox.Show("****..");

                }
            }
            else
            {
                MessageBox.Show("Нет интернет соединения...");
            }
        }

Результат:

Скрытый текст

Первый опыт разработки под Windows Phone: In App Purchasing
Первый опыт разработки под Windows Phone: In App Purchasing

В играх реализация похожа, как и в Windows Stor. Если что-то забыл описать, пишите в комментарии, буду рад ответить на все ваши вопросы.

офф топ

Решил рассказать про In-App Purchasing, так как не нашел исчерпывающей информации на просторах русского интернета, в том чесле и на habr, остальные этапы разработки(UI, Async/await, JSON) решил пропустить так как на хабре есть похожие статьи, но если будут желающие узнать об этом, пишите в комментарии, ссылки на свое приложение тоже не оставляю дабы не подумали, что я пиарюсь, его легко можно найти по названию

Автор: vangogh_rus

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js