GS2-Money2 Deploy/CDK リファレンス
エンティティ
Deploy処理で操作の対象となるリソース
Namespace
ネームスペース
ネームスペースは、一つのプロジェクト内で同じサービスを異なる用途で複数利用するためのエンティティです。
GS2 の各サービスはネームスペース単位で管理されます。ネームスペースが異なれば、同じサービスでも完全に独立したデータ空間として扱われます。
そのため、各サービスの利用を開始するにあたってネームスペースを作成する必要があります。
Request
リソースの生成・更新リクエスト
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128文字 | ネームスペース名 ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 | ||||||||
| currencyUsagePriority | 文字列列挙型 enum { “PrioritizeFree”, “PrioritizePaid” } | ✓ | 消費優先度 ウォレットから出金する際に有償通貨と無償通貨のどちらを先に消費するかを決定します。“PrioritizeFree” は無償通貨を優先し、“PrioritizePaid” は有償通貨を優先します。
| |||||||||
| description | string | ~ 1024文字 | 説明文 | |||||||||
| transactionSetting | TransactionSetting | トランザクション設定 通貨の入金・出金時に使用される分散トランザクションの設定です。 | ||||||||||
| sharedFreeCurrency | bool | ✓ | 無償通貨を異なるスロットで共有するか 有効にすると、無償通貨の残高がすべてのウォレットスロット(プラットフォーム)間で共有されます。有償通貨はスロットごとに分離されたままです。この設定はネームスペース作成時のみ設定可能で、後から変更できません。 | |||||||||
| platformSetting | PlatformSetting | ✓ | ストアプラットフォーム設定 サポートされている各ストアプラットフォーム(Apple App Store、Google Play、テスト用Fake)の設定です。各プラットフォームでのレシート検証に必要な認証情報やキーを含みます。 | |||||||||
| depositBalanceScript | ScriptSetting | ウォレット残高を加算したときに実行するスクリプトの設定 Script トリガーリファレンス - deposit | ||||||||||
| withdrawBalanceScript | ScriptSetting | ウォレット残高を消費したときに実行するスクリプトの設定 Script トリガーリファレンス - withdraw | ||||||||||
| verifyReceiptScript | ScriptSetting | レシート検証を実行したときに実行するスクリプトの設定 Script トリガーリファレンス - verifyReceipt | ||||||||||
| subscribeScript | string | ~ 1024文字 | 期間課金を新規契約するときに実行する GS2-Script スクリプトGRN(ユーザーの紐づけ変更時には呼び出されない/一度契約失効後に再度契約した場合も呼び出される) Script トリガーリファレンス - subscribe | |||||||||
| renewScript | string | ~ 1024文字 | 期間課金を更新するときに実行する GS2-Script スクリプトGRN Script トリガーリファレンス - renew | |||||||||
| unsubscribeScript | string | ~ 1024文字 | 期間課金を解約するときに実行する GS2-Script スクリプトGRN(ユーザーの紐づけ変更時には呼び出されない) Script トリガーリファレンス - unsubscribe | |||||||||
| takeOverScript | ScriptSetting | 期間課金に紐づけられたユーザーを変更するときに実行するスクリプトの設定 Script トリガーリファレンス - takeOver | ||||||||||
| changeSubscriptionStatusNotification | NotificationSetting | 期間課金の契約状況が変化したときのプッシュ通知 サブスクリプションのステータスが変化した際(有効化、更新、解約、期限切れ、取り消しなど)に GS2-Gateway を通じて配信されるプッシュ通知の設定です。ゲームクライアントがサブスクリプション状態の変化にリアルタイムで対応できるようにします。 | ||||||||||
| logSetting | LogSetting | ログの出力設定 このネームスペースに対するAPIリクエスト・レスポンスログの出力先となる GS2-Log のネームスペースを指定します。入金、出金、レシート検証、サブスクリプションイベントの追跡に役立ちます。 |
GetAttr
!GetAttrタグで取得可能なリソースの生成結果
| 型 | 説明 | |
|---|---|---|
| Item | Namespace | 作成したネームスペース |
実装例
Type: GS2::Money2::Namespace
Properties:
Name: namespace-0001
CurrencyUsagePriority: PrioritizeFree
Description: null
TransactionSetting: null
SharedFreeCurrency: false
PlatformSetting: {}
DepositBalanceScript: null
WithdrawBalanceScript: null
VerifyReceiptScript: null
SubscribeScript: null
RenewScript: null
UnsubscribeScript: null
TakeOverScript: null
ChangeSubscriptionStatusNotification: null
LogSetting:
LoggingNamespaceId: grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001import (
"github.com/gs2io/gs2-golang-cdk/core"
"github.com/gs2io/gs2-golang-cdk/money2"
)
SampleStack := core.NewStack()
money2.NewNamespace(
&SampleStack,
"namespace-0001",
money2.NamespaceCurrencyUsagePriorityPrioritizeFree,
false,
money2.PlatformSetting{
AppleAppStore: nil,
GooglePlay: nil,
Fake: nil,
},
money2.NamespaceOptions{
LogSetting: &core.LogSetting{
LoggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001",
},
},
)
println(SampleStack.Yaml()) // Generate Templateclass SampleStack extends \Gs2Cdk\Core\Model\Stack
{
function __construct() {
parent::__construct();
new \Gs2Cdk\Money2\Model\Namespace_(
stack: $this,
name: "namespace-0001",
currencyUsagePriority: \Gs2Cdk\Money2\Model\Enums\NamespaceCurrencyUsagePriority::PRIORITIZE_FREE,
sharedFreeCurrency: false,
platformSetting: new \Gs2Cdk\Money2\Model\PlatformSetting(),
options: new \Gs2Cdk\Money2\Model\Options\NamespaceOptions(
logSetting: new \Gs2Cdk\Core\Model\LogSetting(
loggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
)
)
);
}
}
print((new SampleStack())->yaml()); // Generate Templateclass SampleStack extends io.gs2.cdk.core.model.Stack
{
public SampleStack() {
super();
new io.gs2.cdk.money2.model.Namespace(
this,
"namespace-0001",
io.gs2.cdk.money2.model.enums.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
false,
new io.gs2.cdk.money2.model.PlatformSetting(),
new io.gs2.cdk.money2.model.options.NamespaceOptions()
.withLogSetting(new io.gs2.cdk.core.model.LogSetting(
"grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
))
);
}
}
System.out.println(new SampleStack().yaml()); // Generate Templatepublic class SampleStack : Gs2Cdk.Core.Model.Stack
{
public SampleStack() {
new Gs2Cdk.Gs2Money2.Model.Namespace(
stack: this,
name: "namespace-0001",
currencyUsagePriority: Gs2Cdk.Gs2Money2.Model.Enums.NamespaceCurrencyUsagePriority.PrioritizeFree,
sharedFreeCurrency: false,
platformSetting: new Gs2Cdk.Gs2Money2.Model.PlatformSetting(),
options: new Gs2Cdk.Gs2Money2.Model.Options.NamespaceOptions
{
logSetting = new Gs2Cdk.Core.Model.LogSetting(
loggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
)
}
);
}
}
Debug.Log(new SampleStack().Yaml()); // Generate Templateimport core from "@/gs2cdk/core";
import money2 from "@/gs2cdk/money2";
class SampleStack extends core.Stack
{
public constructor() {
super();
new money2.model.Namespace(
this,
"namespace-0001",
money2.model.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
false,
new money2.model.PlatformSetting(),
{
logSetting: new core.LogSetting(
"grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
)
}
);
}
}
console.log(new SampleStack().yaml()); // Generate Templatefrom gs2_cdk import Stack, core, money2
class SampleStack(Stack):
def __init__(self):
super().__init__()
money2.Namespace(
stack=self,
name='namespace-0001',
currency_usage_priority=money2.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
shared_free_currency=False,
platform_setting=money2.PlatformSetting(),
options=money2.NamespaceOptions(
log_setting=core.LogSetting(
logging_namespace_id='grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001',
),
),
)
print(SampleStack().yaml()) # Generate TemplateTransactionSetting
トランザクション設定
トランザクション設定は、トランザクションの実行方法・整合性・非同期処理・競合回避の仕組みを制御する設定です。
自動実行(AutoRun)、アトミック実行(AtomicCommit)、GS2-Distributor を利用した非同期実行、スクリプト結果の一括適用、GS2-JobQueue による入手アクションの非同期化などを組み合わせ、ゲームロジックに応じた堅牢なトランザクション管理を可能にします。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| enableAutoRun | bool | false | 発行したトランザクションをサーバーサイドで自動的に実行するか | |||
| enableAtomicCommit | bool | {enableAutoRun} == true | false | トランザクションの実行をアトミックにコミットするか ※ enableAutoRun が true であれば 有効 | ||
| transactionUseDistributor | bool | {enableAtomicCommit} == true | false | トランザクションを非同期処理で実行する ※ enableAtomicCommit が true であれば 有効 | ||
| commitScriptResultInUseDistributor | bool | {transactionUseDistributor} == true | false | スクリプトの結果コミット処理を非同期処理で実行するか ※ transactionUseDistributor が true であれば 有効 | ||
| acquireActionUseJobQueue | bool | {enableAtomicCommit} == true | false | 入手アクションを実行する際に GS2-JobQueue を使用するか ※ enableAtomicCommit が true であれば 有効 | ||
| distributorNamespaceId | string | “grn:gs2:{region}:{ownerId}:distributor:default” | ~ 1024文字 | トランザクションの実行に使用する GS2-Distributor ネームスペース GRN | ||
| queueNamespaceId | string | “grn:gs2:{region}:{ownerId}:queue:default” | ~ 1024文字 | トランザクションの実行に使用する GS2-JobQueue のネームスペース GRN |
ScriptSetting
スクリプト設定
GS2 ではマイクロサービスのイベントに関連づけて、カスタムスクリプトを実行することができます。
このモデルは、スクリプトの実行をトリガーするための設定を保持します。
スクリプトの実行方式は大きく2種類あり、それは「同期実行」と「非同期実行」です。
同期実行は、スクリプトの実行が完了するまで処理がブロックされます。
代わりに、スクリプトの実行結果を使って API の実行を止めたり、API のレスポンス内容を制御することができます。
一方、非同期実行ではスクリプトの完了を待つために処理がブロックされることはありません。
ただし、スクリプトの実行結果を利用して API の実行を停止したり、API の応答内容を変更することはできません。
非同期実行は API の応答フローに影響を与えないため、原則として非同期実行を推奨します。
非同期実行には実行方式が2種類あり、GS2-Script と Amazon EventBridge があります。
Amazon EventBridge を使用することで、Lua 以外の言語で処理を記述することができます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| triggerScriptId | string | ~ 1024文字 | API 実行時に同期的に実行される GS2-Script のスクリプト
GRN 「grn:gs2:」ではじまる GRN 形式のIDで指定する必要があります。 | |||||||||||
| doneTriggerTargetType | 文字列列挙型 enum { “none”, “gs2_script”, “aws” } | “none” | 非同期スクリプトの実行方法 非同期実行で使用するスクリプトの種類を指定します。 「非同期実行のスクリプトを使用しない(none)」「GS2-Scriptを使用する(gs2_script)」「Amazon EventBridgeを使用する(aws)」が選択できます。
| |||||||||||
| doneTriggerScriptId | string | {doneTriggerTargetType} == “gs2_script” | ~ 1024文字 | 非同期実行する GS2-Script スクリプト
GRN 「grn:gs2:」ではじまる GRN 形式のIDで指定する必要があります。 ※ doneTriggerTargetType が “gs2_script” であれば 有効 | ||||||||||
| doneTriggerQueueNamespaceId | string | {doneTriggerTargetType} == “gs2_script” | ~ 1024文字 | 非同期実行スクリプトを実行する GS2-JobQueue ネームスペース
GRN 非同期実行スクリプトを直接実行するのではなく、GS2-JobQueue を経由する場合は GS2-JobQueue のネームスペースGRN を指定します。 GS2-JobQueue を利用する理由は多くはありませんので、特に理由がなければ指定する必要はありません。 ※ doneTriggerTargetType が “gs2_script” であれば 有効 |
NotificationSetting
プッシュ通知に関する設定
GS2 のマイクロサービス内で何らかのイベントが発生した際に、プッシュ通知を送信するための設定です。
ここでいうプッシュ通知は GS2-Gateway の提供する WebSocket インターフェースを経由した処理であり、スマートフォンのプッシュ通知とは性質が異なります。
たとえば、マッチメイキングが完了した時やフレンドリクエストが届いた時など、ゲームクライアントの操作とは関係なく状態が変化した際に GS2-Gateway を経由してプッシュ通知をすることで、ゲームクライアントは状態の変化を検知することができます。
GS2-Gateway のプッシュ通知は通知先のデバイスがオフラインだった時に追加の処理としてモバイルプッシュ通知を送信できます。
モバイルプッシュ通知をうまく利用すれば、マッチメイキング中にゲームを終了しても、モバイルプッシュ通知を使用してプレイヤーに通知し、ゲームに戻ってくるフローを実現できる可能性があります。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gatewayNamespaceId | string | “grn:gs2:{region}:{ownerId}:gateway:default” | ~ 1024文字 | プッシュ通知に使用する GS2-Gateway のネームスペース 「grn:gs2:」から始まる GRN 形式で GS2-Gateway のネームスペースIDを指定します。 | ||||||||
| enableTransferMobileNotification | bool? | false | モバイルプッシュ通知へ転送するか この通知を送信しようとした時、通知先のデバイスがオフラインだった場合、モバイルプッシュ通知へ転送するかどうかを指定します。 | |||||||||
| sound | string | {enableTransferMobileNotification} == true | ~ 1024文字 | モバイルプッシュ通知で使用するサウンドファイル名 ここで指定したサウンドファイル名は、モバイルプッシュ通知を送信する際に使用され、特別なサウンドで通知を出すことができます。 ※ enableTransferMobileNotification が true であれば 有効 | ||||||||
| enable | 文字列列挙型 enum { “Enabled”, “Disabled” } | “Enabled” | プッシュ通知を有効にするか
|
LogSetting
ログの出力設定
ログデータの出力設定を管理します。この型は、ログデータを書き出すために使用される GS2-Log ネームスペースの識別子(Namespace ID)を保持します。
ログネームスペースID(loggingNamespaceId)には、ログデータを収集し保存する GS2-Log のネームスペースを、GRNの形式で指定します。
この設定をすることで、設定されたネームスペース内で発生したAPIリクエスト・レスポンスのログデータが、対象の GS2-Log ネームスペース側へ出力されるようになります。
GS2-Log ではリアルタイムでログが提供され、システムの監視や分析、デバッグなどに利用できます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| loggingNamespaceId | string | ✓ | ~ 1024文字 | ログを出力する GS2-Log のネームスペース
GRN 「grn:gs2:」ではじまる GRN 形式のIDで指定する必要があります。 |
PlatformSetting
ストアプラットフォームの設定
サポートされている全ストアプラットフォームの設定を集約します。Apple App Store、Google Play、Fake(Unity Editorでのテスト用)の設定を含みます。各プラットフォーム設定にはレシート検証に必要な認証情報やキーが含まれます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| appleAppStore | AppleAppStoreSetting | Apple AppStore の設定 Apple App Store のレシート検証に使用する認証情報です。バンドルID、共有秘密鍵、Issuer ID、キーID、秘密鍵を含みます。 | ||||
| googlePlay | GooglePlaySetting | Google Play の設定 Google Play のレシート検証に使用する認証情報です。パッケージ名と署名検証用の公開鍵を含みます。 | ||||
| fake | FakeSetting | Fake (Unity Editor) の設定 開発・テスト中に Unity Editor が生成するフェイクレシートの受け入れに関する設定です。 |
AppleAppStoreSetting
Apple AppStore の設定
Apple App Store のレシート検証のための設定です。Apple のレシート検証サーバーとの通信に必要な認証情報を含みます。バンドルID、共有秘密鍵、App Store Connect の Issuer ID、キーID、秘密鍵が含まれます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| bundleId | string | ~ 1024文字 | Apple AppStore のバンドルID | |||
| sharedSecretKey | string | ~ 1024文字 | AppStore Connect で発行したレシートの暗号化に使用する共有秘密鍵 | |||
| issuerId | string | ~ 1024文字 | AppStore Connect で登録したアプリ内課金の Issuer ID | |||
| keyId | string | ~ 1024文字 | Apple に登録済みのキーID | |||
| privateKeyPem | string | ~ 10240文字 | Apple から受け取った秘密鍵 |
GooglePlaySetting
Google Play の設定
Google Play のレシート検証のための設定です。Google Play からの購入署名を検証するために必要なパッケージ名と公開鍵を含みます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| packageName | string | ~ 5120文字 | Google Play で配信するパッケージ名 | |||
| publicKey | string | ~ 5120文字 | 署名検証に使用する暗号鍵 |
FakeSetting
デバッグ用の偽のプラットフォームの設定
開発中に Unity Editor が生成するフェイクレシートの処理に関する設定です。フェイクレシートを受け入れるか拒否するかを制御し、実際のストアプラットフォームを使わずにアプリ内課金フローをテストできるようにします。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| acceptFakeReceipt | 文字列列挙型 enum { “Accept”, “Reject” } | “Reject” | Unity Editor が出力する偽のレシートで決済できるようにするか フェイクレシートの受け入れを制御します。開発・テスト中は “Accept” に設定し、本番環境では不正な通貨入金を防ぐために “Reject” に設定してください。
|
CurrentModelMaster
現在アクティブなモデルのマスターデータ
現在ネームスペース内で有効なモデルの定義を記述したマスターデータです。
GS2ではマスターデータの管理にJSON形式のファイルを使用します。
ファイルをアップロードすることで、実際にサーバーに設定を反映することができます。
JSONファイルを作成する方法として、マネージメントコンソール内にマスターデータエディタを提供しています。
また、よりゲームの運営に相応しいツールを作成し、適切なフォーマットのJSONファイルを書き出すことでもサービスを利用可能です。
Note
JSONファイルの形式については GS2-Money2 マスターデータリファレンス をご参照ください。Request
リソースの生成・更新リクエスト
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128文字 | ネームスペース名 ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 | ||||||||
| mode | 文字列列挙型 enum { “direct”, “preUpload” } | “direct” | 更新モード
| |||||||||
| settings | string | {mode} == “direct” | ✓※ | ~ 5242880文字 | マスターデータ ※ mode が “direct” であれば必須 | |||||||
| uploadToken | string | {mode} == “preUpload” | ✓※ | ~ 1024文字 | 事前アップロードで取得したトークン アップロードしたマスターデータを適用するために使用されます。 ※ mode が “preUpload” であれば必須 |
GetAttr
!GetAttrタグで取得可能なリソースの生成結果
| 型 | 説明 | |
|---|---|---|
| Item | CurrentModelMaster | 更新された現在アクティブなモデルのマスターデータ |
実装例
Type: GS2::Money2::CurrentModelMaster
Properties:
NamespaceName: namespace-0001
Mode: direct
Settings: {
"version": "2024-06-20",
"storeContentModels": [
{
"name": "content-0001",
"appleAppStore":
{
"productId": "io.gs2.sample.apple.product1"
},
"googlePlay":
{
"productId": "io.gs2.sample.google.product1"
}
},
{
"name": "content-0002",
"appleAppStore":
{
"productId": "io.gs2.sample.apple.product2"
},
"googlePlay":
{
"productId": "io.gs2.sample.google.product2"
}
},
{
"name": "apple-only-0001",
"appleAppStore":
{
"productId": "io.gs2.sample.apple.product3"
}
},
{
"name": "google-only-0001",
"googlePlay":
{
"productId": "io.gs2.sample.google.product3"
}
}
],
"storeSubscriptionContentModels": []
}
UploadToken: nullimport (
"github.com/gs2io/gs2-golang-cdk/core"
"github.com/gs2io/gs2-golang-cdk/money2"
"github.com/openlyinc/pointy"
)
SampleStack := core.NewStack()
money2.NewNamespace(
&SampleStack,
"namespace-0001",
money2.NamespaceCurrencyUsagePriorityPrioritizeFree,
false,
money2.PlatformSetting{
AppleAppStore: nil,
GooglePlay: nil,
Fake: nil,
},
money2.NamespaceOptions{},
).MasterData(
[]money2.StoreContentModel{
money2.NewStoreContentModel(
"content-0001",
money2.StoreContentModelOptions{
AppleAppStore: &money2.AppleAppStoreContent{
ProductId: pointy.String("io.gs2.sample.apple.product1"),
},
GooglePlay: &money2.GooglePlayContent{
ProductId: pointy.String("io.gs2.sample.google.product1"),
},
},
),
money2.NewStoreContentModel(
"content-0002",
money2.StoreContentModelOptions{
AppleAppStore: &money2.AppleAppStoreContent{
ProductId: pointy.String("io.gs2.sample.apple.product2"),
},
GooglePlay: &money2.GooglePlayContent{
ProductId: pointy.String("io.gs2.sample.google.product2"),
},
},
),
money2.NewStoreContentModel(
"apple-only-0001",
money2.StoreContentModelOptions{
AppleAppStore: &money2.AppleAppStoreContent{
ProductId: pointy.String("io.gs2.sample.apple.product3"),
},
},
),
money2.NewStoreContentModel(
"google-only-0001",
money2.StoreContentModelOptions{
GooglePlay: &money2.GooglePlayContent{
ProductId: pointy.String("io.gs2.sample.google.product3"),
},
},
),
},
[]money2.StoreSubscriptionContentModel{
},
)
println(SampleStack.Yaml()) // Generate Templateclass SampleStack extends \Gs2Cdk\Core\Model\Stack
{
function __construct() {
parent::__construct();
(new \Gs2Cdk\Money2\Model\Namespace_(
stack: $this,
name: "namespace-0001",
currencyUsagePriority: \Gs2Cdk\Money2\Model\Enums\NamespaceCurrencyUsagePriority::PRIORITIZE_FREE,
sharedFreeCurrency: false,
platformSetting: new \Gs2Cdk\Money2\Model\PlatformSetting(),
))->masterData(
[
new \Gs2Cdk\Money2\Model\StoreContentModel(
name:"content-0001",
options: new \Gs2Cdk\Money2\Model\Options\StoreContentModelOptions(
appleAppStore:new \Gs2Cdk\Money2\Model\AppleAppStoreContent(
options: new \Gs2Cdk\Money2\Model\Options\AppleAppStoreContentOptions(
productId: "io.gs2.sample.apple.product1",
),
),
googlePlay:new \Gs2Cdk\Money2\Model\GooglePlayContent(
options: new \Gs2Cdk\Money2\Model\Options\GooglePlayContentOptions(
productId: "io.gs2.sample.google.product1",
),
)
)
),
new \Gs2Cdk\Money2\Model\StoreContentModel(
name:"content-0002",
options: new \Gs2Cdk\Money2\Model\Options\StoreContentModelOptions(
appleAppStore:new \Gs2Cdk\Money2\Model\AppleAppStoreContent(
options: new \Gs2Cdk\Money2\Model\Options\AppleAppStoreContentOptions(
productId: "io.gs2.sample.apple.product2",
),
),
googlePlay:new \Gs2Cdk\Money2\Model\GooglePlayContent(
options: new \Gs2Cdk\Money2\Model\Options\GooglePlayContentOptions(
productId: "io.gs2.sample.google.product2",
),
)
)
),
new \Gs2Cdk\Money2\Model\StoreContentModel(
name:"apple-only-0001",
options: new \Gs2Cdk\Money2\Model\Options\StoreContentModelOptions(
appleAppStore:new \Gs2Cdk\Money2\Model\AppleAppStoreContent(
options: new \Gs2Cdk\Money2\Model\Options\AppleAppStoreContentOptions(
productId: "io.gs2.sample.apple.product3",
),
)
)
),
new \Gs2Cdk\Money2\Model\StoreContentModel(
name:"google-only-0001",
options: new \Gs2Cdk\Money2\Model\Options\StoreContentModelOptions(
googlePlay:new \Gs2Cdk\Money2\Model\GooglePlayContent(
options: new \Gs2Cdk\Money2\Model\Options\GooglePlayContentOptions(
productId: "io.gs2.sample.google.product3",
),
)
)
)
],
[
]
);
}
}
print((new SampleStack())->yaml()); // Generate Templateclass SampleStack extends io.gs2.cdk.core.model.Stack
{
public SampleStack() {
super();
new io.gs2.cdk.money2.model.Namespace(
this,
"namespace-0001",
io.gs2.cdk.money2.model.enums.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
false,
null
).masterData(
Arrays.asList(
new io.gs2.cdk.money2.model.StoreContentModel(
"content-0001",
new io.gs2.cdk.money2.model.options.StoreContentModelOptions()
.withAppleAppStore(new io.gs2.cdk.money2.model.AppleAppStoreContent(
new io.gs2.cdk.money2.model.options.AppleAppStoreContentOptions()
.withProductId("io.gs2.sample.apple.product1")
))
.withGooglePlay(new io.gs2.cdk.money2.model.GooglePlayContent(
new io.gs2.cdk.money2.model.options.GooglePlayContentOptions()
.withProductId("io.gs2.sample.google.product1")
))
),
new io.gs2.cdk.money2.model.StoreContentModel(
"content-0002",
new io.gs2.cdk.money2.model.options.StoreContentModelOptions()
.withAppleAppStore(new io.gs2.cdk.money2.model.AppleAppStoreContent(
new io.gs2.cdk.money2.model.options.AppleAppStoreContentOptions()
.withProductId("io.gs2.sample.apple.product2")
))
.withGooglePlay(new io.gs2.cdk.money2.model.GooglePlayContent(
new io.gs2.cdk.money2.model.options.GooglePlayContentOptions()
.withProductId("io.gs2.sample.google.product2")
))
),
new io.gs2.cdk.money2.model.StoreContentModel(
"apple-only-0001",
new io.gs2.cdk.money2.model.options.StoreContentModelOptions()
.withAppleAppStore(new io.gs2.cdk.money2.model.AppleAppStoreContent(
new io.gs2.cdk.money2.model.options.AppleAppStoreContentOptions()
.withProductId("io.gs2.sample.apple.product3")
))
),
new io.gs2.cdk.money2.model.StoreContentModel(
"google-only-0001",
new io.gs2.cdk.money2.model.options.StoreContentModelOptions()
.withGooglePlay(new io.gs2.cdk.money2.model.GooglePlayContent(
new io.gs2.cdk.money2.model.options.GooglePlayContentOptions()
.withProductId("io.gs2.sample.google.product3")
))
)
),
Arrays.asList(
)
);
}
}
System.out.println(new SampleStack().yaml()); // Generate Templatepublic class SampleStack : Gs2Cdk.Core.Model.Stack
{
public SampleStack() {
new Gs2Cdk.Gs2Money2.Model.Namespace(
stack: this,
name: "namespace-0001",
currencyUsagePriority: Gs2Cdk.Gs2Money2.Model.Enums.NamespaceCurrencyUsagePriority.PrioritizeFree,
sharedFreeCurrency: false,
platformSetting: null
).MasterData(
new Gs2Cdk.Gs2Money2.Model.StoreContentModel[] {
new Gs2Cdk.Gs2Money2.Model.StoreContentModel(
name: "content-0001",
options: new Gs2Cdk.Gs2Money2.Model.Options.StoreContentModelOptions
{
appleAppStore = new Gs2Cdk.Gs2Money2.Model.AppleAppStoreContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.AppleAppStoreContentOptions
{
productId = "io.gs2.sample.apple.product1"
}
),
googlePlay = new Gs2Cdk.Gs2Money2.Model.GooglePlayContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.GooglePlayContentOptions
{
productId = "io.gs2.sample.google.product1"
}
)
}
),
new Gs2Cdk.Gs2Money2.Model.StoreContentModel(
name: "content-0002",
options: new Gs2Cdk.Gs2Money2.Model.Options.StoreContentModelOptions
{
appleAppStore = new Gs2Cdk.Gs2Money2.Model.AppleAppStoreContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.AppleAppStoreContentOptions
{
productId = "io.gs2.sample.apple.product2"
}
),
googlePlay = new Gs2Cdk.Gs2Money2.Model.GooglePlayContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.GooglePlayContentOptions
{
productId = "io.gs2.sample.google.product2"
}
)
}
),
new Gs2Cdk.Gs2Money2.Model.StoreContentModel(
name: "apple-only-0001",
options: new Gs2Cdk.Gs2Money2.Model.Options.StoreContentModelOptions
{
appleAppStore = new Gs2Cdk.Gs2Money2.Model.AppleAppStoreContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.AppleAppStoreContentOptions
{
productId = "io.gs2.sample.apple.product3"
}
)
}
),
new Gs2Cdk.Gs2Money2.Model.StoreContentModel(
name: "google-only-0001",
options: new Gs2Cdk.Gs2Money2.Model.Options.StoreContentModelOptions
{
googlePlay = new Gs2Cdk.Gs2Money2.Model.GooglePlayContent(
options: new Gs2Cdk.Gs2Money2.Model.Options.GooglePlayContentOptions
{
productId = "io.gs2.sample.google.product3"
}
)
}
)
},
new Gs2Cdk.Gs2Money2.Model.StoreSubscriptionContentModel[] {
}
);
}
}
Debug.Log(new SampleStack().Yaml()); // Generate Templateimport core from "@/gs2cdk/core";
import money2 from "@/gs2cdk/money2";
class SampleStack extends core.Stack
{
public constructor() {
super();
new money2.model.Namespace(
this,
"namespace-0001",
money2.model.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
false,
new money2.model.PlatformSetting()
).masterData(
[
new money2.model.StoreContentModel(
"content-0001",
{
appleAppStore: new money2.model.AppleAppStoreContent(
{
productId: "io.gs2.sample.apple.product1"
}
),
googlePlay: new money2.model.GooglePlayContent(
{
productId: "io.gs2.sample.google.product1"
}
)
}
),
new money2.model.StoreContentModel(
"content-0002",
{
appleAppStore: new money2.model.AppleAppStoreContent(
{
productId: "io.gs2.sample.apple.product2"
}
),
googlePlay: new money2.model.GooglePlayContent(
{
productId: "io.gs2.sample.google.product2"
}
)
}
),
new money2.model.StoreContentModel(
"apple-only-0001",
{
appleAppStore: new money2.model.AppleAppStoreContent(
{
productId: "io.gs2.sample.apple.product3"
}
)
}
),
new money2.model.StoreContentModel(
"google-only-0001",
{
googlePlay: new money2.model.GooglePlayContent(
{
productId: "io.gs2.sample.google.product3"
}
)
}
)
],
[
]
);
}
}
console.log(new SampleStack().yaml()); // Generate Templatefrom gs2_cdk import Stack, core, money2
class SampleStack(Stack):
def __init__(self):
super().__init__()
money2.Namespace(
stack=self,
name="namespace-0001",
currency_usage_priority=money2.NamespaceCurrencyUsagePriority.PRIORITIZE_FREE,
shared_free_currency=False,
platform_setting=money2.PlatformSetting(),
).master_data(
store_content_models=[
money2.StoreContentModel(
name='content-0001',
options=money2.StoreContentModelOptions(
apple_app_store = money2.AppleAppStoreContent(
options=money2.AppleAppStoreContentOptions(
product_id='io.gs2.sample.apple.product1',
),
),
google_play = money2.GooglePlayContent(
options=money2.GooglePlayContentOptions(
product_id='io.gs2.sample.google.product1',
),
)
),
),
money2.StoreContentModel(
name='content-0002',
options=money2.StoreContentModelOptions(
apple_app_store = money2.AppleAppStoreContent(
options=money2.AppleAppStoreContentOptions(
product_id='io.gs2.sample.apple.product2',
),
),
google_play = money2.GooglePlayContent(
options=money2.GooglePlayContentOptions(
product_id='io.gs2.sample.google.product2',
),
)
),
),
money2.StoreContentModel(
name='apple-only-0001',
options=money2.StoreContentModelOptions(
apple_app_store = money2.AppleAppStoreContent(
options=money2.AppleAppStoreContentOptions(
product_id='io.gs2.sample.apple.product3',
),
)
),
),
money2.StoreContentModel(
name='google-only-0001',
options=money2.StoreContentModelOptions(
google_play = money2.GooglePlayContent(
options=money2.GooglePlayContentOptions(
product_id='io.gs2.sample.google.product3',
),
)
),
),
],
store_subscription_content_models=[
],
)
print(SampleStack().yaml()) # Generate TemplateStoreContentModel
ストアコンテンツモデル
各種ストアプラットフォームのコンテンツを格納するモデルです。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| storeContentModelId | string | ※ | ~ 1024文字 | ストアコンテンツモデル
GRN ※ サーバーが自動で設定 | ||
| name | string | ✓ | ~ 128文字 | ストアコンテンツモデル名 | ||
| metadata | string | ~ 1024文字 | メタデータ メタデータには任意の値を設定できます。 これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。 | |||
| appleAppStore | AppleAppStoreContent | Apple AppStore のコンテンツ このストアコンテンツの Apple App Store 商品情報(プロダクトID)です。レシート検証時に購入された商品との照合に使用されます。 | ||||
| googlePlay | GooglePlayContent | Google Play のコンテンツ このストアコンテンツの Google Play 商品情報(プロダクトID)です。レシート検証時に購入された商品との照合に使用されます。 |
AppleAppStoreContent
Apple AppStore のコンテンツ
アプリ内課金商品に対応する Apple App Store のプロダクトIDを含みます。レシート検証時の照合に使用されます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| productId | string | ~ 1024文字 | プロダクトID このアプリ内課金アイテムについて App Store Connect に登録されている Apple App Store のプロダクト識別子です。 |
GooglePlayContent
Google Play のコンテンツ
アプリ内課金商品に対応する Google Play のプロダクトIDを含みます。レシート検証時の照合に使用されます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| productId | string | ~ 1024文字 | プロダクトID このアプリ内課金アイテムについて Google Play Console に登録されている Google Play のプロダクト識別子です。 |
StoreSubscriptionContentModel
ストア定期課金コンテンツモデル
各種ストアプラットフォームの定期課金コンテンツを格納するモデルです。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| storeSubscriptionContentModelId | string | ※ | ~ 1024文字 | 期間課金コンテンツモデル
GRN ※ サーバーが自動で設定 | ||||||||
| name | string | ✓ | ~ 128文字 | ストア定期課金コンテンツモデル名 | ||||||||
| metadata | string | ~ 1024文字 | メタデータ | |||||||||
| scheduleNamespaceId | string | ✓ | ~ 1024文字 | サブスクリプション期間を連動させる GS2-Schedule のネームスペース GRN | ||||||||
| triggerName | string | ✓ | ~ 128文字 | サブスクリプション期間を反映するトリガー名 サブスクリプションの有効期間を反映するために起動される GS2-Schedule のトリガー名です。トリガーの持続時間はサブスクリプションの有効期限に設定されます。 | ||||||||
| triggerExtendMode | 文字列列挙型 enum { “just”, “rollupHour” } | “just” | サブスクリプション期間をトリガーに反映する時のモード サブスクリプションの有効期限をトリガーの持続時間にどのようにマッピングするかを制御します。“just” はサブスクリプション期間をそのまま使用します。“rollupHour” は指定した時刻(UTC)まで延長し、日中の期限切れを回避します。
| |||||||||
| rollupHour | int | {triggerExtendMode} == “rollupHour” | 0 | 0 ~ 23 | 日跨ぎの時刻 (UTC) triggerExtendMode が “rollupHour” の場合、サブスクリプション期間は有効期限日のこの時刻(0〜23、UTC)まで延長されます。ユーザーのプレイセッション中にサブスクリプションが期限切れになるのを防ぎます。 ※ triggerExtendMode が “rollupHour” であれば 有効 | |||||||
| reallocateSpanDays | int | 30 | 0 ~ 365 | サブスクリプションの契約情報を他のユーザーに割り当て可能となる期間(日) 最後の割り当てから、サブスクリプション契約を別のユーザーに再割り当てできるようになるまでの日数です。ユーザーがアカウントを変更する際の不正利用を防止するため、サブスクリプションの移行に待機期間を設けます。 | ||||||||
| appleAppStore | AppleAppStoreSubscriptionContent | Apple AppStore のコンテンツ このサブスクリプションコンテンツの Apple App Store のサブスクリプション情報(サブスクリプショングループID)です。 | ||||||||||
| googlePlay | GooglePlaySubscriptionContent | Google Play のコンテンツ このサブスクリプションコンテンツの Google Play のサブスクリプション情報(プロダクトID)です。 |
AppleAppStoreSubscriptionContent
Apple AppStore の期間課金コンテンツ
サブスクリプションベースの商品の Apple App Store サブスクリプショングループ識別子を含みます。自動更新サブスクリプションの管理と検証に使用されます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| subscriptionGroupIdentifier | string | ~ 64文字 | サブスクリプショングループID App Store Connect に登録されたサブスクリプショングループ識別子です。同じグループ内のサブスクリプションは相互排他的で、ユーザーは同時に1つしか契約できません。 |
GooglePlaySubscriptionContent
Google Play の期間課金コンテンツ
サブスクリプションベースの商品の Google Play プロダクトIDを含みます。Google Play での自動更新サブスクリプションの管理と検証に使用されます。
| 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 | |
|---|---|---|---|---|---|---|
| productId | string | ~ 1024文字 | プロダクトID |