Part 4 - Displaying the Catalog

By Richard Davey on 12th March 2019   @photonstorm

After creating our items they're now available to be purchased in-game. When your game starts, you can get a list of all items using the plugin method getCatalog and by listening for the resulting getcatalog event:

this.facebook.on('getcatalog', function (catalog)
{
    console.log(catalog);
});

this.facebook.getCatalog();

This can only be called after your game has started. Assuming that your app is approved for In App purchases, you'll see a response similar to the following in the console:

CatalogResponse

What we have returned here is an array of Product objects. Each product contains the information you need in order to both display it in-game, and allow someone to buy it, as configured in your App Dashboard.

Once getCatalog has been called, the product catalog is available at any point via this.facebook.catalog, meaning you don't have to store a local copy of it yourself. It's always accessible in the Facebook Instant Games plugin.

Currency Conversion

Notice how, in the catalog image above, the price is in UK Pounds, even though we gave it a US Dollar price in the App Dashboard? That's because the Facebook account of the person playing the game, from which this log was taken, is based in the UK. It has converted the price for them automatically. The price value returned in the catalog data is the price you should always use in-game.

Displaying the Catalog

Every game is going to handle this slightly differently, of course. The core requirements are the same, however. Once you've got your catalog from the API call, which is sent to your getcatalog event handler, you should store it locally in your game, ready to display it as-needed later on.

Here is a sample Phaser script that gets our catalog and renders them using Phaser Text and Image Game Objects:

create ()
{
    this.add.image(400, 300, 'background');

    this.facebook.on('getcatalog', this.showCatalog, this);

    this.facebook.getCatalog();
}

showCatalog ()
{
    let x = 10;
    let y = 30;

    for (let i = 0; i < this.facebook.catalog.length; i++)
    {
        let midX = x + 125;

        let product = this.facebook.catalog[i];

        let panel = this.add.image(x, y, 'panel').setOrigin(0).setInteractive();

        panel.on('pointerdown', () => this.buyProduct(product.productID), this);

        this.add.text(midX, y + 6, product.title, { fontFamily: 'Arial', fontSize: 18, color: '#ffffff' }).setOrigin(0.5, 0).setFontStyle('bold').setShadow(2, 2, "#2e305b", 2);

        this.add.image(midX, y + 158, product.productID).setScale(0.8);

        let wrap = (product.productID.substr(0, 4) === 'gold') ? 120 : 180;

        this.add.text(midX, y + 270, product.description, { fontFamily: 'Arial', fontSize: 16, color: '#ffffff', align: 'center', wordWrap: { width: wrap, useAdvancedWrap: false } }).setOrigin(0.5, 0);

        this.add.text(midX, y + 326, product.price, { fontFamily: 'Arial', fontSize: 28, color: '#ffffff' }).setOrigin(0.5, 0).setFontStyle('bold').setShadow(2, 2, "#000000", 1);

        x += 264;

        if (i === 2)
        {
            x = 10;
            y += 420;
        }
    }
}

Clearly this is using a lot of images and alignment values specific to our game, yet the key points remain the same: We're using the price returned in the catalog for the player, not a pre-defined one, and we ensure that the Product Title is displayed and matches what they'll see if they buy it. When run it looks like this in-game:

Catalog

Clicking any of the products will launch the buyProduct method, sending across the Product ID the user wishes to buy, which is handled in the next section of this tutorial.

If your game is unable to get the catalog it will throw a getcatalogfail event, which you should handle accordingly. There are a number of reasons it could fail, including network requests timeouts, but your game should ensure it doesn't hang waiting for only a successful event.

Although getCatalog returns all products you have configured, it's entirely up to you how many of them you show and when. You may wish to create a set of products that your game only displays during the Christmas period, or create variations of a product with discounts applied, i.e. "Super Strength Potion" and "Super Strength Potion Half Price", which is priced differently, and you decide which one to show the player based on various in-game criteria.