Начало работы с покупками Qt в QML
Данное руководство предполагает, что вы зарегистрировали продукты приложения в внешнем магазине. Дополнительную информацию о регистрации продуктов см. в Регистрация продуктов в Google Play и Регистрация продуктов в App Store
Подготовка приложения
Используйте следующее import утверждение в файлах QML для доступа к типам QML Qt Purchasing:
import QtPurchasing 1.0
Добавьте следующее утверждение в ваш .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/archives/qt-5.11/qtpurchasing-gettingstarted-qml.html