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を選択します。
    • リストアップされたファイルをすべて選択し、インポートをクリックします。

すべてのモジュールファイルがインポートされると、「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を初期化できます。

たとえば、次のコードでは、productId「coin1」と「coin2」の2つの消耗型IAP商品と、productId「monthlyPack」のサブスクリプションを追加しています。

同様に、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("monthlyPack", ProductType.Subscription);

     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のレスポンスは、上記のようにコールバック関数を使って記録されます。
  • 注意 – NowGGPaymentsSdkManager

重要な情報:

  • IN_GAME_IDは、ユーザー固有の識別子です。
    • IN_GAME_IDはユーザーごとに固有であることを確認してください。
      • IN_GAME_IDが一意であることは重要です。それは、ユーザが購入時に支払い関連情報を保存するように決定した場合、その情報は特定のIN_GAME_IDにリンクされるからです。
      • 支払い統合のテスト: 特定のIN_GAME_IDを使用して支払いをテストしたい場合は、nowStudioの内部テスターとして追加してください。
  • 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 productId
    string price = coin1.price;
    string currencyCode = coin1.priceCurrencyCode;

    Product monthlyPack = NowGGPaymentsSdkManager.Instance.GetProductWithID("monthlyPack");
    string monthlyPackSubscriptionPeriod = monthlyPack.subscriptionPeriod;
 }

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

注意:


3. 購入の開始

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

public void PurchaseProduct(string productId, string developerPayload=null)
 {
     NowGGPaymentsSdkManager.Instance.PurchaseProduct(productId, developerPayload);
 }

注意:

注意:


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

購入が行われた後、アプリ内の購入済みプロダクトをユーザーに割り当てることができます。

購入を消費するために下記2つのメソッドを使用します:


A. を使用 PurchaseProcessingResult

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

     // 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 if (String.Equals(purchasedProduct.productId, "monthlyPack", StringComparison.Ordinal))
     {
         Debug.Log(string.Format("OnPurchaseProduct: PASS. Product: '{0}'", purchasedProduct.productId));
         Debug.Log("Subscription: " + purchasedProduct.subscriptionStatus + " " + purchasedProduct.subscriptionPeriod + " " + purchasedProduct.expiryTimeMillis + " " + purchasedProduct.subscriptionPurchaseDateMillis);
     
         if (purchasedProduct.subscriptionStatus == "ACTIVE" && purchaseProduct.isAcknowledged == false)
         {
            // 定期購読が正常に購入されました。定期購読の特典をプレイヤーに渡してください。
            // 購入した定期購読の状態、請求期間、および有効期限を反映するようにUIを更新してください。
            // 購入が確認されたことを認めるために、PurchaseProcessingResult.Completeを返します(サブスクリプション)。
         }
     }
     else
     {
         Debug.Log(string.Format("OnPurchaseProduct: FAIL. Unrecognized product: '{0}'", purchasedProduct.productId));
     }

     // この製品が受け取られたか、または次回アプリ起動時にこの購入を通知する必要があるかを示すフラグを返します。
     // アプリ/ゲームの次回起動時にこの購入を通知したい場合は、PurchaseProcessingResult.Pending を返します。
     // この購入が消費された(消耗品)または承認された(定期購読)ことを確認し、購入の特典をユーザーに渡したことを確認するには、PurchaseProcessingResult.Complete を返します。

     return PurchaseProcessingResult.Complete;
 }

참고:

  • 백엔드 서버에서 구매를 처리하거나 구현에 따라 다른 방법으로 구매를 완료해야 하는 경우, 앱은 OnPurchaseProduct에서 PurchaseProcessingResult.Pending을 반환해야 합니다.
    • 대기 중인 구매가 있는 경우 앱/게임을 다음에 실행할 때 다시 알림이 표시됩니다.
  • 대기 중인 구매를 확인하고 권한을 부여하려면 – 이 섹션을 참조하십시오.

注意:

重要な情報

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

consumePurchase APIを使用 – 消耗品

consumePurchase APIは、バックエンドサーバを持つアプリのサーバサイドでの購入消費に使用する必要があります。
購入を確認したら、それを消費済みとして処理する必要があります。

消費購入には以下が含まれます。:

  • 購入した製品をユーザに割り当てます。
  • 商品が消費されたことをnow.ggに通知します。
消費購入コードのサンプル

以下のサンプルコードはconsumePurchase API を使用した関連リクエストの例です。

import requests

  url = "https://cloud-api.bluestacks.cn/v2/order/consumePurchase"

  payload = 'purchaseToken=nowgg-_purchase_token'
  headers = {
    'Authorization': 'payment_api_key_here',
    'Content-Type': 'application/x-www-form-urlencoded'
  }

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

  print(response.text)

注意:

重要な情報

  • 購入した商品をconsumePurchase APIを呼び出す前にユーザーに割り当ててください。
  • API KeyPayments API Key はnowStudioのクレデンシャルセクションで確認することができます。 詳細はこちら
  • 購入が成功すると、PurchaseTokenが返されます。詳細については、以下の参考ドキュメントを参照してください:
  • 購入日から3日以内に権利が付与されない場合、取引はキャンセルされ、ユーザーに返金が開始されます。

acknowledgePurchase APIを使用  – 購読

acknowledgePurchase APIは、バックエンドサーバーを持つアプリのサーバーサイド購入確認に使用されるべきです。

購入を確認した後、それを承認済みとしてマークする必要があります。
以下のサンプルコードはacknowledgePurchase API を使用した関連リクエストの例です。

import requests

  url = "https://cloud-api.bluestacks.cn/v2/seller/order/acknowledgepurchase"

  payload = 'purchaseToken=nowgg-_purchase_token'
  headers = {
    'Authorization': 'payment_api_key_here',
    'Content-Type': 'application/x-www-form-urlencoded'
  }

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

  print(response.text)

注意:

重要な情報

  • API KeyPayments API Key はnowStudioのクレデンシャルセクションで確認することができます。 詳細はこちら
  • 購入が成功すると、PurchaseTokenが返されます。詳細については、以下の参考ドキュメントを参照してください:
  • 購入日から3日以内に権利が付与されない場合、取引はキャンセルされ、ユーザーに返金が開始されます。

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

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

クライアント側

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

public void ConfirmPendingPurchase(string purchasetoken, ProductType productType) {
   if (productType == ProductType.Consumable) {
       ConsumeProduct(purchasetoken);
   } else {
       AcknowledgePurchase(purchasetoken);
   }
 }

注意:

サーバー側

アプリのバックエンドサーバーを使用して購入フローを完了し、購入の権利を付与するには、次を呼び出してください:

重要な情報

  • 保留中の購入が確認されると、now.gg IAPサービスはその購入についてアプリに通知しません。
    • 保留中の購入がある場合、アプリ/ゲームを次回起動時にリマインドされます。
  • サブスクリプション期間は認識された日から始まります。
  • 購入日から3日以内に権利が付与されない場合、取引はキャンセルされ、ユーザーに返金が開始されます。

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

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

NowGGPaymentsSdkManager.Instance.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 関数に関連するレスポンスコードはこちらを参照してください。

9. Subscription Status Callback API

(開発者提供)

このセクションでは、SubscriptionStatusCallback API を提供し、サブスクリプションの状態更新に関する通知を送信するための API 仕様を示しています。

以下は関連するワークフローです:

  • nowStudio はこのAPIを使用して、リクエストデータをゲームのバックエンドに送信します。
  • ゲームのバックエンドは、当社から提供されたAPIキー(Webhook APIキー)を使用してリクエストを認証できます。
  • サブスクリプションの現在のステータスに基づいて、ユーザーに購入権を割り当てることができます。 (こちらで定義されています)。
  • 提供されたコールバックURLを使用してリクエストデータを送信した後、当社のAPIからの応答を待ちます。
    • 成功ステータスが true の200のレスポンスが得られない場合、一定時間リトライを続けます。

注意: Subscription Status Callback API.



購入の検証

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

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

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

1. Verify Purchase APIを使用する

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

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

curl --location 'https://cloud-api.bluestacks.cn/v2/seller/order/verifyPurchase' \
 --header 'Authorization: <payment_api_key_here>' \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data-urlencode 'purchaseToken=<nowgg_purchase_token>'
import requests

  url = "https://cloud-api.bluestacks.cn/v2/seller/order/verifyPurchase"

  payload = 'purchaseToken=<nowgg_purchase_token>'
  headers = {
  'Authorization': '<payment_api_key_here>',
  'Content-Type': 'application/x-www-form-urlencoded'
  }

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

  print(response.text)

重要な情報

  • verifyPurchase APIは、アプリのバックエンドサーバーから呼び出す必要があります。
  • 購入が成功すると、purchaseTokenが返されます。詳細は以下のドキュメントを参照してください:

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関数を参照してください。

重要な情報

×

目次

Unity専用決済モジュール

目次

ドキュメント改訂版 1.0

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