コマース

【PlayFab】リアルマネーでアイテムを購入する手順【Steam編】

playfab-payment-steam

PC ゲームといえば、Steam というサービスが世界で大人気ですよね。

規模としては、数百万人もの人が同時に接続しているほどです。

Unity を使えば、Steam にも自分で作ったゲームを出すことができます。

実は PlayFab では、Steam のゲーム内アイテムをリアルマネーで購入させたい、という場合にも対応しているんです。

しかし、手順が少し難しいため、この記事でわかりやすくまとめました。

この記事を読むことで、PlayFab と Steam をすぐに連携できるはずです。

Steamworks でリリースできるアプリがないと、この先の作業ができません。

今から登録する人は、英語の電子資料をマイナンバー付きで提出したり、アプリ登録料で1万円かかったりするのでご注意ください。

ねこじょーかー
ねこじょーかー
ちなみに私はスマホゲームもリリースできると勘違いして、うっかり登録しました(笑)

では、さっそく見ていきましょう。

Steam アカウントで PlayFab にログインする

リアルマネーでアイテムを購入する前に、PlayFab と Steam を紐付けして上げる必要があります。

まずは、ログインが正常にできるところまでやっていきましょう。

Steam のインストール

まずは Steam がないと何も始まらないので、インストールをしましょう。

アカウントがない人は、同時に登録も必要です。

Steam アドオンの導入

PlayFab 管理画面左のアドオンより、Steam を選択して Steam を有効にします。

playfab-payment-steam



アプリケーション ID は7桁の数値、Web API キーは Guid となっていて、これらは Steamworks で確認できます。

playfab-payment-steam

そもそもこのページにたどり着けない人は、Web API キーを使用した認証を参照してください。

PlayFab 管理画面で入力が終わったら、「Steam をインストール」を押して完了です。

Steam アカウントで Unity にログインする

アドオンを使う上で Steam アカウントの紐付けが必要なので、Steam アカウントで PlayFab にログインします。

まずは、Steam SDK の unitypackage をダウンロードしましょう。

これを Unity プロジェクトにインポートします。

playfab-payment-steam

インポートできたら、いったん Unity を閉じて、Unity プロジェクトのルートにある「steam_appid.txt」を開きます。

playfab-payment-steam

ID を自分のアプリケーション ID に書き換えた後、再度 Unity プロジェクトを開きましょう。

playfab-payment-steam

次はログインの処理を書いていきます。

名前は何でもいいですが、SteamScript というクラスを作成しました。

using System;
using System.Collections.Generic;
using System.Text;
using PlayFab;
using PlayFab.ClientModels;
using Steamworks;
using UnityEngine;
using UnityEngine.UI;

public class SteamScript : MonoBehaviour
{
    private void Start()
    {
        if (SteamManager.Initialized)
        {
            PlayFabClientAPI.LoginWithSteam(new LoginWithSteamRequest
            {
                CreateAccount = true,
                SteamTicket = GetSteamAuthTicket()
            }, result =>
            {
                Debug.Log("Success!");
            }
            , error => { Debug.Log("Failed: " + error.GenerateErrorReport()); });
        }
    }

    public string GetSteamAuthTicket()
    {
        byte[] ticketBlob = new byte[1024];

        // Retrieve ticket; hTicket should be a field in the class so you can use it to cancel the ticket later
        // When you pass an object, the object can be modified by the callee. This function modifies the byte array you've passed to it.
        HAuthTicket hTicket = SteamUser.GetAuthSessionTicket(ticketBlob, ticketBlob.Length, out uint ticketSize);

        // Resize the buffer to actual length
        Array.Resize(ref ticketBlob, (int)ticketSize);

        // Convert bytes to string
        StringBuilder sb = new StringBuilder();
        foreach (byte b in ticketBlob)
        {
            sb.AppendFormat("{0:x2}", b);
        }
        return sb.ToString();
    }
}

Login With Steam を使うことで、PlayFab のアカウントを作成すると同時に、Steam のアカウントを紐付けることができます。

このスクリプトと、SteamManager をアタッチすればログインの準備は完了です。

playfab-payment-steam

ログインの動作確認

Unity エディタ上で実行しただけでは、正常に動作しません。

まず最初に、インストールした Steam を起動してログインする必要があります。

Steam のアプリ上でログインが完了したら、Unity エディター上で実行をしましょう。

ログに「Success!!」が表示され、PlayFab のアカウントが作成されれば成功です。

playfab-payment-steam

リアルマネーでアイテムを購入する

このセクションは、レシート以外の支払い処理を参考にしました。

ログインができたので、ここからはリアルマネーでアイテムを購入する手順について解説します。

全体の流れが少し難しいので、図で整理してみました。

playfab-payment-steam

リストにするとこんな感じ。

購入完了までの流れ
  1. Start Purchase を実行
  2. Pay For Purchase を実行
  3. Steam Overlay が自動で表示
  4. 購入されたら Confirm Purchase を実行
  5. アイテムがプレイヤーに反映

少し長いですが、やることは難しくないので、まずは全体のプログラムを見てみましょう。

このセクションの内容だけでは、この手順を実行できません。
実際の動作確認は次のセクションを参照してください。
プログラム全体
using System;
using System.Collections.Generic;
using System.Text;
using PlayFab;
using PlayFab.ClientModels;
using Steamworks;
using UnityEngine;

public class SteamScript : MonoBehaviour
{
    private string orderId;

    // Steam のオーバーレイでアイテムを購入した場合のコールバック
    protected Callback<MicroTxnAuthorizationResponse_t> m_MicroTxnAuthorizationResponse;

    private void OnMicroTxnAuthorizationResponse(MicroTxnAuthorizationResponse_t callBack)
    {
        PlayFabClientAPI.ConfirmPurchase(new ConfirmPurchaseRequest()
        {
            OrderId = orderId,
        }, result =>
        {
            Debug.Log("ConfirmPurchase Success!!");
        }, error =>
        {
            Debug.Log("ConfirmPurchase Failed..." + error.GenerateErrorReport());
        });
    }
    private void Start()
    {
        if (SteamManager.Initialized)
        {
            m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);

            PlayFabClientAPI.LoginWithSteam(new LoginWithSteamRequest
            {
                CreateAccount = true,
                SteamTicket = GetSteamAuthTicket()
            }, result =>
            {
                Debug.Log("Success!");
            }
            , error => { Debug.Log("Failed: " + error.GenerateErrorReport()); });
        }
    }

    public void PurchaseGem()
    {
        Debug.Log("StartPurchase!!");
        PlayFabClientAPI.StartPurchase(new StartPurchaseRequest
        {
            CatalogVersion = "Main",
            Items = new List<ItemPurchaseRequest>
            {
                new ItemPurchaseRequest()
                {
                    ItemId = "gem_10_bundle",
                    Quantity = 1,
                    Annotation = "Purchased via in-game store"
                }
            },
        }, startPurchaseResult =>
        {
            Debug.Log("StartPurchase Success!!");
            PlayFabClientAPI.PayForPurchase(new PayForPurchaseRequest
            {
                OrderId = startPurchaseResult.OrderId,
                ProviderName = "Steam",
                Currency = "RM"
            }, payForPurchaseResult =>
            {
                orderId = payForPurchaseResult.OrderId;
                Debug.Log("Status: " + payForPurchaseResult.Status + ", Currency: " + payForPurchaseResult.PurchaseCurrency +
                        ", Price: " + payForPurchaseResult.PurchasePrice + ", ProviderData: " + payForPurchaseResult.ProviderData);

            }, error =>
            {
                Debug.Log("PayForPurchase Failed..." + error.GenerateErrorReport());
            });
        }, error =>
        {
            Debug.Log("StartPurchase Failed..." + error.GenerateErrorReport());
        });
    }

    public string GetSteamAuthTicket()
    {
        byte[] ticketBlob = new byte[1024];

        // Retrieve ticket; hTicket should be a field in the class so you can use it to cancel the ticket later
        // When you pass an object, the object can be modified by the callee. This function modifies the byte array you've passed to it.
        HAuthTicket hTicket = SteamUser.GetAuthSessionTicket(ticketBlob, ticketBlob.Length, out uint ticketSize);

        // Resize the buffer to actual length
        Array.Resize(ref ticketBlob, (int)ticketSize);

        // Convert bytes to string
        StringBuilder sb = new StringBuilder();
        foreach (byte b in ticketBlob)
        {
            sb.AppendFormat("{0:x2}", b);
        }
        return sb.ToString();
    }
}

細かく見ていきます。

StartPurchase を実行

PlayFabClientAPI.StartPurchase(new StartPurchaseRequest
{
    CatalogVersion = "Main",
    Items = new List<ItemPurchaseRequest>
    {
        new ItemPurchaseRequest()
        {
            ItemId = "gem_10_bundle",
            Quantity = 1,
            Annotation = "Purchased via in-game store"
        }
    },
}, startPurchaseResult =>

日本語でいうと、「Main カタログで登録されている gem_10_bundle というアイテムを、これから1つ買うぞ!」という処理です。

今回は、「10ジェムが入ったバンドルアイテム」を100円で登録してみました。

playfab-payment-steam
playfab-payment-steam
カタログや仮想通貨の設定がまだの人は、ストアのアイテムを一覧表示して購入する手順をご覧ください。
バンドルについては、ストアでバンドルを売る手順をご覧ください。

RM という通貨はリアルマネー(Real Money)のことで、PlayFab で最初から定義されています。

PayForPurchase を実行

PlayFabClientAPI.PayForPurchase(new PayForPurchaseRequest
{
    OrderId = startPurchaseResult.OrderId,
    ProviderName = "Steam",
    Currency = "RM"
}, payForPurchaseResult =>
{
    orderId = payForPurchaseResult.OrderId;

支払先は Steam、通貨はリアルマネーなので RM とします。

StartPurchase で実行したときに取得した OrderId は最後まで使うので、クラス変数として取っておきましょう。

Steam Overlay が自動で表示

PayForPurchase が正常に終了したタイミングで、Steam の購入確認がオーバーレイ表示されます。

playfab-payment-steam

少し小さいので拡大します。

playfab-payment-steam

先ほど指定した数量とアイテムの名前、金額が表示されているのがわかります。

ペンギンくん
ペンギンくん
単位がドルになってるけど…
ねこじょーかー
ねこじょーかー
今のところはドル表記しかできないみたい。

PlayFab コミュニティの記事によると、将来的にはできるようになる予定ですが、具体的な日程は未定とのことです。

2年半前くらいの投稿なので、対応は年単位で先のような気がします。

購入されたら ConfirmPurchase を実行

// Steam のオーバーレイでアイテムを購入した場合のコールバック
protected Callback<MicroTxnAuthorizationResponse_t> m_MicroTxnAuthorizationResponse;

private void OnMicroTxnAuthorizationResponse(MicroTxnAuthorizationResponse_t callBack)
{
    PlayFabClientAPI.ConfirmPurchase(new ConfirmPurchaseRequest()
    {
        OrderId = orderId,
    }, result =>
    {
        Debug.Log("ConfirmPurchase Success!!");
    }, error =>
    {
        Debug.Log("ConfirmPurchase Failed..." + error.GenerateErrorReport());
    });
}

「購入されたら」というを判断するのに、コールバック関数を登録しておく必要があります。

上記のコールバック関数を、Start メソッドで紐付けをしています。

m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);

これで、実際に購入された場合にだけ ComfirmPurchase を実行することができます。

取っておいた OrderId をキーに処理を呼び出してあげれば、アイテムの購入が完了です。

アイテムがプレイヤーに反映

以下は PlayStream のログです。

playfab-payment-steam

こんな感じで、購入したバンドルが展開され、1ドルと引き換えに10ジェムが付与されていることがわかります。

また、「プレイヤー > 購入」と進んでいくと、購入履歴の確認も可能です。

playfab-payment-steam

ここまでで、ひと通りの流れを確認しました。

通しで動作確認をする

ログインの確認だけであれば、Steam にログインした上で Unity エディタ上でデバッグ実行をすれば OK でした。

しかし、Steam のオーバーレイ表示をするとなると、ビルドしたものを Steam にアップロードする必要があります。

ビルド方法については、公式のSteam へのアップロードを参照してください。

ちなみに、経験ない人は難易度が高いです…

ビルドの難易度が高いので、容量が 1024 MB 以下の人は、HTTP で直接アップロードできるので、その方法を強くおすすめします。

playfab-payment-steam

無事にビルドして公開ができたら、Steam のアプリを起動すると、ライブラリに自分のゲームが追加されています。

ここからインストールしましょう。

playfab-payment-steam

インストールができたら「プレイ」のボタンに変わるので、プレイしましょう。

playfab-payment-steam

ここから起動すると、PlayFab と Steam が裏で正しく連携されて、オーバーレイ表示も出るようになります。

これですべての流れを確認しました。

お疲れさまでした!

最後に

PlayFab と Steam を連携する方法について解説してきました。

Steam SDK の使い方や、ビルドしてアップロードするところが少し難しいですが、一度やってしまえば大丈夫です。

Steam でアイテムを販売して PlayFab に連携したいときは、ぜひこの記事を参考に試してみてください。

PlayFab の書籍も好評発売中!
playfab-book

PlayFab のことをもっと皆さんに知ってもらいたくて、合計500ページ以上にもなる書籍を5冊に分けて執筆しました。

私の知識をすべて詰め込んでいるので、ゲーム開発をさらに加速させたい方はぜひご覧ください。

POSTED COMMENT

  1. t より:

    最初のSteamScriptのコードだと下記エラーが出てしまいました。

    Assets/Scripts/SteamScript.cs(34,97): error CS1644: Feature `out variable declaration’ cannot be used because it is not part of the C# 4.0 language specification

COMMENT

メールアドレスが公開されることはありません。