GS2-Money2 SDK for Game Engine API リファレンス
モデル
EzWallet
ウォレット
ウォレット内の通貨は大きく有償で購入した通貨と、無償で入手した通貨が分けて管理されます。
有償で購入した通貨は更に購入時の単価毎に管理され、サービス終了になってしまった際の返金や資金決済法に該当するだけの残高が存在するかが集計できます。
ウォレットにはスロットがあり、スロットごとに異なる残高を管理できます。
プラットフォームをまたいで残高を共有できない場合にはプラットフォーム毎に異なるスロットを利用することで分けて管理することができます。
その際に無償で入手した通貨は全てのプラットフォームで共通した値を利用することもできます。
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
slot | int | ✓ | ~ 100000000 | スロット番号 | |
summary | EzWalletSummary | ✓ | ウォレットの状態 | ||
sharedFreeCurrency | bool | ✓ | 無償課金通貨を共有するか | ||
updatedAt | long | ✓ | 現在時刻 | 最終更新日時 (UNIX時間 単位:ミリ秒) |
EzWalletSummary
ウォレットの状態
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
paid | int | ✓ | 0 | ~ 2147483646 | 有償課金通貨 |
free | int | ✓ | 0 | ~ 2147483646 | 無償課金通貨 |
total | int | ✓ | 0 | ~ 2147483646 | 総数 |
EzDepositTransaction
入金トランザクション
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
price | float | ✓ | ~ 1000000.0 | 購入価格 | |
currency | string | {price} > 0 | ~ 8文字 | 通貨コード | |
count | int | ✓ | ~ 2147483646 | 所持量 |
EzSubscribeTransaction
サブスクリプションの購入情報
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
contentName | string | ✓ | ~ 128文字 | 定期課金ストアコンテンツモデル名 | |
store | enum { “AppleAppStore”, “GooglePlay”, “fake” } | ✓ | ~ 128文字 | ストア | |
transactionId | string | ✓ | ~ 1024文字 | トランザクションID | |
statusDetail | enum { “active@active”, “active@converted_from_trial”, “active@in_trial”, “active@in_intro_offer”, “grace@canceled”, “grace@grace_period”, “grace@on_hold”, “inactive@expired”, “inactive@revoked” } | ✓ | ~ 128文字 | ステータス | |
expiresAt | long | ✓ | 有効期限 (UNIX時間 単位:ミリ秒) |
store に指定する列挙型の定義
定義 | 説明 |
---|---|
AppleAppStore | Apple App Store |
GooglePlay | Google Play |
fake | Fake |
statusDetail に指定する列挙型の定義
定義 | 説明 |
---|---|
active@active | 有効 |
active@converted_from_trial | 無料トライアルが終了し、有料プランに移行 |
active@in_trial | 無料トライアル期間中 |
active@in_intro_offer | 初回割引期間中 |
grace@canceled | ユーザーが手動で解約済み |
grace@grace_period | 支払いが失敗したが、猶予期間内 |
grace@on_hold | 支払いが失敗し、一定期間内に支払いが完了しなければ利用不可 |
inactive@expired | 有効期限が切れ |
inactive@revoked | 払い戻しなどで強制的にキャンセルされた |
EzSubscriptionStatus
サブスクリプションの契約状況
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
contentName | string | ✓ | ~ 128文字 | 定期課金ストアコンテンツモデル名 | |
userId | string | ~ 128文字 | ユーザーID | ||
status | enum { “active”, “inactive” } | ✓ | ~ 128文字 | ステータス | |
expiresAt | long | ✓ | 有効期限 (UNIX時間 単位:ミリ秒) | ||
detail | List<EzSubscribeTransaction> | [] | ~ 100 items | 契約状況の詳細 |
status に指定する列挙型の定義
定義 | 説明 |
---|---|
active | 有効 |
inactive | 無効 |
メソッド
get
ウォレットを取得
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ✓ | ~ 128文字 | アクセストークン | |
slot | int | ✓ | ~ 100000000 | スロット番号 |
Result
型 | 説明 | |
---|---|---|
item | EzWallet | ウォレット |
実装例
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
var item = await domain.ModelAsync();
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Wallet(
0 // slot
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
値の変更イベントハンドリング
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
// イベントハンドリングを開始
var callbackId = domain.Subscribe(
value => {
// 値が変化した時に呼び出される
// value には変更後の値が渡ってくる
}
);
// イベントハンドリングを停止
domain.Unsubscribe(callbackId);
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Wallet(
0 // slot
);
// イベントハンドリングを開始
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Money2::Model::FWallet> value) {
// 値が変化した時に呼び出される
// value には変更後の値が渡ってくる
}
);
// イベントハンドリングを停止
Domain->Unsubscribe(CallbackId);
Warning
このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。
ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。
そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
list
ウォレットの一覧を取得
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ✓ | ~ 128文字 | アクセストークン |
Result
型 | 説明 | |
---|---|---|
items | List<EzWallet> | ウォレットのリスト |
nextPageToken | string | リストの続きを取得するためのページトークン |
実装例
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.WalletsAsync(
).ToListAsync();
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Wallets(
);
List<EzWallet> items = new List<EzWallet>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
}
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Wallets(
);
TArray<Gs2::UE5::Money2::Model::FEzWalletPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}
値の変更イベントハンドリング
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// イベントハンドリングを開始
var callbackId = domain.SubscribeWallets(
() => {
// リストの要素が変化した時に呼び出される
}
);
// イベントハンドリングを停止
domain.UnsubscribeWallets(callbackId);
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Wallets(
);
List<EzWallet> items = new List<EzWallet>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
}
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// イベントハンドリングを開始
const auto CallbackId = Domain->SubscribeWallets(
[]() {
// リストの要素が変化した時に呼び出される
}
);
// イベントハンドリングを停止
Domain->UnsubscribeWallets(CallbackId);
Warning
このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。
ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。
そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
withdraw
ウォレットから残高を消費
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ✓ | ~ 128文字 | アクセストークン | |
slot | int | ✓ | ~ 100000000 | スロット番号 | |
withdrawCount | int | ✓ | 1 ~ 2147483646 | 消費する課金通貨の数量 | |
paidOnly | bool | ✓ | false | 有償課金通貨のみを対象とするか |
Result
型 | 説明 | |
---|---|---|
item | EzWallet | 消費後のウォレット |
withdrawTransactions | List<EzDepositTransaction> | 消費した入金トランザクションリスト |
Error
このAPIには特別な例外が定義されています。
GS2-SDK for GameEngine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。
一般的なエラーの種類や、ハンドリング方法は こちら のドキュメントを参考にしてください。
型 | 基底クラス | 説明 |
---|---|---|
ConflictException | ConflictException | ウォレットの操作処理が衝突しました。リトライが必要です |
InsufficientException | BadRequestException | ウォレットの残高が不足しています |
実装例
try {
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
var result = await domain.WithdrawAsync(
withdrawCount: 50,
paidOnly: null
);
var item = await result.ModelAsync();
var withdrawTransactions = result.WithdrawTransactions;
} catch(Gs2.Gs2Money2.Exception.Conflict e) {
// The wallet operation process conflicted. Retry required.
} catch(Gs2.Gs2Money2.Exception.Insufficient e) {
// Wallet balance is insufficient.
}
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Wallet(
slot: 0
);
var future = domain.WithdrawFuture(
withdrawCount: 50,
paidOnly: null
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Money2.Exception.ConflictException)
{
// The wallet operation process conflicted. Retry required.
}
if (future.Error is Gs2.Gs2Money2.Exception.InsufficientException)
{
// Wallet balance is insufficient.
}
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result;
var withdrawTransactions = future.Result.WithdrawTransactions;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Wallet(
0 // slot
);
const auto Future = Domain->Withdraw(
50 // withdrawCount
// paidOnly
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Money2::Error::FConflictError::Class))
{
// The wallet operation process conflicted. Retry required.
}
if (e->IsChildOf(Gs2::Money2::Error::FInsufficientError::Class))
{
// Wallet balance is insufficient.
}
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();
const auto WithdrawTransactions = Result->WithdrawTransactions;
allocateSubscriptionStatus
レシートからサブスクリプションの契約状況を割り当て
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ~ 128文字 | アクセストークン | ||
receipt | string | ✓ | ~ 1024文字 | レシート |
Result
型 | 説明 | |
---|---|---|
item | EzSubscriptionStatus | サブスクリプションの契約状況 |
Error
このAPIには特別な例外が定義されています。
GS2-SDK for GameEngine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。
一般的なエラーの種類や、ハンドリング方法は こちら のドキュメントを参考にしてください。
型 | 基底クラス | 説明 |
---|---|---|
AlreadyUsedException | BadRequestException | すでにその期間課金契約は他のユーザーによって利用されています |
実装例
try {
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.AllocateSubscriptionStatusAsync(
receipt: "{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}"
);
var item = await result.ModelAsync();
} catch(Gs2.Gs2Money2.Exception.AlreadyUsed e) {
// The subscription contract for that period has already been used by another user.
}
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var future = domain.AllocateSubscriptionStatusFuture(
receipt: "{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}"
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Money2.Exception.AlreadyUsedException)
{
// The subscription contract for that period has already been used by another user.
}
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto Future = Domain->AllocateSubscriptionStatus(
"{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}" // receipt
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Money2::Error::FAlreadyUsedError::Class))
{
// The subscription contract for that period has already been used by another user.
}
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();
getSubscriptionStatus
サブスクリプションの契約状況を取得
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ~ 128文字 | アクセストークン | ||
contentName | string | ✓ | ~ 128文字 | 定期課金ストアコンテンツモデル名 |
Result
型 | 説明 | |
---|---|---|
item | EzSubscriptionStatus | サブスクリプションの契約状況 |
実装例
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).SubscriptionStatus(
contentName: "content-0001"
);
var item = await domain.ModelAsync();
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).SubscriptionStatus(
contentName: "content-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->SubscriptionStatus(
"content-0001" // contentName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
値の変更イベントハンドリング
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).SubscriptionStatus(
contentName: "content-0001"
);
// イベントハンドリングを開始
var callbackId = domain.Subscribe(
value => {
// 値が変化した時に呼び出される
// value には変更後の値が渡ってくる
}
);
// イベントハンドリングを停止
domain.Unsubscribe(callbackId);
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).SubscriptionStatus(
contentName: "content-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->SubscriptionStatus(
"content-0001" // contentName
);
// イベントハンドリングを開始
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Money2::Model::FSubscriptionStatus> value) {
// 値が変化した時に呼び出される
// value には変更後の値が渡ってくる
}
);
// イベントハンドリングを停止
Domain->Unsubscribe(CallbackId);
Warning
このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。
ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。
そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
listSubscriptionStatuses
サブスクリプションの契約状況の一覧を取得
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ~ 128文字 | アクセストークン |
Result
型 | 説明 | |
---|---|---|
items | List<EzSubscriptionStatus> | サブスクリプションの契約状況のリスト |
実装例
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.SubscriptionStatusesAsync(
).ToListAsync();
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.SubscriptionStatuses(
);
List<EzSubscriptionStatus> items = new List<EzSubscriptionStatus>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
}
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->SubscriptionStatuses(
);
TArray<Gs2::UE5::Money2::Model::FEzSubscriptionStatusPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}
値の変更イベントハンドリング
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// イベントハンドリングを開始
var callbackId = domain.SubscribeSubscriptionStatuses(
() => {
// リストの要素が変化した時に呼び出される
}
);
// イベントハンドリングを停止
domain.UnsubscribeSubscriptionStatuses(callbackId);
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.SubscriptionStatuses(
);
List<EzSubscriptionStatus> items = new List<EzSubscriptionStatus>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
}
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// イベントハンドリングを開始
const auto CallbackId = Domain->SubscribeSubscriptionStatuses(
[]() {
// リストの要素が変化した時に呼び出される
}
);
// イベントハンドリングを停止
Domain->UnsubscribeSubscriptionStatuses(CallbackId);
Warning
このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。
ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。
そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
takeOverSubscriptionStatus
すでに他のユーザーに割り当てられているサブスクリプションの契約状況を引き継ぐ
Request
型 | 必須 | デフォルト | 値の制限 | 説明 | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128文字 | ネームスペースの名前 | |
accessToken | string | ~ 128文字 | アクセストークン | ||
receipt | string | ✓ | ~ 1024文字 | レシート |
Result
型 | 説明 | |
---|---|---|
item | EzSubscriptionStatus | サブスクリプションの契約状況 |
Error
このAPIには特別な例外が定義されています。
GS2-SDK for GameEngine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。
一般的なエラーの種類や、ハンドリング方法は こちら のドキュメントを参考にしてください。
型 | 基底クラス | 説明 |
---|---|---|
LockPeriodNotElapsedException | BadRequestException | 前回のユーザーの付け替えから、ロック期間が経過していません |
実装例
try {
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.TakeOverSubscriptionStatusAsync(
receipt: "{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}"
);
var item = await result.ModelAsync();
} catch(Gs2.Gs2Money2.Exception.LockPeriodNotElapsed e) {
// The lock period has not elapsed since the last user change.
}
var domain = gs2.Money2.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var future = domain.TakeOverSubscriptionStatusFuture(
receipt: "{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}"
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Money2.Exception.LockPeriodNotElapsedException)
{
// The lock period has not elapsed since the last user change.
}
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result;
const auto Domain = Gs2->Money2->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto Future = Domain->TakeOverSubscriptionStatus(
"{\"Store\": \"AppleAppStore\", \"TransactionID\": \"transaction-0001\", \"Payload\": \"payload\"}" // receipt
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Money2::Error::FLockPeriodNotElapsedError::Class))
{
// The lock period has not elapsed since the last user change.
}
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();
イベントハンドラ
OnChangeSubscriptionStatus
期間課金の契約状況が変化したときに使用する通知
名前 | 型 | 説明 |
---|---|---|
namespaceName | string | ネームスペースの名前 |
userId | string | ユーザーID |
contentName | string | 定期課金ストアコンテンツモデル名 |
実装例
gs2.Money2.OnChangeSubscriptionStatus += notification =>
{
var namespaceName = notification.NamespaceName;
var userId = notification.UserId;
var contentName = notification.ContentName;
};
gs2.Money2.OnChangeSubscriptionStatus += notification =>
{
var namespaceName = notification.NamespaceName;
var userId = notification.UserId;
var contentName = notification.ContentName;
};
Gs2->Money2->OnChangeSubscriptionStatus().AddLambda([](const auto Notification)
{
const auto NamespaceName = Notification->NamespaceNameValue;
const auto UserId = Notification->UserIdValue;
const auto ContentName = Notification->ContentNameValue;
});