Начало работы с Qt Purchasing в C++
В данном руководстве предполагается, что вы зарегистрировали внутриигровые продукты для вашего приложения в внешнем магазине. Для получения дополнительной информации о регистрации продуктов см. Регистрация продуктов в Google Play, Регистрация продуктов в App Store и Регистрация продуктов в Windows Store.
Подготовка приложения
Используйте следующую директиву подключения для доступа к классам C++:
#include <QtPurchasing>
Перед компиляцией приложения добавьте следующую строку в ваш .pro файл для линковки с библиотекой Qt Purchasing:
QT += purchasing
Регистрация продуктов
Для поддержки внутриигровых покупок в вашем приложении, зарегистрируйте продукты в приложении. Начните с создания глобальной для приложения инстанции QInAppStore и используйте функцию registerProduct() для регистрации каждого продукта.
Следующий пример — это гипотетическая ролевая игра, предоставляющая пользователю два внутриигровых продукта.
MyApplication::MyApplication(QObject *parent)
: QObject(parent)
{
m_myStore = new QInAppStore(this);
setupConnections();
m_myStore->registerProduct(QInAppProduct::Consumable,
QStringLiteral("healthPotion"));
m_myStore->registerProduct(QInAppProduct::Unlockable,
QStringLiteral("dlcForestOfFooBar"));
} Как видите, существуют потребляемые продукты и разблокируемые продукты. Первые могут быть приобретены пользователем любое количество раз, а вторые — только один раз.
В нашем примере "healthPotion" — это потребляемый продукт, потому что пользователь должен иметь возможность покупать любое количество зелий здоровья и добавлять их в свой инвентарь в игре.
"dlcForestOfFooBar" — это загружаемый контент, который разблокирует новую часть игры, и после покупки он сохраняется на устройствах пользователя и после переустановок.
Установление подключений
Регистрация продукта — асинхронная операция, как и все операции, поддерживаемые Qt Purchasing. Перед началом регистрации продукта необходимо прослушивать сигналы QInAppStore::productRegistered() и QInAppStore::productUnknown() в QInAppStore для получения статуса вашей регистрации.
Если приложение должно позволять пользователям покупать продукты, оно также должно прослушивать сигнал QInAppStore::transactionReady(), чтобы получать уведомления о том, когда транзакция ожидает обработки.
void MyApplication::setupConnections()
{
connect(m_myStore, SIGNAL(productRegistered(QInAppProduct*)),
this, SLOT(markProductAvailable(QInAppProduct*)));
connect(m_myStore, SIGNAL(productUnknown(QInAppProduct*)),
this, SLOT(handleErrorGracefully(QInAppProduct*)));
connect(m_myStore, SIGNAL(transactionReady(QInAppTransaction*)),
this, SLOT(handleTransaction(QInAppTransaction*)));
} Покупка продукта
Когда пользователь хочет приобрести продукт, вызовите QInAppProduct::purchase() для данного продукта. Это запускает платформозависимый асинхронный процесс покупки продукта, например, запрашивая пароль пользователя и подтверждение покупки. В большинстве случаев необходимо убедиться, что пользовательский интерфейс приложения не принимает ввод, пока обрабатывается запрос на покупку, так как это не обрабатывается автоматически на всех платформах.
void MyApplication::purchaseHealthPotion()
{
QInAppProduct *product = m_myStore->registeredProduct(QStringLiteral("healthPotion"));
// Should not get here if product is not registered
Q_ASSERT(product != 0);
product->purchase();
} После вызова этой функции процесс покупки запускается. В какой-то момент процесса испускается сигнал QInAppStore::transactionReady(), и вызывается ранее зарегистрированный слот. В этой функции вы можете сохранить данные о успешной покупке, чтобы они сохранились при последующих запусках приложения. После проверки того, что данные были сохранены, завершите транзакцию. В случае неудачи транзакции отобразите пользователю информацию об ошибке и завершите транзакцию.
void MyApplication::handleTransaction(QInAppTransaction *transaction)
{
if (transaction->status() == QInAppTransaction::PurchaseApproved
&& transaction->product()->identifier() == QStringLiteral("healthPotion")) {
if (!hasAlreadyStoredTransaction(transaction->orderId()) {
++m_healthPotions;
if (!addHealthPotionToPersistentStorage(transaction->orderId())
popupErrorDialog(tr("Unable to write to persistent storage. Please make sure there is sufficient space and restart."))
else
transaction->finalize();
}
} else if (transaction->status() == QInAppTransaction::PurchaseFailed) {
popupErrorDialog(tr("Purchase not completed."));
transaction->finalize();
}
} Если транзакция не завершена, сигнал transactionReady() испускается снова для той же транзакции при следующей регистрации продукта, предоставляя ещё одну возможность для сохранения данных. Транзакция для потребляемого продукта должна быть завершена перед тем, как этот продукт можно будет купить снова.
Восстановление ранее купленных продуктов
Если приложение было удалено и затем повторно установлено (или установлено тем же пользователем на другом устройстве), вы должны предоставить способ восстановления ранее купленных разблокируемых продуктов.
Для начала процесса восстановления покупок вызовите функцию QInAppStore::restorePurchases(). Это испускает сигнал QInAppStore::transactionReady() для каждого разблокируемого продукта приложения, который был ранее куплен текущим пользователем. Статус этих транзакций будет QInAppTransaction::PurchaseRestored.
Продолжая пример из предыдущего пункта, представим, что в игре есть загружаемый контент, который можно купить для расширения игры. Это должен быть разблокируемый продукт, поскольку пользователь не должен покупать его более одного раза.
void MyApplication::handleTransaction(QInAppTransaction *transaction)
{
if ((transaction->status() == QInAppTransaction::PurchaseApproved
|| transaction->status() == QInAppTransaction::PurchaseRestored)
&& transaction->product()->identifier() == QStringLiteral("dlcForestOfFooBar"))
{
if (!hasMap(QStringLiteral("forestOfFooBar.map")) {
if (!downloadExtraMap(QStringLiteral("forestOfFooBar.map")))
popupErrorDialog(tr("Unable to download The Forest of FooBar map. Please make sure there is sufficient space and restart."))
else
transaction->finalize()
}
} else if (transaction->status() == QInAppTransaction::PurchaseApproved
&& transaction->product()->identifier() == QStringLiteral("healthPotion")) {
// ... handle healthPotion purchase
} else {
popupErrorDialog(tr("Purchase not completed."));
transaction->finalize();
}
} Если пользователь покупает загружаемый контент, а затем устанавливает игру на другое устройство или удаляет и переустанавливает игру, вы можете предоставить способ восстановления покупки, вызвав QInAppStore::restorePurchases(). Покупки должны быть восстановлены в ответ на ввод пользователя, так как на некоторых платформах может появиться диалоговое окно с паролем.
Примечание: Хотя функция ведет себя как описано в документации на Android, эта функциональность технически там не нужна. Android обрабатывает все разблокируемые покупки без вмешательства приложения. Если приложение удалено и переустановлено (или установлено на другом устройстве Android), QInAppStore::transactionReady() испускается при запуске приложения для каждого ранее купленного разблокируемого продукта со статусом QInAppTransaction::PurchaseApproved.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.9/qtpurchasing-gettingstarted-cpp.html