Integrate SDK on application side

  1. Design an interface for the login system, in-game store, and other pages for your application.
  2. Implement in your application logic for user authentication, store display, purchase, and more using SDK methods.
Note
You can create your own solution by following the Cocos Creator manual, or use the demo scene as a template.
To get started with the basic SDK features, follow these step-by-step tutorials:You can find the scripts used in the <xsollaExtention>/assets/scripts/samples directory of SDK.
Note
The scripts in the tutorials use SDK methods. Make sure you install and initialize the SDK correctly.

User signup and login via username, email and password

This instruction shows how to use SDK methods to implement:

You can authenticate users with their username or email address. In the following examples we authenticate users with their username, whereas the email address is used to confirm sign-up and to reset the password.

Note
If you use the Login widget on your site (in a web store, for example), make sure that you implemented the same user authentication methods on your site and in your application. The widget uses the email address for authentication by default. To set up user login via username, contact your Customer Success Manager or email to csm@xsolla.com.

Implement user sign-up

This tutorial describes the implementation of the following logic:

Create page interface

Create a scene for a sign-up page and add the following elements:

  • username field
  • user email address field
  • user password field
  • sign-up button

Example of a page structure:

Create registration script component

  1. Create a RegistrationComponent and add the following properties:
    • usernameEditBox
    • emailEditBox
    • passwordEditBox
    • signUpButton — optional. Used when binding a callback function to the button using code

  1. Add a method to the RegistrationComponent class that is called when clicking SignUpButton, and add the logic to handle the click event, as shown in the script example.
  2. Add the RegistrationComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the scene elements to the properties of the RegistrationComponent as shown in the picture:

  1. Bind a callback to the sign-up button in one of the following ways:
    • using the Inspector panel, as shown in the picture below
    • by inserting the code block below into the page script

Binding callback using Inspector panel:

Binding callback via code:

Copy
Full screen
Small screen
start() {
 this.signUpButton.node.on(Button.EventType.CLICK, this.onSignUpClicked, this);
 }
Note

In the script’s examples, the onComplete and onError methods call the standard console.log method. In case of an error, the error code and description are passed in the error parameter.

You can add other actions like opening a page with a resend request for a sign-up email or opening a login page if sign-up is successful.

Example of a class script (RegistrationComponent):
Copy
Full screen
Small screen
import { _decorator, Button, Component, EditBox } from 'cc';
import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
const { ccclass, property } = _decorator;


@ccclass('RegistrationComponent')
export class RegistrationComponent extends Component {

    @property(EditBox)
    usernameEditBox: EditBox;

    @property(EditBox)
    emailEditBox: EditBox;

    @property(EditBox)
    passwordEditBox: EditBox;

    @property(Button)
    signUpButton: Button;

    start() {
        this.signUpButton.node.on(Button.EventType.CLICK, this.onSignUpClicked, this);
    }

    onSignUpClicked() {
        XsollaAuth.registerNewUser(this.usernameEditBox.string, this.passwordEditBox.string, this.emailEditBox.string, 'xsollatest', null, null, token => {
            if(token != null) {
                console.log(`Successful login. Token - ${token.access_token}`);
            }
            else {
                console.log('Thank you! We have sent you a confirmation email');
            }
        }, err => {
            console.log(err);
        });
    }
}

Set up sign-up confirmation email

After successful sign-up, a user receives a sign-up confirmation email to a specified address. You can customize emails sent to users in Publisher Account.

If you are developing a mobile application, set up deep links to return a user to an application after they confirm sign-up.

Note
You can disable sign-up confirmation via an email address if your security standards allow you to do this. Contact your Customer Success Manager to disable it or contact us at csm@xsolla.com.

Implement sign-up confirmation email resend request

This tutorial describes the implementation of the following logic:

Create page interface

Create a scene for a page with a request to resend a confirmation email and add the following elements:

  • username/email field
  • resend email button

Example of a page structure:

Create resend email script component

  1. Create a ResendConfirmationEmailComponent and add the following properties:
    • usernameTextBox
    • resendEmailButton — optional. Used when binding a callback function to the button using code

  1. Add a method to the ResendConfirmationEmailComponent class that is called when clicking ResendEmail, and add the logic to handle the click event, as shown in the script example.
  2. Add the ResendConfirmationEmailComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the scene elements to the properties of the ResendConfirmationEmailComponent as shown in the picture:

  1. Bind a callback to the sign-up confirmation email request button in one of the following ways:
    • using the Inspector panel, as shown in the picture below
    • by inserting the code block below into the script of the page with a request to resend a confirmation email

Binding callback using Inspector panel:

Binding callback via code:

Copy
Full screen
Small screen
start() {
	this.resendEmailButton.node.on(Button.EventType.CLICK, this.onResendEmailClicked, this);
  }

If the request is successful, the user receives a sign-up confirmation email to the email address specified during sign-up.

Note

In the script’s examples, the onComplete and onError methods call the standard console.log method. You can add other actions.

In case of an error, the error code and description are passed in the error parameter.

Example of a class script (ResendConfirmationEmailComponent):
Copy
Full screen
Small screen
import { _decorator, Button, Component, EditBox } from 'cc';
import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
const { ccclass, property } = _decorator;


@ccclass('ResendConfirmationEmailComponent')
export class ResendConfirmationEmailComponent extends Component {

    @property(EditBox)
    usernameEditBox: EditBox;

    @property(Button)
    resendEmailButton: Button;

    start() {
        this.resendEmailButton.node.on(Button.EventType.CLICK, this.onResendEmailClicked, this);
    }

    onResendEmailClicked() {
        XsollaAuth.resendAccountConfirmationEmail(this.usernameEditBox.string, 'xsollatest', null, () => {
            console.log('A verification link has been successfully sent to your email');
        }, err => {
            console.log(err);
        });
    }
}

Implement user login

This tutorial describes the implementation of the following logic:

Create page interface

Create a scene for a login page and add the following elements:

  • username field
  • password field
  • remember me toggle
  • login button

Example of a page structure:

Create login script component

  1. Create a LoginComponent and add the following properties:
    • usernameEditBox
    • passwordEditBox
    • remeberMeToggle
    • loginButton — optional. Used when binding a callback function to the button using code

  1. Add a method to the LoginComponent class that is called when clicking LoginButton, and add the logic to handle the click event, as shown in the script example.
  2. Add the LoginComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the scene elements to the properties of the LoginComponent as shown in the picture:

  1. Bind a callback to the login button in one of the following ways:
    • using the Inspector panel, as shown in the picture below
    • by inserting the code block below into the page script

Binding callback using Inspector panel:

Binding callback via code:

Copy
Full screen
Small screen
start() {
	 this.loginButton.node.on(Button.EventType.CLICK, this.onLoginClicked, this);
  }
Note

In the script’s examples, the onComplete and onError methods call the standard console.log method. You can add other actions.

In case of an error, the error code and description are passed in the error parameter.

Example of a class script (LoginComponent):
Copy
Full screen
Small screen
import { _decorator, Button, Component, EditBox, Toggle } from 'cc';
import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
const { ccclass, property } = _decorator;


@ccclass('LoginComponent')
export class LoginComponent extends Component {

    @property(EditBox)
    usernameEditBox: EditBox;

    @property(EditBox)
    passwordEditBox: EditBox;

    @property(Toggle)
    remeberMeToggle: Toggle;

    @property(Button)
    loginButton: Button;

    start() {
        this.loginButton.node.on(Button.EventType.CLICK, this.onLoginClicked, this);
    }

    onLoginClicked() {
        XsollaAuth.authByUsernameAndPassword(this.usernameEditBox.string, this.passwordEditBox.string, this.remeberMeToggle.isChecked, token => {
            console.log('Successful login. Token - ${token.access_token}');
        }, err => {
            console.log(err);
        });
    }
}

Implement password reset

This tutorial describes the implementation of the following logic:

Create page interface

Create a scene for a reset password page and add the following:

  • username field
  • reset password button

Example of a page structure:

Create reset password script component

  1. Create a ResetPasswordComponent and add the following properties:
    • usernameEditBox
    • resetPasswordButton — optional. Used when binding a callback function to the button using code

  1. Add a method to the ResetPasswordComponent class that is called when clicking ResetPassword, and add the logic to handle the click event, as shown in the script example.
  2. Add the ResetPasswordComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the scene elements to the properties of the ResetPasswordComponent as shown in the picture:

  1. Bind a callback to the password reset button in one of the following ways:
    • using the Inspector panel, as shown in the picture below
    • by inserting the code block below into the page script

Binding callback using Inspector panel:

Binding callback via code:

Copy
Full screen
Small screen
start() {
        this.resetPasswordButton.node.on(Button.EventType.CLICK, this.onResetPasswordClicked, this);
    }
Note

In the script’s examples, the onComplete and onError methods call the standard console.log method. You can add other actions.

In case of an error, the error code and description are passed in the error parameter.

Example of a class script (ResetPasswordComponent):
Copy
Full screen
Small screen
import { _decorator, Button, Component, EditBox } from 'cc';
import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
const { ccclass, property } = _decorator;


@ccclass('ResetPasswordComponent')
export class ResetPasswordComponent extends Component {

    @property(EditBox)
    usernameEditBox: EditBox;

    @property(Button)
    resetPasswordButton: Button;

    start() {
        this.resetPasswordButton.node.on(Button.EventType.CLICK, this.onResetPasswordClicked, this);
    }

    onResetPasswordClicked() {
        XsollaAuth.resetPassword(this.usernameEditBox.string, null, () => {
            console.log('Follow the instructions we sent to your email');
        }, err => {
            console.log(err);
        });
    }
}

Social login

Note
The SDK for Cocos Creator supports social login only for Android and iOS builds.

This guide shows how you can use SDK methods to implement user sign-up and login via their social network account.

Unlike for user authentication via username/user email address and password, you don’t have to implement separate logics for user sign-up. If the user’s first login is via a social network, a new account is created automatically.

If you have implemented social login in your application as an alternative authentication method, the social network account automatically links to an existing user account if the following conditions are met:

  • A user who signed up with username/email address and password logged into your application via a social network account.
  • A social network returns an email address.
  • User email address in a social network is the same as the email address used for sign-up in your application.

This tutorial describes the implementation of the following logic:

The examples show how to set up user login via a Facebook account. You can set up all social networks in the same way.

The examples provide a basic introduction to the SDK methods. Applications usually require more complex interfaces and logic.

Create page interface

Create a scene for a social login page and add the social login button to it.

Example of a page structure:

Create social login script component

  1. Create a SocialLoginComponent. To bind callback function to social login button using code, add the socialLoginButton property.
  2. Add a method to the SocialLoginComponent class that is called when clicking SocialLogin, and add the logic to handle the click event, as shown in the script example.

  1. Add the SocialLoginComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  2. Bind the SocialLogin button to the socialLoginButton property of the SocialLoginComponent as shown in the picture:

  1. Bind a callback to the social login button in one of the following ways:
    • using the Inspector panel, as shown in the picture below
    • by inserting the code block below into the page script

Binding callback using Inspector panel:

Binding callback via code:

Copy
Full screen
Small screen
start() {
        this.socialLoginButton.node.on(Button.EventType.CLICK, this.onSocialLoginClicked, this);
}
Note

In the script’s examples, the onComplete, onCanceled and onError methods call the standard console.log method. In case of an error, the error code and description are passed in the error parameter.

You can add other actions like opening a page with a resend request for a sign-up email or opening a login page if sign-up is successful.

Example of a class script (SocialLoginComponent):
Copy
Full screen
Small screen
import { _decorator, Button, Component } from 'cc';
import { Token, XsollaAuth } from '../../api/XsollaAuth';
const { ccclass, property } = _decorator;


namespace authorization {

    @ccclass('SocialLoginComponent')
    export class SocialLoginComponent extends Component {

        @property(Button)
        socialLoginButton: Button;


        start() {
            this.socialLoginButton.node.on(Button.EventType.CLICK, this.onSocialLoginClicked, this);
        }


        onSocialLoginClicked() {
            XsollaAuth.authSocial('facebook', (token: Token) => {
                console.log(`Successful social authentication. Token - ${token.access_token}`);
            }, () => {
                console.log('Social auth was canceled');
            }, (error:string) => {
                console.log(error);
            });
        }
    }
}

Display of items catalog

This tutorial shows how to use the SDK methods to display the following items in an in-game store:

  • virtual items
  • bundles
  • packages of virtual currency

Before you start, configure items in Publisher Account:

  1. Configure virtual items and groups of virtual items.
  2. Configure packages of virtual currencies.
  3. Configure bundles.

This tutorial describes the implementation of the following logic:

Note

The example of every item in a catalog shows:

  • name
  • description
  • price
  • image

You can also show other information about the item if this information is stored in an in-game store.

Implement display of virtual items

Create item widget

  1. Create a prefab. To do this, select Create > Node Prefab from the context menu of the folder.
  2. Open the created prefab.
  3. Add a UITransform component to the root of the prefab as shown in the image below and set the content size.

  1. Add the following UI elements as prefab child objects and configure their visuals:
    • widget background image
    • item name
    • Item description
    • item price
    • item image

Example of the widget structure:

Create item widget script

  1. Create a StoreItemComponent and add the following properties:
    • iconSprite
    • itemNameLabel
    • itemDescriptionLabel
    • priceLabel

  1. Add an init method and initialization logic to the StoreItemComponent class as shown in the script example.
  2. Attach the StoreItemComponent component to the root node of the prefab.
  3. Bind the prefab elements to the properties of the StoreItemComponent as shown in the picture:

Example of a widget script (StoreItemComponent):

Copy
Full screen
Small screen
import { _decorator, assetManager, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
import { StoreItem } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
const { ccclass, property } = _decorator;


@ccclass('StoreItemComponent')
export class StoreItemComponent extends Component {

    @property(Sprite)
    iconSprite: Sprite;

    @property(Label)
    itemNameLabel: Label;

    @property(Label)
    itemDescriptionLabel: Label;

    @property(Label)
    priceLabel: Label;

    private _data: StoreItem;

    init(data: StoreItem) {

        this._data = data;

        this.itemNameLabel.string = data.name;
        this.itemDescriptionLabel.string = data.description;

        if (data.virtual_prices.length > 0) {
            this.priceLabel.string = data.virtual_prices[0].amount.toString() + ' ' + data.virtual_prices[0].name;
        } else {
            this.priceLabel.string = parseFloat(data.price.amount) + ' ' + data.price.currency;
        }

        assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
            if(err == null) {
            const spriteFrame = new SpriteFrame();
            const texture = new Texture2D();
            texture.image = imageAsset;
            spriteFrame.texture = texture;
            this.iconSprite.spriteFrame = spriteFrame;
            } else {
                console.log(`Can’t load image with URL ${data.image_url}`);
            }
        });
    }
}

Create page interface

Create a scene for an items catalog page and add the ScrollView element to it.

Example of a page structure:

To make the ScrollView match the created StoreItem prefab, set up its size:

  1. Change the value of the ContentSize parameter in the ScrollView node and the inner view node.
  2. Bind the Layout component to the content node and set it up. In the example, the following settings are selected:
    • Type == vertical
    • ResizeMode == Container

Create items catalog script component

  1. Create a ItemsCatalogComponent and add the following properties:
    • itemsScrollView
    • storeItemPrefab

  1. Add the start life cycle function and initialization logic to the ItemsCatalogComponent class as shown in the script example.
  2. Add the ItemsCatalogComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the prefab elements to the properties of the ItemsCatalogComponent as shown in the picture:

Example of a class script (ItemsCatalogComponent):

Copy
Full screen
Small screen
import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
import { XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
import { StoreItemComponent } from './StoreItemComponent';
const { ccclass, property } = _decorator;


@ccclass('ItemsCatalogComponent')
export class ItemsCatalogComponent extends Component {

    @property(ScrollView)
    itemsScrollView: ScrollView;

    @property(Prefab)
    storeItemPrefab: Prefab;

    start() {
        XsollaCatalog.getCatalog(null, null, [], itemsData => {
            for (let i = 0; i < itemsData.items.length; ++i) {
                let storeItem = instantiate(this.storeItemPrefab);
                this.itemsScrollView.content.addChild(storeItem);
                storeItem.getComponent(StoreItemComponent).init(itemsData.items[i]);
            }
        });
    }
}

Example of the script’s work result:

Implement display of bundles

Create bundle widget

  1. Create a prefab. To do this, select Create > Node Prefab from the context menu of the folder.
  2. Open the created prefab.
  3. Add a UITransform component to the root of the prefab as shown in the image below and set the content size.

  1. Add the following UI elements as prefab child objects and configure their visuals:
    • widget background image
    • bundle name
    • bundle description
    • bundle price
    • bundle image
    • bundle content description (items and their quantity)

Example of the widget structure:

Create bundle widget script

  1. Create a BundleItemComponent and add the following properties:
    • iconSprite
    • bundleNameLabel
    • bundleDescriptionLabel
    • priceLabel
    • contentDescriptionlabel

  1. Add an init method and initialization logic to the BundleItemComponent class as shown in the script example.
  2. Attach the BundleItemComponent to the root node of the prefab.
  3. Bind the prefab elements to the properties of the BundleItemComponent as shown in the picture:

Example of a widget script (BundleItemComponent):

Copy
Full screen
Small screen
import { _decorator, assetManager, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
import { StoreBundle } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
const { ccclass, property } = _decorator;


@ccclass('BundleItemComponent')
export class BundleItemComponent extends Component {

    @property(Sprite)
    iconSprite: Sprite;

    @property(Label)
    bundleNameLabel: Label;

    @property(Label)
    bundleDescriptionLabel: Label;

    @property(Label)
    priceLabel: Label;

    @property(Label)
    contentDescriptionLabel: Label;

    init(data: StoreBundle) {

        this.bundleNameLabel.string = data.name;
        this.bundleDescriptionLabel.string = data.description;

        if (data.virtual_prices.length > 0) {
            this.priceLabel.string = data.virtual_prices[0].amount.toString() + ' ' + data.virtual_prices[0].name;
        } else {
            this.priceLabel.string = parseFloat(data.price.amount) + ' ' + data.price.currency;
        }

        assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
            if(err == null) {
            const spriteFrame = new SpriteFrame();
            const texture = new Texture2D();
            texture.image = imageAsset;
            spriteFrame.texture = texture;
            this.iconSprite.spriteFrame = spriteFrame;
            } else {
                console.log(`Can’t load image with URL ${data.image_url}`);
            }
        });

        this.contentDescriptionLabel.string = 'This bundle includes '+ data.content.length + ' items: ';
        var bandles = data.content.map(bundle => bundle.name).join(', ');
        this.contentDescriptionLabel.string += bandles;
    }
}

Create page interface

Create a scene for a bundle catalog page and add the ScrollView element to it.

Example of a page structure:

To make the ScrollView match the created BundleItem prefab, set up its size:

  1. Change the value of the ContentSize parameter in the ScrollView node and the inner view node.
  2. Bind the Layout component to the content node and set it up. In the example, the following settings are selected:
    • Type == vertical
    • ResizeMode == Container

Create bundles catalog script component

  1. Create a BundlesCatalogComponent and add the following properties:
    • itemsScrollView
    • bundleItemPrefab

  1. Add the start life cycle function and initialization logic to the BundlesCatalogComponent class as shown in the script example.
  2. Add the BundlesCatalogComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the prefab elements to the properties of the BundlesCatalogComponent as shown in the picture:

Example of a class script (BundlesCatalogComponent):

Copy
Full screen
Small screen
import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
import { XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
import { BundleItemComponent } from './BundleItemComponent';
const { ccclass, property } = _decorator;


@ccclass('BundlesCatalogComponent')
export class BundlesCatalogComponent extends Component {

    @property(ScrollView)
    itemsScrollView: ScrollView;

    @property(Prefab)
    bundleItemPrefab: Prefab;

    start() {
        XsollaCatalog.getBundleList(null, null, [], itemsData => {
        for (let i = 0; i < itemsData.items.length; ++i) {
                let bundleItem = instantiate(this.bundleItemPrefab);
                this.itemsScrollView.content.addChild(bundleItem);
                bundleItem.getComponent(BundleItemComponent).init(itemsData.items[i]);
            }
        });
    }
}

Example of the script’s work result:

Implement display of virtual currency packages catalog

Create widget for virtual currency package

  1. Create a prefab. To do this, select Create > Node Prefab from the context menu of the folder.
  2. Open the created prefab.
  3. Add a UITransform component to the root of the prefab as shown in the image below and set the content size.

  1. Add the following UI elements as prefab child objects and configure their visuals:
    • widget background image
    • currency name
    • currency description
    • currency price
    • currency image

Example of the widget structure:

Create widget script for virtual currency package

  1. Create a CurrencyPackageItemComponent and add the following properties:
    • iconSprite
    • currencyNameLabel
    • currencyDescriptionLabel
    • priceLabel

  1. Add an init method and initialization logic to the CurrencyPackageItemComponent class as shown in the script example.
  2. Attach the CurrencyPackageItemComponent component to the root node of the prefab.
  3. Bind the prefab elements to the properties of the CurrencyPackageItemComponent as shown in the picture:

Example of a widget script (CurrencyPackageItemComponent):

Copy
Full screen
Small screen
import { _decorator, assetManager, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
import { VirtualCurrencyPackage } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
const { ccclass, property } = _decorator;


@ccclass('CurrencyPackageItemComponent')
export class CurrencyPackageItemComponent extends Component {

    @property(Sprite)
    iconSprite: Sprite;

    @property(Label)
    currencyNameLabel: Label;

    @property(Label)
    currencyDescriptionLabel: Label;

    @property(Label)
    priceLabel: Label;

    init(data: VirtualCurrencyPackage) {

        this.currencyNameLabel.string = data.name;
        this.currencyDescriptionLabel.string = data.description;

        if (data.virtual_prices.length > 0) {
            this.priceLabel.string = data.virtual_prices[0].amount.toString() + ' ' + data.virtual_prices[0].name;
        } else {
            this.priceLabel.string = parseFloat(data.price.amount) + ' ' + data.price.currency;
        }

        assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
            if(err == null) {
            const spriteFrame = new SpriteFrame();
            const texture = new Texture2D();
            texture.image = imageAsset;
            spriteFrame.texture = texture;
            this.iconSprite.spriteFrame = spriteFrame;
            } else {
                console.log(`Can’t load image with URL ${data.image_url}`);
            }
        });
    }
}

Create page interface

Create a scene for a virtual currency package catalog page and add the ScrollView element to it.

Example of a page structure:

To make the ScrollView match the created CurrencyPackageItem prefab, set up its size:

  1. Change the value of the ContentSize parameter in the ScrollView node and the inner view node.
  2. Bind the Layout component to the content node and set it up. In the example, the following settings are selected:
    • Type == vertical
    • ResizeMode == Container

Create currency packages catalog script component

  1. Create a CurrencyPackagesCatalogComponent and add the following properties:
    • itemsScrollView
    • currencyPackageItemPrefab

  1. Add the start life cycle function and initialization logic to the CurrencyPackagesCatalogComponent class as shown in the script example.
  2. Add the CurrencyPackagesCatalogComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
  3. Bind the prefab elements to the properties of the CurrencyPackagesCatalogComponent as shown in the picture:

Example of a class script (CurrencyPackagesCatalogComponent):

Copy
Full screen
Small screen
    import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
    import { XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
    import { CurrencyPackageItemComponent } from './CurrencyPackageItemComponent';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('CurrencyPackagesCatalogComponent')
    export class CurrencyPackagesCatalogComponent extends Component {
    
        @property(ScrollView)
        itemsScrollView: ScrollView;
    
        @property(Prefab)
        currencyPackageItemPrefab: Prefab;
    
        start() {
            XsollaCatalog.getVirtualCurrencyPackages(null, null, [], itemsData => {
            for (let i = 0; i < itemsData.items.length; ++i) {
                    let currencyPackageItem = instantiate(this.currencyPackageItemPrefab);
                    this.itemsScrollView.content.addChild(currencyPackageItem);
                    currencyPackageItem.getComponent(CurrencyPackageItemComponent).init(itemsData.items[i]);
                }
            });
        }
    }
    

    Example of the script’s work result:

    Sell virtual items for real currency

    This section explains how to use the SDK methods to implement selling items for real currency using virtual items.

    Before you start, implement a display of virtual items in a catalog. In the following example, we describe how to implement purchasing of virtual items. Configuration for other item types is similar.

    This tutorial describes the implementation of the following logic:

    Notice

    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla). This account is only available for the demo project.

    The script sample doesn’t contain implementation of the page-by-page display of items in the catalog (pagination). Use the offset and limit parameters of the getCatalog SDK method to implement pagination. The maximum number of items on a page is 50. If the catalog has more than 50 items, pagination is necessary.

    Complete item widget

    Add a buy button to the item widget and configure its visuals.
    Note
    In the example, the modified class is changed to RC_StoreItemComponent.
    Example of the widget structure:

    Complete item widget script

    1. To bind a callback function to buy button using code, add the buyButton property to the RC_StoreItemComponent.
    2. Add a method to the RC_StoreItemComponent class that is called when clicking BuyButton, and add the logic to handle the click event, as shown in the script example.
    3. Bind a callback to the buy button in one of the following ways:

      • using the Inspector panel, as shown in the picture below
      • by inserting the code block below into the page script

    Binding callback using Inspector panel:

    Binding callback via code:

    Copy
    Full screen
    Small screen
    start() {
    	this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
      }
    

    Example of a widget script (RC_StoreItemComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, assetManager, Button, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
    import { StoreItem, XsollaCatalog } from '../../api/XsollaCatalog';
    import { TokenStorage } from '../../common/TokenStorage';
    import { OrderTracker } from '../../common/OrderTracker';
    import { XsollaPayments } from '../../api/XsollaPayments';
    const { ccclass, property } = _decorator;
    
    
    export namespace sellForRealMoneyItem {
    
    
        @ccclass('RC_StoreItemComponent')
        export class RC_StoreItemComponent extends Component {
    
    
            @property(Sprite)
            iconSprite: Sprite;
    
    
            @property(Label)
            itemNameLabel: Label;
    
    
            @property(Label)
            itemDescriptionLabel: Label;
    
    
            @property(Label)
            priceLabel: Label;
    
    
            @property(Button)
            buyButton: Button;
    
    
            private _data: StoreItem;
    
    
            start() {
                this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
            }
    
    
            init(data: StoreItem) {
    
                this._data = data;
    
    
                this.itemNameLabel.string = data.name;
                this.itemDescriptionLabel.string = data.description;
    
                if (data.virtual_prices.length > 0) {
                    this.priceLabel.string = data.virtual_prices[0].amount.toString() + ' ' + data.virtual_prices[0].name;
                } else {
                    this.priceLabel.string = parseFloat(data.price.amount) + ' ' + data.price.currency;
                }
    
    
                assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
                    if(err == null) {
                    const spriteFrame = new SpriteFrame();
                    const texture = new Texture2D();
                    texture.image = imageAsset;
                    spriteFrame.texture = texture;
                    this.iconSprite.spriteFrame = spriteFrame;
                    } else {
                        console.log(`Cant load image with url ${data.image_url}`);
                    }
                });
            }
    
    
            onBuyClicked() {
                XsollaCatalog.fetchPaymentToken(TokenStorage.getToken().access_token, this._data.sku, 1, undefined, undefined, undefined, undefined, undefined, result => {
                    OrderTracker.checkPendingOrder(result.token, result.orderId, () => {
                        console.log('success purchase!');
                    }, error => {
                        console.log(`Order checking failed - Status code: ${error.status}, Error code: ${error.code}, Error message: ${error.description}`);
                    });
                    XsollaPayments.openPurchaseUI(result.token);
                }, error => {
                    console.log(error.description);
                });
            }
        }
    }
    

    Complete items catalog script component

    Note
    In the example script, the modified class is changed to RC_ItemsCatalogComponent.

    Add the logic for getting a valid authorization token to the start method of the RC_ItemsCatalogComponent class, as shown in the script example.

    Example of a class script (RC_ItemsCatalogComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
    import { XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
    import { RC_StoreItemComponent } from './RC_StoreItemComponent';
    import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
    import { TokenStorage } from 'db://xsolla-commerce-sdk/scripts/common/TokenStorage';
    const { ccclass, property } = _decorator;
    
    
    
    
    @ccclass('RC_ItemsCatalogComponent')
    export class RC_ItemsCatalogComponent extends Component {
    
        @property(ScrollView)
        itemsScrollView: ScrollView;
    
    
        @property(Prefab)
        storeItemPrefab: Prefab;
    
    
        start() {
            XsollaAuth.authByUsernameAndPassword('xsolla', 'xsolla', false, token => {
                TokenStorage.saveToken(token, false);
                XsollaCatalog.getCatalog(null, null, [], itemsData => {
                    for (let i = 0; i < itemsData.items.length; ++i) {
                            let storeItem = instantiate(this.storeItemPrefab);
                            this.itemsScrollView.content.addChild(storeItem);
                            storeItem.getComponent(RC_StoreItemComponent).init(itemsData.items[i]);
                        }
                    });
            });
        }
    }
    

    Example of the script’s work result:

    Sell virtual items for virtual currency

    This section explains how to use the SDK methods to implement selling items for virtual currency using virtual items.

    Before you start, implement a display of virtual items in a catalog. In the following example, we describe how to implement purchasing of virtual items. Configuration for other item types is similar.

    This tutorial describes the implementation of the following logic:

    Notice

    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla). This account is only available for the demo project.

    The script sample doesn’t contain implementation of the page-by-page display of items in the catalog (pagination). Use the offset and limit parameters of the getCatalog SDK method to implement pagination. The maximum number of items on a page is 50. If the catalog has more than 50 items, pagination is necessary.

    Complete item widget

    Add a buy button to the item widget and configure its visuals.
    Note
    In the example, the modified class is changed to VC_StoreItemComponent.
    Example of the widget structure:

    Complete item widget script

    1. To bind a callback function to buy button using code, add the buyButton property to the VC_StoreItemComponent.
    2. Add a method to the VC_StoreItemComponent class that is called when clicking BuyButton, and add the logic to handle the click event, as shown in the script example.
    3. Bind a callback to the buy button in one of the following ways:

      • using the Inspector panel, as shown in the picture below
      • by inserting the code block below into the page script

    Binding callback using Inspector panel:

    Binding callback via code:

    Copy
    Full screen
    Small screen
    start() {
    	this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
      }
    

    Example of a widget script (VC_StoreItemComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, assetManager, Button, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
    import { StoreItem, XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
    import { TokenStorage } from 'db://xsolla-commerce-sdk/scripts/common/TokenStorage';
    import { OrderTracker } from 'db://xsolla-commerce-sdk/scripts/common/OrderTracker';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('VC_StoreItemComponent')
    export class VC_StoreItemComponent extends Component {
    
        @property(Sprite)
        iconSprite: Sprite;
    
        @property(Label)
        itemNameLabel: Label;
    
        @property(Label)
        itemDescriptionLabel: Label;
    
        @property(Label)
        priceLabel: Label;
    
        @property(Button)
        buyButton: Button;
    
        private _data: StoreItem;
    
        start() {
            this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
        }
    
        init(data: StoreItem) {
    
            this._data = data;
    
            this.itemNameLabel.string = data.name;
            this.itemDescriptionLabel.string = data.description;
    
            if (data.virtual_prices.length > 0) {
                this.priceLabel.string = data.virtual_prices[0].amount.toString() + ' ' + data.virtual_prices[0].name;
            } else {
                this.priceLabel.string = parseFloat(data.price.amount) + ' ' + data.price.currency;
            }
    
            assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
                if(err == null) {
                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                this.iconSprite.spriteFrame = spriteFrame;
                } else {
                    console.log(`Can’t load image with URL ${data.image_url}`);
                }
            });
        }
    
        onBuyClicked() {
            XsollaCatalog.purchaseItemForVirtualCurrency(TokenStorage.getToken().access_token, this._data.sku, this._data.virtual_prices[0].sku, orderId => {
                OrderTracker.checkPendingOrder(TokenStorage.getToken().access_token, orderId, () => {
                    console.log('success purchase!');
                }, error => {
                    console.log(`Order checking failed - Status code: ${error.status}, Error code: ${error.code}, Error message: ${error.description}`);
                });
            }, error => {
                console.log(error.description);
            });
        }
    }
    

    Complete items catalog script component

    Note
    In the example script, the modified class is changed to VC_ItemsCatalogComponent.

    Add the logic for getting a valid authorization token to the start method of the VC_ItemsCatalogComponent class, as shown in the script example.

    Example of a class script (VC_ItemsCatalogComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
    import { XsollaCatalog } from 'db://xsolla-commerce-sdk/scripts/api/XsollaCatalog';
    import { VC_StoreItemComponent } from './VC_StoreItemComponent';
    import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
    import { TokenStorage } from 'db://xsolla-commerce-sdk/scripts/common/TokenStorage';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('VC_ItemsCatalogComponent')
    export class VC_ItemsCatalogComponent extends Component {
    
        @property(ScrollView)
        itemsScrollView: ScrollView;
    
        @property(Prefab)
        storeItemPrefab: Prefab;
    
        start() {
            XsollaAuth.authByUsernameAndPassword('xsolla', 'xsolla', false, token => {
                TokenStorage.saveToken(token, false);
                XsollaCatalog.getCatalog(null, null, [], itemsData => {
                    for (let i = 0; i < itemsData.items.length; ++i) {
                            let storeItem = instantiate(this.storeItemPrefab);
                            this.itemsScrollView.content.addChild(storeItem);
                            storeItem.getComponent(VC_StoreItemComponent).init(itemsData.items[i]);
                        }
                    });
            });
        }
    }
    

    Example of the script’s work result:

    Display of virtual currency balance

    This tutorial shows how to use the SDK methods to display the balance of virtual currency in your app.

    Create widget for display of balance

    1. Create a prefab. To do this, select Create > Node Prefab from the context menu of the folder.
    2. Open the created prefab.
    3. Add a UITransform component to the root of the prefab as shown in the image below and set the content size.

    1. Add the following UI elements as prefab child objects and configure their visuals:
      • widget background image
      • currency name
      • currency quantity
      • currency image

    Example of the widget structure:

    Create widget script to show balance

    1. Create a CurrencyBalanceItemComponent and add the following properties:
      • iconSprite
      • currencyNameLabel
      • quantityLabel

    1. Add an init method and initialization logic to the CurrencyBalanceItemComponent class as shown in the script example.
    2. Attach the CurrencyBalanceItemComponent component to the root node of the prefab.
    3. Bind the prefab elements to the properties of the CurrencyBalanceItemComponent as shown in the picture:

    Example of a widget script (CurrencyBalanceItemComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, assetManager, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
    import { VirtualCurrencyBalance } from 'db://xsolla-commerce-sdk/scripts/api/XsollaInventory';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('CurrencyBalanceItemComponent')
    export class CurrencyBalanceItemComponent extends Component {
    
        @property(Sprite)
        iconSprite: Sprite;
    
        @property(Label)
        currencyNameLabel: Label;
    
        @property(Label)
        quantityLabel: Label;
    
        init(data: VirtualCurrencyBalance) {
    
            this.currencyNameLabel.string = data.name;
            this.quantityLabel.string = data.amount.toString();
    
            assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
                if(err == null) {
                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                this.iconSprite.spriteFrame = spriteFrame;
                } else {
                    console.log(`Can’t load image with URL ${data.image_url}`);
                }
            });
        }
    }
    

    Create page interface

    Create a scene for a virtual currency balance page and add the ScrollView element to it.

    Example of a page structure:

    To make the ScrollView match the created CurrencyBalanceItem prefab, set up its size:

    1. Change the value of the ContentSize parameter in the ScrollView node and the inner view node.
    2. Bind the Layout component to the content node and set it up. In the example, the following settings are selected:
      • Type == vertical
      • ResizeMode == Container

    Create currency balance script component

    1. Create a CurrencyBalanceComponent and add the following properties:
      • itemsScrollView
      • currencyBalanceItemPrefab

    1. Add the start life cycle function and initialization logic to the CurrencyBalanceComponent class as shown in the script example.
    2. Add the CurrencyBalanceComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
    3. Bind the prefab elements to the properties of the CurrencyBalanceItemComponent as shown in the picture:
    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla). This account is only available for the demo project.
    Example of a class script (CurrencyBalanceComponent):
    Copy
    Full screen
    Small screen
    import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
    import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
    import { XsollaInventory } from 'db://xsolla-commerce-sdk/scripts/api/XsollaInventory';
    import { CurrencyBalanceItemComponent } from './CurrencyBalanceItemComponent';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('CurrencyBalanceComponent')
    export class CurrencyBalanceComponent extends Component {
    
        @property(ScrollView)
        itemsList: ScrollView;
    
        @property(Prefab)
        currencyBalanceItemPrefab: Prefab;
    
        start() {
            XsollaAuth.authByUsernameAndPassword('xsolla', 'xsolla', false, token => {
                XsollaInventory.getVirtualCurrencyBalance(token.access_token, null, itemsData => {
                    for (let i = 0; i < itemsData.items.length; ++i) {
                            let currencyBalanceItem = instantiate(this.currencyBalanceItemPrefab);
                            this.itemsList.content.addChild(currencyBalanceItem);
                                 currencyBalanceItem.getComponent(CurrencyBalanceItemComponent).init(itemsData.items[i]);
                        }
                    });
            });
    
        }
    }
    

    Example of the script’s work result:

    Display of items in inventory

    This tutorial shows how to use the SDK methods to display items in the user inventory.

    Create item widget

    1. Create a prefab. To do this, select Create > Node Prefab from the context menu of the folder.
    2. Open the created prefab.
    3. Add a UITransform component to the root of the prefab as shown in the image below and set the content size.

    1. Add the following UI elements as prefab child objects and configure their visuals:
      • widget background image
      • inventory item name
      • inventory item description
      • item quantity
      • item image

    Example of the widget structure:

    Create item widget script

    1. Create an InventoryItemComponent and add the following properties:
      • iconSprite
      • itemNameLabel
      • itemDescriptionLabel
      • quantityLabel

    1. Add an init method and initialization logic to the InventoryItemComponent class as shown in the script example.
    2. Attach the InventoryItemComponent component to the root node of the prefab.
    3. Bind the prefab elements to the properties of the InventoryItemComponent as shown in the picture:

    Example of a widget script (InventoryItemComponent):

    Copy
    Full screen
    Small screen
    import { _decorator, assetManager, Component, ImageAsset, Label, Sprite, SpriteFrame, Texture2D } from 'cc';
    import { InventoryItem } from 'db://xsolla-commerce-sdk/scripts/api/XsollaInventory';
    const { ccclass, property } = _decorator;
    
    @ccclass('InventoryItemComponent')
    export class InventoryItemComponent extends Component {
    
        @property(Sprite)
        iconSprite: Sprite;
    
        @property(Label)
        itemNameLabel: Label;
    
        @property(Label)
        itemDescriptionLabel: Label;
    
        @property(Label)
        quantityLabel: Label;
    
        init(data: InventoryItem) {
    
            this.itemNameLabel.string = data.name;
            this.itemDescriptionLabel.string = data.description;
            this.quantityLabel.string = data.quantity.toString();
    
            assetManager.loadRemote<ImageAsset>(data.image_url, (err, imageAsset) => {
                if(err == null) {
                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                this.iconSprite.spriteFrame = spriteFrame;
                } else {
                    console.log(`Can’t load image with URL ${data.image_url}`);
                }
            });
        }
    }
    

    Create page interface

    Create a scene for an inventory page and add the ScrollView element to it.

    Example of a page structure:

    To make the ScrollView match the created InventoryItem prefab, set up its size:

    1. Change the value of the ContentSize parameter in the ScrollView node and the inner view node.
    2. Bind the Layout component to the content node and set it up. In the example, the following settings are selected:
      • Type == vertical
      • ResizeMode == Container

    Create inventory page script component

    1. Create a InventoryItemsComponent and add the following properties:
      • itemsScrollView
      • inventoryItemPrefab

    1. Add the start life cycle function and initialization logic to the InventoryItemsComponent as shown in the script example.
    2. Add the InventoryItemsComponent to the node on the scene. You can add a new node or use an existing node with the XsollaSettingsManager component that you added during SDK initialization.
    3. Bind the prefab elements to the properties of the InventoryItemsComponent as shown in the picture:
    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla). This account is only available for the demo project.
    Example of a class script (InventoryItemsComponent):
    Copy
    Full screen
    Small screen
    import { _decorator, Component, instantiate, Prefab, ScrollView } from 'cc';
    import { XsollaAuth } from 'db://xsolla-commerce-sdk/scripts/api/XsollaAuth';
    import { XsollaInventory } from 'db://xsolla-commerce-sdk/scripts/api/XsollaInventory';
    import { InventoryItemComponent } from './InventoryItemComponent';
    const { ccclass, property } = _decorator;
    
    
    @ccclass('InventoryItemsComponent')
    export class InventoryItemsComponent extends Component {
    
        @property(ScrollView)
        itemsScrollView: ScrollView;
    
        @property(Prefab)
        inventoryItemPrefab: Prefab;
    
        start() {
            XsollaAuth.authByUsernameAndPassword('xsolla', 'xsolla', false, token => {
                XsollaInventory.getInventory(token.access_token, null, itemsData => {
                    for (let i = 0; i < itemsData.items.length; ++i) {
                            let inventoryItem = instantiate(this.inventoryItemPrefab);
                            this.itemsScrollView.content.addChild(inventoryItem);
                            inventoryItem.getComponent(InventoryItemComponent).init(itemsData.items[i]);
                        }
                    });
            });
    
        }
    }
    

    Example of the script’s work result:

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Last updated: January 22, 2024

    Found a typo or other text error? Select the text and press Ctrl+Enter.

    Report a problem
    We always review our content. Your feedback helps us improve it.
    Provide an email so we can follow up
    Thank you for your feedback!