Unity専用決済モジュール

Unity専用now.gg決済モジュールを使用すると、Unity上のゲーム内でアプリ内課金を実装することができます。

now.gg決済モジュールを使用してアプリ内課金を実装する方法:

  1. Unity専用now.gg決済モジュールをダウンロードしてインポートします。
  2. 必要な依存関係を追加します。
  3. プロジェクトにnow.gg決済を実装します。

モジュールのダウンロードとインポート

Unity専用now.gg決済モジュールはUnityパッケージファイルnowgg-payments-login.unitypackageとして含まれています。

Unityプロジェクトにモジュールを追加する方法:

  1. Unity専用now.gg決済モジュールの最新バージョンを含むパッケージをダウンロードします。
  2. モジュールをダウンロードしたら、Unityプロジェクトにインポートします。手順は以下の通りです:
    • 以下のようにAssets > Import Package > Custom Packageの順に進みます:
    • 以前ダウンロードしたnowgg-payments-login.unitypackageを選択します。
    • リストアップされたファイルをすべて選択し、インポートをクリックします。
      payments-login-unitypackage

すべてのモジュールファイルがインポートされると、「NowGGSdk」という名前のフォルダがプロ ジェクトに追加されます。このフォルダは「アセット」フォルダのルートにあります。

NowGGSdkフォルダには、now.gg決済に関連するすべてのアセットが含まれているため、変更しないでください。

必要な依存関係の追加

この操作は、Unity External Dependency Managerを使用して、プロジェクトのAssets/Plugins/Androidディレクトリに必要なすべての依存関係をダウンロードして追加します。

必要な依存関係を追加する方法:

  • Assets > External Dependency Manager > Android Resolver > Resolveの順に進みます。

now.gg決済の実装

now.gg決済モジュールがインポートされ、依存関係が追加されたら、このセクションに従って、自身のアプリ/ゲームにnow.gg決済を実装することができます。

Unity IAPの実装にプラットフォームチェックを追加する

now.gg IAPサービスを実行するには、now.ggプラットフォームが必要です。Unity IAP (またはその他のIAP サービス) は、now.ggプラットフォームで実行していない時にのみ初期化する必要があります。

プラットフォームを確認するには、以下のコードを実装に追加して、アプリがnow.ggプラットフォームで実行されているときにUnity IAPが有効にならないようにします:

public void Start()
 {
 	 if (NowGG.Sdk.NowGGPaymentsSdkManager.IsNowGGIapAvailable())
            return;

	 // Your Unity IAP code here...
 }

Unityにnow.gg IAPを実装する

このセクションでは、Unityのアプリ/ゲームから呼び出すことができるnow.gg IAP関数の実装を説明します。

now.gg IAP実装を含むクラスを作成し、アプリ内課金を初期化ために使用可能なゲームオブジェクトにアタッチします。

1. プロダクトの追加とSDKの初期化

このステップでは、アプリ/ゲームにアプリ内課金プロダクトを追加し、SDKを初期化します。

例えば、以下のコードでは、プロダクトID が「coin1」と「coin2」の2つのIAP消費プロダクトと、プロダクトID が「gunSkin」の非消費プロダクトを追加しています。

同様に、nowStudio内で追加したプロダクトIDに対応する他のプロダクトを追加することができます。

now.gg Payments moduleは、ユーザを識別し、トランザクションを開始するために一意のuserIDを必要とします。オプションとして、ユーザーは支払い情報を保存することを選択でき、アプリで将来取引を行う際にこれらの詳細を入力する必要がなくなります。

now.gg Payments moduleの初期化時に、以下のサンプルコードのように、ユーザ固有のユーザID(IN_GAME_ID)を渡す必要があります:

public void Start()
 {
	 // Only initialize Now.gg IAP if running on Now.gg platform
	 if (!NowGG.Sdk.NowGGPaymentsSdkManager.IsNowGGIapAvailable())
		 return;

	 NowGGProductBuilder.Instance.AddProduct("coin1", ProductType.Consumable);
	 NowGGProductBuilder.Instance.AddProduct("coin2", ProductType.Consumable);
	 NowGGProductBuilder.Instance.AddProduct("gunSkin", ProductType.NonConsumable);

	 NowGGPaymentsSdkManager.Instance.OnInitSuccess += OnInitSuccess;
	 NowGGPaymentsSdkManager.Instance.OnInitFailed += OnInitFailed;
	 NowGGPaymentsSdkManager.Instance.OnPurchaseCompleted += OnPurchaseProduct;
     NowGGPaymentsSdkManager.Instance.OnPurchaseFailed += OnPurchaseFailed;

	 NowGGPaymentsSdkManager.Instance.InitializeIap(PAYMENT_ID, IN_GAME_ID);
 }

例:

  • now.ggプラットフォーム上でnow.gg決済サービスを初期化していることを確認するための初期チェックが行われます。
  • アプリ内プロダクトはNowGGProductBuilderクラスに追加されます。
  • NowGGPaymentsSdkManagerクラスのInitializeIap関数が呼び出され、PAYMENT_IDを使用して決済モジュールが初期化されます。
  • SDKのレスポンスは、上記のようにコールバック関数を使って記録されます。

重要な情報:

  • IN_GAME_IDは、ユーザー固有の識別子です。
    • IN_GAME_IDはユーザーごとに固有であることを確認してください。
      • IN_GAME_IDが一意であることは重要です。それは、ユーザが購入時に支払い関連情報を保存するように決定した場合、その情報は特定のIN_GAME_IDにリンクされるからです。
  • PAYMENT_IDは、アプリの固有の識別子です。
    • nowStudioで追加した各アプリは、固有のPAYMENT_IDを生成します。
    • 対応するPAYMENT_IDはnowStudioのアプリ詳細セクションで確認することができます。 – 詳細はこちら
  • 払い戻し処理 – ご注文の払い戻し手続きは、こちらの手順に従って行ってください。

2. プロダクトの詳細を取得する

初期化に成功すると、プロダクトIDを使用してアプリでプロダクトの詳細を取得できます。

プロダクトの詳細を取得するには、以下の実装を参照してください:

private void OnInitSuccess()
 {
    Debug.Log($"IAP init success");
    Product coin1 = NowGGPaymentsSdkManager.Instance.GetProductWithID("coin1");

    // now you can get product details using product id
    string price = coin1.price;
    string currencyCode = coin1.priceCurrencyCode;
 }

 private void OnInitFailed(string reason)
 {
   Debug.Log($"IAP init failed {reason}");
 }

3. 購入の開始

プロダクトの詳細を取得した後、プロダクトの購入を開始します。そのためには、以下のようにPurchaseProduct()関数を呼び出す必要があります:

public void PurchaseProduct(string productId)
 {
     NowGGPaymentsSdkManager.Instance.PurchaseProduct(productId);
 }

注意:

注意:


4. ユーザーに購入済みのプロダクトを割り当てる

購入が行われた後、アプリ内の購入済みプロダクトをユーザーに割り当てることができます。そのためには、以下の実装を参照してください:

private PurchaseProcessingResult OnPurchaseProduct(PurchasedProduct purchasedProduct)
 {
     string orderId = purchasedProduct.orderId;
     string purchaseToken = purchasedProduct.purchaseToken;

     // A consumable product has been purchased by this user.
     if (String.Equals(purchasedProduct.productId, "coin1", StringComparison.Ordinal))
     {
         Debug.Log(string.Format("OnPurchaseProduct: PASS. Product: '{0}'", purchasedProduct.productId));
         // The consumable item has been successfully purchased, add 100 coins to the player's in-game currency.
         // coin += 100;
     }
     else if (String.Equals(purchasedProduct.productId, "coin2", StringComparison.Ordinal))
     {
         Debug.Log(string.Format("OnPurchaseProduct: PASS. Product: '{0}'", purchasedProduct.productId));
         // The consumable item has been successfully purchased, add 200 coins to the player's in-game currency.
         // coin += 200;
     }
     else
     {
         Debug.Log(string.Format("OnPurchaseProduct: FAIL. Unrecognized product: '{0}'", purchasedProduct.productId));
     }

     // Return a flag indicating whether this product has been received or if the application needs to be reminded of this purchase at the next app launch.
     // Return PurchaseProcessingResult.Pending if you want to be reminded of this purchase on the next launch of your app/game.
     // Return PurchaseProcessingResult.Complete to specify that this is a one-time purchase and you have allotted the purchased in-game item to the user.

     return PurchaseProcessingResult.Complete;
 }

重要な情報

  • PurchaseToken は、購入が成功した後に生成される固有の識別子です。
  • 注文ごとにOrderIDも生成されます。
    • OrderIDやその他の関連情報が記載された購入のコピーも、ユーザーにメールで送信されます。

5. 保留中の購入を確認する

バックエンドサーバーで購入処理を行いたい場合、または実装に基づいて別のメソッドで購入を完了する必要がある場合、アプリはOnPurchaseProductからPurchaseProcessingResult.Pendingを返す必要があります。

購入フローを完了するには、ConfirmPendingPurchaseメソッドを使用して、アプリが購入の記録を作成したことをnow.gg IAPサービスに通知します。

void ConfirmPendingPurchase(PurchasedProduct purchasedProduct)
 {
   NowGGPaymentsSdkManager.Instance.ConfirmPendingPurchase(purchasedProduct);
 }

保留中の購入が確認されると、now.gg IAP サービスは再び購入についてアプリに通知しません。


6. 保留中の購入をクエリする

保留中の購入をクエリする必要がある場合は、NowGGPaymentsSdkManagerクラスのQueryPendingPurchases関数を呼び出すことができます。
この関数は、保留中の購入をすべてクエリし、保留中の購入と共にOnPurchaseProductコールバックを呼び出します。


7. 追加プロダクトの取得

購入するプロダクトを追加で取得したい場合、または既存のプロダクトに関連付けられている詳細/メタデータを更新したい場合は、以下のようにFetchAdditionalProducts関数を使用できます。

var newProducts = new System.Collections.Generic.Dictionary<string, ProductType>();
 newProducts.Add("coin2", ProductType.Consumable);
 newProducts.Add("coin3", ProductType.Consumable);

 NowGGPaymentsSdkManager.Instance.FetchAdditionalProducts(newProducts,
       () =>
       {
           //Additional products fetched can now be purchased.
           Debug.Log($"Successfully fetched additional products");
           Product coin1 = NowGGPaymentsSdkManager.Instance.GetProductWithID("coin1");
           string price = coin1.price;
           string currencyCode = coin1.priceCurrencyCode;
       },
      reason =>
      {
          Debug.Log($"Fetching additional products failed: {reason}");
      });

8. 購入失敗の処理

購入は、以下のような様々な理由で失敗する可能性があります:

  • ネットワーク/接続性の問題
  • 決済の失敗
  • 設定の問題

以下の実装を参照して、失敗した購入を調査・処理することができます:

public void OnPurchaseFailed(int errorCode, string errorMessage)
 {
    Debug.Log($"OnPurchaseFailed: errorCode: {errorCode} and msg: {errorMessage}");
 }

注意:

  • OnPurchaseFailed 関数に関連するレスポンスコードはこちらを参照してください。


購入の検証

購入を検証することで、購入の真正性を確立することができます。不正行為を減らすためのベストプラクティスは、ユーザーにプロダクトを割り当てる前に、すべての購入を認証することです。

購入の検証は、以下のいずれかの方法で行うことができます:

  • Verify Payment APIを使用する。
  • パブリックキーを使用する。

1. Verify Payment APIを使用する

購入を検証する最初の方法は、Verify Payment APIを使用することです。このAPIを使用して、バックエンドサーバーで購入を検証することができます。

購入を検証するには、アプリのバックエンドサーバーから、次のサンプルリクエストコードに示されているように、purchaseTokenorderIdを指定してverifyPayment APIを呼び出します:

curl --location 'https://payments.now.gg/v1/console/order/verifyPayment'\
      --header 'publisherToken: <your_publisherToken_here>'\
      --header 'Content-Type: application/json'\
      --data '{
  "purchaseToken": "<your_purchaseToken_here>",
  "orderId": "<your_orderId_here>"
  }'
import requests
 import json

 url = "https://payments.now.gg/v1/console/order/verifyPayment"

 payload = json.dumps(
     {
         "purchaseToken": "<your_purchaseToken_here>",
         "orderId": "<your_orderId_here>",
     }
 )
 headers = {
     "publisherToken": "<your_publisherToken_here>",
     "Content-Type": "application/json",
 }

 response = requests.request("POST", url, headers=headers, data=payload)

 print(response.text)

重要な情報

  • verifyPayment APIは、アプリのバックエンドサーバーから呼び出す必要があります。
  • publisherTokennowStudioアカウント情報セクションにあります。(詳細)。
  • 購入が成功すると、purchaseTokenorderIdが返されます。詳細は以下のドキュメントを参照してください:

2. 自身のパブリックキーで購入を検証する

購入の検証は、ローカルまたは、バックエンドサーバーを使用して行えます。ただし、購入の検証にはバックエンドサーバーを使用することをお勧めします。

  • こちらに記載されている手順に従って、パブリックキーを生成することができます。

以下のコードセグメントは、ローカルでの購入とバックエンドサーバーを使用した購入の検証を示しています。詳細はデモプロジェクトを参照してください。

private PurchaseProcessingResult OnPurchaseProduct(PurchasedProduct purchasedProduct) {
    // If you want to do local verification, use this sample code
    bool isValidPurchase = PurchaseVerification.Instance.VerifyPurchaseLocally(
        BASE_64_ENCODED_PUBLIC_KEY,
        purchasedProduct.originalJson,
        purchasedProduct.signature); 

    // We recommend you to verify purchases on your backend server.
    // You need to send signature and original data to your backend server for verification.
    PurchaseVerification.Instance.VerifyValidSignatureOnBackend(
        purchasedProduct.originalJson,
        purchasedProduct.signature);

    // A consumable product has been purchased by this user.
    if (String.Equals(purchasedProduct.productId, "coin1", StringComparison.Ordinal))
    {
        Debug.Log(string.Format("OnPurchaseProduct: PASS. Product: '{0}'", purchasedProduct.productId));
        // The consumable item has been successfully purchased, add 100 coins to the player's in-game currency.
        // coin += 100;
    } 
    else if (String.Equals(purchasedProduct.productId, "coin2", StringComparison.Ordinal)) 
    {
        Debug.Log(string.Format("OnPurchaseProduct: PASS. Product: '{0}'", purchasedProduct.productId));
        // The consumable item has been successfully purchased, add 200 coins to the player's in-game currency.
        // coin += 200;
    } 
    else 
    {
        Debug.Log(string.Format("OnPurchaseProduct: FAIL. Unrecognized product: '{0}'", purchasedProduct.productId));
    }

    return PurchaseProcessingResult.Complete;
}
サーバーの検証

ダウンロードパッケージには、バックエンドサーバーを使用して購入を検証するサンプル実装が含まれており、自身の実装を書き込むために使用することができます。

サンプル実装には以下が含まれます。

  • PurchaseVerificationクラス: デモプロジェクト内にあり、購入データと署名をバックエンドサーバーに送信するUnity固有のコードが含まれています。
  • Server.py: ダウンロードパッケージの中に別にあり、ローカルサーバーを実行し、バックエンド検証を実行するためのサンプルPythonコードが含まれています。
ローカル検証

ダウンロードパッケージの中に、購入のローカル検証のためのサンプル実装が用意されています。用意されたサンプルを使用して、自身の実装を書き込むことができます。

サンプル実装において –

  • PurchaseVerificationクラスのVerifyPurchaseLocally関数を参照してください。

重要な情報

×
テキストがクリップボードにコピーされました。
copyLinkText
ご不明な点がございましたら、お気軽にお問い合わせください。 dev-support@now.gg