Unity専用now.gg決済モジュールを使用すると、Unity上のゲーム内でアプリ内課金を実装することができます。
now.gg決済モジュールを使用してアプリ内課金を実装する方法:
Unity専用now.gg決済モジュールはUnityパッケージファイルNowGGUnitySdk.unitypackageとして含まれています。
Unityプロジェクトにモジュールを追加する方法:
NowGGUnitySdk.unitypackage を選択します。
Assets/Plugins/Android ディレクトリにダウンロードされ追加されます。now.gg決済モジュールがインポートされ、依存関係が追加されたら、このセクションに従って、自身のアプリ/ゲームにnow.gg決済を実装することができます。
now.gg Paymentsを初期化する前に、必ずnow.gg IAPが利用可能かどうかを確認してください。now.gg IAPが利用できない場合にのみ、他のIAPサービスを初期化してください。
public void Start()
{
if (!NowGG.Sdk.NowGGPaymentsSdkManager.IsNowGGIapAvailable())
return;
// ここにUnity IAPのコードを記述してください...
}
このセクションでは、Unityのアプリ/ゲームから呼び出すことができるnow.gg IAP関数の実装を説明します。
now.gg IAP実装を含むクラスを作成し、アプリ内課金を初期化ために使用可能なゲームオブジェクトにアタッチします。
このステップでは、アプリ/ゲームにアプリ内購入商品を追加し、SDKを初期化できます。
たとえば、次のコードでは、productId「coin1」と「coin2」の2つの消耗型IAP商品と、productId「monthlyPack」のサブスクリプションを追加しています。
同様に、nowStudio 内で追加した対応する productId を使用して、他の製品やサブスクリプションを追加できます。以下のサンプルコードで示しています:
public void Start()
{
// now.gg IAPが利用可能な場合にのみPaymentsを初期化してください
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);
}
例:
NowGGProductBuilder クラスに追加されています。InitializeIap関数が呼び出され、PAYMENT_IDを使用して決済モジュールが初期化されます。初期化に成功すると、プロダクト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}");
}
注意:
プロダクトの詳細を取得した後、プロダクトの購入を開始します。そのためには、以下のようにPurchaseProduct()関数を呼び出す必要があります:
public void PurchaseProduct(string productId, string developerPayload=null)
{
NowGGPaymentsSdkManager.Instance.PurchaseProduct(productId, developerPayload);
}
注意:
購入を消費するために下記2つのメソッドを使用します:
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も生成されます。
consumePurchase APIは、バックエンドサーバを持つアプリのサーバサイドでの購入消費に使用する必要があります。
購入を確認したら、それを消費済みとして処理する必要があります。
消費購入には以下が含まれます。:
以下のサンプルコードはconsumePurchase API を使用した関連リクエストの例です。
import requests
url = "https://payments-api.now.gg/v2/order/consumePurchase"
headers = {
"Authorization": "<payment_api_key_here>",
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"purchaseToken": "<purchase_token_here>",
"developerPayload": "developerPayload" // オプション
}
response = requests.post(url, headers=headers, data=data)
print("レスポンスステータスコード:", response.status_code)
print("レスポンスボディ:", response.text)
curl --location --request POST 'https://payments-api.now.gg/v2/order/consumePurchase' \
--header 'Authorization: <payment_api_key_here>' \
--header 'Content-Type': 'application/x-www-form-urlencoded' \
--data '{
"purchaseToken": "<purchase_token_here>",
"developerPayload" : "developerPayload" // オプション
}'
注意:
consumePurchase APIを呼び出す前にユーザーに割り当ててください。Payments API Key はnowStudioのクレデンシャルセクションで確認することができます。 詳細はこちらacknowledgePurchase APIは、バックエンドサーバーを持つアプリのサーバーサイド購入確認に使用されるべきです。
購入を確認した後、それを承認済みとしてマークする必要があります。
以下のサンプルコードはacknowledgePurchase API を使用した関連リクエストの例です。
import requests
url = "https://payments-api.now.gg/v2/seller/order/acknowledgepurchase"
payload = 'purchaseToken=-nowgg-purchaseToken'
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)
注意:
Payments API Key はnowStudioのクレデンシャルセクションで確認することができます。 詳細はこちらバックエンドサーバーで購入処理を行いたい場合、または実装に基づいて別のメソッドで購入を完了する必要がある場合、アプリはOnPurchaseProductからPurchaseProcessingResult.Pendingを返す必要があります。
購入フローを完了するには、ConfirmPendingPurchaseメソッドを使用して、アプリが購入を記録したことをnow.gg IAPサービスに通知できます。
public void ConfirmPendingPurchase(string purchasetoken, ProductType productType) {
if (productType == ProductType.Consumable) {
ConsumeProduct(purchasetoken);
} else {
AcknowledgePurchase(purchasetoken);
}
}
注意:
アプリのバックエンドサーバーを使用して購入フローを完了し、購入の権利を付与するには、次を呼び出してください:
保留中の購入をクエリする必要がある場合は、NowGGPaymentsSdkManagerクラスのQueryPendingPurchases関数を呼び出すことができます。
この関数は、保留中の購入をすべてクエリし、保留中の購入と共にOnPurchaseProductコールバックを呼び出します。
NowGGPaymentsSdkManager.Instance.QueryPendingPurchases();
参照: OnPurchaseProduct.
購入するプロダクトを追加で取得したい場合、または既存のプロダクトに関連付けられている詳細/メタデータを更新したい場合は、以下のように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}");
});
購入は、以下のような様々な理由で失敗する可能性があります:
以下の実装を参照して、失敗した購入を調査・処理することができます:
public void OnPurchaseFailed(int errorCode, string errorMessage)
{
Debug.Log($"OnPurchaseFailed: errorCode: {errorCode} and msg: {errorMessage}");
}
注意:
OnPurchaseFailed 関数に関連するレスポンスコードはこちらを参照してください。このセクションでは、SubscriptionStatusCallback API を提供し、サブスクリプションの状態更新に関する通知を送信するための API 仕様を示しています。
以下は関連するワークフローです:
注意: Subscription Status Callback API.
購入は verifyPurchase API を使用して確認できます。
購入を検証するには、アプリのバックエンドサーバーから、次のサンプルリクエストコードに示されているように、purchaseTokenを指定してverifyPurchase APIを呼び出します:
import requests
url = "https://payments-api.now.gg/v2/sellers/order/verifyPurchase"
headers = {
"Authorization": "<payment_api_key_here>",
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"purchaseToken": "<purchase_token_here>"
}
response = requests.post(url, headers=headers, data=data)
print("レスポンスステータスコード:", response.status_code)
print("レスポンスボディ:", response.text)
curl -X \ POST "https://payments-api.now.gg/v2/sellers/order/verifyPurchase" \ -H \ "Authorization: <payment_api_key_here>" \ -H \ "Content-Type: application/x-www-form-urlencoded" \ -d "purchaseToken=<purchase_token_here>"
ドキュメント改訂版 1.0