Integrate SDK on application side
- Design an interface for the login system, in-game store, and other pages for your application.
- Implement in your application logic for user authentication, store display, purchase, and more using SDK methods.
<xsollaExtention>/assets/scripts/samples
directory of SDK.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.
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
- Create a RegistrationComponent and add the following properties:
usernameEditBox
emailEditBox
passwordEditBox
signUpButton
— optional. Used when binding a callback function to the button using code
- Add a method to the
RegistrationComponent
class that is called when clickingSignUpButton
, and add the logic to handle the click event, as shown in the script example. - 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. - Bind the scene elements to the properties of the
RegistrationComponent
as shown in the picture:
- 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.signUpButton.node.on(Button.EventType.CLICK, this.onSignUpClicked, this);
}
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.
- typescript
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.
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
- Create a ResendConfirmationEmailComponent and add the following properties:
usernameTextBox
resendEmailButton
— optional. Used when binding a callback function to the button using code
- Add a method to the
ResendConfirmationEmailComponent
class that is called when clickingResendEmail
, and add the logic to handle the click event, as shown in the script example. - 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. - Bind the scene elements to the properties of the
ResendConfirmationEmailComponent
as shown in the picture:
- 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
- using the
Binding callback using
Binding callback via code:
- typescript
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.
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.
- typescript
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
- Create a LoginComponent and add the following properties:
usernameEditBox
passwordEditBox
remeberMeToggle
loginButton
— optional. Used when binding a callback function to the button using code
- Add a method to the
LoginComponent
class that is called when clickingLoginButton
, and add the logic to handle the click event, as shown in the script example. - 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. - Bind the scene elements to the properties of the
LoginComponent
as shown in the picture:
- 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginClicked, this);
}
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.
- typescript
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
- Create a ResetPasswordComponent and add the following properties:
usernameEditBox
resetPasswordButton
— optional. Used when binding a callback function to the button using code
- Add a method to the
ResetPasswordComponent
class that is called when clickingResetPassword
, and add the logic to handle the click event, as shown in the script example. - 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. - Bind the scene elements to the properties of the
ResetPasswordComponent
as shown in the picture:
- 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.resetPasswordButton.node.on(Button.EventType.CLICK, this.onResetPasswordClicked, this);
}
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.
- typescript
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
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
- Create a SocialLoginComponent. To bind callback function to social login button using code, add the
socialLoginButton
property. - Add a method to the
SocialLoginComponent
class that is called when clickingSocialLogin
, and add the logic to handle the click event, as shown in the script example.
- 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. - Bind the
SocialLogin
button to thesocialLoginButton
property of theSocialLoginComponent
as shown in the picture:
- 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.socialLoginButton.node.on(Button.EventType.CLICK, this.onSocialLoginClicked, this);
}
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.
- typescript
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:
- Configure virtual items and groups of virtual items.
- Configure packages of virtual currencies.
- Configure bundles.
This tutorial describes the implementation of the following logic:
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
- Create a prefab. To do this, select
Create > Node Prefab from the context menu of the folder. - Open the created prefab.
- Add a
UITransform
component to the root of the prefab as shown in the image below and set the content size.
- 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
- Create a
StoreItemComponent
and add the following properties:iconSprite
itemNameLabel
itemDescriptionLabel
priceLabel
- Add an
init
method and initialization logic to theStoreItemComponent
class as shown in the script example. - Attach the StoreItemComponent component to the root node of the prefab.
- Bind the prefab elements to the properties of the
StoreItemComponent
as shown in the picture:
Example of a widget script (StoreItemComponent):
- typescript
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:
- Change the value of the
ContentSize
parameter in theScrollView
node and the innerview
node. - Bind the
Layout
component to thecontent
node and set it up. In the example, the following settings are selected:Type == vertical
ResizeMode == Container
Create items catalog script component
- Create a ItemsCatalogComponent and add the following properties:
itemsScrollView
storeItemPrefab
- Add the
start life cycle function and initialization logic to theItemsCatalogComponent
class as shown in the script example. - 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. - Bind the prefab elements to the properties of the
ItemsCatalogComponent
as shown in the picture:
Example of a class script (ItemsCatalogComponent):
- typescript
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
- Create a prefab. To do this, select
Create > Node Prefab from the context menu of the folder. - Open the created prefab.
- Add a
UITransform
component to the root of the prefab as shown in the image below and set the content size.
- 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
- Create a BundleItemComponent and add the following properties:
iconSprite
bundleNameLabel
bundleDescriptionLabel
priceLabel
contentDescriptionlabel
- Add an
init
method and initialization logic to theBundleItemComponent
class as shown in the script example. - Attach the BundleItemComponent to the root node of the prefab.
- Bind the prefab elements to the properties of the
BundleItemComponent
as shown in the picture:
Example of a widget script (BundleItemComponent):
- typescript
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:
- Change the value of the
ContentSize
parameter in theScrollView
node and the innerview
node. - Bind the
Layout
component to thecontent
node and set it up. In the example, the following settings are selected:Type == vertical
ResizeMode == Container
Create bundles catalog script component
- Create a BundlesCatalogComponent and add the following properties:
itemsScrollView
bundleItemPrefab
- Add the
start life cycle function and initialization logic to theBundlesCatalogComponent
class as shown in the script example. - 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. - Bind the prefab elements to the properties of the
BundlesCatalogComponent
as shown in the picture:
Example of a class script (BundlesCatalogComponent):
- typescript
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
- Create a prefab. To do this, select
Create > Node Prefab from the context menu of the folder. - Open the created prefab.
- Add a
UITransform
component to the root of the prefab as shown in the image below and set the content size.
- 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
- Create a CurrencyPackageItemComponent and add the following properties:
iconSprite
currencyNameLabel
currencyDescriptionLabel
priceLabel
- Add an
init
method and initialization logic to theCurrencyPackageItemComponent
class as shown in the script example. - Attach the CurrencyPackageItemComponent component to the root node of the prefab.
- Bind the prefab elements to the properties of the
CurrencyPackageItemComponent
as shown in the picture:
Example of a widget script (CurrencyPackageItemComponent):
- typescript
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:
- Change the value of the
ContentSize
parameter in theScrollView
node and the innerview
node. - Bind the
Layout
component to thecontent
node and set it up. In the example, the following settings are selected:Type == vertical
ResizeMode == Container
Create currency packages catalog script component
- Create a
CurrencyPackagesCatalogComponent
and add the following properties:itemsScrollView
currencyPackageItemPrefab
- Add the
start life cycle function and initialization logic to theCurrencyPackagesCatalogComponent
class as shown in the script example. - 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. - Bind the prefab elements to the properties of the
CurrencyPackagesCatalogComponent
as shown in the picture:
Example of a class script (CurrencyPackagesCatalogComponent):
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:
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.RC_StoreItemComponent
.Complete item widget script
- To bind a callback function to buy button using code, add the
buyButton
property to theRC_StoreItemComponent
. - Add a method to the
RC_StoreItemComponent
class that is called when clickingBuyButton
, and add the logic to handle the click event, as shown in the script example. - 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
}
Example of a widget script (RC_StoreItemComponent):
- typescript
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
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):
- typescript
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:
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.VC_StoreItemComponent
.Complete item widget script
- To bind a callback function to buy button using code, add the
buyButton
property to theVC_StoreItemComponent
. - Add a method to the
VC_StoreItemComponent
class that is called when clickingBuyButton
, and add the logic to handle the click event, as shown in the script example. - 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
- using the
Binding callback using
Binding callback via code:
- typescript
start() {
this.buyButton.node.on(Button.EventType.CLICK, this.onBuyClicked, this);
}
Example of a widget script (VC_StoreItemComponent):
- typescript
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
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):
- typescript
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
- Create a prefab. To do this, select
Create > Node Prefab from the context menu of the folder. - Open the created prefab.
- Add a
UITransform
component to the root of the prefab as shown in the image below and set the content size.
- 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
- Create a CurrencyBalanceItemComponent and add the following properties:
iconSprite
currencyNameLabel
quantityLabel
- Add an
init
method and initialization logic to theCurrencyBalanceItemComponent
class as shown in the script example. - Attach the CurrencyBalanceItemComponent component to the root node of the prefab.
- Bind the prefab elements to the properties of the
CurrencyBalanceItemComponent
as shown in the picture:
Example of a widget script (CurrencyBalanceItemComponent):
- typescript
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:
- Change the value of the
ContentSize
parameter in theScrollView
node and the innerview
node. - Bind the
Layout
component to thecontent
node and set it up. In the example, the following settings are selected:Type == vertical
ResizeMode == Container
Create currency balance script component
- Create a CurrencyBalanceComponent and add the following properties:
itemsScrollView
currencyBalanceItemPrefab
- Add the
start life cycle function and initialization logic to theCurrencyBalanceComponent
class as shown in the script example. - Add the
CurrencyBalanceComponent to the node on the scene. You can add a new node or use an existing node with theXsollaSettingsManager
component that you added during SDK initialization. - Bind the prefab elements to the properties of the
CurrencyBalanceItemComponent
as shown in the picture:
xsolla
, password: xsolla
). This account is only available for the demo project.- typescript
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
- Create a prefab. To do this, select
Create > Node Prefab from the context menu of the folder. - Open the created prefab.
- Add a
UITransform
component to the root of the prefab as shown in the image below and set the content size.
- 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
- Create an InventoryItemComponent and add the following properties:
iconSprite
itemNameLabel
itemDescriptionLabel
quantityLabel
- Add an
init
method and initialization logic to theInventoryItemComponent
class as shown in the script example. - Attach the InventoryItemComponent component to the root node of the prefab.
- Bind the prefab elements to the properties of the
InventoryItemComponent
as shown in the picture:
Example of a widget script (InventoryItemComponent):
- typescript
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:
- Change the value of the
ContentSize
parameter in theScrollView
node and the innerview
node. - Bind the
Layout
component to thecontent
node and set it up. In the example, the following settings are selected:Type == vertical
ResizeMode == Container
Create inventory page script component
- Create a InventoryItemsComponent and add the following properties:
itemsScrollView
inventoryItemPrefab
- Add the
start life cycle function and initialization logic to theInventoryItemsComponent
as shown in the script example. - 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. - Bind the prefab elements to the properties of the
InventoryItemsComponent
as shown in the picture:
xsolla
, password: xsolla
). This account is only available for the demo project.- typescript
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:
Found a typo or other text error? Select the text and press Ctrl+Enter.