このページでは

アプリ内課金のデモ

アプリ内商品の購入を実演する完全なモバイルアプリケーションです。

注: Qt Purchasingモジュールは 、Qt 6.0で削除されたモジュールの一つでしたが、現在、このサンプルには、Qtを使用して一般的なマーケットプレイスと連携する方法のガイドとして、そのコードが含まれています。

このデモとは?

文字キーボードと隠された単語を表すダッシュを使ったハングマンゲーム

このデモは、古典的な単語当てゲーム「ハングマン」をベースにしたモバイルゲームアプリケーションで、デモ内のストアを通じて母音を購入することができます。ゲームでは、当てるべき単語の文字を表すダッシュの列が表示されます。 与えられた単語に含まれる正しい文字を当てると、その文字が単語内の対応するダッシュに配置されます。単語のすべての文字を当てたり、いつでも単語全体を正しく当てたりすると、ゲームは終了し、勝利となります。答えが間違っていると、首吊りの棒人間の一部分が1つ描かれます。 その人物の絵が完成すると、推測回数が尽き、ゲームオーバーとなります。

このデモでは、AndroidおよびiOSプラットフォーム向けのQtアプリケーション内で、アプリ内課金商品をどのように提供できるかを示しています。デモでアプリ内課金機能をテストするには、まず外部ストアでアプリケーションとその商品を登録する必要があります。その方法については、Google Play およびApp Storeの各ガイドを参照してください。

サードパーティのアプリストア

アプリ内で商品を検索または購入できるようにするには、事前に各ストアにアプリ内商品を登録しておく必要があります。各ストアで商品に同じ識別子を使用することをお勧めします。これにより、商品の検索や購入に関するコードが簡素化されます。

デモの仕組み

このデモは、アプリ内商品に関する情報にアクセスしたり、それらの商品の購入をリクエストしたりするために QML タイプを登録する QML アプリケーションです。これらは、対象プラットフォームの外部ストアに登録されています。

アプリ内課金をアプリケーションに追加するには、まず Store オブジェクトを追加します。このデモでは、アプリケーションの起動時に読み込まれる MainView コンポーネントによって Store オブジェクトが作成されます。

Store {
    id: iapStore
}

このデモでは、利用可能なアプリ内商品を購入するためのストアを表示するコンポーネントが定義されています。これらの商品は、まず前述の MainView で作成した Store オブジェクトに登録する必要があります。利用可能な商品は 2 つあり、1 つ目は消費型商品です。

Product {
    id: product100Vowels
    store: iapStore
    type: Product.Consumable
    identifier: "qt.io.demo.hangman.100vowels"

    onPurchaseSucceeded: {
        console.log(identifier + " purchase successful");
        //Add 100 Vowels
        applicationData.vowelsAvailable += 100;
        transaction.finalize();
        pageStack.pop();
    }

    onPurchaseFailed: {
        console.log(identifier + " purchase failed");
        console.log("reason: "
                    + transaction.failureReason === Transaction.CanceledByUser ? "Canceled" : transaction.errorString);
        transaction.finalize();
    }
}

この消費型商品は、ゲーム内で単語を推測する際に使用できる母音を100個追加で提供します。購入が成功すると、アプリケーションの状態を更新して、100個の母音を追加します。その後、トランザクションオブジェクトのfinalize()を呼び出し、消費型商品が提供されたことをプラットフォームのストアに通知します。

2つ目の商品は、将来的に母音を恒久的にアンロックする非消耗品タイプです。購入時にアプリケーションの状態を更新することに加え、エンドユーザーが使用する他のデバイスでもこの購入履歴を復元できる仕組みを用意する必要があります。この場合、onPurchaseRestored用のシグナルハンドラを作成します。

Product {
    id: productUnlockVowels
    type: Product.Unlockable
    store: iapStore
    identifier: "qt.io.demo.hangman.unlockvowels"

    onPurchaseSucceeded: {
        console.log(identifier + " purchase successful");
        applicationData.vowelsUnlocked = true;
        transaction.finalize();
        pageStack.pop();
    }

    onPurchaseFailed: {
        console.log(identifier + " purchase failed");
        console.log("reason: "
                    + transaction.failureReason === Transaction.CanceledByUser ? "Canceled" : transaction.errorString);
        transaction.finalize();
    }

    onPurchaseRestored: {
        console.log(identifier + " purchase restored");
        applicationData.vowelsUnlocked = true;
        console.log("timestamp: " + transaction.timestamp);
        transaction.finalize();
        pageStack.pop();
    }
}

母音の購入オプションと価格を備えた「ハングマン・ストア」

製品の登録に加え、このデモでは登録された製品を実際に購入するためのインターフェースも提供しています。デモでは、購入操作の表示と処理を行うために、StoreItem というカスタムコンポーネントを定義しています。

Product {
    id: productUnlockVowels
    type: Product.Unlockable
    store: iapStore
    identifier: "qt.io.demo.hangman.unlockvowels"

    onPurchaseSucceeded: {
        console.log(identifier + " purchase successful");
        applicationData.vowelsUnlocked = true;
        transaction.finalize();
        pageStack.pop();
    }

    onPurchaseFailed: {
        console.log(identifier + " purchase failed");
        console.log("reason: "
                    + transaction.failureReason === Transaction.CanceledByUser ? "Canceled" : transaction.errorString);
        transaction.finalize();
    }

    onPurchaseRestored: {
        console.log(identifier + " purchase restored");
        applicationData.vowelsUnlocked = true;
        console.log("timestamp: " + transaction.timestamp);
        transaction.finalize();
        pageStack.pop();
    }
}

StoreItemコンポーネントは、プラットフォームのストアから取得した商品データを表示し、ユーザーがクリックした際にその商品のpurchase()メソッドを呼び出します。

Text {
    id: titleText
    text: product.title
    font.bold: true
    anchors.right: priceText.left
    anchors.rightMargin: topLevel.globalMargin
    anchors.top: parent.top
    anchors.topMargin: topLevel.globalMargin
    anchors.left: parent.left
    anchors.leftMargin: topLevel.globalMargin
}

Text {
    id: descriptionText
    text: product.description
    anchors.right: priceText.left
    anchors.rightMargin: topLevel.globalMargin
    anchors.left: parent.left
    anchors.leftMargin: topLevel.globalMargin
    anchors.top: titleText.bottom
    anchors.topMargin: topLevel.globalMargin / 2
    wrapMode: Text.WordWrap
}

Text {
    id: priceText
    text: product.price
    anchors.right: parent.right
    anchors.rightMargin: topLevel.globalMargin
    anchors.verticalCenter: parent.verticalCenter
}

MouseArea {
    anchors.fill: parent
    onClicked: {
        pendingRect.visible = true;
        spinBox.visible = true;
        statusText.text = "Purchasing...";
        storeItem.state = "PURCHASING";
        product.purchase();
    }
    onPressed: {
        storeItem.state = "PRESSED";
    }
    onReleased: {
        storeItem.state = "NORMAL";
    }
}

AndroidとiOSでは基底クラスが使用されます。基底クラスから、AndroidおよびiOS用の派生クラスが定義されています:

アプリ内課金

アプリ内課金は、アプリケーションを収益化する方法の一つです。これらの課金はアプリケーション内から行われ、コンテンツのロック解除から仮想アイテムの購入まで、あらゆるものが対象となります。 このデモでは、アプリ内購入用のシステムAPIを使用しています。これにより、ユーザーにとって購入プロセスがより馴染み深いものとなり、プラットフォームにすでに保存されている情報(クレジットカード情報など)を利用して、購入プロセスを簡略化することができます。

ライセンスおよび帰属表示

Android でのデモの展開については、「AndroidGNU C++ ランタイムのライセンス」を参照してください。

サンプルプロジェクト @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.