レシートの検証
未提供のアイテム領収書¶
アイテムの送信は、購入後に時折失敗したりキャンセルされたりします。この状況を防ぐために、IAPV4クラスのrestore()
メソッドを呼び出して、渡されていないアイテムの領収書情報を要求してください。
SUCCESS
が返され、restore()
を呼び出した後にReceiptListが送信されると、復元が必要なアイテムが存在します。未提供のアイテムを送信し、復元プロセスを完了してください。restore()
を呼び出した後にSUCCESS
が返されない場合、ゲームスタジオに対してはこれ以上の処理は必要ありません。restore()
メソッドを呼び出す際にエラーが発生した場合、認識する必要があるエラーのみを通知し、他のエラーはスキップしてユーザーがゲームを続けられるようにしてください。- Google PlayのWindowsアプリで
GOOGLE_PLAYSTORE
マーケットを使用する場合(Hive SDK v4 Unity Windows 23.0.0以上)、restore()
メソッドを呼び出す際に支払いに使用されるGoogleアカウントの認証情報が期限切れの場合、Hive SDKは自動的に再認証プロセスを開始します。
以下は、提供されていないアイテムの領収書情報をリクエストするためのサンプルコードです。
APIリファレンス: hive .IAPV4.restore
using hive;
IAPV4.restore((ResultAPI result, List receiptList) => {
if (result.isSuccess()) {
if (result.errorCode = ResultAPI.ErrorCode.SUCCESS) {
// TODO: Request receipt verification using the received receiptList
} else if (result.errorCode = ResultAPI.ErrorCode.NOT_OWNED) {
// No unpaid items
}
}
}
#include "HiveIAPV4.h"
FHiveIAPV4::Restore(FHiveIAPV4OnRestoreDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TArray<FHiveIAPV4Receipt>& IAPV4ReceiptList) {
if (Result.IsSuccess()) {
if (Result.ErrorCode == FHiveResultAPI::EErrorCode::SUCCESS) {
// TODO: 受け取ったレシートリストを使用してレシートの検証をリクエストする
} else if (Result.ErrorCode == FHiveResultAPI::EErrorCode::RESTORE_NOT_OWNED) {
// 未払いのアイテムはありません
}
}
}));
APIリファレンス: IAPV4 ::restore
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;
IAPV4::restore([=](ResultAPI const & result, vector<reference_wrapper<IAPV4Receipt>> receiptList) {
if (result.isSuccess()) {
if (result.errorCode == ResultAPI::ErrorCode::SUCCESS) {
// TODO: 受け取ったreceiptListを使用してレシートの検証をリクエストする
} else if (result.errorCode == ResultAPI::ErrorCode::RESTORE_NOT_OWNED) {
// 未払いのアイテムはありません
}
}
});
APIリファレンス: IAPV4.restore
import com.hive.IAPV4
import com.hive.ResultAPI
IAPV4.restore(object : IAPV4.IAPV4RestoreListener {
override fun onIAPV4Restore(result: ResultAPI, iapv4ReceiptList: ArrayList<IAPV4.IAPV4Receipt>?) {
if (result.isSuccess) {
if (result.errorCode == ResultAPI.SUCCESS) {
// TODO: 受け取ったiapv4ReceiptListを使用してレシート検証をリクエスト
} else if (result.errorCode == ResultAPI.RESTORE_NOT_OWNED) {
// 未払いのアイテムはありません
}
}
}
})
APIリファレンス: com.hive.IAPV4.restore
import com.hive.IAPV4;
import com.hive.ResultAPI;
IAPV4.INSTANCE.restore((result, iapv4ReceiptList) -> {
if (result.isSuccess()) {
if (result.getErrorCode() == ResultAPI.Companion.getSUCCESS()) {
// TODO: 受け取ったiapv4ReceiptListを使用してレシート検証をリクエストする
} else if (result.getErrorCode() == ResultAPI.Companion.getRESTORE_NOT_OWNED()) {
// 未払いのアイテムはありません
}
}
});
APIリファレンス: IAPV4Interface .restore
APIリファレンス: HIVEIAPV4::restore
#import <HIVEService/HIVEService-Swift.h>
[HIVEIAPV4 restore: ^(HIVEResultAPI *result, NSArray<HIVEIAPV4Receipt *> *receiptList) {
if ([result isSuccess]) {
if ([result getErrorCode] == HIVEResultAPITypeSuccess) {
// TODO: 受け取ったreceiptListを使用してレシートの検証をリクエストする
} else if ([result getErrorCode] == HIVEResultAPITypeNotOwned){
// 未払いのアイテムはありません
}
}
}];
Note
may differ by operating system/market. For more details, see the status of supported features.
購入復元エラーコードのリスト¶
エラーコード | 説明 |
---|---|
NEED_INITIALIZE | 初期化できません |
NETWORK | ネットワークエラー |
NOT_SUPPORTED | 復元できません(デバイスでのアプリ内購入が拒否されたなど)。ユーザーが利用できないストアを設定 |
INVALID_SESSION | 復元するための無効なセッション |
IN_PROGRESS | 復元APIが進行中 |
RESTORE_NOT_OWNED | 復元するアイテムがありません |
NOT_OWNED | 復元するアイテムがありません |
RESPONSE_FAIL | IAPサーバーエラー |
購入レシートの確認¶
ゲームサーバーからアイテムを送信する前に、IAPの検証APIがレシートが有効かどうかを確認する必要があります。 検証APIのhiveiap_transaction_id
はレシートによって発行されるユニークIDです。したがって、重複したレシートを確認するために、ゲームサーバーにIDを保存してください。 検証APIを使用してからリクエストパラメータからすべてのデータを送信すると、IAPサーバーはゲームデータを転送して販売状況を分析します。Hive One > Search Allでも、支払いを検索するためにAPIを利用してください。 詳細については、IAPレシート検証APIを参照してください。
購入済みまたは未購入のアイテムを提供する¶
ゲームサーバーが購入後にアイテムを送信する場合は、購入を完了するためにIAPV4クラスのtransactionFinish()
メソッドを呼び出すことを確認してください。
Warning
transactionFinish()
メソッドを呼び出さないと、アイテムは未渡しの状態のままになります。
この原因は、restore()
メソッドを呼び出す際に受け取った領収書です。すべてのプロセスが完了した後にフィニッシュAPIを呼び出すことを確認してください。
Note
Hive SDK v4.12.0以降、Android Google Playストアで、支払い後にIAPV4クラスのTransactionFinish()
メソッドの実装結果が3日以内またはテスト状態で5分以内に成功しない場合、支払いは自動的に返金されます。
以下は、アイテム送信のリクエストを完了するサンプルコードです。
APIリファレンス: hive .IAPV4.transactionFinish
APIリファレンス: IAPV4 ::transactionFinish
APIリファレンス: IAPV4.transactionFinish
import com.hive.IAPV4
import com.hive.ResultAPI
val marketPid = "{YOUR_PRODUCT_MARKET_PID}"
IAPV4.transactionFinish(marketPid, object : IAPV4.IAPV4TransactionFinishListener {
override fun onIAPV4TransactionFinish(result: ResultAPI, marketPid: String) {
if (result.isSuccess) {
// call successful
}
}
})
APIリファレンス: com.hive.IAPV4.transactionFinish
APIリファレンス: IAPV4Interface.transactionFinish
APIリファレンス: HIVEIAPV4::transactionFinish:handler:
以下は、複数のアイテムを送信するリクエストのサンプルコードです。
APIリファレンス: hive .IAPV4.transactionMultiFinish
using hive;
List marketPidList = new List();
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_01}");
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_02}");
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_03}");
IAPV4.transactionMultiFinish((List<ResultAPI> resultList, List<String> marketPidList) => {
for (ResultAPI result in resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
#include "HiveIAPV4.h"
TArray<FString> MarketPidList;
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_01"));
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_02"));
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_03"));
FHiveIAPV4::TransactionMultiFinish(MarketPidList, FHiveIAPV4OnTransactionMultiFinishDelegate::CreateLambda([this](const TArray<FHiveResultAPI>& ResultList, const TArray<FString>& MarketPidList) {
for (const auto& Result : ResultList) {
if (Result.IsSuccess()) {
// API呼び出し成功
}
}
}));
APIリファレンス: IAPV4 ::transactionMultiFinish
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;
vector<string> marketPidList;
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_01}");
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_02}");
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_03}");
IAPV4::transactionMultiFinish(marketPidList, [=](vector<ResultAPI> const & resultList, vector<string> const & marketPidList) {
for (ResultAPI result : resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
APIリファレンス: IAPV4.transactionMultiFinish
import com.hive.IAPV4
import com.hive.ResultAPI
val marketPidList = arrayListOf(
"{YOUR_PRODUCT_MARKET_PID_01}",
"{YOUR_PRODUCT_MARKET_PID_02}",
"{YOUR_PRODUCT_MARKET_PID_03}"
)
IAPV4.transactionMultiFinish(marketPidList, object : IAPV4.IAPV4TransactionMultiFinishListener {
override fun onIAPV4TransactionMultiFinish(resultList: ArrayList<ResultAPI>, marketPidList: ArrayList<String>) {
for (i in 0 until resultList.size) {
if (resultList[i].isSuccess) {
// call successful
}
}
}
})
API リファレンス: com.hive.IAPV4.transactionMultiFinish
import com.hive.IAPV4;
import com.hive.ResultAPI;
ArrayList<String> marketPidList = new ArrayList<>(Arrays.asList(
"{YOUR_PRODUCT_MARKET_PID_01}",
"{YOUR_PRODUCT_MARKET_PID_02}",
"{YOUR_PRODUCT_MARKET_PID_03}"
));
IAPV4.INSTANCE.transactionMultiFinish(marketPidList, (resultList, marketPidList1) -> {
for (ResultAPI result : resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
APIリファレンス: IAPV4Interface.transactionMultiFinish
import HIVEService
var marketPidList = [String]()
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_01}")
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_02}")
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_03}")
IAPV4Interface.transactionMultiFinish(marketPidList) { resultList, marketPidList in
for result in resultList {
if result.isSuccess() {
// call successful
}
}
}
APIリファレンス: HIVEIAPV4::transactionMultiFinish
#import <HIVEService/HIVEService-Swift.h>
NSMutableArray<NSString *> *maketPidList = [NSMutableArray array];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_01}"];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_02}"];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_03}"];
[HIVEIAPV4 transactionMultiFinish: maketPidList handler: ^(NSArray<HIVEResultAPI *> *resultList, NSArray<NSString *> *marketPidList) {
for (HIVEResultAPI *result in resultList) {
if ([result isSuccess]) {
// call successful
}
}
}];
ユーザーの購入活動情報を取得: AccountUuid
を使用¶
支払いシステムを悪用するユーザーがいるかもしれません。たとえば、1つのゲームアカウントが複数のアプリストアアカウントを使用して支払いを行う場合です。ゲームスタジオ側では、支払いユーザー情報(AccountUuid)を比較することで、特定のユーザー行動を取得し、分析することができます。
以下のメソッドは、AccountUuid
を返します。これは、UUID v3形式でのPlayerIdのハッシュ値であり、Hive SDKがアプリストアに渡すものです。
APIリファレンス: IAPV4.getAccountUuid
APIリファレンス: IAPV4 ::getAccountUuid
APIリファレンス: IAPV4.getAccountUuid
APIリファレンス: IAPV4.INSTANCE .getAccountUuid
APIリファレンス: IAPV4Interface.getAccountUuid
APIリファレンス: [HIVEIAPV4 getAccountUuid ]
ゲームスタジオは、このハッシュ値を購入領収書情報と共に使用して、ユーザーの購入を分析できます。以下の例は、複数のゲーム内キャラクターがこのゲームアカウントに存在する場合に、特定のPlayerIdを介してAccountUuid
でゲームアカウントの購入活動を分析する方法を示しています。この例は開発の参考のためのものであり、実際の動作を保証するものではありません。
ゲームサーバーに事前に購入メタ情報を保存する¶
購入リクエストが行われる前に、購入メタ情報(AccountUuid
およびキャラクター情報)をゲームサーバーに保存します。
/* The game client pass the info to the game server before the purchase occurs.
*
* @param purchaseTime: purchase time. The receipts are usually based on UTC. since the epoch (Jan 1, 1970).
* @param productId: purchase product ID.
* @param accountUuId: hashed PlayerId. It is included in the receipt and can be obtained with IAPV4.getAccountUuid().
* @param characterId: the character identifier within PlayerId.
*/
game.sendPurchaseGameData(purchaseTime, productId, accountUuid, characterId)
bypassInfo
を送信¶
購入リクエストが発生した場合、bypassInfo
データをゲームサーバーに送信します。以下のコードは開発の参考のための擬似コードです。
領収書確認のリクエスト¶
ゲームサーバーはbypassInfo
データをIAP v4サーバーに渡し、レシートの検証をリクエストします。レシート検証のリクエストの詳細については、こちらを参照してください。 hiveiap_receipt
に含まれるAccountUuid
は、レスポンス値内で受け取ったアプリマーケット/ストアの元のレシートです。
# Apple
# Purchase time: purchase_date_ms
# Purchased products: product_id
# AccountUuid: app_account_token
# Google
# Purchase time: purchaseTime
# Purchased products: productId
# AccountUuid: obfuscatedAccountId
購入メタ情報のAccountUuid
をhiveiap_receipt
のAccountUuid
と照合して分析する¶
分析に必要なユーザー情報を見つけます。これは、購入メタ情報に以前保存されていたAccountUuid
と、領収書の検証結果から取得したAccountUuid
を照合することによって、ゲームキャラクター情報などを取得します。購入メタ情報と領収書情報を照合することで、対応するゲームアカウントの購入活動を分析できます。
ユーザーが複数のアイテムを購入した場合、各購入はhiveiap_receipt
のpurchaseTime
と購入メタ情報を照合することで特定できます。hiveiap_receipt
の詳細については、領収書の確認を参照し、マーケットごとのAPIレスポンスを確認してください。
ユーザーの購入活動情報を取得: iadPayload
を使用¶
Purchase()を使用して購入をリクエストする際、ゲーム会社がユーザーの購入活動を分析するための事前定義されたデータも提供する場合、iapPayload
、Hive サーバーはiapPayload
に対応する購入レシートを照合し、これをゲームサーバーに送信します。ゲーム会社は、レシートの情報とiadPayload
の情報を組み合わせて、ユーザーの購入活動を分析することができます。
Note
この方法では、Hive サーバーが各購入のメタ情報を各レシートと照合し、それをあなたのゲームサーバーに送信するため、上記のように自分でAccountUuid
と購入メタ情報およびレシートを照合する必要はありません。
iapPayload
を定義し、Purchase()
を実行する¶
各製品購入リクエストを実行する際に、iapPayload
に必要なフィールドと値を定義し、それを引数として使用します。このプロセスは、購入メタデータを定義するのと似ています。
レシートの検証をリクエストし、iapPayload
と対応するレシートを受け取ります。¶
支払いが完了し、レシートの検証がリクエストされると、Hive サーバーはiapPayload
を対応するレシートと照合し、それらをゲームサーバーに配信します。ゲームスタジオは、iapPayload
とレシートの情報を使用してユーザーの購入活動を分析できます。