Начало работы с Qt Purchasing в QML
Данное руководство предполагает, что вы зарегистрировали внутриприложение продукты для вашего приложения в внешнем магазине. Для получения дополнительной информации о регистрации продуктов см. Регистрация продуктов в Google Play и Регистрация продуктов в App Store
Подготовка приложения
Используйте следующую import инструкцию в файлах QML для доступа к типам QML Qt Purchasing:
import QtPurchasing 1.15
Добавьте следующую инструкцию в ваш .pro файл, чтобы связать библиотеку Qt Purchasing:
QT += purchasing
Регистрация продуктов
Прежде чем вы сможете работать с продуктами в вашем коде, они должны быть зарегистрированы в QML-графе. Вы начинаете с создания элемента Store, а затем создаете каждый продукт в качестве дочернего элемента этого элемента.
Store {
Product {
identifier: "consumableProduct"
type: Product.Consumable
// ...
}
Product {
identifier: "unlockableProduct"
type: Product.Unlockable
// ...
}
} Как вы можете видеть, существуют потребляемые продукты и продукты, разблокирующие доступ. Первые могут быть приобретены неограниченное количество раз одним и тем же пользователем, в то время как вторые могут быть приобретены только один раз.
Описание продукта
Для каждого продукта необходимо заполнить identifier, прежде чем продукт сможет быть запрошен из внешнего магазина. Вы также должны всегда добавлять обработчик onPurchaseSucceeded и обработчик onPurchaseFailed, если вы хотите предоставить возможность приобретения продуктов. Если вы также используете функцию восстановления, вы должны добавить обработчик onPurchaseRestored для продуктов, разблокирующих доступ.
Обработчики сигналов должны обрабатывать входящие транзакции. После того, как транзакция была обработана должным образом, она должна быть завершена. Например, когда покупка прошла успешно, уместно сохранить информацию о приобретенном продукте в постоянном хранилище, чтобы этот продукт оставался доступным при следующем запуске приложения.
Следующий пример вызывает пользовательские методы для сохранения данных о успешной покупке, чтобы они сохранились при повторных запусках приложения. После проверки того, что данные были сохранены, он завершает транзакцию. Когда транзакция завершается неудачно, он отображает пользователю информацию об ошибке и завершает транзакцию.
Store {
id: store
Product {
id: healthPotionProduct
identifier: "healthPotion"
type: Product.Consumable
property bool purchasing: false
onPurchaseSucceeded: {
if (!hasAlreadyStoredTransaction(transaction.orderId)) {
++healthPotions
if (!addHealthPotionToPersistentStorage(transaction.orderId)) {
popupErrorDialog(qsTr("Unable to write to persistent storage. Please make sure there is sufficient space and restart."))
} else {
transaction.finalize()
}
}
// Reset purchasing flag
purchasing = false
}
onPurchaseFailed: {
popupErrorDialog(qsTr("Purchase not completed."))
transaction.finalize()
// Reset purchasing flag
purchasing = false
}
}
} Если транзакция не завершена, она будет вызвана снова для той же транзакции при следующем запуске приложения, предоставляя еще одну возможность сохранить данные. Транзакция для потребляемого продукта должна быть завершена, прежде чем продукт сможет быть приобретен снова.
Покупка продукта
Для покупки продукта вызовите метод purchase() объекта. Это запускает платформенно-специфичный асинхронный процесс покупки продукта, например, запрашивая пароль пользователя и подтверждение покупки. В большинстве случаев необходимо убедиться, что пользовательский интерфейс приложения не принимает ввод данных во время обработки запроса на покупку, так как это не обрабатывается автоматически на всех платформах.
Следующий пример добавляет кнопку для использования с примерным продуктом в предыдущем разделе:
Rectangle {
id: button
width: 100
height: 50
Text {
anchors.centerIn: parent
text: qsTr("Buy health potion for only " + healthPotionProduct.price + "!")
}
MouseArea {
enabled: !healthPotionProduct.purchasing && healthPotionProduct.status === Product.Registered
anchors.fill: parent
onClicked: {
healthPotionProduct.purchasing = true
healthPotionProduct.purchase()
}
}
} При нажатии кнопки запускается процесс покупки. В какой-то момент в будущем будет вызван обработчик onPurchaseFailed (например, если пользователь отменит транзакцию) или обработчик onPurchaseSucceeded.
Примечание: Кнопка активна только в том случае, если статус продукта установлен как Registered. Процесс регистрации продукта асинхронный, поэтому попытки покупки продукта до его успешной регистрации всегда приведут к ошибке.
Восстановление ранее купленных продуктов
Если приложение удаляется и затем повторно устанавливается (или устанавливается тем же пользователем на другом устройстве), вам необходимо предоставить способ восстановления ранее приобретенных продуктов, разблокирующих доступ, во внешнем рынке.
Чтобы запустить процесс восстановления покупок, вы должны вызвать метод restorePurchases() в объекте Store. Это приведет к вызову обработчика onPurchaseRestored для каждого из продуктов, разблокирующих доступ в приложении, которые были ранее приобретены текущим пользователем.
Продолжая пример из предыдущего раздела, который мог бы быть какой-то ролевой компьютерной игрой, представим, что игра имеет загружаемый контент, который можно купить, чтобы расширить игру дальше. Это должен быть продукт, разблокирующий доступ, потому что пользователь не должен покупать его более одного раза.
Store {
id: store
// ... other products
Product {
id: dlcForestOfFooBarProduct
identifier: "dlcForestOfFooBar"
type: Product.Unlockable
property bool purchasing: false
onPurchaseSucceeded: {
if (!hasMap("forestOfFooBar.map")) {
if (!downloadExtraMap("forestOfFooBar.map")) {
popupErrorDialog(qsTr("Unable to download The Forest of FooBar map. Please make sure there is sufficient space and restart."))
} else {
transaction.finalize()
}
}
// Reset purchasing flag
purchasing = false
}
onPurchaseFailed: {
popupErrorDialog(qsTr("Purchase not completed."))
transaction.finalize()
// Reset purchasing flag
purchasing = false
}
onPurchaseRestored: {
if (!hasMap("forestOfFooBar.map")) {
if (!downloadExtraMap("forestOfFooBar.map")) {
popupErrorDialog(qsTr("Unable to download The Forest of FooBar map. Please make sure there is sufficient space and restart."))
} else {
transaction.finalize()
}
}
}
}
} Если пользователь купил загружаемый контент и позже установил игру на другое устройство или удалил и повторно установил игру, вы можете предоставить способ восстановления покупки, например, следующую кнопку:
Rectangle {
id: restoreButton
width: 100
height: 50
Text {
anchors.centerIn: parent
text: "Restore previously purchased content"
}
MouseArea {
anchors.fill: parent
onClicked: {
store.restorePurchases()
}
}
} Восстановление покупок всегда должно выполняться в ответ на ввод данных пользователя, так как на некоторых платформах может быть представлен диалог пароля. Вызов метода restorePurchases() запускает процесс восстановления асинхронно. В какой-то момент в будущем обработчик onPurchaseRestored будет вызван, если продукт был ранее приобретен.
Примечание: Хотя функция ведет себя в соответствии с документацией на Android, эта функциональность технически не требуется там. Причина в том, что устройство Android управляет всеми приобретениями, разблокирующими доступ, без вмешательства приложения. Если приложение удаляется и повторно устанавливается (или устанавливается на другом устройстве) на Android, то onPurchaseSucceeded будет вызван для каждого ранее приобретенного продукта, разблокирующего доступ, при запуске приложения.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qtpurchasing-gettingstarted-qml.html