GS2-Money

課金通貨管理機能

ゲーム内のリソースのうち、現金相当の価値を持つリソースを扱う機能です。 日本の資金決済法の前払い式支払い手段(自家型)に該当する資産を取り扱う場合は必ずこの機能を利用してください。

残高

GS2-Money はプレイヤーのもつ課金通貨の残高を単純な数量では管理せず、購入時の価値ごとに数量を管理します。

例えば、100円で100個の課金通貨を購入した場合は課金通貨1個の価値は1円相当となります。 同時に1000円で1200個の課金通貨を購入できるとしましょう。あくまで課金通貨の単価は1円とし、200個はおまけとして無料で処理するのも一つの手段ですし、1000円で購入した場合は単価を 0.8334円 として異なる単価で扱うのも一つの手段です。

後者のような方式を採用した場合、GS2-Money は「単価1円の課金通貨の残高」「単価0.8334円の課金通貨の残高」をそれぞれ分けて管理する機能を持っています。

後者を選択するメリットは?

明らかに後者は会計処理が複雑になり、メリットがないように感じるかもしれません。 サービス提供側としては全くのその通りです。しかし、立場を変えてゲームプレイヤーの立場で考えてみましょう。

ゲームの中には運営によって配られた現金相当の価値が0円の課金通貨(通称 無償通貨)があります。 プレイヤーに課金通貨を購入してもらうために、有償で購入した課金通貨(通称 有償通貨)でしか購入できない魅力的な商品を課金通貨300個で販売したとしましょう。

1000円 で 1200個の課金通貨を購入した際に、1000個の有償通貨と200個の無償通貨 を付与するように処理した場合 プレイヤーは有償通貨300個で購入できる商品を3回しか購入できません。 一方で、単価を0.8334円として1200個全てを有償通貨として取り扱う方法であればプレイヤーは4回購入できます。 この差はプレイヤー心理に多少なりとも影響を与えます。

会計上の都合を優先するか、プレイヤーの利益を優先するか 慎重に検討するべき仕様でしょう。

スロット

GS2-Money ではウォレットを複数持つことができます。 その複数のウォレットを区別するためのキーがスロットです。

この機能は他のプラットフォームで購入した課金通貨を持ち込ませないようにしているプラットフォーマーが存在するため、そのガイドラインを遵守するために存在する機能です。

しかし、これらのガイドラインは有償通貨にのみ適用されるため、無償通貨については全てのスロットで共有できる機能があります。

消費優先度

プレイヤーが課金通貨を消費する時に、無償通貨を優先して消費するか、有償通貨を優先して消費するかを選択できます。 一般的に無償通貨を優先して消費する仕様が採用されますが、会計上の都合がある場合は有償通貨を優先できます。 有償通貨を消費する場合は、より単価の高い通貨から優先して消費されます。

無償・有償問わず、あるいは有償通貨の中で入手した順番に消費したいというニーズがあることを我々は理解しています。 ただし、現在はその機能は実装されていません。この要件が重要なプロジェクトを検討中の場合は開発チームにご連絡ください。

レシートの検証

ゲームの配信プラットフォームで追加コンテンツの購入時に得られるレシートの検証機能を有しています。 レシートを検証し、正しくプラットフォーマーによって発行された内容であることを確認するとともに、過去にゲーム内で使用したことがないかも確認します。

この機能を利用することで、不正なレシートを利用して課金通貨を入手しようとする攻撃を回避できます。

トランザクションログ

レシートの検証履歴はもちろんですが、課金通貨の加算・減算履歴も全て記録されます。 そして、毎日数回 現在ゲーム内には未使用の課金通貨が現金相当額でいくらプールされているかを集計します。

状況に応じて未使用残高の一部を第三者機関に供託する対応が必要になることがありますが、その時にこの計算結果を利用できます。

法的手続き

GS2-Money は各種法的手続きをとるために必要なデータを収集し、APIによってアクセス可能な状態で保持しますが、 法的手続き自体はGS2の利用者である あなた/あなたが所属する組織 が実行する必要があります。

どのような手続きが必要となるかは、GS2では責任を持つことができないためアドバイスもできません。顧問弁護士に相談するようにしてください。

実装例

残高を取得

    var item = await gs2.Money.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Wallet(
        slot: 0
    ).ModelAsync();
    const auto Domain = Gs2->Money->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Wallet(
        0 // slot
    );
    const auto item = Domain.Model();

残高を加算

残高を加算する処理はゲームエンジン用の SDK では処理できません。

GS2-Showcase の購入時の報酬として残高を加算するといった方法で実装してください。

残高を消費

このAPIで残高の消費処理を行うことは推奨していません。 GS2-Showcase といったサービスを通して課金通貨の消費を行う代わりに 何らかの処理を実行することを推奨します。

    var result = await gs2.Money.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Wallet(
        slot: 0
    ).WithdrawAsync(
        count: 50,
        paidOnly: false
    );
    var item = await result.ModelAsync();
    var price = result.Price;
    const auto Future = Gs2->Money->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Wallet(
        0 // slot
    )->Withdraw(
        50,
        nullptr // paidOnly
    );
    Future->StartSynchronousTask();
    if (!TestFalse(WHAT, Future->GetTask().IsError())) return false;

詳細なリファレンス